Index: /osgVisual/trunk/AUTHORS.txt
===================================================================
--- /osgVisual/trunk/AUTHORS.txt	(revision 176)
+++ /osgVisual/trunk/AUTHORS.txt	(revision 176)
@@ -0,0 +1,10 @@
+osgVisual 0.5
+
+Project lead: Torben Dannhauer
+
+2 Contributors:
+
+Firstname Surname
+----------------
+Dannhauer Torben
+Heise Marius
Index: /osgVisual/trunk/CMakeLists.txt
===================================================================
--- /osgVisual/trunk/CMakeLists.txt	(revision 176)
+++ /osgVisual/trunk/CMakeLists.txt	(revision 176)
@@ -0,0 +1,424 @@
+#################################################################################################
+# This file allows to configure osgVisual with CMAKE to generate native build solutions.		#
+#																								#
+# Specify the following environment variables to use osgVisual and this CMAKE script:			#
+#	* OSG_ROOT: Path to your 32 bit (x86) OSG, e.g. D:\OSG\OpenSceneGraph-2.9.8_x86				# 
+#	* OSG_ROOT_X64: Path to your 64 bit (x64) OSG, e.g. D:\OSG\OpenSceneGraph-2.9.8_x64			#
+#	* OSG: Path to your 32 bit (x86) OSG and 3rdParty binary folder,							#
+#		 e.g. %OSG_ROOT%\bin;D:\OSG\3rdParty\bin\x86											#
+#	* OSG_X64: Path to your 64 bit (x64) OSG and 3rdParty binary folder,						#
+#		 e.g. %OSG_ROOT_X64%\bin;D:\OSG\3rdParty\bin\x64										#
+#	* PATH: Extend with %OSG% or %OSG_X64% to use OSG and osgVisual from command line,			#
+#		 e.g. PATH=%PATH%;%OSG%																	#
+#																								#
+#	NOTE:	On Visual Studio and x64 Arch, CMAKE uses the project settings to specify the		#
+#			correct x64 OSG path, so you can use osg as 32 bit in your system path.				#
+#																								#
+#																								#
+#################################################################################################
+
+cmake_minimum_required(VERSION 2.8)
+
+
+PROJECT(osgVisual)
+#SET(CMAKE_MODULE_PATH "${osgVisual_SOURCE_DIR}/../CMakeModules;${CMAKE_MODULE_PATH}")
+
+# Check Architecture
+IF( CMAKE_SIZEOF_VOID_P EQUAL 4 )
+    MESSAGE( STATUS "32 bit architecture detected" )
+    SET(DESTINATION_ARCH "x86")
+ENDIF()
+IF( CMAKE_SIZEOF_VOID_P EQUAL 8 )
+    MESSAGE( STATUS "64 bit architecture detected" )
+    SET(DESTINATION_ARCH "x64")
+ENDIF()
+
+
+# Get required packages
+IF(DESTINATION_ARCH STREQUAL "x64")
+	SET(OSG_ROOT_BKP $ENV{OSG_ROOT})	# BACKUP old OSG_ROOT
+	SET(ENV{OSG_ROOT} $ENV{OSG_ROOT_X64})	# Replace OSGROOT with OSG_ROOT_X64 to force CMAKE to find the correct OSG version (64 bit)
+ENDIF ()
+
+SET(OpenSceneGraph_MARK_AS_ADVANCED ON)
+FIND_PACKAGE(OpenSceneGraph 2.9.9 REQUIRED osgViewer OpenThreads osgDB osgTerrain osgGA osgText osgSim osgUtil)
+FIND_PACKAGE(OpenGL REQUIRED)
+
+
+IF(DESTINATION_ARCH STREQUAL "x64")
+	SET(ENV{OSG_ROOT} ${OSG_ROOT_BKP})	# Restore old OSG_ROOT
+	UNSET(OSG_ROOT_BKP)					# Delete backup
+ENDIF ()
+
+# LIBXML2
+SET(LIBXML2_LIBRARY ../../OpenSceneGraph/3rdParty_x86_x64/${DESTINATION_ARCH}/lib/libxml2 CACHE FILEPATH "Select the libxml2 library to link osgVisual against. REQUIRED!" )
+SET(LIBXML2_INCLUDE ../../OpenSceneGraph/3rdParty_x86_x64/${DESTINATION_ARCH}/include CACHE PATH "Select the libxml2 include path to link osgVisual against. REQUIRED!" )
+INCLUDE_DIRECTORIES( ${LIBXML2_INCLUDE} )	
+
+# Module sky-silverlining
+# OPTION( OPTION_VAR "description string" [initial value] )
+IF ( WIN32 )
+	
+	SET(USE_SKY_SILVERLINING ON CACHE BOOL "Enable to use Sundog-soft's Silverlining SDK for sky & weather")
+	IF(USE_SKY_SILVERLINING )
+		SET(SOURCES
+			${SOURCES}
+			include/sky_Silverlining/skySilverLining_AtmosphereReference.h
+			include/sky_Silverlining/skySilverLining_cloudLayerSlot.h
+			include/sky_Silverlining/skySilverLining_cloudsDrawable.h
+			include/sky_Silverlining/skySilverLining_ProjectionMatrixCallback.h
+			include/sky_Silverlining/skySilverLining_skyDrawable.h
+			include/sky_Silverlining/visual_skySilverLining.h
+			src/sky_Silverlining/skySilverLining_cloudsDrawable.cpp
+			src/sky_Silverlining/skySilverLining_skyDrawable.cpp
+			src/sky_Silverlining/visual_skySilverLining.cpp			
+		)
+		
+		IF (DESTINATION_ARCH STREQUAL "x86")
+			SET(SILVERLINING_ARCH "win32")
+		ELSEIF ( DESTINATION_ARCH STREQUAL "x64" )
+			SET(SILVERLINING_ARCH "x64")
+		ENDIF ()
+		SET(SILVERLINING_LIBRARY_RELEASE $ENV{SILVERLINING_PATH}\\lib\\vc9\\${SILVERLINING_ARCH}\\SilverLining-MT-DLL.lib CACHE FILEPATH "Select the release library of Sundog-Soft's Silverlining SDK to link against." )
+		SET(SILVERLINING_LIBRARY_DEBUG $ENV{SILVERLINING_PATH}\\lib\\vc9\\${SILVERLINING_ARCH}\\SilverLining-MTD-DLL.lib CACHE FILEPATH "Select the debug library of Sundog-Soft's Silverlining SDK to link against." )
+		SET(SILVERLINING_INCLUDE_DIR "$ENV{SILVERLINING_PATH}\\Public Headers" CACHE PATH "Enter the path to the the public Include directory of Sundog-Soft's Silverlining SDK" )
+		SET(SILVERLINING_LICENSEE "Your user name" CACHE STRING "Enter your Silverlining licensee name. If you license available, osgVisual will work with silverlining as 5 minute demo with the default value." )
+		SET(SILVERLINING_LICENSE "Your license code" CACHE STRING "Enter your Silverlining license key. If you license available, osgVisual will work with silverlining as 5 minute demo with the default value." )
+		INCLUDE_DIRECTORIES(${SILVERLINING_INCLUDE_DIR} include/sky_Silverlining)
+		ADD_DEFINITIONS( "-DUSE_SKY_SILVERLINING" )
+		ADD_DEFINITIONS( "-DSILVERLINING_LICENSEE=\"${SILVERLINING_LICENSEE}\"" )
+		ADD_DEFINITIONS( "-DSILVERLINING_LICENSE=\"${SILVERLINING_LICENSE}\"" )
+		
+	ELSE(USE_SKY_SILVERLINING)
+		UNSET(SILVERLINING_LIBRARY_RELEASE CACHE)
+		UNSET(SILVERLINING_LIBRARY_DEBUG CACHE)
+		UNSET(SILVERLINING_INCLUDE_DIR CACHE)
+		UNSET(SILVERLINING_LICENSEE)
+		UNSET(SILVERLINING_LICENSE)
+	ENDIF(USE_SKY_SILVERLINING)
+ENDIF(WIN32)
+IF(UNIX)
+	SET(USE_SKY_SILVERLINING ON CACHE BOOL "Enable to use Sundog-soft's Silverlining SDK for sky & weather")
+	IF(USE_SKY_SILVERLINING )
+		SET(SOURCES
+			${SOURCES}
+			include/sky_Silverlining/skySilverLining_AtmosphereReference.h
+			include/sky_Silverlining/skySilverLining_cloudLayerSlot.h
+			include/sky_Silverlining/skySilverLining_cloudsDrawable.h
+			include/sky_Silverlining/skySilverLining_ProjectionMatrixCallback.h
+			include/sky_Silverlining/skySilverLining_skyDrawable.h
+			include/sky_Silverlining/visual_skySilverLining.h
+			src/sky_Silverlining/skySilverLining_cloudsDrawable.cpp
+			src/sky_Silverlining/skySilverLining_skyDrawable.cpp
+			src/sky_Silverlining/visual_skySilverLining.cpp			
+		)
+		
+		IF (DESTINATION_ARCH STREQUAL "x86")
+			SET(SILVERLINING_ARCH "win32")
+		ELSEIF ( DESTINATION_ARCH STREQUAL "x64" )
+			SET(SILVERLINING_ARCH "x64")
+		ENDIF ()
+		SET(SILVERLINING_LIBRARY_RELEASE $ENV{SILVERLINING_PATH}\\lib\\vc9\\${SILVERLINING_ARCH}\\SilverLining-MT-DLL.lib CACHE FILEPATH "Select the release library of Sundog-Soft's Silverlining SDK to link against." )
+		SET(SILVERLINING_LIBRARY_DEBUG $ENV{SILVERLINING_PATH}\\lib\\vc9\\${SILVERLINING_ARCH}\\SilverLining-MTD-DLL.lib CACHE FILEPATH "Select the debug library of Sundog-Soft's Silverlining SDK to link against." )
+		SET(SILVERLINING_INCLUDE_DIR "$ENV{SILVERLINING_PATH}\\Public Headers" CACHE PATH "Enter the path to the the public Include directory of Sundog-Soft's Silverlining SDK" )
+		SET(SILVERLINING_LICENSEE "Your user name" CACHE STRING "Enter your Silverlining licensee name. If you license available, osgVisual will work with silverlining as 5 minute demo with the default value." )
+		SET(SILVERLINING_LICENSE "Your license code" CACHE STRING "Enter your Silverlining license key. If you license available, osgVisual will work with silverlining as 5 minute demo with the default value." )
+		INCLUDE_DIRECTORIES(${SILVERLINING_INCLUDE_DIR} "include/sky_Silverlining" )
+		ADD_DEFINITIONS( "-DUSE_SKY_SILVERLINING" )
+		ADD_DEFINITIONS( "-DSILVERLINING_LICENSEE=\"${SILVERLINING_LICENSEE}\"" )
+		ADD_DEFINITIONS( "-DSILVERLINING_LICENSE=\"${SILVERLINING_LICENSE}\"" )
+		
+	ELSE(USE_SKY_SILVERLINING)
+		UNSET(SILVERLINING_LIBRARY_RELEASE CACHE)
+		UNSET(SILVERLINING_LIBRARY_DEBUG CACHE)
+		UNSET(SILVERLINING_INCLUDE_DIR CACHE)
+		UNSET(SILVERLINING_LICENSEE)
+		UNSET(SILVERLINING_LICENSE)
+	ENDIF(USE_SKY_SILVERLINING)
+ENDIF()
+
+# Module distortion
+SET(USE_DISTORTION OFF CACHE BOOL "Enable to use distortion with Projection Designer's distortion maps")
+IF(USE_DISTORTION)
+	SET(SOURCES
+		${SOURCES}
+		include/distortion/visual_distortion.h
+		src/distortion/visual_distortion.cpp
+	)
+	INCLUDE_DIRECTORIES(include/distortion)
+	ADD_DEFINITIONS( "-DUSE_DISTORTION" )
+ENDIF(USE_DISTORTION)
+
+
+# Module Vista2D - Only available under Win32
+if( WIN32 )
+	SET(USE_VISTA2D OFF CACHE BOOL "Enable to use Vista2D by Wetzel Technology")
+	IF( USE_VISTA2D )
+		INCLUDE_DIRECTORIES( include/vista2D )
+		SET(SOURCES
+			${SOURCES}
+			include/vista2D/visual_vista2D.h
+			src/vista2D/visual_vista2D.cpp	
+		)
+		SET(VISTA2D_INCLUDE_DIR . CACHE PATH "Select the INCLUDE directory path for Vista2D by Wetzel Technology." )
+		SET(VISTA2D_LIBRARY_DEBUG . CACHE FILEPATH "Select debug LIBRARY path for linking against Vista2D by Wetzel Technology." )
+		SET(VISTA2D_LIBRARY_RELEASE . CACHE FILEPATH "Select release LIBRARY path for linking against Vista2D by Wetzel Technology." )
+		INCLUDE_DIRECTORIES(${VISTA2D_INCLUDE_DIR})
+		ADD_DEFINITIONS( "-DUSE_VISTA2D" )
+	ELSE(USE_VISTA2D)
+		UNSET(VISTA2D_INCLUDE_DIR CACHE)
+		UNSET(VISTA2D_LIBRARY_DEBUG CACHE)
+		UNSET(VISTA2D_LIBRARY_RELEASE CACHE)
+	ENDIF(USE_VISTA2D)
+ENDIF(WIN32)
+
+
+# Module Spacenavigator manipulator - ONLY under WIN32
+if( WIN32 )
+	# No header or linking required, because WIN32 COM interface used.
+	SET(USE_SPACEMOUSE ON CACHE BOOL "Enable to use camera manipulator based on Spacenavigator by 3DConnexion")
+	IF( USE_SPACEMOUSE )
+		SET(SOURCES
+			${SOURCES}
+			include/manip_Spacemouse/manip_spaceMouse.h
+			include/manip_Spacemouse/manip_freeSpaceMouse.h
+			include/manip_Spacemouse/manip_nodeTrackerSpaceMouse.h
+			src/manip_Spacemouse/manip_spaceMouse.cpp
+			src/manip_Spacemouse/manip_freeSpaceMouse.cpp
+			src/manip_Spacemouse/manip_nodeTrackerSpaceMouse.cpp
+		)
+		INCLUDE_DIRECTORIES(include/manip_Spacemouse)
+		ADD_DEFINITIONS( "-DUSE_SPACENAVIGATOR" )
+	ENDIF(USE_SPACEMOUSE)
+ENDIF(WIN32)
+
+
+# Module cluster
+SET(USE_CLUSTER_ASIO_TCP_IOSTREAM OFF CACHE BOOL "Enable to use the Boost ASIO TCP iostream implementation for the cluster interface")
+SET(USE_CLUSTER_ENET ON CACHE BOOL "Enable to use the ENet reliable UDP library implementation for the cluster interface")
+IF( USE_CLUSTER_ASIO_TCP_IOSTREAM )
+		SET(SOURCES
+			${SOURCES}
+			include/cluster/dataIO_cluster.h
+			include/cluster/dataIO_clusterAsioTcpIostream.h
+			src/cluster/dataIO_clusterAsioTcpIostream.cpp
+		)
+		ADD_DEFINITIONS( "-DUSE_CLUSTER_ASIO_TCP_IOSTREAM" )
+		ADD_DEFINITIONS( "-D_WIN32_WINNT=0x0501" )
+		SET(BOOST_LIBRARY_PATH "../../3rdParty_x86_x64/lib/${DESTINATION_ARCH}/" CACHE PATH "Select the library folder of Boost libraries to link against." )
+		SET(BOOST_INCLUDE_DIR "../../3rdParty_x86_x64/include/boost-1.43.0/" CACHE PATH "Enter the path to the the include directory of Boost" )
+		INCLUDE_DIRECTORIES(${BOOST_INCLUDE_DIR})
+		LINK_DIRECTORIES(${BOOST_LIBRARY_PATH})
+ELSE()
+		UNSET(BOOST_LIBRARY_PATH CACHE)
+		UNSET(BOOST_ASIO_INCLUDE_DIR CACHE)	
+ENDIF()
+
+IF( USE_CLUSTER_ENET )
+		SET(SOURCES
+			${SOURCES}
+			include/cluster/dataIO_cluster.h
+			include/cluster/dataIO_clusterENet.h
+			src/cluster/dataIO_clusterENet.cpp
+			include/cluster/dataIO_clusterENet_implementation.h
+			src/cluster/dataIO_clusterENet_implementation.cpp
+			src/cluster/enet/callbacks.c
+			src/cluster/enet/compress.c
+			src/cluster/enet/host.c
+			src/cluster/enet/list.c
+			src/cluster/enet/packet.c
+			src/cluster/enet/peer.c
+			src/cluster/enet/protocol.c
+			src/cluster/enet/unix.c
+			src/cluster/enet/win32.c
+			include/cluster/enet/callbacks.h
+			include/cluster/enet/enet.h
+			include/cluster/enet/list.h
+			include/cluster/enet/protocol.h
+			include/cluster/enet/time.h
+			include/cluster/enet/types.h
+			include/cluster/enet/unix.h
+			include/cluster/enet/utility.h
+			include/cluster/enet/win32.h
+		)
+		ADD_DEFINITIONS( "-DUSE_CLUSTER_ENET" )
+		
+ENDIF()
+
+IF(NOT USE_CLUSTER_ASIO_TCP_IOSTREAM AND NOT USE_CLUSTER_ENET)
+		SET(SOURCES
+			${SOURCES}
+			include/cluster/dataIO_cluster.h
+			include/cluster/dataIO_clusterDummy.h
+			src/cluster/dataIO_clusterDummy.cpp
+		)
+		ADD_DEFINITIONS( "-DUSE_CLUSTER_DUMMY" )
+ENDIF()
+
+
+# Module extLink
+SET(SOURCES
+	${SOURCES}
+	include/extLink/dataIO_extLink.h
+	include/extLink/manip_extLink.h
+	src/extLink/manip_extLink.cpp
+)
+IF ( WIN32 )
+	SET(USE_EXTLINK_VCL ON CACHE BOOL "Enable to use the VCL Implementation for the externalLink interface")
+	IF( USE_EXTLINK_VCL )
+		SET(EXTLINK_VCL_INCLUDE_DIR ../VCL_1.0.3.4/source/include/VCL CACHE PATH "Select the INCLUDE directory path for extLink VCL Implementation." )
+		SET(SOURCES
+			${SOURCES}
+			include/extLink/dataIO_extLinkVCL.h
+			src/extLink/dataIO_extLinkVCL.cpp
+		)
+		INCLUDE_DIRECTORIES(${EXTLINK_VCL_INCLUDE_DIR})
+		ADD_DEFINITIONS( "-DUSE_EXTLINK_VCL" )
+		#Linking: VCL uses #pragma to link, no need for linking configuration in CMAKE
+	ELSE(USE_EXTLINK_VCL)
+		SET(SOURCES
+			${SOURCES}
+			include/extLink/dataIO_extLinkDummy.h
+			src/extLink/dataIO_extLinkDummy.cpp
+		)
+		UNSET(EXTLINK_VCL_INCLUDE_DIR CACHE)
+		ADD_DEFINITIONS( "-DUSE_EXTLINK_DUMMY" )
+	ENDIF(USE_EXTLINK_VCL)
+ELSE(WIN32)
+	UNSET(EXTLINK_VCL_INCLUDE_DIR CACHE)
+	SET(SOURCES
+		${SOURCES}
+		include/extLink/dataIO_extLinkDummy.h
+		src/extLink/dataIO_extLinkDummy.cpp
+	)
+	ADD_DEFINITIONS( "-DUSE_EXTLINK_DUMMY" )
+ENDIF(WIN32)
+
+
+
+# Set core sources
+SET(SOURCES
+	${SOURCES}
+	# Core
+	include/core/visual_core.h
+	src/core/visual_core.cpp
+	src/core/osgVisual.cpp
+	# Memory Leak debugging
+	include/core/leakDetection.h
+	# Util
+	include/util/visual_util.h
+	src/util/visual_util.cpp
+	# Draw 2D
+	include/draw2D/visual_draw2D.h
+	src/draw2D/visual_draw2D.cpp
+	# Debug HUD
+	include/draw2D/visual_debug_hud.h
+	src/draw2D/visual_debug_hud.cpp
+	# Example HUD
+	include/draw2D/visual_hud.h
+	src/draw2D/visual_hud.cpp
+	# Draw 3D
+	include/draw3D/visual_draw3D.h
+	src/draw3D/visual_draw3D.cpp
+	# Object Mounted Manipulator
+	include/manip_ObjectMounted/manip_objectMounted.h
+	src/manip_ObjectMounted/manip_objectMounted.cpp
+	# Objects
+	include/object/visual_object.h
+	include/object/object_updater.h
+	src/object/visual_object.cpp
+	src/object/object_updater.cpp
+	# DataIO
+	include/dataIO/visual_dataIO.h
+	include/dataIO/dataIO_transportContainer.h
+	include/dataIO/dataIO_slot.h
+	include/dataIO/dataIO_executer.h
+	src/dataIO/visual_dataIO.cpp
+	src/dataIO/dataIO_transportContainer.cpp
+	src/dataIO/dataIO_slot.cpp
+	src/dataIO/dataIO_executer.cpp
+)
+
+INCLUDE_DIRECTORIES(include/core include/util include/draw2D include/draw3D include/object include/manip_ObjectMounted)
+INCLUDE_DIRECTORIES(include/dataIO include/cluster include/extLink ${OPENSCENEGRAPH_INCLUDE_DIRS} .)
+
+
+# Executable Output 
+SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
+ADD_EXECUTABLE(osgVisual ${SOURCES})
+
+
+# Linking
+TARGET_LINK_LIBRARIES(osgVisual ${OPENSCENEGRAPH_LIBRARIES} ${OPENGL_LIBRARIES} ${LIBXML2_LIBRARY})
+
+
+IF(USE_SKY_SILVERLINING )
+	IF(WIN32)
+		TARGET_LINK_LIBRARIES(osgVisual "winmm.lib")
+	ENDIF(WIN32)
+	TARGET_LINK_LIBRARIES(osgVisual debug ${SILVERLINING_LIBRARY_DEBUG} optimized ${SILVERLINING_LIBRARY_RELEASE})
+ENDIF(USE_SKY_SILVERLINING)
+		
+IF(USE_VISTA2D)
+	TARGET_LINK_LIBRARIES(osgVisual  debug ${VISTA2D_LIBRARY_DEBUG} optimized ${VISTA2D_LIBRARY_RELEASE})
+ENDIF(USE_VISTA2D)
+
+IF(USE_CLUSTER_ENET AND WIN32)
+	TARGET_LINK_LIBRARIES(osgVisual "winmm.lib" "ws2_32.lib" )
+ENDIF(USE_CLUSTER_ENET AND WIN32)
+
+# CMAKE Fix for VS to not prepend build type to path.
+IF(MSVC)
+	SET_TARGET_PROPERTIES(osgVisual PROPERTIES PREFIX "../") 
+ENDIF(MSVC)
+SET_TARGET_PROPERTIES( osgVisual PROPERTIES DEBUG_POSTFIX d )
+
+# Adding definitions to disable multicore compiling
+IF(MSVC)
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP1")
+ENDIF(MSVC)
+
+# Generating vcproj file, if MSVC to preset debugging parameter	 - based on http://stackoverflow.com/questions/1005901/how-to-set-path-environment-variable-using-cmake-and-visual-studio-to-run-test
+IF (MSVC)
+    # Set up a default .user file that contains the debugging setup
+    ## Find user and system name
+	SET(SYSTEM_NAME $ENV{USERDOMAIN} CACHE STRING "Build System Name")
+	SET(USER_NAME $ENV{USERNAME} CACHE STRING "Build System UserName")
+	SET(USERFILE_COMMAND_DEBUG "$(TargetPath)" CACHE STRING "Command to execute on debugging (VS Project settings)" )
+	SET(USERFILE_WORKING_DIRECTORY_DEBUG "bin" CACHE STRING "Working directory on debugging (VS Project settings)" )
+	SET(USERFILE_COMMAND_ARGUMENTS_DEBUG " --window 100 100 800 600 D:/OpenSceneGraph/VPB-Testdatensatz/DB_Small/database.ive -p salzburg.path --config osgVisualConfig.xml" CACHE STRING "Command arguments (VS Project settings)" )
+	SET(USERFILE_REMOTE_MACHINE_DEBUG ${USER_NAME} CACHE STRING "Remote Debugging Machine (VS Project settings)")
+	IF (DESTINATION_ARCH STREQUAL "x64")
+		SET(USERFILE_ENVIRONMENT "PATH=%OSG_X64%;%PATH%" CACHE STRING "Environment Variables that VS should merge on thy fly with system environment to run osgVisual (VS Project settings)")
+	ENDIF ()
+
+
+    # Only do this if one doesn't already exist
+    SET (USER_FILE ${PROJECT_NAME}.vcproj.${SYSTEM_NAME}.${USER_NAME}.user)
+    IF (NOT EXISTS "${USER_FILE}")
+        message (STATUS "Creating ${USER_FILE} with default debug settings")
+        # These are the configuration variables
+        IF (CMAKE_GENERATOR MATCHES "Win64")
+            SET (USERFILE_PLATFORM "x64")
+        ELSE ()
+            SET (USERFILE_PLATFORM "Win32")
+        ENDIF ()
+
+		# Configure the template file
+		# MSC_VER 1300: MSC 13.0, VC 7.0, VS 2002
+		# MSC_VER 1310: MSC 13.1, VC 7.1, VS 2003
+		# MSC_VER 1400: MSC 14.0, VC 8.0, VS 2005
+		# MSC_VER 1500: MSC 15.0, VC 9.0, VS 2008
+		# MSC_VER 1600: MSC ??.0, VC 10.0, VS 2010
+		IF (MSVC_VERSION EQUAL 1400)
+			CONFIGURE_FILE(VC80.vcproj.user.template ${USER_FILE} @ONLY)
+		ENDIF()
+		IF (MSVC_VERSION EQUAL 1500)
+			CONFIGURE_FILE(VC90.vcproj.user.template ${USER_FILE} @ONLY)
+		ENDIF()		
+	ELSE()
+		message (STATUS "Userfile ${USER_FILE} already exist: Skipping")
+    ENDIF()
+ENDIF()
+
+
Index: /osgVisual/trunk/ChangeLog
===================================================================
--- /osgVisual/trunk/ChangeLog	(revision 176)
+++ /osgVisual/trunk/ChangeLog	(revision 176)
@@ -0,0 +1,5 @@
+2010-04-05 20:29  torben
+
+	* Initial software version of osgVisual
+
+	  Starts with version 0.5, because osgVisual bases on protopye  applications 
Index: /osgVisual/trunk/Doxyfile
===================================================================
--- /osgVisual/trunk/Doxyfile	(revision 176)
+++ /osgVisual/trunk/Doxyfile	(revision 176)
@@ -0,0 +1,1617 @@
+# Doxyfile 1.6.3
+
+# 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
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = osgVisual
+
+# 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         = Trunk
+
+# 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       = ./doc
+
+# 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: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, 
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English 
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, 
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+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        = /Users/dimitri/doxygen/mail/1.5.7/doxywizard/
+
+# 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    = 
+
+# 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 regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# 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 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               = 8
+
+# 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
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it parses. 
+# With this tag you can assign which parser to use for a given extension. 
+# Doxygen has a built-in mapping, but you can override or extend it using this tag. 
+# The format is ext=language, where ext is a file extension, and language is one of 
+# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, 
+# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat 
+# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), 
+# use: inc=Fortran f=C. Note that for custom extensions you also need to set
+# FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# 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 you use Microsoft's C++/CLI language, you should set this option to YES to 
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter 
+# and setter methods for a property. Setting this option to YES (the default) 
+# will make doxygen to replace the get and set methods by a property in the 
+# documentation. This will only work if the methods are indeed getting or 
+# setting a simple type. If this is not the case, or you want to show the 
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# 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
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 
+# determine which symbols to keep in memory and which to flush to disk. 
+# When the cache is full, less often used symbols will be written to disk. 
+# For small to medium size projects (<1000 input files) the default value is 
+# probably good enough. For larger projects a too small cache size can cause 
+# doxygen to be busy swapping symbols to and from disk most of the time 
+# causing a significant performance penality. 
+# If the system has enough physical memory increasing the cache will improve the 
+# performance by keeping more symbols in memory. Note that the value works on 
+# a logarithmic scale so increasing the size by one will rougly double the 
+# memory usage. The cache size is given by this formula: 
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# 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        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# 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 this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES   = 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       = NO
+
+# 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 FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen 
+# will list include files with double quotes in the documentation 
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# 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        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# 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       = 
+
+# 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 NO.
+
+SHOW_DIRECTORIES       = NO
+
+# 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    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by 
+# doxygen. The layout file controls the global structure of the generated output files 
+# in an output format independent way. The create the layout file that represents 
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a 
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name 
+# of the layout file.
+
+LAYOUT_FILE            = 
+
+#---------------------------------------------------------------------------
+# 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       = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. 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            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = ./include
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# 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 *.f90
+
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.d \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.idl \
+                         *.odl \
+                         *.cs \
+                         *.php \
+                         *.php3 \
+                         *.inc \
+                         *.m \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.f90 \
+                         *.f \
+                         *.vhd \
+                         *.vhdl
+
+# 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                = include/cluster/enet/callbacks.h \
+                         include/cluster/enet/enet.h \
+                         include/cluster/enet/list.h \
+                         include/cluster/enet/protocol.h \
+                         include/cluster/enet/time.h \
+                         include/cluster/enet/types.h \
+                         include/cluster/enet/unix.h \
+                         include/cluster/enet/utility.h \
+                         include/cluster/enet/win32.h \
+                         src/cluster/enet/callbacks.c \
+                         src/cluster/enet/compress.c \
+                         src/cluster/enet/host.c \
+                         src/cluster/enet/list.c \
+                         src/cluster/enet/packet.c \
+                         src/cluster/enet/peer.c \
+                         src/cluster/enet/protocol.c \
+                         src/cluster/enet/unix.c \
+                         src/cluster/enet/win32.c
+
+# 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       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = *
+
+# 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      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  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 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) 
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from 
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will 
+# link to the source code.  Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = 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     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_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_TIMESTAMP tag is set to YES then the footer of each generated HTML 
+# page will contain the date and time when the page was generated. Setting 
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP         = YES
+
+# 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 HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup. 
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# 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 compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# 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 CHM_INDEX_ENCODING 
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file 
+# content.
+
+CHM_INDEX_ENCODING     = 
+
+# 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
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER 
+# are set, an additional index file will be generated that can be used as input for 
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated 
+# HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
+# be used to specify the file name of the resulting .qch file. 
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. 
+# For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see 
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's 
+# filter section matches. 
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
+# be used to specify the location of Qt's qhelpgenerator. 
+# If non-empty doxygen will try to run qhelpgenerator on the generated 
+# .qhp file.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files  
+# will be generated, which together with the HTML files, form an Eclipse help  
+# plugin. To install this plugin and make it available under the help contents 
+# menu in Eclipse, the contents of the directory containing the HTML and XML 
+# files needs to be copied into the plugins directory of eclipse. The name of 
+# the directory within the plugins directory should be the same as 
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin 
+# the directory name containing the HTML and XML files should also have 
+# this name.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# 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
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 
+# structure should be generated to display hierarchical information. 
+# If the tag value 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 (i.e. any modern browser). 
+# Windows users are probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, 
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES       = 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
+
+# Use this tag to change the font size of Latex formulas included 
+# as images in the HTML documentation. The default is 10. Note that 
+# when you change the font size after a successful doxygen run you need 
+# to manually remove any form_*.png images from the HTML output directory 
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript 
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should 
+# typically be disabled. For large projects the javascript based search engine 
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE           = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index 
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvances is that it is more difficult to setup 
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH    = NO
+
+#---------------------------------------------------------------------------
+# 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         = YES
+
+# 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. 
+# Note that when enabling USE_PDFLATEX this option is only used for 
+# generating bitmaps for formulas in the HTML output, but not in the 
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME         = latex
+
+# 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
+
+# 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        = NO
+
+# 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
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE      = 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        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# 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             = 
+
+# 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       = 
+
+# 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
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH            = 
+
+# 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
+
+# By default doxygen will write a font called FreeSans.ttf to the output 
+# directory and reference it in all dot files that doxygen generates. This 
+# font does not include all possible unicode characters however, so when you need 
+# these (or just want a differently looking font) you can specify the font name 
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font, 
+# which can be done by putting it in a standard location or by setting the 
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory 
+# containing the font.
+
+DOT_FONTNAME           = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the output directory to look for the 
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a 
+# different font using DOT_FONTNAME you can set the path where dot 
+# can find it using this tag.
+
+DOT_FONTPATH           = 
+
+# 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 options 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 CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller 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 caller 
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_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               = 
+
+# 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           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# 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 the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, because dot on Windows does not 
+# seem to support this out of the box. 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
Index: /osgVisual/trunk/LICENSE.txt
===================================================================
--- /osgVisual/trunk/LICENSE.txt	(revision 176)
+++ /osgVisual/trunk/LICENSE.txt	(revision 176)
@@ -0,0 +1,587 @@
+                OpenSceneGraph Public License, Version 0.0
+                ==========================================
+                
+  Copyright (C) 2002 Robert Osfield.
+  
+  Everyone is permitted to copy and distribute verbatim copies
+  of this licence document, but changing it is not allowed.
+
+                       OPENSCENEGRAPH PUBLIC LICENCE
+     TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  This library is free software; you can redistribute it and/or modify it
+  under the terms of the OpenSceneGraph Public License (OSGPL) version 0.0
+  or later.
+  
+  Notes: the OSGPL is based on the LGPL, with the 4 exceptions laid
+  out in the wxWindows section below.  The LGPL is contained in the
+  final section of this license.
+
+
+-------------------------------------------------------------------------------
+
+                wxWindows Library Licence, Version 3
+                ====================================
+
+  Copyright (C) 1998 Julian Smart, Robert Roebling [, ...]
+
+  Everyone is permitted to copy and distribute verbatim copies
+  of this licence document, but changing it is not allowed.
+
+                       WXWINDOWS LIBRARY LICENCE
+     TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  This library is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Library General Public Licence as published by
+  the Free Software Foundation; either version 2 of the Licence, 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 Library
+  General Public Licence for more details.
+
+  You should have received a copy of the GNU Library General Public Licence
+  along with this software, usually in a file named COPYING.LIB.  If not,
+  write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+  Boston, MA 02111-1307 USA.
+
+  EXCEPTION NOTICE
+
+  1. As a special exception, the copyright holders of this library give
+  permission for additional uses of the text contained in this release of
+  the library as licenced under the wxWindows Library Licence, applying
+  either version 3 of the Licence, or (at your option) any later version of
+  the Licence as published by the copyright holders of version 3 of the
+  Licence document.
+
+  2. The exception is that you may use, copy, link, modify and distribute
+  under the user's own terms, binary object code versions of works based
+  on the Library.
+
+  3. If you copy code from files distributed under the terms of the GNU
+  General Public Licence or the GNU Library General Public Licence into a
+  copy of this library, as this licence permits, the exception does not
+  apply to the code that you add in this way.  To avoid misleading anyone as
+  to the status of such modified files, you must delete this exception
+  notice from such code and/or adjust the licensing conditions notice
+  accordingly.
+
+  4. If you write modifications of your own for this library, it is your
+  choice whether to permit this exception to apply to your modifications.
+  If you do not wish that, you must delete the exception notice from such
+  code and/or adjust the licensing conditions notice accordingly.
+  
+  
+------------------------------------------------------------------------------
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 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.
+
+[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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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: /osgVisual/trunk/VC80.vcproj.user.template
===================================================================
--- /osgVisual/trunk/VC80.vcproj.user.template	(revision 176)
+++ /osgVisual/trunk/VC80.vcproj.user.template	(revision 176)
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioUserFile
+	ProjectType="Visual C++"
+	Version="8,00"
+	ShowAllFiles="false"
+	>
+	<Configurations>
+		<Configuration
+			Name="Debug|@USERFILE_PLATFORM@"
+			>
+			<DebugSettings
+				Command="@USERFILE_COMMAND_DEBUG@"
+				WorkingDirectory="@USERFILE_WORKING_DIRECTORY_DEBUG@"
+				CommandArguments="@USERFILE_COMMAND_ARGUMENTS_DEBUG@"
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="@USERFILE_REMOTE_MACHINE_DEBUG@"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment="@USERFILE_ENVIRONMENT@"
+				EnvironmentMerge="true"
+				DebuggerFlavor="0"
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|@USERFILE_PLATFORM@"
+			>
+			<DebugSettings
+				Command="@USERFILE_COMMAND_DEBUG@"
+				WorkingDirectory="@USERFILE_WORKING_DIRECTORY_DEBUG@"
+				CommandArguments="@USERFILE_COMMAND_ARGUMENTS_DEBUG@"
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="@USERFILE_REMOTE_MACHINE_DEBUG@"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment="@USERFILE_ENVIRONMENT@"
+				EnvironmentMerge="true"
+				DebuggerFlavor="0"
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="MinSizeRel|@USERFILE_PLATFORM@"
+			>
+			<DebugSettings
+				Command="@USERFILE_COMMAND_DEBUG@"
+				WorkingDirectory="@USERFILE_WORKING_DIRECTORY_DEBUG@"
+				CommandArguments="@USERFILE_COMMAND_ARGUMENTS_DEBUG@"
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="@USERFILE_REMOTE_MACHINE_DEBUG@"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment="@USERFILE_ENVIRONMENT@"
+				EnvironmentMerge="true"
+				DebuggerFlavor=""
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="RelWithDebInfo|@USERFILE_PLATFORM@"
+			>
+			<DebugSettings
+				Command="@USERFILE_COMMAND_DEBUG@"
+				WorkingDirectory="@USERFILE_WORKING_DIRECTORY_DEBUG@"
+				CommandArguments="@USERFILE_COMMAND_ARGUMENTS_DEBUG@"
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="@USERFILE_REMOTE_MACHINE_DEBUG@"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment="@USERFILE_ENVIRONMENT@"
+				EnvironmentMerge="true"
+				DebuggerFlavor=""
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+	</Configurations>
+</VisualStudioUserFile>
+
Index: /osgVisual/trunk/VC90.vcproj.user.template
===================================================================
--- /osgVisual/trunk/VC90.vcproj.user.template	(revision 176)
+++ /osgVisual/trunk/VC90.vcproj.user.template	(revision 176)
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioUserFile
+	ProjectType="Visual C++"
+	Version="9,00"
+	ShowAllFiles="false"
+	>
+	<Configurations>
+		<Configuration
+			Name="Debug|@USERFILE_PLATFORM@"
+			>
+			<DebugSettings
+				Command="@USERFILE_COMMAND_DEBUG@"
+				WorkingDirectory="@USERFILE_WORKING_DIRECTORY_DEBUG@"
+				CommandArguments="@USERFILE_COMMAND_ARGUMENTS_DEBUG@"
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="@USERFILE_REMOTE_MACHINE_DEBUG@"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment="@USERFILE_ENVIRONMENT@"
+				EnvironmentMerge="true"
+				DebuggerFlavor="0"
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|@USERFILE_PLATFORM@"
+			>
+			<DebugSettings
+				Command="@USERFILE_COMMAND_DEBUG@"
+				WorkingDirectory="@USERFILE_WORKING_DIRECTORY_DEBUG@"
+				CommandArguments="@USERFILE_COMMAND_ARGUMENTS_DEBUG@"
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="@USERFILE_REMOTE_MACHINE_DEBUG@"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment="@USERFILE_ENVIRONMENT@"
+				EnvironmentMerge="true"
+				DebuggerFlavor="0"
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="MinSizeRel|@USERFILE_PLATFORM@"
+			>
+			<DebugSettings
+				Command="@USERFILE_COMMAND_DEBUG@"
+				WorkingDirectory="@USERFILE_WORKING_DIRECTORY_DEBUG@"
+				CommandArguments="@USERFILE_COMMAND_ARGUMENTS_DEBUG@"
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="@USERFILE_REMOTE_MACHINE_DEBUG@"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment="@USERFILE_ENVIRONMENT@"
+				EnvironmentMerge="true"
+				DebuggerFlavor=""
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="RelWithDebInfo|@USERFILE_PLATFORM@"
+			>
+			<DebugSettings
+				Command="@USERFILE_COMMAND_DEBUG@"
+				WorkingDirectory="@USERFILE_WORKING_DIRECTORY_DEBUG@"
+				CommandArguments="@USERFILE_COMMAND_ARGUMENTS_DEBUG@"
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine="@USERFILE_REMOTE_MACHINE_DEBUG@"
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment="@USERFILE_ENVIRONMENT@"
+				EnvironmentMerge="true"
+				DebuggerFlavor=""
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+	</Configurations>
+</VisualStudioUserFile>
+
Index: /osgVisual/trunk/bin/airport_eddf.path
===================================================================
--- /osgVisual/trunk/bin/airport_eddf.path	(revision 176)
+++ /osgVisual/trunk/bin/airport_eddf.path	(revision 176)
@@ -0,0 +1,62 @@
+0.000427219101869092 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+0.0718712154757099 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+0.144408996115428 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+0.216471367170967 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+0.288842017630732 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+0.361766090382996 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+0.433832791597815 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+0.506785150067956 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+0.579340391027351 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+0.651566190675072 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+0.723962822090517 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+0.796465053519372 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+0.868978529394099 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+0.941691122754428 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+1.01384805890134 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+1.08628945857644 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+1.15963411550909 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+1.23112560395246 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+1.30311450198279 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+1.37621366682078 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+1.44862196172977 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+1.52079614867253 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+1.59437163103132 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+1.66610889093446 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+1.73861251918889 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+1.8115863189316 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+1.88417899481638 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+1.95623277539464 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+2.02951289898576 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+2.10184632404398 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+2.19273608796649 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+2.24688528849337 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+2.31957546280323 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+2.39185015134605 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+2.46513900509702 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+2.53693129992778 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+2.61001656635131 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+2.68202467073329 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+2.75463655296972 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+2.82711664471322 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+2.89980898410273 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+2.97187421865069 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+3.04436820880866 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+3.11690577992454 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+3.18966984630728 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+3.26240911903608 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+3.33497958539423 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+3.40715775328987 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+3.47963540058862 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+3.5521470605901 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+3.62479693648215 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+3.69717694567326 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+3.7701749104984 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+3.84260583398169 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+3.91524027495115 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+3.98748227777553 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+4.06048694736342 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+4.1325245946063 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+4.20477819108295 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+4.27757103207251 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+4.35066433024309 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
+4.42260852985505 4057529.33868806 612889.95447976 4866710.49250841 0.0419203667847569 0.501984537982303 0.724681239999288 -0.470203473900841
Index: /osgVisual/trunk/bin/airport_muc.path
===================================================================
--- /osgVisual/trunk/bin/airport_muc.path	(revision 176)
+++ /osgVisual/trunk/bin/airport_muc.path	(revision 176)
@@ -0,0 +1,65 @@
+0.000309606388521446 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+0.0711619772904098 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+0.142431999038984 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+0.21377717000345 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+0.285071286993179 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+0.356039594417726 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+0.427298441561707 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+0.498525860130268 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+0.569687837420678 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+0.640921821069438 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+0.712152452336819 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+0.783387902652432 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+0.854545759307398 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+0.925745590570869 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+0.997704806057753 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+1.0689483579617 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+1.14015007493969 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+1.21141024906797 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+1.28268550891245 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+1.35385328302899 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+1.42505234603839 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+1.49630853921378 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+1.55068416516624 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+1.62099268203082 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+1.69211128788715 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+1.76335630645794 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+1.83458693772533 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+1.9058093975631 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+1.977353895537 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+2.0486336950646 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+2.11995365332745 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+2.1911315544294 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+2.26234472537711 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+2.33367180745039 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+2.40485585458487 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+2.47609402871035 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+2.55040801275022 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+2.6197291136164 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+2.69090666551196 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+2.76207688407326 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+2.83335835979154 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+2.90463683233484 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+2.97597397155225 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+3.04718574567438 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+3.11838844043028 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+3.18956270978574 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+3.2608668839196 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+3.33207425804118 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+3.4033316385183 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+3.47442328564105 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+3.54571642485288 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+3.61737357680934 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+3.68853848743346 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+3.75981877585 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+3.83106924204054 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+3.90234987966348 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+3.97362723474632 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+4.04479312314833 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+4.11634551318673 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+4.1872619285412 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+4.25847600742553 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+4.32969329900867 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+4.40098804456991 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+4.47206397740495 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
+4.54326283089052 4157774.07996608 866213.175127536 4744730.1072493 0.464750203409089 0.594801650808533 0.59437433468026 0.277375909011673
Index: /osgVisual/trunk/bin/alps.path
===================================================================
--- /osgVisual/trunk/bin/alps.path	(revision 176)
+++ /osgVisual/trunk/bin/alps.path	(revision 176)
@@ -0,0 +1,80 @@
+0.0550106228584918 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+0.177819457500883 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+0.262233538061402 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+0.359418655164274 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+0.49682250118381 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+0.548962507804763 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+0.636378576048073 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+0.687896995288507 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+0.779457864058142 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+0.917604821283152 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+1.01386922080879 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+1.1057680515261 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+1.20759293429752 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+1.35457662915259 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+1.4512433144436 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+1.50139766366954 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+1.59392953573708 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+1.68529736321236 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+1.7755076413343 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+1.85322366390142 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+1.90035074290168 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+1.98232659458116 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+2.07175548847689 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+2.1226880790715 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+2.17062797087339 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+2.21563641468399 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+2.35660970877584 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+2.49665669798815 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+2.54676467260504 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+2.59669322497692 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+2.73043040386418 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+2.77631514619875 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+2.82373199666438 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+2.87095999631238 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+2.91856751346889 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+2.99354952933962 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+3.05538741655713 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+3.17922466402853 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+3.27272921558466 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+3.41322276993305 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+3.46858176108975 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+3.54324718644409 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+3.59347172615514 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+3.72521298097943 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+3.77610729855331 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+3.82586704455455 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+3.9624890873002 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+4.01062816642897 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+4.08817740802253 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+4.24669601862807 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+4.37176582498614 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+4.45860165188592 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+4.52547160323449 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+4.66658618623317 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+4.71681331007153 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+4.79485374537825 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+4.93398315987088 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+5.06726050377911 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+5.16049763307907 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+5.21525717654059 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+5.28691684278309 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+5.33709940788564 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+5.42565046674927 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+5.52308345055028 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+5.57014418033577 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+5.65967162027576 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+5.76110602045791 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+5.83027228320918 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+5.88486769966574 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+6.01831727216727 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+6.11620233856538 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+6.20578425470276 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+6.35044684450119 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+6.44495445650215 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+6.58015306414642 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+6.67447706342566 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+6.73366908364052 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+6.9591269281431 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+7.02172154561543 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
+7.11236518887177 4250961.35112522 974533.244576662 4655326.23072276 0.530006089921581 0.678473769046237 0.399145502314451 0.315356555892493
Index: /osgVisual/trunk/bin/osgVisualConfig.xml
===================================================================
--- /osgVisual/trunk/bin/osgVisualConfig.xml	(revision 176)
+++ /osgVisual/trunk/bin/osgVisualConfig.xml	(revision 176)
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<osgvisualconfiguration>
+  <module name="distortion" enabled="no">
+    <!-- XML configuration of the module "distortion"
+      channelname = name of the channel, used to load the distortion- and blendmaps
+      renderimplementation = technique to distort.
+      Available options: 
+          fbo : renderImplementation = osg::Camera::FRAME_BUFFER_OBJECT
+          pbuffer : renderImplementation = osg::Camera::PIXEL_BUFFER
+          pbuffer-rtt :  renderImplementation = osg::Camera::PIXEL_BUFFER_RTT
+          fb : renderImplementation = osg::Camera::FRAME_BUFFER
+          window : renderImplementation = osg::Camera::SEPERATE_WINDOW
+    -->
+    <distortion channelname="center" renderimplemmentation="fbo" width="2048" height="2048" useshader="yes" hdr="yes" usetexturerectangle="no"></distortion>
+    <!-- optional: <distortionmap filename="distmap.png"></distortionmap> to set distortionmap independend from channel map-->
+    <!-- optional: <blendmap filename="blendmap.png"></blendmap> to set blendmap independend from channel map -->
+  </module>
+  <module name="sky_silverlining" enabled="yes"></module>
+  <module name="vista2d" enabled="yes">
+    <vista2d filename="D:\osgVisual\osgVisual\bin\altimeterSimple.v" paintBackground="no" position_x="1" position_y="1" zoom="1.0" playanimation="yes"></vista2d>
+  </module>
+  <module name="dataio" enabled="yes">
+    <!-- XML configuration of the module "dataIO" 
+        Available clusterroles:
+        master: This role recieves all relevant information via the extLink implementation and sends it via cluster implementation to the slave nodes.
+        slave: This role recieves all relevant rendering information via the cluster implementation.
+        standalone: This role recieves all relevant data via the extLink and renders it. No cluster functionality is used.
+    -->
+    <dataio clusterrole="standalone"></dataio>
+    <cluster implementation="enet" master_ip="10.10.10.10" port="1234" use_zlib_compressor="yes" ></cluster>
+    <extlink implementation="vcl" filename="osgVisual.xml"></extlink>
+  </module>
+  
+  <scenery>
+    <terrain filename="d:\my\path\database.ive"></terrain>
+    <animationpath filename="salzburgerEcke.path"></animationpath>
+    <models>
+      <model filename="cessna" type="plain" label="TestText!" dynamic="yes">
+        <position lat="47.12345" lon="11.234567" alt="1500.0"></position>
+        <attitude rot_x="0.0" rot_y="0.0" rot_z="0.0"></attitude>
+        <cameraoffset>
+          <translation trans_x="0.0" trans_y="0.0" trans_z="0.0"></translation>
+          <rotation rot_x="0.0" rot_y="0.0" rot_z="0.0"></rotation>
+        </cameraoffset>
+      </model>
+    </models>
+    <datetime day="01" month="02" year="2010" hour="23" minute="45"></datetime>
+    <visibility range="50000" turbidity="2.2" ></visibility>
+    <cloudlayer slot="1" type="cumulusCongestus" enabled="true" fadetime="15">
+      <geometry baselength="50000" basewidth="50000" thickness="500" baseHeight="1700" density="0.3"></geometry>
+      <precipitation rate_mmPerHour_rain="5.0" rate_mmPerHour_drySnow="7.0" rate_mmPerHour_wetSnow="10.0" rate_mmPerHour_sleet="0.0"></precipitation>
+    </cloudlayer>
+    <windlayer bottom="500.0" top="700." speed="25.0" direction="90.0"></windlayer>
+  </scenery>
+</osgvisualconfiguration>
+
Index: /osgVisual/trunk/bin/salzburg.path
===================================================================
--- /osgVisual/trunk/bin/salzburg.path	(revision 176)
+++ /osgVisual/trunk/bin/salzburg.path	(revision 176)
@@ -0,0 +1,94 @@
+0.000334609566299628 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+0.104497638666367 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+0.20794786767592 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+0.311850458647677 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+0.415845309948611 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+0.520673786752227 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+0.624043837973821 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+0.693105338807027 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+0.827218612980141 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+0.903774083018931 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+1.0058992832888 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+1.10991746157682 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+1.21747149428209 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+1.32376642841478 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+1.42330289184799 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+1.52696809231341 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+1.62892434653008 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+1.73373340745821 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+1.83552742038443 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+1.94010879874397 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+2.04152119892333 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+2.18662323004739 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+2.28167218179964 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+2.38721806821817 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+2.61559059880516 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+2.74385124366365 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+2.82194399008813 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+2.93043424513451 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+3.04161785925306 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+3.1477000568508 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+3.32861103855378 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+3.4373367285507 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+3.55145151129543 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+3.66377982397204 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+3.77587060645976 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+3.8879180175134 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+4.05067704135582 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+4.15447459104439 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+4.26959871994904 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+4.38493893777002 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+4.48668929989705 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+4.57691368595729 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+4.70371604491632 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+4.80855213441932 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+4.92361564109405 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+5.03797877942588 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+5.16588965916059 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+5.28104340076742 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+5.3612582744455 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+5.44334412613894 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+5.56300109371442 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+5.681678537356 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+5.88071472770981 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+5.9737722950822 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+6.08904923670466 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+6.17155518368955 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+6.25572021025019 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+6.37972312123468 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+6.46301031276322 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+6.54371079285216 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+6.62677477165394 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+6.70929929641896 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+6.80309585436138 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+6.92642828907026 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+7.00934546150419 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+7.09224314822135 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+7.17660987639491 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+7.35423978466537 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+7.4524915177767 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+7.53458533137592 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+7.62045944386787 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+7.74278972606854 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+7.82613509538223 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+7.91077399501892 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+7.99398003098159 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+8.07650811765182 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+8.15941774722765 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+8.33871644301161 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+8.57754973048251 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+8.6660343004488 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+8.74929194911644 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+8.83318913437322 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+8.91705195772088 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+9.00076427311292 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+9.08462115995189 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+9.16893655478559 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+9.25253419079799 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+9.33617827126073 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+9.42092339948234 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+9.50456021645209 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+9.58807676673991 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+9.67153234559141 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+9.75527036257401 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
+9.8393167986434 4178295.70749852 958058.332787633 4708084.14347966 0.272710045638959 -0.227092524368542 -0.620058706705827 0.699703806350814
Index: /osgVisual/trunk/bin/visual_master.bat
===================================================================
--- /osgVisual/trunk/bin/visual_master.bat	(revision 176)
+++ /osgVisual/trunk/bin/visual_master.bat	(revision 176)
@@ -0,0 +1,1 @@
+osgVisual.exe -c osgVisualconfig.xml -C center --window 950 50 600 350 J:\BRD1m_MUC0.25m_srtmEU_BM\terrain.ive -p salzburg.path
Index: /osgVisual/trunk/bin/visual_slave.bat
===================================================================
--- /osgVisual/trunk/bin/visual_slave.bat	(revision 176)
+++ /osgVisual/trunk/bin/visual_slave.bat	(revision 176)
@@ -0,0 +1,1 @@
+osgVisual.exe -s --server 192.168.0.101 12345 --window 950 450 600 350 D:/OpenSceneGraph/VPB-Testdatensatz/DB_Small/database.ive
Index: /osgVisual/trunk/bin/visual_standalone.bat
===================================================================
--- /osgVisual/trunk/bin/visual_standalone.bat	(revision 176)
+++ /osgVisual/trunk/bin/visual_standalone.bat	(revision 176)
@@ -0,0 +1,1 @@
+osgVisual.exe -C center  --window 100 100 800 600 J:\BRD1m_MUC0.25m_srtmEU_BM\terrain.ive -p watzmann.path
Index: /osgVisual/trunk/bin/watzmann.path
===================================================================
--- /osgVisual/trunk/bin/watzmann.path	(revision 176)
+++ /osgVisual/trunk/bin/watzmann.path	(revision 176)
@@ -0,0 +1,46 @@
+0.000427299017885928 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+0.066461357829244 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+0.133349052291199 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+0.199860133354506 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+0.266410351414947 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+0.332791831274631 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+0.39841815956667 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+0.465148985245031 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+0.531597511271936 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+0.598498999921405 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+0.665097978830734 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+0.732173979992012 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+0.799193842018058 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+0.86533408399377 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+0.932192265310345 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+0.999008743269319 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+1.06608602761083 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+1.13253423284268 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+1.19980656057974 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+1.26621466642928 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+1.33345170670991 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+1.39925511387423 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+1.46604239948288 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+1.53273922088504 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+1.59947132974364 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+1.66686267244739 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+1.73253840317844 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+1.79980142785881 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+1.86629711075931 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+1.93315176333024 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+2.00024604980985 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+2.06708337944762 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+2.13320758167041 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+2.20022551892611 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+2.26634170127243 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+2.33343887490757 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+2.40000417033576 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+2.46657588166512 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+2.53409105126145 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+2.60019215624003 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+2.66866169113531 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+2.7333111984743 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+2.80053219900201 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+2.86705482868742 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+2.93375742440063 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
+3.00111604600843 4205439.30316196 964499.616532745 4685138.8938753 0.523868183761952 0.737968532214391 0.368849694525826 0.211930352596074
Index: /osgVisual/trunk/configure
===================================================================
--- /osgVisual/trunk/configure	(revision 176)
+++ /osgVisual/trunk/configure	(revision 176)
@@ -0,0 +1,1 @@
+cmake . -DCMAKE_BUILD_TYPE=Release $@
Index: /osgVisual/trunk/configure_debug
===================================================================
--- /osgVisual/trunk/configure_debug	(revision 176)
+++ /osgVisual/trunk/configure_debug	(revision 176)
@@ -0,0 +1,1 @@
+cmake . -DCMAKE_BUILD_TYPE=Debug $@
Index: /osgVisual/trunk/include/cluster/ENET_LICENSE
===================================================================
--- /osgVisual/trunk/include/cluster/ENET_LICENSE	(revision 176)
+++ /osgVisual/trunk/include/cluster/ENET_LICENSE	(revision 176)
@@ -0,0 +1,7 @@
+Copyright (c) 2002-2010 Lee Salzman
+
+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: /osgVisual/trunk/include/cluster/dataIO_cluster.h
===================================================================
--- /osgVisual/trunk/include/cluster/dataIO_cluster.h	(revision 176)
+++ /osgVisual/trunk/include/cluster/dataIO_cluster.h	(revision 176)
@@ -0,0 +1,139 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <osg/Referenced>
+#include <osgViewer/Viewer>
+
+#include "dataIO_slot.h"
+
+#include "dataIO_transportContainer.h"
+
+
+namespace osgVisual
+{
+
+/**
+ * \brief This class is the interface definition class for valid cluster implementations.
+ * 
+ * This class is an abstract class, thus cannot be instantiated. Derive this class for usage.
+ * 
+ * @author Torben Dannhauer
+ * @date  Feb 2010
+ */ 
+class dataIO_cluster :	public osg::Referenced
+{
+	#include <leakDetection.h>
+public:
+	/**
+	 * This enum defines the three modi of the cluster engine.
+	 */ 
+	enum clustermode {MASTER, SLAVE, STANDALONE};
+
+	/**
+	 * \brief Empty constructor.
+	 * 
+	 */ 
+	dataIO_cluster() {}
+
+	/**
+	 * \brief Empty destructor
+	 * 
+	 * @return 
+	 */ 
+	virtual ~dataIO_cluster() {}
+
+	/**
+	 * \brief Pure virtual function for initialization. Must be implemented in derived class.
+	 * 
+	 */ 
+	virtual void init( osg::ArgumentParser& arguments_, osgViewer::Viewer* viewer_, clustermode clusterMode_, osgVisual::dataIO_transportContainer* sendContainer_, bool compressionEnabled_, bool asAscii_ ) = 0;
+
+	void enableHardSync(bool hardSync_){hardSync=hardSync_;};
+	
+	bool isHardSyncEnabled(){return hardSync;};
+
+	virtual void shutdown() = 0;
+
+	/**
+	 * \brief This function sets the current transportContainer the cluster should send.
+	 * 
+	 * The previous container is removed, if set. (smartpointer, will delete itself.). If the cluster is in slave mode, the send_container is ignored.
+	 * 
+	 * @param sendContainer_ : New container to set.
+	 */ 
+	void setSendTransportContainer( osgVisual::dataIO_transportContainer* sendContainer_ ) {sendContainer=sendContainer_;}
+
+	/**
+	 * \brief Pure virtual function for sending TO_OBJ values via cluster to slave. Must be implemented in derived class.
+	 * 
+	 * @param viewMatrix_ :  Viewmatrix to send to the Slave.
+	 * @return : See derived class.
+	 */ 
+	virtual bool sendTO_OBJvaluesToSlaves(osg::Matrixd viewMatrix_) = 0;
+
+	/**
+	 * \brief Pure virtual function for reading TO_OBJ values from master. Must be implemented in derived class.
+	 * 
+	 * @return : See derived class.
+	 */ 
+	virtual bool readTO_OBJvaluesFromMaster() = 0;
+
+	/**
+	 * \brief Pure virtual function for reporting slave as ready to swap. Must be implemented in derived class.
+	 * 
+	 */ 
+	virtual void reportAsReadyToSwap() = 0;
+
+	/**
+	 * \brief Pure virtual function for waiting as slave for swap command. Must be implemented in derived class.
+	 * 
+	 * @return : See derived class.
+	 */ 
+	virtual bool waitForSwap() = 0;
+
+	/**
+	 * \brief Pure virtual function for waiting as master for all slaves reported as ready to swap. Must be implemented in derived class.
+	 * 
+	 * @return : See derived class.
+	 */ 
+	virtual bool waitForAllReadyToSwap() = 0;
+
+	/**
+	 * \brief Pure virtual function for sending swap command to all slaves. Must be implemented in derived class.
+	 * 
+	 * @return : See derived class.
+	 */ 
+	virtual bool sendSwapCommand() = 0;
+
+
+
+protected:
+	osgVisual::dataIO_cluster::clustermode clusterMode;	// This variable only mirrors the variable of dataIO. will be set during initialize.
+	bool initialized;
+	int port;
+	bool hardSync;
+
+	/**
+	 * Referenced Pointer to the applications viewer.
+	 */ 
+	osg::ref_ptr<osgViewer::Viewer> viewer;
+
+	osg::ref_ptr<osgVisual::dataIO_transportContainer> sendContainer;	// Points to the send container of dataIO.
+	std::string receivedTransportContainer;
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/cluster/dataIO_clusterAsioTcpIostream.h
===================================================================
--- /osgVisual/trunk/include/cluster/dataIO_clusterAsioTcpIostream.h	(revision 176)
+++ /osgVisual/trunk/include/cluster/dataIO_clusterAsioTcpIostream.h	(revision 176)
@@ -0,0 +1,73 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include "dataIO_cluster.h"
+
+#include <osg/notify>
+#include <osg/ArgumentParser>
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <boost/asio.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+
+namespace osgVisual
+{
+
+/**
+ * \brief This is a Boost ASIO iostream implementation of dataIO_cluster..
+ * 
+ * This class uses Boost ASIO and it iostream privider to fullfil the functions of dataIO_cluster.
+ * It sends the clusterdata into the network to any connected client.
+ * 
+ * 
+ * \todo Add getHorizonColor to transport it to slave for consistent fog.
+ * @author Torben Dannhauer
+ * @date  May 2010
+ */ 
+class dataIO_clusterAsioTcpIostream :	public dataIO_cluster
+{
+
+public:
+
+	dataIO_clusterAsioTcpIostream();
+	virtual ~dataIO_clusterAsioTcpIostream();
+
+	void init( osg::ArgumentParser& arguments_, clustermode clusterMode_, osgVisual::dataIO_transportContainer* sendContainer_, bool compressionEnabled_, bool asAscii_ );
+	void shutdown();
+	bool sendTO_OBJvaluesToSlaves();
+	bool readTO_OBJvaluesFromMaster();
+	void reportAsReadyToSwap();
+	bool waitForSwap();
+	bool waitForAllReadyToSwap();
+	bool sendSwapCommand();
+
+private:
+	/**
+	 * This list contains the connections to communicate with in each frame. 
+	 * 
+	 * As slave, contains only one entry: connection to master.
+	 * As Master,contains the connection to all slaves which use this connection.
+	 */ 
+	std::vector<boost::asio::ip::tcp::iostream> clientlists;
+
+	boost::asio::io_service io_service;
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/cluster/dataIO_clusterDummy.h
===================================================================
--- /osgVisual/trunk/include/cluster/dataIO_clusterDummy.h	(revision 176)
+++ /osgVisual/trunk/include/cluster/dataIO_clusterDummy.h	(revision 176)
@@ -0,0 +1,52 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <osg/notify>
+#include <osg/ArgumentParser>
+
+#include <dataIO_cluster.h>
+
+namespace osgVisual
+{
+
+/**
+ * \brief This class is a dummy class for the cluster.
+ * 
+ * All functions which are called always return true and send a debug string to stdout to announce that they were called.
+ * 
+ * @author Torben Dannhauer
+ * @date  Sep 2009
+ */ 
+class dataIO_clusterDummy :	public dataIO_cluster
+{
+public:
+	dataIO_clusterDummy();
+	virtual ~dataIO_clusterDummy(void);
+
+	void init( osg::ArgumentParser& arguments_, clustermode clusterMode_, osgVisual::dataIO_transportContainer* sendContainer_, bool compressionEnabled_, bool asAscii_ );
+	void shutdown();
+
+	void init();
+	bool sendTO_OBJvaluesToSlaves();
+	bool readTO_OBJvaluesFromMaster();
+	void reportAsReadyToSwap();
+	bool waitForSwap();
+	bool waitForAllReadyToSwap();
+	bool sendSwapCommand();
+};
+
+} //END NAMESPACE
Index: /osgVisual/trunk/include/cluster/dataIO_clusterENet.h
===================================================================
--- /osgVisual/trunk/include/cluster/dataIO_clusterENet.h	(revision 176)
+++ /osgVisual/trunk/include/cluster/dataIO_clusterENet.h	(revision 176)
@@ -0,0 +1,68 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <osg/Notify>
+#include <osg/ArgumentParser>
+#include <osgDB/Registry>
+#include <osgDB/ReaderWriter>
+#include <iostream>
+#include <cstdlib>	// Clearscrean console
+
+#include <dataIO_cluster.h>
+#include <dataIO_clusterENet_implementation.h>
+
+namespace osgVisual
+{
+
+/**
+ * \brief This class is a ENet based cluster implementation class for osgVisuals cluster capabilities.
+ * 
+ * All functions which are called always return true and send a debug string to stdout to announce that they were called.
+ * 
+ * @author Torben Dannhauer
+ * @date  July 2010
+ */ 
+class dataIO_clusterENet :	public dataIO_cluster
+{
+	#include <leakDetection.h>
+public:
+	dataIO_clusterENet();
+	virtual ~dataIO_clusterENet(void);
+
+	void init( osg::ArgumentParser& arguments_, osgViewer::Viewer* viewer_, clustermode clusterMode_, osgVisual::dataIO_transportContainer* sendContainer_, bool compressionEnabled_, bool asAscii_ );
+	void shutdown();
+
+	void init();
+	bool sendTO_OBJvaluesToSlaves(osg::Matrixd viewMatrix_);
+	bool readTO_OBJvaluesFromMaster();
+	void reportAsReadyToSwap();
+	bool waitForSwap();
+	bool waitForAllReadyToSwap();
+	bool sendSwapCommand();
+
+private:
+	osg::ref_ptr<osgVisual::dataIO_clusterENet_implementation> enet_impl;
+	std::string serverToConnect;
+	osgVisual::dataIO_cluster::clustermode clusterMode;
+	std::string receivedTransportContainer;
+
+	osg::ref_ptr<osgDB::Options> readOptions;
+	osg::ref_ptr<osgDB::Options> writeOptions;
+	osg::ref_ptr<osgDB::ReaderWriter> rw;
+};
+
+} //END NAMESPACE
Index: /osgVisual/trunk/include/cluster/dataIO_clusterENet_implementation.h
===================================================================
--- /osgVisual/trunk/include/cluster/dataIO_clusterENet_implementation.h	(revision 176)
+++ /osgVisual/trunk/include/cluster/dataIO_clusterENet_implementation.h	(revision 176)
@@ -0,0 +1,191 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+
+#include <osg/Referenced>
+#include <enet/enet.h>
+#include <iostream>
+#include <string>
+#include <vector>
+
+namespace osgVisual
+{
+
+/**
+ * \brief This class is a object oriented wrapper for the ENet UDP implementation.
+ * 
+ * This class allows to create a handler for the complete ENet operations.
+ * ENet is a cross plattform UDP implementation with some reliability functions.
+ * For further details, loot at http://enet.bespin.org/index.html
+ * 
+ * @author Torben Dannhauer
+ * @date  Jul 2010
+ */ 
+class dataIO_clusterENet_implementation :	public osg::Referenced
+{
+	#include <leakDetection.h>
+public:
+	/**
+	 * \brief Constructor: Constructs this class and starts the ENet subsystem if this instance is the first instantiated one in the program.
+	 * 
+	 * @param receivedTransportContainer_ : TransportContainer to interact with. See also receivedTransportContainer
+	 */ 
+	dataIO_clusterENet_implementation(std::string& receivedTransportContainer_);
+
+	/**
+	 * \brief Destructor: Destructs this class. In the last program wide application it shuts the ENet subsystem down.
+	 * 
+	 */ 
+	~dataIO_clusterENet_implementation();
+
+	/**
+	 * This enum contains valid roles of this class. In contrast to the dataIO_cluster implementation this class do NOT use MASTER/SLAVE,
+	 * because this class implements an non-abstract DUP connection with SERVER and CLIENT. As soon as osgVisual uses only the convenience
+	 * functions of clusterENet, the roles are called as usual MASTER/SLAVE.
+	 */ 
+	enum role {SERVER, CLIENT};
+
+	/**
+	 * \brief This function initializes this class and allow to use it's service. Call this function as SERVER as well as CLIENT prior to any usage.
+	 * 
+	 * @param role_ : Role to act like (SERVER/CLIENT)
+	 * @param port_ : Port to use.
+	 * @param maxClients_ : Maximum of allowed connected clients. (Affects only the role SERVER)
+	 * @param maxChannels_ : Maximum of channels per client. (Affects only the role SERVER)
+	 * @param maxInBandwidth_ : Maximal incoming bandwith in bytes per second [bps]. Set 0 to rely on ENets internal throtteling algorithm.
+	 * @param maxOutBandwidth_ : Maximal outgoing bandwith in bytes per second [bps]. Set 0 to rely on ENets internal throtteling algorithm.
+	 * @return : True on successful init.
+	 */ 
+	bool init( dataIO_clusterENet_implementation::role role_, unsigned short port_, int maxClients_=10, int maxChannels_=2, int maxInBandwidth_=0, int maxOutBandwidth_=0 );	
+
+	/**
+	 * \brief This function connects to a ENet serverat the specified adress. The function affects only the CLIENT role.
+	 * 
+	 * @param remoteAddr_ : Address of the ENet server to connect to.
+	 * @param connectTimeout_ms_ : Connect timeout in milliseconds [ms].
+	 * @param clientInfo_ : Client data to transfer to the SERVER during connect. Usually not required.
+	 * @param channelToAlloc_ : Max number of non-concurring channels to open.
+	 * @return : True on successful connect.
+	 */ 
+	bool connectTo( const char* remoteAddr_, int connectTimeout_ms_, int clientInfo_=0,  int channelToAlloc_=2 );
+	
+	/**
+	 * \brief This function send a packet to the peer with the specified peer ID (number of the peer in the peer vector). This function works bidirectional from SERVER to CLIENT and vice versa. This function takes ownership of the packet and will destroy it after (un-)successful transmission.
+	 * 
+	 * @param packet_ : Data packet to broadcast.
+	 * @param channelID_ : ID on which channel the broadcast should be done.
+	 * @param peerID_ : Peer ID to send the packet to.
+	 * @param autoFlush_ : Indicates if the packed should be send immediately after append the packet to the ENets internal send list (like processEvents() with only sending the packet).  This function works bidirectional from SERVER to CLIENT and vice versa.
+	 */ 
+	void sendPacket( ENetPacket* packet_, enet_uint8 channelID_, unsigned int peerID_=0, bool autoFlush_=false );
+
+	/**
+	 * \brief This function send a packet to the peer with the specified peerName. This function works bidirectional from SERVER to CLIENT and vice versa. This function takes ownership of the packet and will destroy it after (un-)successful transmission.
+	 * 
+	 * @param channelID_ : ID on which channel the broadcast should be done.
+	 * @param peerName_ : Peer name to send to data to.
+	 * @param packet_ : Data packet to broadcast.
+	 * @param autoFlush_ : Indicates if the packed should be send immediately after append the packet to the ENets internal send list (like processEvents() with only sending the packet.).
+	 */ 
+	void sendPacket( ENetPacket* packet_, enet_uint8 channelID_, std::string peerName_, bool autoFlush_=false );
+
+	/**
+	 * \brief : This function emulates a UDP broadcast by sending the packet manually to all connected peers. This function works only as SERVER. Calls as CLIENT are ignored. 
+	 * 
+	 * @param channelID_ : ID on which channel the broadcast should be done.
+	 * @param packet_ : Data packet to broadcast.
+	 * @param autoFlush_ : Indicates if the packed should be send immediately after append the packet to the ENets internal send list (like processEvents() with only sending the packet.).
+	 */ 
+	void broadcastPacket( enet_uint8 channelID_, ENetPacket* packet_, bool autoFlush_=false );
+
+	/**
+	 * \brief : Call this function to process all pending events like connects, disconnects, receives or sends.
+	 * 
+	 * @param timeout_ms_ :  Maximal time to wait for incomming events in milliseconds [ms].
+	 */ 
+	void processEvents( int timeout_ms_ = 0 );
+	
+	/**
+	 * \brief This function handles the receive of a data packet.
+	 * 
+	 * @param event_ : Receive event.
+	 */ 
+	virtual inline void onReceivePacket(ENetEvent* event_);
+
+	/**
+	 * \brief This function handles the connect of a peer. This function will be called only by the host waiting for the connection.
+	 * 
+	 * @param event_ : Connect event.
+	 */ 
+	virtual inline void onConnect(ENetEvent* event_);
+	
+	/**
+	 * \brief This function handles the disconnect of a peer.
+	 * 
+	 * @param event_ : Disconnect event.
+	 */ 
+	virtual inline void onDisconnect(ENetEvent* event_);
+
+protected:
+	/**
+	 * UDP port to use.
+	 */ 
+	unsigned short port;
+
+	/**
+	 * This enum indicates the current role this class at as.
+	 */ 
+	dataIO_clusterENet_implementation::role currentRole;
+
+	/**
+	 * This variable indicates the number of programm wide used instances of this class. one the first class starts the ENet subsystem and only the 
+	 * last one shuts the ENet subsystem down.
+	 */
+	static int activeENetInstances;
+
+	/**
+	 * This flag indicates if the complete ENet wrapper class is initialized. (After init())
+	 */ 
+	bool enetInitialized;
+
+	/**
+	 * ENet adress structure, which contains information regarding the interface and address.
+	 */ 
+	ENetAddress address; 
+
+	/**
+	 * Host structure, which contains the own host role for the conmmunication.
+	 */ 
+    ENetHost* host;
+
+	/**
+	 * Lisst of the ENet remote peers. This list contains only the server during acting as CLIENT (peerList[0]=server), and multiple slave entries during acting as SERVER (peerList[0-n]=client0-n).
+	 */ 
+	std::vector<ENetPeer*> peerList;
+
+	/**
+	 * Eventclass which contains the data of the events dureing connect, resieve or send.
+	 */ 
+	ENetEvent event;
+
+	/**
+	 * Reference to the transportContainer class to store data into on receive and read from during sending.
+	 */ 
+	std::string& receivedTransportContainer;
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/cluster/enet/callbacks.h
===================================================================
--- /osgVisual/trunk/include/cluster/enet/callbacks.h	(revision 176)
+++ /osgVisual/trunk/include/cluster/enet/callbacks.h	(revision 176)
@@ -0,0 +1,27 @@
+/** 
+ @file  callbacks.h
+ @brief ENet callbacks
+*/
+#ifndef __ENET_CALLBACKS_H__
+#define __ENET_CALLBACKS_H__
+
+#include <stdlib.h>
+
+typedef struct _ENetCallbacks
+{
+    void * (ENET_CALLBACK * malloc) (size_t size);
+    void (ENET_CALLBACK * free) (void * memory);
+    void (ENET_CALLBACK * no_memory) (void);
+} ENetCallbacks;
+
+/** @defgroup callbacks ENet internal callbacks
+    @{
+    @ingroup private
+*/
+extern void * enet_malloc (size_t);
+extern void   enet_free (void *);
+
+/** @} */
+
+#endif /* __ENET_CALLBACKS_H__ */
+
Index: /osgVisual/trunk/include/cluster/enet/enet.h
===================================================================
--- /osgVisual/trunk/include/cluster/enet/enet.h	(revision 176)
+++ /osgVisual/trunk/include/cluster/enet/enet.h	(revision 176)
@@ -0,0 +1,540 @@
+/** 
+ @file  enet.h
+ @brief ENet public header file
+*/
+#ifndef __ENET_ENET_H__
+#define __ENET_ENET_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdlib.h>
+
+#ifdef WIN32
+#include "enet/win32.h"
+#else
+#include "enet/unix.h"
+#endif
+
+#include "enet/types.h"
+#include "enet/protocol.h"
+#include "enet/list.h"
+#include "enet/callbacks.h"
+
+#define ENET_VERSION_MAJOR 1
+#define ENET_VERSION_MINOR 3
+#define ENET_VERSION_PATCH 0
+#define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch))
+#define ENET_VERSION ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR, ENET_VERSION_PATCH)
+
+typedef enet_uint32 ENetVersion;
+
+typedef enum _ENetSocketType
+{
+   ENET_SOCKET_TYPE_STREAM   = 1,
+   ENET_SOCKET_TYPE_DATAGRAM = 2
+} ENetSocketType;
+
+typedef enum _ENetSocketWait
+{
+   ENET_SOCKET_WAIT_NONE    = 0,
+   ENET_SOCKET_WAIT_SEND    = (1 << 0),
+   ENET_SOCKET_WAIT_RECEIVE = (1 << 1)
+} ENetSocketWait;
+
+typedef enum _ENetSocketOption
+{
+   ENET_SOCKOPT_NONBLOCK  = 1,
+   ENET_SOCKOPT_BROADCAST = 2,
+   ENET_SOCKOPT_RCVBUF    = 3,
+   ENET_SOCKOPT_SNDBUF    = 4,
+   ENET_SOCKOPT_REUSEADDR = 5
+} ENetSocketOption;
+
+enum
+{
+   ENET_HOST_ANY       = 0,            /**< specifies the default server host */
+   ENET_HOST_BROADCAST = 0xFFFFFFFF,   /**< specifies a subnet-wide broadcast */
+
+   ENET_PORT_ANY       = 0             /**< specifies that a port should be automatically chosen */
+};
+
+/**
+ * Portable internet address structure. 
+ *
+ * The host must be specified in network byte-order, and the port must be in host 
+ * byte-order. The constant ENET_HOST_ANY may be used to specify the default 
+ * server host. The constant ENET_HOST_BROADCAST may be used to specify the
+ * broadcast address (255.255.255.255).  This makes sense for enet_host_connect,
+ * but not for enet_host_create.  Once a server responds to a broadcast, the
+ * address is updated from ENET_HOST_BROADCAST to the server's actual IP address.
+ */
+typedef struct _ENetAddress
+{
+   enet_uint32 host;
+   enet_uint16 port;
+} ENetAddress;
+
+/**
+ * Packet flag bit constants.
+ *
+ * The host must be specified in network byte-order, and the port must be in
+ * host byte-order. The constant ENET_HOST_ANY may be used to specify the
+ * default server host.
+ 
+   @sa ENetPacket
+*/
+typedef enum _ENetPacketFlag
+{
+   /** packet must be received by the target peer and resend attempts should be
+     * made until the packet is delivered */
+   ENET_PACKET_FLAG_RELIABLE    = (1 << 0),
+   /** packet will not be sequenced with other packets
+     * not supported for reliable packets
+     */
+   ENET_PACKET_FLAG_UNSEQUENCED = (1 << 1),
+   /** packet will not allocate data, and user must supply it instead */
+   ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2)
+} ENetPacketFlag;
+
+struct _ENetPacket;
+typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *);
+
+/**
+ * ENet packet structure.
+ *
+ * An ENet data packet that may be sent to or received from a peer. The shown 
+ * fields should only be read and never modified. The data field contains the 
+ * allocated data for the packet. The dataLength fields specifies the length 
+ * of the allocated data.  The flags field is either 0 (specifying no flags), 
+ * or a bitwise-or of any combination of the following flags:
+ *
+ *    ENET_PACKET_FLAG_RELIABLE - packet must be received by the target peer
+ *    and resend attempts should be made until the packet is delivered
+ *
+ *    ENET_PACKET_FLAG_UNSEQUENCED - packet will not be sequenced with other packets 
+ *    (not supported for reliable packets)
+ *
+ *    ENET_PACKET_FLAG_NO_ALLOCATE - packet will not allocate data, and user must supply it instead
+ 
+   @sa ENetPacketFlag
+ */
+typedef struct _ENetPacket
+{
+   size_t                   referenceCount;  /**< internal use only */
+   enet_uint32              flags;           /**< bitwise-or of ENetPacketFlag constants */
+   enet_uint8 *             data;            /**< allocated data for packet */
+   size_t                   dataLength;      /**< length of data */
+   ENetPacketFreeCallback   freeCallback;    /**< function to be called when the packet is no longer in use */
+} ENetPacket;
+
+typedef struct _ENetAcknowledgement
+{
+   ENetListNode acknowledgementList;
+   enet_uint32  sentTime;
+   ENetProtocol command;
+} ENetAcknowledgement;
+
+typedef struct _ENetOutgoingCommand
+{
+   ENetListNode outgoingCommandList;
+   enet_uint16  reliableSequenceNumber;
+   enet_uint16  unreliableSequenceNumber;
+   enet_uint32  sentTime;
+   enet_uint32  roundTripTimeout;
+   enet_uint32  roundTripTimeoutLimit;
+   enet_uint32  fragmentOffset;
+   enet_uint16  fragmentLength;
+   enet_uint16  sendAttempts;
+   ENetProtocol command;
+   ENetPacket * packet;
+} ENetOutgoingCommand;
+
+typedef struct _ENetIncomingCommand
+{  
+   ENetListNode     incomingCommandList;
+   enet_uint16      reliableSequenceNumber;
+   enet_uint16      unreliableSequenceNumber;
+   ENetProtocol     command;
+   enet_uint32      fragmentCount;
+   enet_uint32      fragmentsRemaining;
+   enet_uint32 *    fragments;
+   ENetPacket *     packet;
+} ENetIncomingCommand;
+
+typedef enum _ENetPeerState
+{
+   ENET_PEER_STATE_DISCONNECTED                = 0,
+   ENET_PEER_STATE_CONNECTING                  = 1,
+   ENET_PEER_STATE_ACKNOWLEDGING_CONNECT       = 2,
+   ENET_PEER_STATE_CONNECTION_PENDING          = 3,
+   ENET_PEER_STATE_CONNECTION_SUCCEEDED        = 4,
+   ENET_PEER_STATE_CONNECTED                   = 5,
+   ENET_PEER_STATE_DISCONNECT_LATER            = 6,
+   ENET_PEER_STATE_DISCONNECTING               = 7,
+   ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT    = 8,
+   ENET_PEER_STATE_ZOMBIE                      = 9 
+} ENetPeerState;
+
+#ifndef ENET_BUFFER_MAXIMUM
+#define ENET_BUFFER_MAXIMUM (1 + 2 * ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS)
+#endif
+
+enum
+{
+   ENET_HOST_RECEIVE_BUFFER_SIZE          = 256 * 1024,
+   ENET_HOST_SEND_BUFFER_SIZE             = 256 * 1024,
+   ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL  = 1000,
+   ENET_HOST_DEFAULT_MTU                  = 1400,
+
+   ENET_PEER_DEFAULT_ROUND_TRIP_TIME      = 500,
+   ENET_PEER_DEFAULT_PACKET_THROTTLE      = 32,
+   ENET_PEER_PACKET_THROTTLE_SCALE        = 32,
+   ENET_PEER_PACKET_THROTTLE_COUNTER      = 7, 
+   ENET_PEER_PACKET_THROTTLE_ACCELERATION = 2,
+   ENET_PEER_PACKET_THROTTLE_DECELERATION = 2,
+   ENET_PEER_PACKET_THROTTLE_INTERVAL     = 5000,
+   ENET_PEER_PACKET_LOSS_SCALE            = (1 << 16),
+   ENET_PEER_PACKET_LOSS_INTERVAL         = 10000,
+   ENET_PEER_WINDOW_SIZE_SCALE            = 64 * 1024,
+   ENET_PEER_TIMEOUT_LIMIT                = 32,
+   ENET_PEER_TIMEOUT_MINIMUM              = 5000,
+   ENET_PEER_TIMEOUT_MAXIMUM              = 30000,
+   ENET_PEER_PING_INTERVAL                = 500,
+   ENET_PEER_UNSEQUENCED_WINDOWS          = 64,
+   ENET_PEER_UNSEQUENCED_WINDOW_SIZE      = 1024,
+   ENET_PEER_FREE_UNSEQUENCED_WINDOWS     = 32,
+   ENET_PEER_RELIABLE_WINDOWS             = 16,
+   ENET_PEER_RELIABLE_WINDOW_SIZE         = 0x1000,
+   ENET_PEER_FREE_RELIABLE_WINDOWS        = 8
+};
+
+typedef struct _ENetChannel
+{
+   enet_uint16  outgoingReliableSequenceNumber;
+   enet_uint16  outgoingUnreliableSequenceNumber;
+   enet_uint16  usedReliableWindows;
+   enet_uint16  reliableWindows [ENET_PEER_RELIABLE_WINDOWS];
+   enet_uint16  incomingReliableSequenceNumber;
+   ENetList     incomingReliableCommands;
+   ENetList     incomingUnreliableCommands;
+} ENetChannel;
+
+/**
+ * An ENet peer which data packets may be sent or received from. 
+ *
+ * No fields should be modified unless otherwise specified. 
+ */
+typedef struct _ENetPeer
+{ 
+   ENetListNode  dispatchList;
+   struct _ENetHost * host;
+   enet_uint16   outgoingPeerID;
+   enet_uint16   incomingPeerID;
+   enet_uint32   connectID;
+   enet_uint8    outgoingSessionID;
+   enet_uint8    incomingSessionID;
+   ENetAddress   address;            /**< Internet address of the peer */
+   void *        data;               /**< Application private data, may be freely modified */
+   ENetPeerState state;
+   ENetChannel * channels;
+   size_t        channelCount;       /**< Number of channels allocated for communication with peer */
+   enet_uint32   incomingBandwidth;  /**< Downstream bandwidth of the client in bytes/second */
+   enet_uint32   outgoingBandwidth;  /**< Upstream bandwidth of the client in bytes/second */
+   enet_uint32   incomingBandwidthThrottleEpoch;
+   enet_uint32   outgoingBandwidthThrottleEpoch;
+   enet_uint32   incomingDataTotal;
+   enet_uint32   outgoingDataTotal;
+   enet_uint32   lastSendTime;
+   enet_uint32   lastReceiveTime;
+   enet_uint32   nextTimeout;
+   enet_uint32   earliestTimeout;
+   enet_uint32   packetLossEpoch;
+   enet_uint32   packetsSent;
+   enet_uint32   packetsLost;
+   enet_uint32   packetLoss;          /**< mean packet loss of reliable packets as a ratio with respect to the constant ENET_PEER_PACKET_LOSS_SCALE */
+   enet_uint32   packetLossVariance;
+   enet_uint32   packetThrottle;
+   enet_uint32   packetThrottleLimit;
+   enet_uint32   packetThrottleCounter;
+   enet_uint32   packetThrottleEpoch;
+   enet_uint32   packetThrottleAcceleration;
+   enet_uint32   packetThrottleDeceleration;
+   enet_uint32   packetThrottleInterval;
+   enet_uint32   lastRoundTripTime;
+   enet_uint32   lowestRoundTripTime;
+   enet_uint32   lastRoundTripTimeVariance;
+   enet_uint32   highestRoundTripTimeVariance;
+   enet_uint32   roundTripTime;            /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement */
+   enet_uint32   roundTripTimeVariance;
+   enet_uint32   mtu;
+   enet_uint32   windowSize;
+   enet_uint32   reliableDataInTransit;
+   enet_uint16   outgoingReliableSequenceNumber;
+   ENetList      acknowledgements;
+   ENetList      sentReliableCommands;
+   ENetList      sentUnreliableCommands;
+   ENetList      outgoingReliableCommands;
+   ENetList      outgoingUnreliableCommands;
+   ENetList      dispatchedCommands;
+   int           needsDispatch;
+   enet_uint16   incomingUnsequencedGroup;
+   enet_uint16   outgoingUnsequencedGroup;
+   enet_uint32   unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32]; 
+   enet_uint32   eventData;
+} ENetPeer;
+
+/** An ENet packet compressor for compressing UDP packets before socket sends or receives.
+ */
+typedef struct _ENetCompressor
+{
+   /** Context data for the compressor. Must be non-NULL. */
+   void * context;
+   /** Compresses from inBuffers[0:inBufferCount-1], containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */
+   size_t (ENET_CALLBACK * compress) (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit);
+   /** Decompresses from inData, containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */
+   size_t (ENET_CALLBACK * decompress) (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit);
+   /** Destroys the context when compression is disabled or the host is destroyed. May be NULL. */
+   void (ENET_CALLBACK * destroy) (void * context);
+} ENetCompressor;
+
+/** Callback that computes the checksum of the data held in buffers[0:bufferCount-1] */
+typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * buffers, size_t bufferCount);
+ 
+/** An ENet host for communicating with peers.
+  *
+  * No fields should be modified unless otherwise stated.
+
+    @sa enet_host_create()
+    @sa enet_host_destroy()
+    @sa enet_host_connect()
+    @sa enet_host_service()
+    @sa enet_host_flush()
+    @sa enet_host_broadcast()
+    @sa enet_host_compress()
+    @sa enet_host_compress_with_range_coder()
+    @sa enet_host_channel_limit()
+    @sa enet_host_bandwidth_limit()
+    @sa enet_host_bandwidth_throttle()
+  */
+typedef struct _ENetHost
+{
+   ENetSocket           socket;
+   ENetAddress          address;                     /**< Internet address of the host */
+   enet_uint32          incomingBandwidth;           /**< downstream bandwidth of the host */
+   enet_uint32          outgoingBandwidth;           /**< upstream bandwidth of the host */
+   enet_uint32          bandwidthThrottleEpoch;
+   enet_uint32          mtu;
+   enet_uint32          randomSeed;
+   int                  recalculateBandwidthLimits;
+   ENetPeer *           peers;                       /**< array of peers allocated for this host */
+   size_t               peerCount;                   /**< number of peers allocated for this host */
+   size_t               channelLimit;                /**< maximum number of channels allowed for connected peers */
+   enet_uint32          serviceTime;
+   ENetList             dispatchQueue;
+   int                  continueSending;
+   size_t               packetSize;
+   enet_uint16          headerFlags;
+   ENetProtocol         commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS];
+   size_t               commandCount;
+   ENetBuffer           buffers [ENET_BUFFER_MAXIMUM];
+   size_t               bufferCount;
+   ENetChecksumCallback checksum;                    /**< callback the user can set to enable packet checksums for this host */
+   ENetCompressor       compressor;
+   enet_uint8           packetData [2][ENET_PROTOCOL_MAXIMUM_MTU];
+   ENetAddress          receivedAddress;
+   enet_uint8 *         receivedData;
+   size_t               receivedDataLength;
+   enet_uint32          totalSentData;               /**< total data sent, user should reset to 0 as needed to prevent overflow */
+   enet_uint32          totalSentPackets;            /**< total UDP packets sent, user should reset to 0 as needed to prevent overflow */
+   enet_uint32          totalReceivedData;           /**< total data received, user should reset to 0 as needed to prevent overflow */
+   enet_uint32          totalReceivedPackets;        /**< total UDP packets received, user should reset to 0 as needed to prevent overflow */
+} ENetHost;
+
+/**
+ * An ENet event type, as specified in @ref ENetEvent.
+ */
+typedef enum _ENetEventType
+{
+   /** no event occurred within the specified time limit */
+   ENET_EVENT_TYPE_NONE       = 0,  
+
+   /** a connection request initiated by enet_host_connect has completed.  
+     * The peer field contains the peer which successfully connected. 
+     */
+   ENET_EVENT_TYPE_CONNECT    = 1,  
+
+   /** a peer has disconnected.  This event is generated on a successful 
+     * completion of a disconnect initiated by enet_pper_disconnect, if 
+     * a peer has timed out, or if a connection request intialized by 
+     * enet_host_connect has timed out.  The peer field contains the peer 
+     * which disconnected. The data field contains user supplied data 
+     * describing the disconnection, or 0, if none is available.
+     */
+   ENET_EVENT_TYPE_DISCONNECT = 2,  
+
+   /** a packet has been received from a peer.  The peer field specifies the
+     * peer which sent the packet.  The channelID field specifies the channel
+     * number upon which the packet was received.  The packet field contains
+     * the packet that was received; this packet must be destroyed with
+     * enet_packet_destroy after use.
+     */
+   ENET_EVENT_TYPE_RECEIVE    = 3
+} ENetEventType;
+
+/**
+ * An ENet event as returned by enet_host_service().
+   
+   @sa enet_host_service
+ */
+typedef struct _ENetEvent 
+{
+   ENetEventType        type;      /**< type of the event */
+   ENetPeer *           peer;      /**< peer that generated a connect, disconnect or receive event */
+   enet_uint8           channelID; /**< channel on the peer that generated the event, if appropriate */
+   enet_uint32          data;      /**< data associated with the event, if appropriate */
+   ENetPacket *         packet;    /**< packet associated with the event, if appropriate */
+} ENetEvent;
+
+/** @defgroup global ENet global functions
+    @{ 
+*/
+
+/** 
+  Initializes ENet globally.  Must be called prior to using any functions in
+  ENet.
+  @returns 0 on success, < 0 on failure
+*/
+ENET_API int enet_initialize (void);
+
+/** 
+  Initializes ENet globally and supplies user-overridden callbacks. Must be called prior to using any functions in ENet. Do not use enet_initialize() if you use this variant. Make sure the ENetCallbacks structure is zeroed out so that any additional callbacks added in future versions will be properly ignored.
+
+  @param version the constant ENET_VERSION should be supplied so ENet knows which version of ENetCallbacks struct to use
+  @param inits user-overriden callbacks where any NULL callbacks will use ENet's defaults
+  @returns 0 on success, < 0 on failure
+*/
+ENET_API int enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits);
+
+/** 
+  Shuts down ENet globally.  Should be called when a program that has
+  initialized ENet exits.
+*/
+ENET_API void enet_deinitialize (void);
+
+/** @} */
+
+/** @defgroup private ENet private implementation functions */
+
+/**
+  Returns the wall-time in milliseconds.  Its initial value is unspecified
+  unless otherwise set.
+  */
+ENET_API enet_uint32 enet_time_get (void);
+/**
+  Sets the current wall-time in milliseconds.
+  */
+ENET_API void enet_time_set (enet_uint32);
+
+/** @defgroup socket ENet socket functions
+    @{
+*/
+ENET_API ENetSocket enet_socket_create (ENetSocketType);
+ENET_API int        enet_socket_bind (ENetSocket, const ENetAddress *);
+ENET_API int        enet_socket_listen (ENetSocket, int);
+ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
+ENET_API int        enet_socket_connect (ENetSocket, const ENetAddress *);
+ENET_API int        enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t);
+ENET_API int        enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
+ENET_API int        enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
+ENET_API int        enet_socket_set_option (ENetSocket, ENetSocketOption, int);
+ENET_API void       enet_socket_destroy (ENetSocket);
+ENET_API int        enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32);
+
+/** @} */
+
+/** @defgroup Address ENet address functions
+    @{
+*/
+/** Attempts to resolve the host named by the parameter hostName and sets
+    the host field in the address parameter if successful.
+    @param address destination to store resolved address
+    @param hostName host name to lookup
+    @retval 0 on success
+    @retval < 0 on failure
+    @returns the address of the given hostName in address on success
+*/
+ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
+
+/** Gives the printable form of the ip address specified in the address parameter.
+    @param address    address printed
+    @param hostName   destination for name, must not be NULL
+    @param nameLength maximum length of hostName.
+    @returns the null-terminated name of the host in hostName on success
+    @retval 0 on success
+    @retval < 0 on failure
+*/
+ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostName, size_t nameLength);
+
+/** Attempts to do a reverse lookup of the host field in the address parameter.
+    @param address    address used for reverse lookup
+    @param hostName   destination for name, must not be NULL
+    @param nameLength maximum length of hostName.
+    @returns the null-terminated name of the host in hostName on success
+    @retval 0 on success
+    @retval < 0 on failure
+*/
+ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength);
+
+/** @} */
+
+ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32);
+ENET_API void         enet_packet_destroy (ENetPacket *);
+ENET_API int          enet_packet_resize  (ENetPacket *, size_t);
+extern enet_uint32    enet_crc32 (const ENetBuffer *, size_t);
+                
+ENET_API ENetHost * enet_host_create (const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32);
+ENET_API void       enet_host_destroy (ENetHost *);
+ENET_API ENetPeer * enet_host_connect (ENetHost *, const ENetAddress *, size_t, enet_uint32);
+ENET_API int        enet_host_check_events (ENetHost *, ENetEvent *);
+ENET_API int        enet_host_service (ENetHost *, ENetEvent *, enet_uint32);
+ENET_API void       enet_host_flush (ENetHost *);
+ENET_API void       enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *);
+ENET_API void       enet_host_compress (ENetHost *, const ENetCompressor *);
+ENET_API int        enet_host_compress_with_range_coder (ENetHost * host);
+ENET_API void       enet_host_channel_limit (ENetHost *, size_t);
+ENET_API void       enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
+extern   void       enet_host_bandwidth_throttle (ENetHost *);
+
+ENET_API int                 enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
+ENET_API ENetPacket *        enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
+ENET_API void                enet_peer_ping (ENetPeer *);
+ENET_API void                enet_peer_reset (ENetPeer *);
+ENET_API void                enet_peer_disconnect (ENetPeer *, enet_uint32);
+ENET_API void                enet_peer_disconnect_now (ENetPeer *, enet_uint32);
+ENET_API void                enet_peer_disconnect_later (ENetPeer *, enet_uint32);
+ENET_API void                enet_peer_throttle_configure (ENetPeer *, enet_uint32, enet_uint32, enet_uint32);
+extern int                   enet_peer_throttle (ENetPeer *, enet_uint32);
+extern void                  enet_peer_reset_queues (ENetPeer *);
+extern void                  enet_peer_setup_outgoing_command (ENetPeer *, ENetOutgoingCommand *);
+extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16);
+extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32);
+extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint16);
+extern void                  enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *);
+extern void                  enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *);
+
+ENET_API void * enet_range_coder_create (void);
+ENET_API void   enet_range_coder_destroy (void *);
+ENET_API size_t enet_range_coder_compress (void *, const ENetBuffer *, size_t, size_t, enet_uint8 *, size_t);
+ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t, enet_uint8 *, size_t);
+   
+extern size_t enet_protocol_command_size (enet_uint8);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ENET_ENET_H__ */
+
Index: /osgVisual/trunk/include/cluster/enet/list.h
===================================================================
--- /osgVisual/trunk/include/cluster/enet/list.h	(revision 176)
+++ /osgVisual/trunk/include/cluster/enet/list.h	(revision 176)
@@ -0,0 +1,43 @@
+/** 
+ @file  list.h
+ @brief ENet list management 
+*/
+#ifndef __ENET_LIST_H__
+#define __ENET_LIST_H__
+
+#include <stdlib.h>
+
+typedef struct _ENetListNode
+{
+   struct _ENetListNode * next;
+   struct _ENetListNode * previous;
+} ENetListNode;
+
+typedef ENetListNode * ENetListIterator;
+
+typedef struct _ENetList
+{
+   ENetListNode sentinel;
+} ENetList;
+
+extern void enet_list_clear (ENetList *);
+
+extern ENetListIterator enet_list_insert (ENetListIterator, void *);
+extern void * enet_list_remove (ENetListIterator);
+extern ENetListIterator enet_list_move (ENetListIterator, void *, void *);
+
+extern size_t enet_list_size (ENetList *);
+
+#define enet_list_begin(list) ((list) -> sentinel.next)
+#define enet_list_end(list) (& (list) -> sentinel)
+
+#define enet_list_empty(list) (enet_list_begin (list) == enet_list_end (list))
+
+#define enet_list_next(iterator) ((iterator) -> next)
+#define enet_list_previous(iterator) ((iterator) -> previous)
+
+#define enet_list_front(list) ((void *) (list) -> sentinel.next)
+#define enet_list_back(list) ((void *) (list) -> sentinel.previous)
+
+#endif /* __ENET_LIST_H__ */
+
Index: /osgVisual/trunk/include/cluster/enet/protocol.h
===================================================================
--- /osgVisual/trunk/include/cluster/enet/protocol.h	(revision 176)
+++ /osgVisual/trunk/include/cluster/enet/protocol.h	(revision 176)
@@ -0,0 +1,196 @@
+/** 
+ @file  protocol.h
+ @brief ENet protocol
+*/
+#ifndef __ENET_PROTOCOL_H__
+#define __ENET_PROTOCOL_H__
+
+#include "enet/types.h"
+
+enum
+{
+   ENET_PROTOCOL_MINIMUM_MTU             = 576,
+   ENET_PROTOCOL_MAXIMUM_MTU             = 4096,
+   ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32,
+   ENET_PROTOCOL_MINIMUM_WINDOW_SIZE     = 4096,
+   ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE     = 32768,
+   ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT   = 1,
+   ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT   = 255,
+   ENET_PROTOCOL_MAXIMUM_PEER_ID         = 0xFFF
+};
+
+typedef enum _ENetProtocolCommand
+{
+   ENET_PROTOCOL_COMMAND_NONE               = 0,
+   ENET_PROTOCOL_COMMAND_ACKNOWLEDGE        = 1,
+   ENET_PROTOCOL_COMMAND_CONNECT            = 2,
+   ENET_PROTOCOL_COMMAND_VERIFY_CONNECT     = 3,
+   ENET_PROTOCOL_COMMAND_DISCONNECT         = 4,
+   ENET_PROTOCOL_COMMAND_PING               = 5,
+   ENET_PROTOCOL_COMMAND_SEND_RELIABLE      = 6,
+   ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE    = 7,
+   ENET_PROTOCOL_COMMAND_SEND_FRAGMENT      = 8,
+   ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED   = 9,
+   ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT    = 10,
+   ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11,
+   ENET_PROTOCOL_COMMAND_COUNT              = 12,
+
+   ENET_PROTOCOL_COMMAND_MASK               = 0x0F
+} ENetProtocolCommand;
+
+typedef enum _ENetProtocolFlag
+{
+   ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7),
+   ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6),
+
+   ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 << 14),
+   ENET_PROTOCOL_HEADER_FLAG_SENT_TIME  = (1 << 15),
+   ENET_PROTOCOL_HEADER_FLAG_MASK       = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED | ENET_PROTOCOL_HEADER_FLAG_SENT_TIME,
+
+   ENET_PROTOCOL_HEADER_SESSION_MASK    = (3 << 12),
+   ENET_PROTOCOL_HEADER_SESSION_SHIFT   = 12
+} ENetProtocolFlag;
+
+#ifdef _MSC_VER_
+#pragma pack(push, 1)
+#define ENET_PACKED
+#elif defined(__GNUC__)
+#define ENET_PACKED __attribute__ ((packed))
+#else
+#define ENET_PACKED
+#endif
+
+typedef struct _ENetProtocolHeader
+{
+   enet_uint16 peerID;
+   enet_uint16 sentTime;
+} ENET_PACKED ENetProtocolHeader;
+
+typedef struct _ENetProtocolCommandHeader
+{
+   enet_uint8 command;
+   enet_uint8 channelID;
+   enet_uint16 reliableSequenceNumber;
+} ENET_PACKED ENetProtocolCommandHeader;
+
+typedef struct _ENetProtocolAcknowledge
+{
+   ENetProtocolCommandHeader header;
+   enet_uint16 receivedReliableSequenceNumber;
+   enet_uint16 receivedSentTime;
+} ENET_PACKED ENetProtocolAcknowledge;
+
+typedef struct _ENetProtocolConnect
+{
+   ENetProtocolCommandHeader header;
+   enet_uint16 outgoingPeerID;
+   enet_uint8  incomingSessionID;
+   enet_uint8  outgoingSessionID;
+   enet_uint32 mtu;
+   enet_uint32 windowSize;
+   enet_uint32 channelCount;
+   enet_uint32 incomingBandwidth;
+   enet_uint32 outgoingBandwidth;
+   enet_uint32 packetThrottleInterval;
+   enet_uint32 packetThrottleAcceleration;
+   enet_uint32 packetThrottleDeceleration;
+   enet_uint32 connectID;
+   enet_uint32 data;
+} ENET_PACKED ENetProtocolConnect;
+
+typedef struct _ENetProtocolVerifyConnect
+{
+   ENetProtocolCommandHeader header;
+   enet_uint16 outgoingPeerID;
+   enet_uint8  incomingSessionID;
+   enet_uint8  outgoingSessionID;
+   enet_uint32 mtu;
+   enet_uint32 windowSize;
+   enet_uint32 channelCount;
+   enet_uint32 incomingBandwidth;
+   enet_uint32 outgoingBandwidth;
+   enet_uint32 packetThrottleInterval;
+   enet_uint32 packetThrottleAcceleration;
+   enet_uint32 packetThrottleDeceleration;
+   enet_uint32 connectID;
+} ENET_PACKED ENetProtocolVerifyConnect;
+
+typedef struct _ENetProtocolBandwidthLimit
+{
+   ENetProtocolCommandHeader header;
+   enet_uint32 incomingBandwidth;
+   enet_uint32 outgoingBandwidth;
+} ENET_PACKED ENetProtocolBandwidthLimit;
+
+typedef struct _ENetProtocolThrottleConfigure
+{
+   ENetProtocolCommandHeader header;
+   enet_uint32 packetThrottleInterval;
+   enet_uint32 packetThrottleAcceleration;
+   enet_uint32 packetThrottleDeceleration;
+} ENET_PACKED ENetProtocolThrottleConfigure;
+
+typedef struct _ENetProtocolDisconnect
+{
+   ENetProtocolCommandHeader header;
+   enet_uint32 data;
+} ENET_PACKED ENetProtocolDisconnect;
+
+typedef struct _ENetProtocolPing
+{
+   ENetProtocolCommandHeader header;
+} ENET_PACKED ENetProtocolPing;
+
+typedef struct _ENetProtocolSendReliable
+{
+   ENetProtocolCommandHeader header;
+   enet_uint16 dataLength;
+} ENET_PACKED ENetProtocolSendReliable;
+
+typedef struct _ENetProtocolSendUnreliable
+{
+   ENetProtocolCommandHeader header;
+   enet_uint16 unreliableSequenceNumber;
+   enet_uint16 dataLength;
+} ENET_PACKED ENetProtocolSendUnreliable;
+
+typedef struct _ENetProtocolSendUnsequenced
+{
+   ENetProtocolCommandHeader header;
+   enet_uint16 unsequencedGroup;
+   enet_uint16 dataLength;
+} ENET_PACKED ENetProtocolSendUnsequenced;
+
+typedef struct _ENetProtocolSendFragment
+{
+   ENetProtocolCommandHeader header;
+   enet_uint16 startSequenceNumber;
+   enet_uint16 dataLength;
+   enet_uint32 fragmentCount;
+   enet_uint32 fragmentNumber;
+   enet_uint32 totalLength;
+   enet_uint32 fragmentOffset;
+} ENET_PACKED ENetProtocolSendFragment;
+
+typedef union _ENetProtocol
+{
+   ENetProtocolCommandHeader header;
+   ENetProtocolAcknowledge acknowledge;
+   ENetProtocolConnect connect;
+   ENetProtocolVerifyConnect verifyConnect;
+   ENetProtocolDisconnect disconnect;
+   ENetProtocolPing ping;
+   ENetProtocolSendReliable sendReliable;
+   ENetProtocolSendUnreliable sendUnreliable;
+   ENetProtocolSendUnsequenced sendUnsequenced;
+   ENetProtocolSendFragment sendFragment;
+   ENetProtocolBandwidthLimit bandwidthLimit;
+   ENetProtocolThrottleConfigure throttleConfigure;
+} ENET_PACKED ENetProtocol;
+
+#ifdef _MSC_VER_
+#pragma pack(pop)
+#endif
+
+#endif /* __ENET_PROTOCOL_H__ */
+
Index: /osgVisual/trunk/include/cluster/enet/time.h
===================================================================
--- /osgVisual/trunk/include/cluster/enet/time.h	(revision 176)
+++ /osgVisual/trunk/include/cluster/enet/time.h	(revision 176)
@@ -0,0 +1,18 @@
+/** 
+ @file  time.h
+ @brief ENet time constants and macros
+*/
+#ifndef __ENET_TIME_H__
+#define __ENET_TIME_H__
+
+#define ENET_TIME_OVERFLOW 86400000
+
+#define ENET_TIME_LESS(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW)
+#define ENET_TIME_GREATER(a, b) ((b) - (a) >= ENET_TIME_OVERFLOW)
+#define ENET_TIME_LESS_EQUAL(a, b) (! ENET_TIME_GREATER (a, b))
+#define ENET_TIME_GREATER_EQUAL(a, b) (! ENET_TIME_LESS (a, b))
+
+#define ENET_TIME_DIFFERENCE(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW ? (b) - (a) : (a) - (b))
+
+#endif /* __ENET_TIME_H__ */
+
Index: /osgVisual/trunk/include/cluster/enet/types.h
===================================================================
--- /osgVisual/trunk/include/cluster/enet/types.h	(revision 176)
+++ /osgVisual/trunk/include/cluster/enet/types.h	(revision 176)
@@ -0,0 +1,13 @@
+/** 
+ @file  types.h
+ @brief type definitions for ENet
+*/
+#ifndef __ENET_TYPES_H__
+#define __ENET_TYPES_H__
+
+typedef unsigned char enet_uint8;       /**< unsigned 8-bit type  */
+typedef unsigned short enet_uint16;     /**< unsigned 16-bit type */
+typedef unsigned int enet_uint32;      /**< unsigned 32-bit type */
+
+#endif /* __ENET_TYPES_H__ */
+
Index: /osgVisual/trunk/include/cluster/enet/unix.h
===================================================================
--- /osgVisual/trunk/include/cluster/enet/unix.h	(revision 176)
+++ /osgVisual/trunk/include/cluster/enet/unix.h	(revision 176)
@@ -0,0 +1,45 @@
+/** 
+ @file  unix.h
+ @brief ENet Unix header
+*/
+#ifndef __ENET_UNIX_H__
+#define __ENET_UNIX_H__
+
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <unistd.h>
+
+typedef int ENetSocket;
+
+enum
+{
+    ENET_SOCKET_NULL = -1
+};
+
+#define ENET_HOST_TO_NET_16(value) (htons (value)) /**< macro that converts host to net byte-order of a 16-bit value */
+#define ENET_HOST_TO_NET_32(value) (htonl (value)) /**< macro that converts host to net byte-order of a 32-bit value */
+
+#define ENET_NET_TO_HOST_16(value) (ntohs (value)) /**< macro that converts net to host byte-order of a 16-bit value */
+#define ENET_NET_TO_HOST_32(value) (ntohl (value)) /**< macro that converts net to host byte-order of a 32-bit value */
+
+typedef struct
+{
+    void * data;
+    size_t dataLength;
+} ENetBuffer;
+
+#define ENET_CALLBACK
+
+#define ENET_API extern
+
+typedef fd_set ENetSocketSet;
+
+#define ENET_SOCKETSET_EMPTY(sockset)          FD_ZERO (& (sockset))
+#define ENET_SOCKETSET_ADD(sockset, socket)    FD_SET (socket, & (sockset))
+#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset))
+#define ENET_SOCKETSET_CHECK(sockset, socket)  FD_ISSET (socket, & (sockset))
+    
+#endif /* __ENET_UNIX_H__ */
+
Index: /osgVisual/trunk/include/cluster/enet/utility.h
===================================================================
--- /osgVisual/trunk/include/cluster/enet/utility.h	(revision 176)
+++ /osgVisual/trunk/include/cluster/enet/utility.h	(revision 176)
@@ -0,0 +1,12 @@
+/** 
+ @file  utility.h
+ @brief ENet utility header
+*/
+#ifndef __ENET_UTILITY_H__
+#define __ENET_UTILITY_H__
+
+#define ENET_MAX(x, y) ((x) > (y) ? (x) : (y))
+#define ENET_MIN(x, y) ((x) < (y) ? (x) : (y))
+
+#endif /* __ENET_UTILITY_H__ */
+
Index: /osgVisual/trunk/include/cluster/enet/win32.h
===================================================================
--- /osgVisual/trunk/include/cluster/enet/win32.h	(revision 176)
+++ /osgVisual/trunk/include/cluster/enet/win32.h	(revision 176)
@@ -0,0 +1,58 @@
+/** 
+ @file  win32.h
+ @brief ENet Win32 header
+*/
+#ifndef __ENET_WIN32_H__
+#define __ENET_WIN32_H__
+
+#ifdef ENET_BUILDING_LIB
+#pragma warning (disable: 4996) // 'strncpy' was declared deprecated
+#pragma warning (disable: 4267) // size_t to int conversion
+#pragma warning (disable: 4244) // 64bit to 32bit int
+#pragma warning (disable: 4018) // signed/unsigned mismatch
+#endif
+
+#include <stdlib.h>
+#include <winsock2.h>
+
+typedef SOCKET ENetSocket;
+
+enum
+{
+    ENET_SOCKET_NULL = INVALID_SOCKET
+};
+
+#define ENET_HOST_TO_NET_16(value) (htons (value))
+#define ENET_HOST_TO_NET_32(value) (htonl (value))
+
+#define ENET_NET_TO_HOST_16(value) (ntohs (value))
+#define ENET_NET_TO_HOST_32(value) (ntohl (value))
+
+typedef struct
+{
+    size_t dataLength;
+    void * data;
+} ENetBuffer;
+
+#define ENET_CALLBACK __cdecl
+
+#if defined ENET_DLL
+#if defined ENET_BUILDING_LIB
+#define ENET_API __declspec( dllexport )
+#else
+#define ENET_API __declspec( dllimport )
+#endif /* ENET_BUILDING_LIB */
+#else /* !ENET_DLL */
+#define ENET_API extern
+#endif /* ENET_DLL */
+
+typedef fd_set ENetSocketSet;
+
+#define ENET_SOCKETSET_EMPTY(sockset)          FD_ZERO (& (sockset))
+#define ENET_SOCKETSET_ADD(sockset, socket)    FD_SET (socket, & (sockset))
+#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset))
+#define ENET_SOCKETSET_CHECK(sockset, socket)  FD_ISSET (socket, & (sockset))
+
+#endif /* __ENET_WIN32_H__ */
+
+
Index: /osgVisual/trunk/include/core/leakDetection.h
===================================================================
--- /osgVisual/trunk/include/core/leakDetection.h	(revision 176)
+++ /osgVisual/trunk/include/core/leakDetection.h	(revision 176)
@@ -0,0 +1,31 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+// Basic ideas for memory leak debugging:
+// http://weseetips.com/2008/06/17/how-to-detect-memory-leaks-by-using-crt/
+// http://stackoverflow.com/questions/532917/dealing-with-incorrect-memory-leak-reports-on-windows
+// http://msdn.microsoft.com/en-us/library/x98tx3cf.aspx
+
+#ifdef _DEBUG
+	#ifdef WIN32
+		#ifndef USE_SKY_SILVERLINING
+			#ifndef DBG_NEW
+				#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
+				#define new DBG_NEW
+			#endif
+		#endif
+	#endif
+#endif
Index: /osgVisual/trunk/include/core/visual_core.h
===================================================================
--- /osgVisual/trunk/include/core/visual_core.h	(revision 176)
+++ /osgVisual/trunk/include/core/visual_core.h	(revision 176)
@@ -0,0 +1,189 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+// XML Parser
+#include <stdio.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+
+#include <osg/Referenced>
+#include <osg/Notify>
+
+#include <osgViewer/Viewer>
+
+#include <osgDB/ReadFile>
+
+// OSG eventhandler
+#include <osgViewer/ViewerEventHandlers>
+
+// OSG manipulator
+#include <osgGA/TrackballManipulator>
+#include <osgGA/FlightManipulator>
+#include <osgGA/DriveManipulator>
+#include <osgGA/KeySwitchMatrixManipulator>
+#include <osgGA/StateSetManipulator>
+#include <osgGA/AnimationPathManipulator>
+#include <osgGA/TerrainManipulator>
+#include <osgGA/NodeTrackerManipulator>
+
+// Spacenavigator manipulator
+#ifdef USE_SPACENAVIGATOR
+#include <manip_spaceMouse.h>
+#include <manip_nodeTrackerSpaceMouse.h>
+#include <manip_freeSpaceMouse.h>
+#endif
+
+// Object mounted manipulator
+#include <manip_objectMounted.h>
+
+#ifdef USE_DISTORTION
+// Distortion
+#include <visual_distortion.h>
+#endif
+
+#ifdef USE_SKY_SILVERLINING
+// Sky
+#include <visual_skySilverLining.h>
+#endif
+
+// DataIO
+#include <visual_dataIO.h>
+#include <object_updater.h>
+
+// visual_object
+#include <visual_object.h>
+
+// visual_hud
+#include <visual_hud.h>
+#include <visual_debug_hud.h>
+
+// visual_draw2D
+#include <visual_draw2D.h>
+#include <visual_draw3D.h>
+
+// visual util
+#include <visual_util.h>
+
+// visual_vista2D
+#ifdef USE_VISTA2D
+#include <visual_vista2D.h>
+#endif
+
+// Test
+#include <dataIO_transportContainer.h>
+#include <osgDB/OutputStream>
+#include <iostream>
+
+
+
+
+namespace osgVisual
+{
+
+class visual_core : public osg::Referenced
+{
+	#include <leakDetection.h>
+
+public:
+	visual_core(osg::ArgumentParser& arguments_);
+	void initialize();
+	void shutdown();
+
+	void addManipulators();
+	void parseConfigFile(osg::ArgumentParser& arguments_);
+	void checkXMLNode(xmlNode * a_node);
+	void parseModule(xmlNode * a_node);
+	void parseScenery(xmlNode * a_node);
+	void config(xmlNode * a_node);
+	bool loadTerrain(osg::ArgumentParser& arguments_);
+	bool checkCommandlineArgumentsForFinalErrors();
+
+	void setupScenery();
+	
+protected:
+	virtual ~visual_core(void);
+
+
+private:
+	void mainLoop();
+
+	/**
+	 * Argument object, with contains all commandline arguments, which where called during programm sstartup
+	 */ 
+	osg::ArgumentParser& arguments;
+
+	/**
+	 * This CSN is at the top node on the complete scenery. Only the nodes for distortion are located above this node.
+	 */ 
+	osg::ref_ptr<osg::CoordinateSystemNode> rootNode;
+
+	/**
+	 * Reference pointer to the viewer instance. The viewer is the core of the graphical subsystem.
+	 */ 
+	osg::ref_ptr<osgViewer::Viewer> viewer;
+
+	/**
+	 * XML configuration filename.
+	 */
+	std::string configFilename;
+
+
+#ifdef USE_SPACENAVIGATOR
+	/**
+	 * Spacemouse node tracker manipulator
+	 */ 
+	osg::ref_ptr<NodeTrackerSpaceMouse> mouseTrackerManip;
+
+	/**
+	 * Space mouse hardware driver instance
+	 */ 
+	SpaceMouse* mouse;
+#endif
+
+	/**
+	 * This Matrix manipulator is used for controlling Camera by Nodes.
+	 */ 
+	osg::ref_ptr<objectMountedManipulator> objectMountedCameraManip;
+
+
+#ifdef USE_SKY_SILVERLINING
+	/**
+	 * Silverlining Sky instance
+	 */ 
+	osg::ref_ptr<visual_skySilverLining> sky;
+
+	xmlNode* skySilverliningConfig;
+#endif
+
+#ifdef USE_DISTORTION
+	/**
+	 * Distortion instance.
+	 */ 
+	osg::ref_ptr<visual_distortion> distortion;
+
+	xmlNode* distortionConfig;
+#endif
+
+	osg::ref_ptr<visual_object> testObj;
+
+	osg::ref_ptr<osgGA::NodeTrackerManipulator> nt;
+
+	osg::ref_ptr<visual_debug_hud> hud;
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/dataIO/dataIO_executer.h
===================================================================
--- /osgVisual/trunk/include/dataIO/dataIO_executer.h	(revision 176)
+++ /osgVisual/trunk/include/dataIO/dataIO_executer.h	(revision 176)
@@ -0,0 +1,75 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <osg/Node>
+#include <osgDB/ObjectWrapper>
+#include <osgDB/InputStream>
+#include <osgDB/OutputStream>
+
+#include <string>
+
+namespace osgVisual {
+
+class dataIO_executer : public osg::Node
+{
+	#include <leakDetection.h>
+public:
+	dataIO_executer() {id=DO_NOTHING;}
+	~dataIO_executer() {}
+
+	// Standart functions of the base-class, required for serialization
+	//// Copy constructor using CopyOp to manage deep vs shallow copy.
+	dataIO_executer(const dataIO_executer& ex, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY) : osg::Node(ex, copyop) {} 
+	//// osg::Objects functions
+	osg::Object* cloneType() const { return new dataIO_executer (); }
+	osg::Object* clone(const osg::CopyOp& copyop) const { return new dataIO_executer (*this,copyop); }
+	bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const dataIO_executer *>(obj)!=NULL; }
+	const char* className() const { return "dataIO_executer"; }
+	const char* libraryName() const { return "osgVisual"; }
+
+	typedef std::vector<double> parameterList;
+	enum executerID {
+		GET_HAT,
+		GET_HOT,
+		GET_LAT,
+		GET_LON,
+		IS_COLLISION, 
+		IS_INSIDE_CLOUD,
+		IS_WIND,
+		IS_PRECIPITATION,
+		DO_NOTHING
+	};
+	
+
+private: 
+	executerID id;
+	parameterList doubleParameter;
+	std::string stringParameter;
+
+// Access functions for Serializer
+public:
+	void setexecuterID(executerID id_) {id=id_;}
+	executerID getexecuterID() const {return id;}
+
+	void setDoubleParameter(const parameterList& doubleParameter_) {doubleParameter=doubleParameter_;}
+	const parameterList& getDoubleParameter() const {return doubleParameter;}
+
+	void setStringParameter(const std::string& stringParameter_) {stringParameter=stringParameter_;}
+	const std::string& getStringParameter() const {return stringParameter;}
+};
+
+} // END NAMESPACE
Index: /osgVisual/trunk/include/dataIO/dataIO_slot.h
===================================================================
--- /osgVisual/trunk/include/dataIO/dataIO_slot.h	(revision 176)
+++ /osgVisual/trunk/include/dataIO/dataIO_slot.h	(revision 176)
@@ -0,0 +1,90 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <osg/Object>
+#include <osgDB/ObjectWrapper>
+#include <osgDB/InputStream>
+#include <osgDB/OutputStream>
+
+#include <string>
+
+
+namespace osgVisual {
+
+class dataIO_slot : public osg::Object
+{
+	#include <leakDetection.h>
+public:
+	META_Object(osgVisual,dataIO_slot);
+	dataIO_slot(const osgVisual::dataIO_slot& slot_, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
+            Object(slot_,copyop),
+			direction(slot_.direction),
+			variableType(slot_.variableType),
+			variableName(slot_.variableName),
+			value(slot_.value),
+			sValue(slot_.sValue){}
+
+	dataIO_slot(){};
+	~dataIO_slot(){};
+
+	dataIO_slot & operator=(const dataIO_slot &rhs)
+	{
+		direction=rhs.direction;
+		variableType=rhs.variableType;
+		variableName=rhs.variableName;
+		value=rhs.value;
+		sValue=rhs.sValue;	
+
+		return *this;
+	}
+
+
+	/**
+	 * This enums defines the data flow direction of a slot.
+	 */ 
+	enum dataDirection {TO_OBJ, FROM_OBJ};
+
+	/**
+	 * This enum defines the two valid valuetypes.
+	 */ 
+	enum varType {DOUBLE, STRING};
+
+	dataDirection direction;
+	varType variableType;
+	std::string variableName;
+	double value;
+	std::string sValue;
+
+
+// Access functions for Serializer
+	void setdataDirection(dataDirection direction_){direction=direction_;}
+	dataDirection getdataDirection() const {return direction;}
+
+	void setvarType(varType variableType_){variableType=variableType_;}
+	varType getvarType() const {return variableType;}
+
+	const std::string& getVariableName() const {return variableName;}
+	void setVariableName(const std::string& variableName_){variableName=variableName_;}
+
+	double getValue() const {return value;}
+	void setValue(double value_){value=value_;}
+
+	const std::string& getSValue() const {return sValue;}
+	void setSValue(const std::string& sValue_){sValue=sValue_;}
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/dataIO/dataIO_transportContainer.h
===================================================================
--- /osgVisual/trunk/include/dataIO/dataIO_transportContainer.h	(revision 176)
+++ /osgVisual/trunk/include/dataIO/dataIO_transportContainer.h	(revision 176)
@@ -0,0 +1,77 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <osg/Object>
+#include <osg/Matrixd>
+#include <osg/Vec3d>
+
+#include <dataIO_executer.h>
+#include <dataIO_slot.h>
+
+#include <vector>
+
+namespace osgVisual {
+
+class dataIO_transportContainer : public osg::Object
+{
+	#include <leakDetection.h>
+public:
+	META_Object(osgVisual,dataIO_transportContainer);	// Required for serializer
+	dataIO_transportContainer(const osgVisual::dataIO_transportContainer& tC_, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):	// Required for serializer
+			Object(tC_,copyop),
+			frameID(tC_.frameID),
+			viewMatrix(tC_.viewMatrix),
+			executer(tC_.executer),
+			ioSlots(tC_.ioSlots){}
+	dataIO_transportContainer(){}
+	virtual ~dataIO_transportContainer(){}
+
+
+	typedef std::vector<osg::ref_ptr<dataIO_executer> > executerList;
+	typedef std::vector<osg::ref_ptr<dataIO_slot> > slotList;
+
+private:
+	int frameID;
+	osg::Matrixd viewMatrix;
+	executerList executer;
+	slotList ioSlots;
+
+// Access functions for Serializer
+public:
+	int getFrameID() const {return frameID;}
+	void setFrameID(int frameID_ ){frameID=frameID_;}
+
+	void setViewMatrix(const osg::Matrixd& viewMatrix_){viewMatrix = viewMatrix_;}
+	const osg::Matrixd& getViewMatrix() const {return viewMatrix;}
+
+	void setExecuter(const executerList& executer_) {executer=executer_;}
+	const executerList& getExecuter() const {return executer;}
+
+	void setIOSlots(const slotList& ioSlots_) {ioSlots=ioSlots_;}
+	const slotList& getIOSlots() const {return ioSlots;}
+
+
+	// Usage functions
+	void addExecuter( osg::ref_ptr<dataIO_executer> executerToAdd_ ) {executer.push_back(executerToAdd_);}
+	void removeAllExecuter() { executer.clear();}
+
+	void addSlot( osg::ref_ptr<dataIO_slot> slotToAdd_ ) {ioSlots.push_back(slotToAdd_);}
+	void removeAllSlots() {ioSlots.clear();}
+
+};
+
+} // END NAMESPACE
Index: /osgVisual/trunk/include/dataIO/visual_dataIO.h
===================================================================
--- /osgVisual/trunk/include/dataIO/visual_dataIO.h	(revision 176)
+++ /osgVisual/trunk/include/dataIO/visual_dataIO.h	(revision 176)
@@ -0,0 +1,230 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <osg/Notify>
+#include <osg/Referenced>
+#include <osg/ArgumentParser>
+
+#include <osgViewer/Viewer>
+
+// osgVisual specifiy includes
+#include <visual_util.h>
+
+// Cluster
+#ifdef USE_CLUSTER_ASIO_TCP_IOSTREAM
+	#include <dataIO_clusterAsioTcpIostream.h>
+#endif
+#ifdef USE_CLUSTER_ENET
+	#include <dataIO_clusterENet.h>
+#endif
+#ifdef USE_CLUSTER_DUMMY
+	#include <dataIO_clusterDummy.h>
+#endif
+
+
+//ExtLink 
+#ifdef USE_EXTLINK_DUMMY
+	#include <dataIO_extLinkDummy.h>
+#endif
+#ifdef USE_EXTLINK_VCL
+	#include <dataIO_extLinkVCL.h>
+#endif
+
+
+// Slot and transportContainer definitions
+#include <dataIO_slot.h>
+#include <dataIO_transportContainer.h>
+
+// XML Parser
+#include <stdio.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+// C++ stl libraries
+#include <vector>
+
+
+
+
+namespace osgVisual {
+
+/**
+ * \brief Zentrale Klasse für Datenanbindung des Sichtsystemnodes an das Gesamtsichtsystem bzw. dem Simulator.
+ * 
+ * Damit nur eine Klasse instantiiert werden kann, ist diese Klasse als Singleton realisiert.
+ * 
+ * 
+ * @author Torben Dannhauer
+ * @date  Nov 2009
+ */ 
+class visual_dataIO : public osg::Referenced
+{
+	#include <leakDetection.h>
+private:
+	class dataIO_eventCallback : public osg::NodeCallback
+	{
+	public: 
+		/**
+		 * \brief Constructor, for setting the member variables.
+		 * 
+		 * @param viewer_ : Pointer to the viewer.
+		 * @param sceneCamera_ : Pointer to the scene camera.
+		 */ 
+		dataIO_eventCallback(visual_dataIO* dataIO_):dataIO(dataIO_){};
+
+		/**
+		 * \brief This function is execute d as callback during update traversal.
+		 * 
+		 */ 
+		virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
+	private:
+		visual_dataIO* dataIO;
+	};
+	osg::ref_ptr<dataIO_eventCallback> eventCallback;
+
+	class dataIO_finalDrawCallback : public osg::Camera::DrawCallback
+	{
+	public:
+		/**
+		 * \brief Constructor
+		 * 
+		 */ 
+		dataIO_finalDrawCallback(visual_dataIO* dataIO_):dataIO(dataIO_){};
+		
+		/**
+		 * \brief Operator executed at callback
+		 * 
+		 */ 
+		virtual void operator () (const osg::Camera& camera) const;
+	private:
+		visual_dataIO* dataIO;
+	};
+
+	osg::ref_ptr<dataIO_finalDrawCallback> finalDrawCallback;
+
+	/**
+	 * \brief Constructor: It is private to prevent creating instances via ptr* = new ..().
+	 * 
+	 */ 
+	visual_dataIO();
+
+	/**
+	 * \brief Copy-Constuctor: It is private to prevent getting instances via copying dataIO instance.
+	 * 
+	 * @param cc : Instance to copy from.
+	 */ 
+	visual_dataIO(const visual_dataIO& cc);
+
+	/**
+	 * \brief This function parses the XML config file for dataIO relevant parameters.
+	 * 
+	 * @return : True if parsing was successful.
+	 */ 
+	bool processXMLConfiguration(); 
+
+	/**
+	 * \brief Todo: required?
+	 * 
+	 * @return 
+	 */ 
+	osg::Matrixd calcViewMatrix();
+
+	/**
+	 * Pointer to the base class of the extLink implementation.
+	 */ 
+	osg::ref_ptr<dataIO_extLink> extLink;
+
+	/**
+	 * Pointer to the base class of the cluster implementation.
+	 */ 
+	osg::ref_ptr<dataIO_cluster> cluster;
+
+	/**
+	 * Referenced pointer to the applications viewer.
+	 */ 
+	osg::ref_ptr<osgViewer::Viewer> viewer;
+
+	/**
+	 * Referenced pointer transport contained user to transport the set of all slots to all rendering machines.
+	 */ 
+	osg::ref_ptr<osgVisual::dataIO_transportContainer> slotContainer;
+
+	/**
+	 * List of SLOT variables dataIO provides.
+	 */ 
+	std::vector<dataIO_slot*> dataSlots;
+
+	/**
+	 * Flag to indicate if dataIO is initialized.
+	 */ 
+	bool initialized;
+
+	/**
+	 * Curent clustermode of the application. Can be MASTER, SLAVE or STANDALONE.
+	 */ 
+	osgVisual::dataIO_cluster::clustermode clusterMode;
+
+	/**
+	 * XML config filename
+	 */ 
+	std::string configFileName;
+
+	/**
+	 * The eventCallback-class is friend to be able to work with all dataIO members without setters/getters.
+	 */ 
+	friend class dataIO_eventCallback;
+
+	/**
+	 *  The FinalDrawCallback-class is friend to be able to work with all dataIO members without setters/getters.
+	 */ 
+	friend class dataIO_finalDrawCallback;
+
+public:
+	/**
+	 * \brief Public destructor to allow singleton cleanup from extern
+	 * 
+	 */ 
+	~visual_dataIO();
+
+	/**
+	 * \brief This function returns an pointer to the singleton instance of dataIO. If no instance exist, it will be instantiated silently.
+	 * 
+	 * After instantiation, dataIO still needs to bei initiialized to configure working mode etc!
+	 * 
+	 * @return : Pointer to the instance. 
+	 */ 
+	static visual_dataIO* getInstance();
+
+	void init(osgViewer::Viewer* viewer_,osg::ArgumentParser& arguments_, std::string configFileName);
+	void shutdown();
+	bool isMaster(){if (clusterMode==osgVisual::dataIO_cluster::MASTER) return true; else return false;};
+	bool isSlave(){if (clusterMode==osgVisual::dataIO_cluster::SLAVE) return true; else return false;};
+	bool isStandalone(){if (clusterMode==osgVisual::dataIO_cluster::STANDALONE) return true; else return false;};
+
+// SLOT Access functions
+	void* getSlotPointer(std::string slotName_, osgVisual::dataIO_slot::dataDirection direction_, osgVisual::dataIO_slot::varType variableTyp_ );
+	double getSlotDataAsDouble(std::string variableName_, osgVisual::dataIO_slot::dataDirection direction_ );
+	std::string getSlotDataAsString(std::string variableName_, osgVisual::dataIO_slot::dataDirection direction_ );
+	osgVisual::dataIO_slot* setSlotData(std::string variableName_, osgVisual::dataIO_slot::dataDirection direction_, std::string sValue_ );
+	osgVisual::dataIO_slot* setSlotData(std::string variableName_, osgVisual::dataIO_slot::dataDirection direction_, double value_ );
+
+	int getSlotNum() {return dataSlots.size();}
+
+};
+
+
+} // END namespace osgVisual
Index: /osgVisual/trunk/include/distortion/visual_distortion.h
===================================================================
--- /osgVisual/trunk/include/distortion/visual_distortion.h	(revision 176)
+++ /osgVisual/trunk/include/distortion/visual_distortion.h	(revision 176)
@@ -0,0 +1,493 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <osg/NodeCallback>
+#include <osg/Node>
+#include <osg/Geode>
+#include <osg/Geometry>
+#include <osg/Texture2D>
+#include <osg/TextureRectangle>
+#include <osg/Notify>
+#include <osg/Referenced>
+
+#include <osgViewer/Viewer>
+
+#include <osgDB/ReadFile>
+#include <osgDB/FileUtils>
+
+#include <osgGA/GUIEventHandler>
+#include <osgGA/GUIActionAdapter>
+
+#include <visual_util.h>
+
+#include <string>
+#include <iostream>
+#include <fstream>
+
+// XML Parser
+#include <stdio.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+
+namespace osgVisual
+{
+
+
+//class CameraConfigParser;
+
+/**
+ * \brief This class distorts and blends the rendered image for projection in curved screens and multi channel setups.
+ * 
+ * @todo Distortion algorithm seems to be erronous, small artefact lines are visible.
+ * 
+ * @author Torben Dannhauer
+ * @date  Jul 2009
+ */ 
+class visual_distortion : public osg::Node
+{
+	#include <leakDetection.h>
+public:
+	/**
+	 * \brief Constructor
+	 * 
+	 */ 
+	visual_distortion(osgViewer::Viewer* viewer_, osg::ArgumentParser& arguments_, std::string configFileName);
+
+	/**
+	 * \brief Destructor
+	 * 
+	 */ 
+	virtual ~visual_distortion(void);
+
+	/**
+	 * \brief This function parses the XML config file for distortion relevant parameters.
+	 * 
+	 * @return : True if parsing was successful.
+	 */ 
+	bool processXMLConfiguration(); 
+
+	/**
+	 * \brief This function initializes the distortion node and creates the distortion camera and scene graph.
+	 * 
+	 * @param subgraph : Undistorted scene graph.
+	 * @param clearColor : Clear color for distortion.
+	 * @return : Group node which contains the distortion and the undistorted scene graph ( distortedGraph ).
+	 */ 
+	osg::Group* initialize(osg::Group* subgraph, const osg::Vec4& clearColor );
+
+	/**
+	 * \brief This function shuts the distortion module down.
+	 * 
+	 */ 
+	void shutdown();
+
+	/**
+	 * \brief This function enabels or disables the distortion
+	 */ 
+	void toggleDistortion();
+
+	/**
+	 * \brief This functions returns a pointer to the scene camera, which renders the undistorted scene (PRE_RENDER).
+	 * 
+	 * @return Pointer to the scene camera.
+	 */ 
+	osg::Camera* getSceneCamera() {return sceneCamera;};
+
+	/**
+	 * \brief This function returns the distortedSceneGraph if the distortion module is initialized.
+	 * 
+	 * @return NULL if not Initialized, Otherwith the distorted sceneGraph.
+	 */ 
+	osg::Group* getDistortedSceneGraph() { if(initialized) return distortedGraph; else return NULL;};
+
+	/**
+	 * \brief The function returns the frustum values which are parsed by the nested cameraConfigParser class.
+	 * 
+	 * @return : Vector of double values which represent the frustum dataset. The order is the standart glu order.
+	 */ 
+	std::vector<double> getFrustumDataset() {return parser->getFrustumDataset();};
+			
+	/**
+	 * \brief This function returns the retation values for the rendering camera for XYZ axis in degree.
+	 * 
+	 * @return : Vector of double values which represent the rotation values for XYZ axis in degree.
+	 */ 
+	std::vector<double> getRotationDataset() {return parser->getRotationDataset();};
+
+	/**
+	 * \brief This function returns the translation values for the rendering camera along the XYZ axis in meter.
+	 * 
+	 * @return : Vector of double values which represent the translation values for XYZ axis in meter.
+	 */ 
+	std::vector<double> getTranslationDataset() {return parser->getTranslationDataset();};
+
+private:
+	/**
+	 * \brief Callback class for update callback.
+	 * 
+	 * This nested class is used for updating the distortion node every frame by installing this class as updateCallback for the distortion node.
+	 * @author Torben Dannhauer
+	 * @date  Jul 2009
+	 */ 
+	class distortionUpdateCallback : public osg::NodeCallback
+	{
+	public: 
+		/**
+		 * \brief Constructor, for setting the member variables.
+		 * 
+		 * @param viewer_ : Pointer to the viewer.
+		 * @param sceneCamera_ : Pointer to the scene camera.
+		 */ 
+		distortionUpdateCallback(osgViewer::Viewer* viewer_, osg::Camera* sceneCamera_)
+			: viewer(viewer_), sceneCamera(sceneCamera_) {};
+
+		/**
+		 * \brief This function is executed as callback during update traversal.
+		 * 
+		 */ 
+		virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
+	private:
+		/**
+		 * Referenced Pointer to the applications viewer.
+		 */ 
+		osg::ref_ptr<osgViewer::Viewer> viewer;
+
+		/**
+		 * Referenced Pointer to the scene camera.
+		 */ 
+		osg::ref_ptr<osg::Camera> sceneCamera;
+	};
+
+	/**
+	 * \brief This nested class is a keyboard event adapter which allows distortion toggle. It never blocks the key event, therefore multiple events on a single key are possible.
+	 * 
+	 * @author Torben Dannhauer
+	 * @date  Jul 2009
+	 */ 
+	class ToggleDistortionKBEventHandler : public osgGA::GUIEventHandler
+	{
+	public:
+		/**
+		 * \brief Constructor
+		 * 
+		 * @param distortion_ : Pointer to the distortion class.
+		 * @param viewer_ : Reference to the applications viewer.
+		 */ 
+		ToggleDistortionKBEventHandler(visual_distortion* distortion_): distortion(distortion_) {}
+
+		/**
+		 * \brief This function is executed if an keyboard event appears
+		 * 
+		 * @param ea : GUI event adapter.
+		 * @param : GUI action adapter.
+		 * @return : Returns always false to pass the event to other event adapter if installed.
+		 */    
+		virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
+		{
+			if ( ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN &&  ea.getKey() == 'd' )
+			{
+				distortion->toggleDistortion();
+				return false;
+			}
+			else
+				return false;	// return false means: hand over the event to the next Eventhandler.  True means: absorb the event.
+		}
+
+	private:
+		/**
+		 * Pointer to he distortion class. INside this EventHandler a Referenced Pointer ist _NOT_ used, 
+		 * because a circulare reference (distortion->kBEventHandler, kbEventHandler->distortion) would block both pointer to unref.
+		 */ 
+		visual_distortion* distortion;
+	};
+
+	/**
+	 * \brief This nested class reads the Projection Designer's project file and extracts the frustum, translation and rotation values
+	 * 
+	 * @author Torben Dannhauer
+	 * @date  Aug 2009
+	 */ 
+	class CameraConfigParser : public osg::Referenced
+	{
+	public:
+		CameraConfigParser(void)
+		{
+			configParsed = false;
+			frustumValues.clear();
+			rotationValues.clear();
+			rotationValues.resize(3,0);
+			translationValues.clear();
+			translationValues.resize(3,0);
+		}
+
+		virtual ~CameraConfigParser(void) {};
+
+		bool parseConfigFile(const char * filename)
+		{
+		  if (! osgDB::fileExists(filename) )
+		  {
+			  OSG_NOTIFY( osg::FATAL ) << "ERROR: File '" << filename << "' does not exist." << std::endl;
+			  return false;
+		  }
+
+		  frustumValues.clear();
+		  rotationValues.clear();
+		  rotationValues.resize(3,0);
+		  translationValues.clear();
+		  translationValues.resize(3,0);
+
+		  std::string line;
+		  std::ifstream configFile (filename);
+
+		  if (configFile.is_open())
+		  {
+			while (! configFile.eof() )
+			{
+			  getline (configFile,line);
+			  //cout << line << endl;
+
+			  // Auf Frustum untersuchen
+			  if( line.find("Frustum") != std::string::npos )
+			  {
+				  extractFrustum(line);
+			  }
+
+			  // Auf Rotation untersuchen
+			  if( line.find("Rotate") != std::string::npos )
+			  {
+				 extractRotation(line);
+			  }
+
+			  // Auf Translation untersuchens
+			  if( line.find("Translate") != std::string::npos )
+			  {
+				 extractTranslation(line);
+			  }
+
+			}
+			configFile.close();
+			configParsed = true;
+			return true;
+		  }
+		  else 
+		  {
+			  OSG_NOTIFY( osg::FATAL ) << "Unable to open file:" << filename << std::endl;
+			  frustumValues.clear();
+			  configParsed = false;
+			  return false;
+		  }
+		}
+
+		bool extractFrustum(std::string data_)
+		{
+			data_.replace(0,16,"");		// Delete leading spaces and "Frustum"
+			data_.replace(data_.length()-1,1,"");	// Delete trailing ";"
+			for( int i=0; i<6; i++)
+			{
+				size_t pos = data_.find(" ");    // Position of first value in string
+				if( pos == -1) pos = data_.length();
+				frustumValues.push_back( atof( data_.substr(0, pos).data() ) );
+				data_.replace(0,pos+1,"");
+			}
+			return true;
+		}
+
+		bool extractRotation(std::string data_)
+		{
+			data_.replace(0,15,"");		// Delete leading spaces and "Rotate"
+			data_.replace(data_.length()-1,1,"");	// Delete trailing ";"
+
+			size_t valuePos = data_.find(" ");    // First Value is RotationValue
+			std::string axis = data_.substr( valuePos+1);
+			switch(axis.find("1"))
+			{
+				case 0: rotationValues[0] = atof( data_.substr(0, valuePos).data() ); // X-Axis
+					break;
+				case 2: rotationValues[1] = atof( data_.substr(0, valuePos).data() ); // Y-Axis
+					break;
+				case 4: rotationValues[2] = atof( data_.substr(0, valuePos).data() ); // Z-Axis
+					break;
+			};
+			return true;
+		}
+
+		bool extractTranslation(std::string data_)
+		{
+			data_.replace(0,18,"");		// Delete leading spaces and "Translate"
+			data_.replace(data_.length()-1,1,"");	// Delete trailing ";"
+			for( unsigned int i=0;i<translationValues.size(); i++)
+			{
+				size_t valuePos = data_.find(" ");
+				std::string value = data_.substr(0, valuePos);
+				data_.replace(0,valuePos+1,"");
+				translationValues[i] = atof( value.data() );
+			}
+			return true;
+		}
+
+		std::vector<double> getFrustumDataset() {return(frustumValues);}
+			
+		std::vector<double> getRotationDataset() {return(rotationValues);}
+
+		std::vector<double> getTranslationDataset() {return(translationValues);}
+
+		bool isConfigParsed() {return configParsed;};
+	private:
+		bool configParsed;
+		std::vector<double> frustumValues;
+		std::vector<double> rotationValues;
+		std::vector<double> translationValues;
+	};
+
+
+
+	/**
+	 * Updatecallback as member variable of this class.
+	 */ 
+	osg::ref_ptr<distortionUpdateCallback> updateCallback;
+
+	/**
+	 * Keyboard Eventhandler for distortion toggle.
+	 */ 
+	//osg::ref_ptr<ToggleDistortionKBEventHandler> kBEventHandler;
+	ToggleDistortionKBEventHandler* kBEventHandler;
+
+	/**
+	 * \brief This functions creates the distortion environment.
+	 * 
+	 * @param subgraph : Undistorted scene graph to distort.
+	 * @param clearColor : OpenGL clear color to use for the distortion.
+	 * @return : Group node which contains the distortion and the undistorted scene graph.
+	 */ 
+	osg::Group* createPreRenderSubGraph(osg::Group* subgraph, const osg::Vec4& clearColor );
+
+	/**
+	 * \brief This function loads a shader source file
+	 * 
+	 * @param shader : Shader to load source in
+	 * @param fileName : Filename of shader source file.
+	 * @return : Returns true if successful.
+	 */ 
+	bool loadShaderSource( osg::Shader* shader, const std::string& fileName );
+
+	/**
+	 * \brief This function loads a shader Texture file
+	 * 
+	 * @param fileName : Texture file to load.
+	 * @return : Returns the loaded Texture.
+	 */ 
+	osg::Texture* loadTexture( const std::string& fileName );
+	
+	/**
+	 * Referenced Pointer to the loaded distortion Map
+	 */ 
+	osg::ref_ptr<osg::Texture> distortMapTexture;
+
+	/**
+	 * Referenced Pointer to the loaded blend map
+	 */ 
+	osg::ref_ptr<osg::Texture> blendMapTexture;
+
+
+	/**
+	 * Flag which indicates the initialization status
+	 */ 
+	bool initialized;
+
+	/**
+	 * Flag that indicates if distortion is actually enabled. This is imported for the toggleDistortion() function.
+	 */ 
+	bool distortionEnabled;
+
+	/**
+	 * Reference pointer to the distorted scene graph.
+	 */ 
+	osg::ref_ptr<osg::Group> distortedGraph;
+
+	/**
+	 * Reference pointer to the undistorted scene graph.
+	 */ 
+	osg::ref_ptr<osg::Group> cleanGraph;
+
+	/**
+	 * Reference pointer to the scen camera (PRE_RENDER)
+	 */ 
+	osg::ref_ptr<osg::Camera> sceneCamera;
+
+	/**
+	 * Referenced pointer to the main applications viewer
+	 */ 
+	osg::ref_ptr<osgViewer::Viewer> viewer;
+
+	/**
+	 * Parser object for parsing the camera configuration file which controlls frustum and camera PAT
+	 */ 
+	osg::ref_ptr<CameraConfigParser> parser;
+
+	/**
+	 * Texture width for render to texture (RTT).
+	 */ 
+	unsigned tex_width;
+
+	/**
+	 * Texture height for using render to texture (RTT).
+	 */ 
+    unsigned tex_height;
+
+	/**
+	 * Indicates of texture rectangle should be used.
+	 */ 
+	bool useTextureRectangle;
+
+	/**
+	 * Indicates if shader distortion should be used.
+	 */ 
+	bool useShaderDistortion;
+
+	/**
+	 * Indicates if high definition rendering shold be used.
+	 */ 
+	bool useHDR;
+
+	/**
+	 * Filename of the distorion map.
+	 */ 
+	std::string distortMapFileName;
+
+	/**
+	 * Filename of the blend map.
+	 */ 
+	std::string blendMapFileName;
+
+	/**
+	 * XML config filename
+	 */ 
+	std::string configFileName;
+
+	/**
+	 * Target implementation which should be used to distort.
+	 */ 
+	osg::Camera::RenderTargetImplementation renderImplementation;
+
+	/**
+	 * Reference to the global ArgumentParser. The arguments are required to add the help entry for the toggle distortion key. All other configuration is located in the XML file.
+	 */ 
+	osg::ArgumentParser& arguments;
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/draw2D/visual_debug_hud.h
===================================================================
--- /osgVisual/trunk/include/draw2D/visual_debug_hud.h	(revision 176)
+++ /osgVisual/trunk/include/draw2D/visual_debug_hud.h	(revision 176)
@@ -0,0 +1,130 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <sstream>
+#include <iostream>
+#include <iomanip>
+
+#include <osg/NodeCallback>
+
+#include <visual_draw2D.h>
+#include <visual_util.h>
+
+
+namespace osgVisual
+{
+
+/**
+ * \brief This class prints debug information about LAT, LON, HAT, HOT on screen.
+ * 
+ * 
+ * @author Torben Dannhauer
+ * @date  Jan 2010
+ */ 
+class visual_debug_hud : public osg::Geode
+{
+	#include <leakDetection.h>
+public:
+	/**
+	 * \brief Empty Constructor.
+	 * 
+	 */ 
+	visual_debug_hud(void);
+
+	/**
+	 * \brief Empty Destructor.
+	 * 
+	 */ 
+	~visual_debug_hud(void);
+
+	/**
+	 * \brief This function initializes the HUD.
+	 * 
+	 * @param viewer_ : Pointer to the viewer instance to get screen size and screen width.
+	 * @param rootNode_ : Pointer to the rootnode of the Scene, which should be a CSN
+	 * @return : True if initialization was successful.
+	 */ 
+	bool init(osgViewer::Viewer *viewer_, osg::CoordinateSystemNode* rootNode_ );
+
+	void shutdown();
+
+private:
+	/**
+	 * \brief This function contains the code to display in the HUD.
+	 * 
+	 * 
+	 * @return Pointer to the Geode which contains the HUD content.
+	 */ 
+	osg::ref_ptr<osg::Geode> addContent();
+
+	/**
+	 * This variable contains the width of the rendering screen during the initialization of this node.
+	 */ 
+	int screen_width;
+
+	/**
+	 * This variable contains the height of the rendering screen during the initialization of this node.
+	 */ 
+	int screen_height;
+
+
+
+	class HudUpdateCallback : public osg::NodeCallback
+	{
+	public:
+		/**
+		 * \brief Constructor
+		 * 
+		 * @param csn_ : Pointer to the Coordinate System Node. Necessary to extract lat, lon and height of the camera position.
+		 * @param sceneCamera_ : Pointer to the scene camera (undistorted camera, type PRE_RENDER)
+		 * @param sky_ : Pointer to the sky system.
+		 */ 
+		HudUpdateCallback(osg::CoordinateSystemNode* csn_, osg::Camera* sceneCamera_)
+			: csn(csn_), sceneCamera(sceneCamera_) {};
+
+		/**
+		 * \brief This function is executed as callback during traversal. It updates values to display.
+		 * 
+		 */ 
+		virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
+	private:
+		/**
+		 * Referenced pointer to the Coordinate System Node. Necessary to extract lat, lon and height of the camera position.
+		 */ 
+		osg::ref_ptr<osg::CoordinateSystemNode> csn;
+		
+		/**
+		 * Referenced pointer to the scene camera (undistorted camera, type PRE_RENDER)
+		 */ 
+		osg::ref_ptr<osg::Camera> sceneCamera;
+
+	};	// Nested class END
+
+	/**
+	 * Referenced Pointer to the updatecallback, which is installed at this node. 
+	 */ 
+	osg::ref_ptr<HudUpdateCallback> updateCallback;
+
+	bool isInitialized;
+
+	osg::ref_ptr<osgText::Text> textLat, textLon, textAlt, textHat, textHot;
+
+	// Friend classes
+	friend class HudUpdateCallback; // Damit der Callback auf alle Member zugreifen kann wie wenn er in der Klasse sitzen würde.
+}; 
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/draw2D/visual_draw2D.h
===================================================================
--- /osgVisual/trunk/include/draw2D/visual_draw2D.h	(revision 176)
+++ /osgVisual/trunk/include/draw2D/visual_draw2D.h	(revision 176)
@@ -0,0 +1,166 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <osg/Referenced>
+#include <osg/Geometry>
+#include <osg/Geode>
+#include <osg/CoordinateSystemNode>
+#include <osgText/Text>
+#include <osgViewer/Viewer>
+#include <osg/MatrixTransform>
+
+#include <visual_util.h>
+
+
+namespace osgVisual
+{
+	#include <leakDetection.h>
+
+/**
+ * \brief This class is the interface to place 2D drawings in screen coordinates over the rendered 3D scene, but before POST_RENDER actions like distortion.
+ * 
+ * This class is realized as singleton to make sure that only one interface controls the 2D drawing.
+ * It is derived vom osg::Geode to be includable into the scenegraph. At every frame, callbacks are possible to use for updating 2D drawings dynamically.
+ * 
+ * If you wish dynamic content in your drawings, implement callbacks in your content geodes. This class is not capable of callbacks, because it is not added into the scenegraph.
+ * 
+ * 
+ * @author Torben Dannhauer
+ * @date  Sep 2009
+ */ 
+class visual_draw2D : public osg::Referenced
+{
+private:
+	/**
+	 * \brief Constructor : Private accessible to prevent instantiation of thsi class by external caller.
+	 * 
+	 */ 
+	visual_draw2D(void);
+
+	/**
+	 * \brief Copy-Constructor: Private accessible to prevent copies (from outside) of this class.
+	 * 
+	 * @param cc : Instance to copy. Not relevant because this funtion is not implemented. If this function is not definied,
+	 * the compiler would create a public accessible dafault copy constructor.
+	 */ 
+	visual_draw2D(const visual_draw2D& cc);
+
+public:
+	/**
+	 * \brief Destructor: Public accessible to allow external functions to clean up this singleton.
+	 * 
+	 */ 
+	~visual_draw2D(void);
+
+	/**
+	 * \brief This function returns the singleton instance for usage.
+	 * 
+	 * @return Pointer to the instance.
+	 */ 
+	static visual_draw2D* getInstance();
+
+	/**
+	 * \brief This function initilizes the 2DDraw interface.
+	 * 
+	 * @param sceneGraphRoot_ : Scene root to add the 2D drawings to.
+	 * @param viewer_ : Applications main viewer to get the screen resolution
+	 * @return : True if successful.
+	 */ 
+	bool init( osg::CoordinateSystemNode *sceneGraphRoot_, osgViewer::Viewer *viewer_ );
+
+	/**
+	 * \brief This function shut "drawing interface down.
+	 * 
+	 * It removes all drawables and shuts them down to allow them to uninstall their updater. 
+	 * 
+	 */ 
+	void shutdown();
+
+	/**
+	 * \brief Call this function to add a Geode with drawables which contain 2d content.
+	 * 
+	 * @param content_ : Geode with drawables to add.
+	 * @param name_ : Name to set the geode to for further identification.
+	 * @param renderBinDetail_ : Renderbin to add the content to. 99 is the default for HUD
+	 * @return : true of adding was successful.
+	 */ 
+	bool addDrawContent( osg::Geode* content_, std::string name_,int renderBinDetail_ = 99 );
+
+	/**
+	 * \brief This function returns a content geode if the name matches the specified one.
+	 * 
+	 * @param name_ : content to search after.
+	 * @return : Pointer to the found geode. If no Node with that name is found, NULL is returned.
+	 */ 
+	osg::Geode* getDrawContent( std::string name_ );
+
+	/**
+	 * \brief This function removes Drawcontent specified by name_.
+	 * 
+	 * @param name_ : Name of drawcontent to remove.
+	 * @return : Returns true if drawcontent was found and successfully removed.
+	 */ 
+	bool removeDrawContent( std::string name_ );
+	
+	/**
+	 * \brief This function removes all drawContents.
+	 * 
+	 */ 
+	void removeAllDrawContents();
+
+	/**
+	 * \brief This function returns the number of registered drawContents.
+	 * 
+	 * @return : Number of registered drawContents.
+	 */ 
+	inline int getDrawContentNum();
+
+private:
+	/**
+	 * This camera ist NESTED_RENDER and renders all "D drawings.
+	 * 
+	 * It is rendered after the 3D scene but before POST_RENDER cameras like distortion.
+	 */ 
+	osg::ref_ptr<osg::Camera> camera;
+
+	/**
+	 * This Modelviewematrix is the parent for all geodes which contain 2D drawings. To be known by the addContent() funtion, it is a classwide member attribute.
+	 */ 
+	osg::ref_ptr<osg::MatrixTransform> draw2DModelViewMatrix;
+
+	/**
+	 * This Projectionmatrix connects the global scenegraph with the 2D modelview matrix. It is used to disconnect the 2D drawing subgraph from the global scenegrpah on shutdown.
+	 */ 
+	osg::ref_ptr<osg::Projection> draw2DProjectionMatrix;
+
+	/**
+	 * This flag indicated whether the draw2D interface is initialized. 
+	 */ 
+	bool initialized;
+
+	/**
+	 * This variable contains the width of the rendering screen during the initialization of this node.
+	 */ 
+	int screen_width;
+
+	/**
+	 * This variable contains the height of the rendering screen during the initialization of this node.
+	 */ 
+	int screen_height;
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/draw2D/visual_hud.h
===================================================================
--- /osgVisual/trunk/include/draw2D/visual_hud.h	(revision 176)
+++ /osgVisual/trunk/include/draw2D/visual_hud.h	(revision 176)
@@ -0,0 +1,79 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <visual_draw2D.h>
+
+
+namespace osgVisual
+{
+
+/**
+ * \brief This class demonstrates how to build a Head Up Display.
+ * 
+ * Replace addContent() to integrate own content.
+ * 
+ * @todo : Check, if the update logic should be implemtented in draw2D or here in.
+ * 
+ * @author Torben Dannhauer
+ * @date  Sep 2009
+ */ 
+class visual_hud : public osg::Geode
+{
+	#include <leakDetection.h>
+public:
+	/**
+	 * \brief Empty Constructor.
+	 * 
+	 */ 
+	visual_hud(void);
+
+	/**
+	 * \brief Empty Destructor.
+	 * 
+	 */ 
+	~visual_hud(void);
+
+	/**
+	 * \brief This function initializes the HUD.
+	 * 
+	 * @param viewer_ : Pointer to the viewer instance to get screen size and screen width.
+	 * @return : True if initialization was successful.
+	 */ 
+	bool init(osgViewer::Viewer *viewer_ );
+
+private:
+	/**
+	 * \brief This function contains the code to display in the HUD.
+	 * 
+	 * Subclass this function to integrate own content.
+	 * 
+	 * @return Pointer to the Geode which contains the HUD content.
+	 */ 
+	osg::ref_ptr<osg::Geode> addContent();
+
+	/**
+	 * This variable contains the width of the rendering screen during the initialization of this node.
+	 */ 
+	int screen_width;
+
+	/**
+	 * This variable contains the height of the rendering screen during the initialization of this node.
+	 */ 
+	int screen_height;
+}; 
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/draw3D/visual_draw3D.h
===================================================================
--- /osgVisual/trunk/include/draw3D/visual_draw3D.h	(revision 176)
+++ /osgVisual/trunk/include/draw3D/visual_draw3D.h	(revision 176)
@@ -0,0 +1,37 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <osg/CoordinateSystemNode>
+#include <osg/Geode>
+#include <osg/Geometry>
+#include <osg/Node>
+
+#include <osgViewer/Viewer>
+
+namespace osgVisual
+{
+
+class visual_draw3D : public osg::Node
+{
+	#include <leakDetection.h>
+public:
+	visual_draw3D(void);
+	virtual ~visual_draw3D(void);
+	void init( osg::CoordinateSystemNode* rootNode_, osgViewer::Viewer *viewer_ );
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/extLink/dataIO_extLink.h
===================================================================
--- /osgVisual/trunk/include/extLink/dataIO_extLink.h	(revision 176)
+++ /osgVisual/trunk/include/extLink/dataIO_extLink.h	(revision 176)
@@ -0,0 +1,93 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <osg/Referenced>
+#include <osg/Node>
+#include <dataIO_slot.h>
+
+
+namespace osgVisual
+{ 
+
+/**
+ * \brief This class is the interface definition class for valid externalLink (extLink) implementations.
+ * 
+ * This class is an abstract class, thus cannot be instantiated. Derive this class for usage.
+ * 
+ * @author Torben Dannhauer
+ * @date  Sep 2009
+ */ 
+
+class dataIO_extLink : public osg::Referenced
+{
+	#include <leakDetection.h>
+public:
+	/**
+	 * \brief Empty constructor
+	 * 
+	 */ 
+	dataIO_extLink(std::vector<osgVisual::dataIO_slot *>& dataSlots_) : dataSlots(dataSlots_){}
+
+	/**
+	 * \brief Empty destructor
+	 * 
+	 * @return 
+	 */ 
+	virtual ~dataIO_extLink() {}
+
+	/**
+	 * \brief Pure virtual function for initialization. Must be implemented in derived class.
+	 * 
+	 */ 
+	virtual void init() = 0;
+
+	virtual void shutdown() = 0;
+
+	/**
+	 * \brief Pure virtual function for reading TO_OBJ values form the external link. Must be implemented in derived class.
+	 * 
+	 * @return : See derived class.
+	 */ 
+	virtual bool readTO_OBJvalues() = 0;
+
+	/**
+	 * \brief Pure virtual function for writing return values back to the external link. Must be implemented in derived class.
+	 * 
+	 * @return : See derived class.
+	 */ 
+	virtual bool writebackFROM_OBJvalues() = 0;
+
+protected:
+	/**
+	 * Nested external link for more then one external source.
+	 */ 
+	osg::ref_ptr<dataIO_extLink> extLink;
+
+	/**
+	 * Flag to indicate if this class is initialized.
+	 */ 
+	bool initialized;
+
+	/**
+	 * Reference to dataIO's central managed dataSlots.
+	 * This central dataSlot array is filled with available slots by this extLink class.
+	 */ 
+	std::vector<dataIO_slot *>& dataSlots;
+ 
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/extLink/dataIO_extLinkDummy.h
===================================================================
--- /osgVisual/trunk/include/extLink/dataIO_extLinkDummy.h	(revision 176)
+++ /osgVisual/trunk/include/extLink/dataIO_extLinkDummy.h	(revision 176)
@@ -0,0 +1,47 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <dataIO_extLink.h>
+#include <osg/Notify>
+#include <vector>
+
+namespace osgVisual
+{
+
+/**
+ * \brief This class is a dummy class for the externalLink.
+ * 
+ * All functions which are called always return true and send a debug string to stdout to announce that they were called.
+ * 
+ * @author Torben Dannhauer
+ * @date  Sep 2009
+ */ 
+class dataIO_extLinkDummy :	public dataIO_extLink
+{
+public:
+	dataIO_extLinkDummy(std::vector<dataIO_slot *>& dataSlots_);
+	virtual ~dataIO_extLinkDummy(void);
+
+	void init();
+	void shutdown();
+
+	bool readTO_OBJvalues();
+	bool writebackFROM_OBJvalues();
+	void provideSlots();
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/extLink/dataIO_extLinkVCL.h
===================================================================
--- /osgVisual/trunk/include/extLink/dataIO_extLinkVCL.h	(revision 176)
+++ /osgVisual/trunk/include/extLink/dataIO_extLinkVCL.h	(revision 176)
@@ -0,0 +1,100 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <dataIO_extLink.h>	// Base class
+#include <osg/Notify>
+#include <osgDB/FileUtils>
+
+// VCL
+#include <winsock2.h>
+
+// XML Parser
+#include <stdio.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+
+// VCL
+//// To keep the VS 2005 Solution file clean from VCL dependencies: Link dependencies here:
+#ifndef _DEBUG
+#pragma comment ( lib, "../VCL_1.0.3.4/source/3rdParty/expatpp/lib/releasemtdll/libexpatMT.lib" )
+#pragma comment ( lib, "../VCL_1.0.3.4/source/3rdParty/expatpp/lib/releasemtdll/expatpp.lib" )
+#pragma comment ( lib, "../VCL_1.0.3.4/source/3rdParty/expatpp/lib.x64/releasemtdll/libexpatMT.lib" )
+#pragma comment ( lib, "../VCL_1.0.3.4/source/3rdParty/expatpp/lib.x64/releasemtdll/expatpp.lib" )
+#pragma comment ( lib, "../VCL_1.0.3.4/source/lib/x86/VCL1_34.lib" )
+#pragma comment ( lib, "../VCL_1.0.3.4/source/lib/x64/VCL1_34.lib" )
+#endif
+#ifdef _DEBUG
+#pragma comment ( lib, "../VCL_1.0.3.4/source/3rdParty/expatpp/lib/debugmtdll/libexpatMT_d.lib" )
+#pragma comment ( lib, "../VCL_1.0.3.4/source/3rdParty/expatpp/lib/debugmtdll/expatpp_d.lib" )
+#pragma comment ( lib, "../VCL_1.0.3.4/source/3rdParty/expatpp/lib.x64/debugmtdll/libexpatMT_d.lib" )
+#pragma comment ( lib, "../VCL_1.0.3.4/source/3rdParty/expatpp/lib.x64/debugmtdll/expatpp_d.lib" )
+#pragma comment ( lib, "../VCL_1.0.3.4/source/lib/x86/VCL1_34D.lib" )
+#pragma comment ( lib, "../VCL_1.0.3.4/source/lib/x64/VCL1_34D.lib" )
+#endif
+//// include VCL header
+#ifdef WIN32
+#include <wtypes.h>
+#endif
+#include "VCLDefinitions.h"
+#include "VCLIO.h"
+#include "VCLIOChannel.h"
+#include "VCLIOChannelEntry.h"
+#include "VCLVariable.h"
+#include "VCLSocketDefs.h"
+#include <conio.h>
+#include "stdlib.h"
+#include <iostream>
+
+
+namespace osgVisual
+{ 
+
+/**
+ * \brief This class is a VCL-based implementation of the externalLink.
+
+ * 
+ * @author Torben Dannhauer
+ * @date  Nov 2009
+ */ 
+class dataIO_extLinkVCL :	public dataIO_extLink
+{
+#include <leakDetection.h>
+public:
+	dataIO_extLinkVCL(std::vector<dataIO_slot *>& dataSlots_);
+	virtual ~dataIO_extLinkVCL(void);
+
+	void init();
+	void shutdown();
+
+	bool readTO_OBJvalues();
+	bool writebackFROM_OBJvalues();
+
+
+private:
+	bool parseVCLConfig();
+	void checkXMLNode(xmlNode * a_node);
+	void addChannels(xmlNode * a_node, std::string channelName_, dataIO_slot::dataDirection direction_ );
+
+	std::string VCLConfigFilename;
+	std::vector< CVCLVariable<double>* > extLinkChannels;
+	std::vector< osgVisual::dataIO_slot* > extLinkSlots;
+	bool configFileValid;
+
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/extLink/manip_extLink.h
===================================================================
--- /osgVisual/trunk/include/extLink/manip_extLink.h	(revision 176)
+++ /osgVisual/trunk/include/extLink/manip_extLink.h	(revision 176)
@@ -0,0 +1,104 @@
+#pragma once 
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <visual_object.h>
+
+
+
+namespace osgVisual
+{ 
+
+/**
+ * \brief This class is a camera manipulator based slots without objects.
+ * 
+ * @author Torben Dannhauer
+ * @date  Aug 2009
+ */ 
+class extLinkManipulator : public osgGA::CameraManipulator
+{
+	#include <leakDetection.h>
+    public:
+		/**
+		 * \brief Constructor
+		 * 
+		 */ 
+        extLinkManipulator();
+
+		/**
+		 * \brief This function returns the classname.
+		 * 
+		 * @return Classname of this manipulator.
+		 */ 
+        virtual const char* className() const { return "extLinkManipulator"; }
+
+		/**
+		 * \brief Set the position of the matrix manipulator using a 4x4 Matrix.
+		 * 
+		 * @param matrix : Matrix to set.
+		 */ 
+        virtual void setByMatrix(const osg::Matrixd& matrix);
+
+		/**
+		 * \brief Set the position of the matrix manipulator using a 4x4 Matrix.
+		 * 
+		 * @param matrix : Inverse Matrix to set.
+		 */ 
+        virtual void setByInverseMatrix(const osg::Matrixd& matrix) { setByMatrix(osg::Matrixd::inverse(matrix)); }
+
+        /** get the position of the manipulator as 4x4 Matrix.*/
+        virtual osg::Matrixd getMatrix() const;
+
+        /** get the position of the manipulator as a inverse matrix of the manipulator, typically used as a model view matrix.*/
+        virtual osg::Matrixd getInverseMatrix() const;
+
+		/**
+		 * \brief Start/restart the manipulator.
+		 * 
+		 * No further implementation
+		 * 
+		 * @param ea : GUI eventadapter to use for initialization. 
+		 * @param us : GUI actionadapter to use for initialization. 
+		 */ 
+        virtual void init(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
+
+        /** handle events, return true if handled, false otherwise.*/
+        virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
+
+        /** Get the keyboard and mouse usage of this manipulator.*/
+        virtual void getUsage(osg::ApplicationUsage& usage) const;
+
+		virtual void setAttachedObject( 
+			visual_object* object_ ) {attachedObject = object_;};
+
+		virtual osgVisual::visual_object* getAttachedObject() {return attachedObject.get();};
+
+
+    protected:
+		/**
+		 * \brief Destructor. Because it is protected, no explicit delete myPointer by external caller is possible.
+		 * This forces the class to be used with osg::ref pointers.
+		 */ 
+        virtual ~extLinkManipulator();
+
+		osg::Matrixd manipMatrix;
+	
+
+		osg::ref_ptr<osgVisual::visual_object> attachedObject;
+};
+
+}	// END NAMESPACE
+
Index: /osgVisual/trunk/include/manip_ObjectMounted/manip_objectMounted.h
===================================================================
--- /osgVisual/trunk/include/manip_ObjectMounted/manip_objectMounted.h	(revision 176)
+++ /osgVisual/trunk/include/manip_ObjectMounted/manip_objectMounted.h	(revision 176)
@@ -0,0 +1,107 @@
+#pragma once 
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <osgGA/CameraManipulator>
+
+#include <osg/Quat>
+#include <osg/observer_ptr>
+
+#include <visual_object.h>
+
+
+namespace osgVisual
+{ 
+
+/**
+ * \brief This class is a free spacemouse manipulator. It uses the 3DConnexion SpaceNavigator, which interface is implemented in manip_spaceMouse.h
+ * 
+ * @author Torben Dannhauer
+ * @date  Aug 2009
+ */ 
+class objectMountedManipulator : public osgGA::CameraManipulator
+{
+	#include <leakDetection.h>
+    public:
+		/**
+		 * \brief Constructor
+		 * 
+		 */ 
+        objectMountedManipulator();
+
+		/**
+		 * \brief This function returns the classname.
+		 * 
+		 * @return Classname of this manipulator.
+		 */ 
+        virtual const char* className() const { return "objectMountedManipulator"; }
+
+		/**
+		 * \brief Set the position of the matrix manipulator using a 4x4 Matrix.
+		 * 
+		 * @param matrix : Matrix to set.
+		 */ 
+        virtual void setByMatrix(const osg::Matrixd& matrix);
+
+		/**
+		 * \brief Set the position of the matrix manipulator using a 4x4 Matrix.
+		 * 
+		 * @param matrix : Inverse Matrix to set.
+		 */ 
+        virtual void setByInverseMatrix(const osg::Matrixd& matrix) { setByMatrix(osg::Matrixd::inverse(matrix)); }
+
+        /** get the position of the manipulator as 4x4 Matrix.*/
+        virtual osg::Matrixd getMatrix() const;
+
+        /** get the position of the manipulator as a inverse matrix of the manipulator, typically used as a model view matrix.*/
+        virtual osg::Matrixd getInverseMatrix() const;
+
+		/**
+		 * \brief Start/restart the manipulator.
+		 * 
+		 * No further implementation
+		 * 
+		 * @param ea : GUI eventadapter to use for initialization. 
+		 * @param us : GUI actionadapter to use for initialization. 
+		 */ 
+        virtual void init(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
+
+        /** handle events, return true if handled, false otherwise.*/
+        virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
+
+        /** Get the keyboard and mouse usage of this manipulator.*/
+        virtual void getUsage(osg::ApplicationUsage& usage) const;
+
+		virtual void setAttachedObject( 
+			osgVisual::visual_object* object_ ) {attachedObject = object_;};
+
+		virtual osgVisual::visual_object* getAttachedObject() {return attachedObject.get();};
+
+
+    protected:
+		/**
+		 * \brief Destructor. Because it is protected, no explicit delete myPointer by external caller is possible.
+		 * This forces the class to be used with osg::ref pointers.
+		 */ 
+        virtual ~objectMountedManipulator();
+
+		osg::Matrixd manipMatrix;
+	
+
+		osg::ref_ptr<osgVisual::visual_object> attachedObject;
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/manip_Spacemouse/manip_freeSpaceMouse.h
===================================================================
--- /osgVisual/trunk/include/manip_Spacemouse/manip_freeSpaceMouse.h	(revision 176)
+++ /osgVisual/trunk/include/manip_Spacemouse/manip_freeSpaceMouse.h	(revision 176)
@@ -0,0 +1,147 @@
+#pragma once 
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+// Spacemouse implementation
+#include <manip_spaceMouse.h>
+
+// OSG includes
+#include <osgGA/CameraManipulator>
+#include <osgGA/GUIEventAdapter>
+#include <osgGA/GUIActionAdapter>
+
+#include <osg/Quat>
+#include <osg/Notify>
+#include <osg/BoundsChecking>
+#include <osg/observer_ptr>
+
+
+namespace osgVisual
+{ 
+
+/**
+ * \brief This class is a free spacemouse manipulator. It uses the 3DConnexion SpaceNavigator, which interface is implemented in manip_spaceMouse.h
+ * 
+ * @author Torben Dannhauer
+ * @date  Aug 2009
+ */ 
+class FreeManipulator : public osgGA::CameraManipulator
+{
+	#include <leakDetection.h>
+    public:
+		/**
+		 * \brief Constructor
+		 * 
+		 * @param spacemouse : Pointer to the space mouse driver instance.
+		 */ 
+        FreeManipulator(SpaceMouse* spacemouse);
+
+		/**
+		 * \brief This function returns the classname.
+		 * 
+		 * @return Classname of this manipulator.
+		 */ 
+        virtual const char* className() const { return "FreeManipulator"; }
+
+		/**
+		 * \brief Set the position of the matrix manipulator using a 4x4 Matrix.
+		 * 
+		 * @param matrix : Matrix to set.
+		 */ 
+        virtual void setByMatrix(const osg::Matrixd& matrix);
+
+		/**
+		 * \brief Set the position of the matrix manipulator using a 4x4 Matrix.
+		 * 
+		 * @param matrix : Inverse Matrix to set.
+		 */ 
+        virtual void setByInverseMatrix(const osg::Matrixd& matrix) { setByMatrix(osg::Matrixd::inverse(matrix)); }
+
+        /** get the position of the manipulator as 4x4 Matrix.*/
+        virtual osg::Matrixd getMatrix() const;
+
+        /** get the position of the manipulator as a inverse matrix of the manipulator, typically used as a model view matrix.*/
+        virtual osg::Matrixd getInverseMatrix() const;
+
+		/**
+		 * \brief Start/restart the manipulator.
+		 * 
+		 * No further implementation
+		 * 
+		 * @param ea : GUI eventadapter to use for initialization. 
+		 * @param us : GUI actionadapter to use for initialization. 
+		 */ 
+        virtual void init(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
+
+        /** handle events, return true if handled, false otherwise.*/
+        virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
+
+        /** Get the keyboard and mouse usage of this manipulator.*/
+        virtual void getUsage(osg::ApplicationUsage& usage) const;
+
+        void setTrackNode(osg::Node* node);
+        osg::Node* getTrackNode() {  return _trackNodePath.empty() ? 0 : _trackNodePath.back().get();  }
+
+        void computeNodeWorldToLocal(osg::Matrixd& worldToLocal) const;
+        void computeNodeLocalToWorld(osg::Matrixd& localToWorld) const;
+        bool validateNodePath() const;
+        osg::NodePath getNodePath() const;
+
+        typedef std::vector< osg::observer_ptr<osg::Node> >   ObserverNodePath;
+
+        ObserverNodePath      _trackNodePath;
+
+
+        void setTrackNodePath(const osg::NodePath& nodePath)
+        {
+           _trackNodePath.clear();
+           _trackNodePath.reserve(nodePath.size());
+           std::copy(nodePath.begin(), nodePath.end(), std::back_inserter(_trackNodePath));
+        }
+
+        osg::Vec3 getTrackNodeCenter();
+
+    protected:
+		/**
+		 * \brief Destructor. Because it is protected, no explicit delete myPointer by external caller is possible.
+		 * This forces the class to be used with osg::ref pointers.
+		 */ 
+        virtual ~FreeManipulator();
+
+		/**
+		 * \brief This function queries the space mouse driver instance and calculates the resultung movement of the manipulator.
+		 * 
+		 * @return : True if calculation was successful.
+		 */ 
+        bool calcMovement();
+
+		/**
+		 * Position of the manipulator.
+		 */ 
+        osg::Vec3d  _position;
+
+		/**
+		 * Attitude of the manipulator.
+		 */ 
+        osg::Quat   _attitude;
+
+		/**
+		 * Pointer to the space mouse driver instance.
+		 */ 
+        SpaceMouse* _spaceMouse;
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/manip_Spacemouse/manip_nodeTrackerSpaceMouse.h
===================================================================
--- /osgVisual/trunk/include/manip_Spacemouse/manip_nodeTrackerSpaceMouse.h	(revision 176)
+++ /osgVisual/trunk/include/manip_Spacemouse/manip_nodeTrackerSpaceMouse.h	(revision 176)
@@ -0,0 +1,285 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <osgGA/OrbitManipulator>
+
+#include <osg/ObserverNodePath>
+#include <osg/Quat>
+#include <osg/Notify>
+#include <osg/Transform>
+
+// Spacemouse implementation
+#include <manip_spaceMouse.h>
+
+
+
+using namespace osgGA;
+
+namespace osgVisual
+{ 
+
+/**
+ * \brief This class provides a nodetracker manipulator controlled be a Space Navigator(SN) 3D mouse by 3DConnexion.
+ * 
+ * This nodetracker is similar to standard osg nodetracker manipulator with the difference,
+ * that the camera is not controlled by mouse but by the Space Navigator.
+ * 
+ * NodeTrackerSpaceMouse provides two modi: Using Space Navigator to control the camera movement, or using Space Navigator to control camera position.
+ * The first one holds camera position if the SN is released to it's origin position, the latter one returns camera position to origin if SN is released and returned to origin ("autohoming").
+ * You can switch between both modi with Space.
+ * 
+ * To toggle between the tracking modes NODE_CENTER, NODE_CENTER_AND_AZIM and NODE_CENTER_AND_ROTATION, press 'm'.
+ * 
+ * To toggle adjustment of angular velocity by distance to tracked node, press 'n'.
+ * 
+ * @author Torben Dannhauer
+ * @date  Apr 2010
+ */ 
+class NodeTrackerSpaceMouse : public osgGA::OrbitManipulator
+{
+	#include <leakDetection.h>
+    public:
+		/**
+		 * \brief Constructor
+		 * 
+		 * @param spacemouse : Pointer to the driver interface class.
+		 */ 
+        NodeTrackerSpaceMouse(SpaceMouse* spacemouse); 
+
+		/**
+		 * \brief This function returns the class name.
+		 * 
+		 * @return : Char array of the class name.
+		 */ 
+        virtual const char* className() const { return "NodeTrackerSpaceMouse"; }
+
+
+        void setTrackNodePath(const osg::NodePath& nodePath) { _trackNodePath.setNodePath(nodePath); }
+        void setTrackNodePath(const osg::ObserverNodePath& nodePath) { _trackNodePath = nodePath; }
+        osg::ObserverNodePath& getTrackNodePath() { return _trackNodePath; }
+
+        void setTrackNode(osg::Node* node);
+        osg::Node* getTrackNode();
+        const osg::Node* getTrackNode() const;
+
+		/**
+		 * Lists the tracking modes the nodetracker can provide.
+		 */ 
+        enum TrackerMode 
+        {
+            /** Track the center of the node's bounding sphere, but not rotations of the node.  
+              * For databases which have a CoordinateSystemNode, the orientation is kept relative the coordinate frame if the center of the node.
+              */
+            NODE_CENTER,
+            /** Track the center of the node's bounding sphere, and the azimuth rotation (about the z axis of the current coordinate frame).
+              * For databases which have a CoordinateSystemNode, the orientation is kept relative the coordinate frame if the center of the node.
+              */
+            NODE_CENTER_AND_AZIM,
+            /** Tack the center of the node's bounding sphere, and the all rotations of the node.
+              */
+            NODE_CENTER_AND_ROTATION
+        };
+        
+		/**
+		 * \brief Sets the tracking mode.
+		 * 
+		 * See TrackerMode
+		 * 
+		 * @param mode : Mode to set
+		 */ 
+        void setTrackerMode(TrackerMode mode);
+
+		/**
+		 * \brief Returns current tracking mode.
+		 * 
+		 * @return : Current tracking mode.
+		 */ 
+        TrackerMode getTrackerMode() const { return _trackerMode; }
+
+
+		/**
+		 * Lists the rotation modes the nodetracker provides.
+		 * 
+		 * At the moment, only ELEVATION_AZIM is supported, TRACKBALL is blocked to prevent software crashes.
+		 */ 
+        enum RotationMode 
+        {
+            /** Use a trackball style manipulation of the view direction w.r.t the tracked orientation.
+              */
+            TRACKBALL,
+            /** Allow the elevation and azimuth angles to be adjust w.r.t the tracked orientation.
+              */
+            ELEVATION_AZIM
+        };
+        
+		/**
+		 * \brief Sets the rotation mode.
+		 * 
+		 * See RotationMode
+		 * 
+		 * @param mode : Mode to set.
+		 */ 
+        void setRotationMode(RotationMode mode);
+
+		/**
+		 * \brief Returns curent rotation mode.
+		 * 
+		 * See RotationMode
+		 * 
+		 * @return : Current rotation mode.
+		 */ 
+        RotationMode getRotationMode() const { return _rotationMode; }
+
+
+        /** set the position of the matrix manipulator using a 4x4 Matrix.*/
+        virtual void setByMatrix(const osg::Matrixd& matrix);
+
+        /** set the position of the matrix manipulator using a 4x4 Matrix.*/
+        virtual void setByInverseMatrix(const osg::Matrixd& matrix) { setByMatrix(osg::Matrixd::inverse(matrix)); }
+
+        /** get the position of the manipulator as 4x4 Matrix.*/
+        virtual osg::Matrixd getMatrix() const;
+
+        /** get the position of the manipulator as a inverse matrix of the manipulator, typically used as a model view matrix.*/
+        virtual osg::Matrixd getInverseMatrix() const;
+
+        /** Get the FusionDistanceMode. Used by SceneView for setting up stereo convergence.*/
+        virtual osgUtil::SceneView::FusionDistanceMode getFusionDistanceMode() const { return osgUtil::SceneView::USE_FUSION_DISTANCE_VALUE; }
+
+        /** Get the FusionDistanceValue. Used by SceneView for setting up stereo convergence.*/
+        virtual float getFusionDistanceValue() const { return _distance; }
+
+        /** Attach a node to the manipulator. 
+            Automatically detaches previously attached node.
+            setNode(NULL) detaches previously nodes.
+            Is ignored by manipulators which do not require a reference model.*/
+        virtual void setNode(osg::Node*);
+
+        /** Return node if attached.*/
+        virtual const osg::Node* getNode() const;
+
+        /** Return node if attached.*/
+        virtual osg::Node* getNode();
+
+        virtual void computeHomePosition();
+
+        /** Move the camera to the default position. 
+            May be ignored by manipulators if home functionality is not appropriate.*/
+        virtual void home(const GUIEventAdapter& ea,GUIActionAdapter& us);
+        
+        /** Start/restart the manipulator.*/
+        virtual void init(const GUIEventAdapter& ea,GUIActionAdapter& us);
+
+        /** handle events, return true if handled, false otherwise.*/
+        virtual bool handle(const GUIEventAdapter& ea,GUIActionAdapter& us);
+
+        /** Get the keyboard and mouse usage of this manipulator.*/
+        virtual void getUsage(osg::ApplicationUsage& usage) const;
+
+    protected:
+
+        virtual ~NodeTrackerSpaceMouse();
+
+        /** Reset the internal GUIEvent stack.*/
+        void flushMouseEventStack();
+
+        /** Add the current mouse GUIEvent to internal stack.*/
+        void addMouseEvent(const GUIEventAdapter& ea);
+
+        void computeNodeCenterAndRotation(osg::Vec3d& center, osg::Quat& rotation) const;
+
+        void computePosition(const osg::Vec3d& eye,const osg::Vec3d& lv,const osg::Vec3d& up);
+
+        /** For the give mouse movement calculate the movement of the camera.
+            Return true is camera has moved and a redraw is required.*/
+        bool calcMovement();
+
+		/**
+		 * \brief Retieves the movements from driver interface and calculates manipulator movements.
+		 * 
+		 * @return : True on success.
+		 */ 
+		bool calcMovementSpaceMouse();
+        
+        void trackball(osg::Vec3& axis,double& angle, double p1x, double p1y, double p2x, double p2y);
+        double tb_project_to_sphere(double r, double x, double y);
+
+
+        /** Check the speed at which the mouse is moving.
+            If speed is below a threshold then return false, otherwise return true.*/
+        bool isMouseMoving();
+
+		/** Empty */
+        void clampOrientation();
+
+
+        // Internal event stack comprising last two mouse events.
+        osg::ref_ptr<const GUIEventAdapter> _ga_t1;
+        osg::ref_ptr<const GUIEventAdapter> _ga_t0;
+
+		/**
+		 * Pointer to node to track.
+		 */ 
+        osg::observer_ptr<osg::Node> _node;
+
+        osg::ObserverNodePath   _trackNodePath;
+
+		/**
+		 * Current Trackermode. See TrackerMode. 
+		 */ 
+        TrackerMode             _trackerMode;
+
+		/**
+		 * Curent Rotation Mode. See RotationMode.
+		 */ 
+        RotationMode            _rotationMode;
+
+        bool                    _thrown;
+
+		/**
+		 * Indicates if auto homing is enabled.
+		 */ 
+		bool					_autohoming;
+		
+		/**
+		 * Indiccates if nodetracker is initialized.
+		 */ 
+		bool					_ah_init;
+
+		/**
+		 * Indicates if angular velocity is adjusted by distance to tracked node.
+		 */ 
+		bool					_distanceDependendAV;
+
+        osg::Quat               _nodeRotation;
+        osg::Quat               _rotation;
+        float                   _distance;
+		float					_lastDistance;
+
+		/** 
+		 * Pointer to Space Navigator interfacce class.
+		 */ 
+		SpaceMouse* _spaceMouse;
+
+		/**
+		 * Discances in translation and rotation of Space Navigator. Used for non-autohoming modus.
+		 */ 
+		double TZ, RX, RY, RZ;
+
+};
+
+}	//	END NAMESPACE
+
Index: /osgVisual/trunk/include/manip_Spacemouse/manip_spaceMouse.h
===================================================================
--- /osgVisual/trunk/include/manip_Spacemouse/manip_spaceMouse.h	(revision 176)
+++ /osgVisual/trunk/include/manip_Spacemouse/manip_spaceMouse.h	(revision 176)
@@ -0,0 +1,92 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+
+namespace osgVisual
+{ 
+
+/**
+ * \brief This class interfaces osg to the device driver of 3Dconnexions Space Navigator
+ * 
+ * @author Marius Heise
+ * @date  Apr 2009
+ */ 
+class SpaceMouse
+{
+public:
+	/**
+	 * \brief Constructor
+	 * 
+	 */ 
+    SpaceMouse();
+
+	/**
+	 * \brief Destructor
+	 * 
+	 * @return 
+	 */ 
+    virtual ~SpaceMouse();
+
+	/**
+	 * \brief This function initializes the device driver.
+	 * 
+	 * @return : 1=sucess, 0=failure.
+	 */ 
+    int initialize();
+
+	/**
+	 * \brief This function shuts the device driver down.
+	 * 
+	 */ 
+    void shutdown();
+
+	/**
+	 * \brief This function writes the detected translation of all three axes to the specified variables.
+	 * 
+	 * @param dX : delta translation along X axis.
+	 * @param dY : delta translation along Y axis.
+	 * @param dZ : delta translation along Y axis.
+	 * @return : 1=sucess, 0=failure.
+	 */ 
+    int getTranslations(double& dX, double& dY, double& dZ);
+
+	/**
+	 * \brief This function writes the detected rotation of all three axes to the specified variables.
+	 * 
+	 * @param dX : delta translation along X axis.
+	 * @param dY : delta translation along Y axis.
+	 * @param dZ : delta translation along Y axis.
+	 * @return : 1=sucess, 0=failure.
+	 */ 
+    int getRotations(double& dX, double& dY, double& dZ);
+
+private:
+	/**
+	 * \brief Device driver class
+	 * 
+	 * @author Unknown/Marius Heise
+	 * @date  Apr 2009
+	 */ 
+	class SpaceMouseImpl;
+
+	/**
+	 * Pointer to the device driver class.
+	 */ 
+    SpaceMouseImpl* _spaceMouseImpl;
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/object/object_updater.h
===================================================================
--- /osgVisual/trunk/include/object/object_updater.h	(revision 176)
+++ /osgVisual/trunk/include/object/object_updater.h	(revision 176)
@@ -0,0 +1,102 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <osg/Node>
+#include <osg/Notify>
+#include <visual_object.h>
+
+namespace osgVisual
+{ 
+class visual_object;	// Forward declaration
+
+
+/**
+ * \brief This class is the base class for visual_object updater.
+ * 
+ * This base implementation updates the object position with the slotnames
+ *  object_->getName()+"_POS_LAT", object_->getName()+"_POS_LON", object_->getName()+"_POS_ALT",
+ * object_->getName()+"_ROT_X", object_->getName()+"_ROT_Y", object_->getName()+"_ROT_Z", 
+ * 
+ * To implement custom updaters, please derive from this class and overwrite the functions preUpdate(..) and postUpdate(..).
+ * Take care to call nested preUpdater and postUpdater to allow updater chains.
+ * 
+ * @author Torben Dannhauer
+ * @date  Apr 2010
+ */ 
+class object_updater : public osg::Node
+{
+	#include <leakDetection.h>
+public:
+	/**
+	 * \brief Empty constructor
+	 * 
+	 * @param object_ : Pointer to the object, calling the constructor (currently not used)
+	 */ 
+	object_updater(osgVisual::visual_object* object_ );
+
+	/**
+	 * \brief Empty destructor
+	 * 
+	 * @return 
+	 */ 
+	virtual ~object_updater(void);
+
+	/**
+	 * \brief This function is called by visual_object before rendering (preFrame).
+	 * 
+	 * This updater function should be used to update the objects state like size, position, attitude etc.
+	 * 
+	 * @param object_ : Pointer to the object calling this updater.
+	 */ 
+	virtual void preUpdate(osgVisual::visual_object* object_ );
+
+	/**
+	 * \brief This function is called by visual_object after rendering (postFrame).
+	 * 
+	 * This updater function should be used for all actions which require the object status of that frame like HAT/HOT etc.
+	 * 
+	 * @param object_ : Pointer to the object calling this updater.
+	 */ 
+	virtual void postUpdate(osgVisual::visual_object* object_);
+
+	/**
+	 * \brief Returns pointer to this updater.
+	 * 
+	 * This function is used for updater list management.
+	 * 
+	 * @return : Pointer to this updater.
+	 */ 
+	object_updater* getPointer(){return this;};
+
+	/**
+	 * \brief This function adds an object_updater as nested updater.
+	 * 
+	 * The nested Updater will be executed in pre and post traversal after this updater.
+	 * 
+	 * @param updater_ 
+	 */ 
+	void addUpdater( object_updater* updater_ );
+
+protected:
+	/**
+	 * Pointer to nested updater.
+	 */ 
+	osg::ref_ptr<object_updater> updater;
+
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/object/visual_object.h
===================================================================
--- /osgVisual/trunk/include/object/visual_object.h	(revision 176)
+++ /osgVisual/trunk/include/object/visual_object.h	(revision 176)
@@ -0,0 +1,455 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <osg/MatrixTransform>
+#include <osg/Matrix>
+#include <osg/NodeCallback>
+#include <osg/CoordinateSystemNode>
+#include <osg/Notify>
+
+#include <osgDB/ReadFile>
+#include <osgDB/FileUtils>
+
+#include <osgText/Text>
+
+#include <osgGA/CameraManipulator>
+
+#include <object_updater.h>
+#include <visual_dataIO.h>
+#include <visual_util.h>
+
+#include <string.h>
+#include <iostream>
+
+namespace osgVisual
+{
+class visual_objectPositionCallback;
+class object_updater;
+}
+
+/**
+ * \brief Standard namespace of osgVisual
+ * 
+ */ 
+namespace osgVisual
+{
+
+/**
+ * \brief This class provides object management for displaying objects in the 3D scene.
+ * 
+ * It allows to control an object in position, attitude and size. To control this object automatically, use object_updaters.
+ * To object itself is invisible, you have to connect a visible geometry to this object.
+ * To display geometries, it provides function to load geometries by geometry pointer or filename.
+ * To correct wrong coordinate frames in the geometries to display,
+ * you can configure a geometry off set in translation in translation and rotation
+ * For object mounted camera, you can configure the camera offset in rotation and translation.
+ * 
+ * Derive from this class to implement your custom visual_object.
+ * 
+ * \todo: Labelmanagement to allow to display a label attached to this object: set/unset label, size, color, offset to object, LOD for label display.
+ * 
+ * @author Torben Dannhauer
+ * @date  Apr 2010
+ */ 
+class visual_object  : public osg::MatrixTransform
+{
+	#include <leakDetection.h>
+public:
+	/**
+	 * \brief Constuctor: Adds this object to the scenegraph,
+	 * initializes this object and installs the callback to calculate its local to world matrix
+	 * 
+	 * @param sceneRoot_ : Scenegraph to add this object to.
+	 * @param nodeName_ : Name of this object, is used for further identification.
+	 */ 
+	visual_object( osg::CoordinateSystemNode* sceneRoot_, std::string nodeName_ );
+	
+	/**
+	 * \brief Empty destructor.
+	 * 
+	 */ 
+	~visual_object();
+
+
+/** @name Position and attitude
+ *  These functions control objects position and attitude
+ */
+/*@{*/
+
+	/**
+	 * \brief This function updates the objects position and attitude. 
+	 * 
+	 * @param lat_ : Latitude to set.
+	 * @param lon_ : Longitude to set.
+	 * @param alt_ : Altitude over ellipsoid to set.
+	 * @param azimuthAngle_psi_ : Psi angle () to set. 
+	 * @param pitchAngle_theta_ : Theta angle () to set.
+	 * @param bankAngle_phi_ : Phi angle () to set.
+	 * 
+	 * All angles are rad!
+	 * 
+	 * \todo: Erklären welche Wirkung die drei Winkel haben.
+	 */ 
+	void setNewPositionAttitude( double lat_, double lon_, double alt_, double azimuthAngle_psi_, double pitchAngle_theta_, double bankAngle_phi_ );
+	
+	/**
+	 * \brief This function updates the objects position.
+	 * 
+	 * @param lat_ : Latitude to set.
+	 * @param lon_ : Longitude to set.
+	 * @param alt_ : Altitude over ellipsoid to set.
+	 */ 
+	void setNewPosition( double lat_, double lon_, double alt_ );
+
+	/**
+	 * \brief This function updates the objects attitude.
+	 * 
+	 * @param azimuthAngle_psi_ : Psi angle () to set. 
+	 * @param pitchAngle_theta_ : Theta angle () to set.
+	 * @param bankAngle_phi_ : Phi angle () to set.
+	 * 
+	 * All angles are rad!
+	 * 
+	 * \todo: Erklären welche Wirkung die drei Winkel haben.
+	 */ 
+	void setNewAttitude( double azimuthAngle_psi_, double pitchAngle_theta_, double bankAngle_phi_ );
+/*@}*/
+/** @name Geometry management
+ *  These functions control which geometry visual_object should display.
+ */
+/*@{*/
+	/**
+	 * \brief This function configures the geometry offset
+	 * 
+	 * @param rotX_ : Geometry rotation along the X axis.
+	 * @param rotY_ : Geometry rotation along the Y axis.
+	 * @param rotZ_ : Geometry rotation along the Z axis.
+	 * 
+	 * It rotates along the axis of the visual_object, not along the geometry axis!
+	 * 
+	 * \todo: Erklären, welche Achsen welche Richtung sind.
+	 */ 
+	void setGeometryOffset( double rotX_, double rotY_, double rotZ_ );
+
+	/**
+	 * \brief This function set the scale to all 3 axis. Use this function to scale objects without distortion.
+	 * 
+	 * @param scale_ : Scale to set for every axis.
+	 */ 
+	void setScale( double scale_ );
+
+	/**
+	 * \brief This function sets the scale factor for all 3 axis independently.
+	 * 
+	 * @param scaleX_ : Scalefactor along X axis.
+	 * @param scaleY_ : Scalefactor along Y axis.
+	 * @param scaleZ_ : Scalefactor along Z axis.
+	 */ 
+	void setScale( double scaleX_, double scaleY_, double scaleZ_ );
+
+	/**
+	 * \brief this function loads a geometry from a file and connects it to this visual_object. All filetypes OSG is aware of can be used.
+	 * 
+	 * @param filename_ : File to load and connect.
+	 * @return : True if loading was successfully
+	 */ 
+	bool loadGeometry( std::string filename_);
+
+	/**
+	 * \brief This function connects a geometry to this visual_object.
+	 * 
+	 * @param geometry_ : Geometry to connect.
+	 * @return : True if successful.
+	 */ 
+	bool setGeometry(osg::Node* geometry_);
+
+	/**
+	 * \brief This function disconnects the connected object.
+	 * 
+	 */ 
+	void unsetGeometry();
+
+	/**
+	 * \brief This function returns the pointer to the loaded geometry.
+	 *
+	 * It returns NULL if no geometry is connected.
+	 * 
+	 * @return : Pointer to the geometry if loaded, otherwise NULL.
+	 */ 
+	osg::Node* getGeometry(){return geometry;}
+
+/*@}*/
+/** @name Object updater
+ *  These functions control objects updater.
+ */
+/*@{*/
+	/**
+	 * \brief This function adds an Updater to this object.
+	 * 
+	 * The updaters postUpdate und preUpdate functions are executed during eventTraversal traversal.
+	 * The preUdate is executed before the objects matrix is calculated from position, the postUpdate is executed after the matrix calculation. 
+	 * 
+	 * @param updater_ : Updater to add.
+	 */ 
+	void addUpdater( object_updater* updater_ );
+
+	/**
+	 * \brief Removes all updater from the visual_object. 
+	 * 
+	 */ 
+	void clearAllUpdater();
+
+	/**
+	 * \brief This function returns a vector containing pointer to all updater of the object.
+	 * 
+	 * @return : vector with pointers to all object_updater.
+	 */ 
+	std::vector<object_updater*> getUpdaterList();
+
+/*@}*/
+/** @name Camera management
+ *  These functions control the camera attitude and position.
+ */
+/*@{*/
+	/**
+	 * \brief This function returns the camera matrix of the scene camera.
+	 * 
+	 * @return : Camera matrix
+	 */ 
+	osg::Matrixd& getCameraMatrix() {return cameraMatrix;};
+
+	/**
+	 * \brief This function rotates and translate the objects camera position.
+	 * 
+	 *  The translation coordinate frame is object fixed, the rotation coordinate frame is camera fixed.
+	 * 
+	 * @param x_ : Translation along object's x axis.
+	 * @param y_ : Translation along object's y axis.
+	 * @param z_ : Translation along object's z axis (positive axis points downwards).
+	 * @param rotX_ : Rotation around camera's x axis in [rad].
+	 * @param rotY_ : Rotation around camera's y axis in [rad]. 
+	 * @param rotZ_ : Rotation around camera's z axis in [rad].
+	 */ 
+	void setCameraOffset(double x_, double y_, double z_, double rotX_, double rotY_, double rotZ_);
+
+	/**
+	 * \brief This function configures the camera offset rotation in that object.
+	 * 
+	 * The coordinate frame for this rotation is camera fixed, NOT object fixed 
+	 * (e.g. rotation around x axis (bank) rotatates always around the cameras visual axis, 
+	 * independent from pitch or azimuth)
+	 * 
+	 * @param rotX_ : Rotation around camera's x axis in [rad].
+	 * @param rotY_ : Rotation around camera's y axis in [rad]. 
+	 * @param rotZ_ : Rotation around camera's z axis in [rad].
+	 */ 
+	void setCameraOffsetRotation(double rotX_, double rotY_, double rotZ_);
+
+	/**
+	 * \brief This function configures the camera offset translation in that object.
+	 * 
+	 * @param x_ : Translate in longitudinal direction. x>0: Camera is in front if the ob
+	 * ject, x<0 behind the object.
+	 * @param y_ : Translate in transversal direction. x>0: Camera is right of the object, x<0 left of the object.
+	 * @param z_ : Translate in vertical direction. x>0: Camera is below the Object, x<0 above the object. (Positiv Z axis points downwards!)
+	 */ 
+	void setCameraOffsetTranslation( double x_, double y_, double z_);
+
+/*@}*/
+/** @name Label management
+ *  These functions allow to display labels attached to visual_object.
+ */
+/*@{*/
+	/**
+	 * \brief This Function removes all labels attached to this object.
+	 * 
+	 */ 
+	void clearLabels();
+
+	/**
+	 * \brief This function adds a label to the object.  
+	 * 
+	 * @param idString_ : Identifiy string, which is used to find and manipulate the label later.
+	 * @param label_ : Message to display as label.
+	 * @param color_ : Textcolor. Defaults to white.
+	 * @param offset_ : Offset im meter in the objects local coordinate frame
+	 */ 
+	void addLabel(std::string idString_, std::string label_, osg::Vec4 color_ = osg::Vec4(1.0f,1.0f,1.0f,1.0f), osg::Vec3 offset_ = osg::Vec3(0,0,0));
+	
+	/**
+	 * \brief This function removes the specified label.
+	 * 
+	 * @param idString_ : idString of the label to remove.
+	 * @return : True if a label with the specified idString_ was found, false if no label with that idString was found.
+	 */ 
+	bool removeLabel(std::string idString_);
+
+	/**
+	 * \brief Update the message of the label specified with the idString_.
+	 * 
+	 * @param idString_ : idString of the label to update.
+	 * @param label_ : New message to set.
+	 * @return : Return true if the specified label was found, return false if the specified label was not found.
+	 */ 
+	bool updateLabelText(std::string idString_, std::string label_);
+
+	/**
+	 * \brief returns the message string of the specified label.
+	 * 
+	 * @param idString_ : idString of the label to return message.
+	 * @return : Pointer to the Label (osgText::Text) if found, otherwise NULL
+	 */ 
+	osgText::Text* getLabel(std::string idString_); 
+
+	/**
+	 * \brief This functions sets the draw mode of the specified label.
+	 * 
+	 * @param idString_ : Label to configure.
+	 * @param drawAsOverlay : Set true to draw the label always over the scene. Set false to draw it 3D into the scene (maybe occluded party by objects)
+	 * @return : Return true if the specified label was found, return false if the specified label was not found. 
+	 */ 
+	bool setDrawLabelAsOverlay(std::string idString_, bool drawAsOverlay);
+
+	/**
+	 * \brief This function returns if the specified label is configured as overlay.
+	 * 
+	 * @param idString_ : Label to configure.
+	 * @return : True if configured as overlay, false if configured for simple draw
+	 */ 
+	bool getDrawLabelAsOverlay(std::string idString_ );
+/*@}*/
+
+protected:
+	/**
+	 * \brief Callback class for updating the visual_object while traversing the scenegraph in the event stage.
+	 * 
+	 * @author Torben Dannhauer
+	 * @date  Jul 2009
+	 */ 
+	class visual_objectPositionCallback : public osg::NodeCallback
+	{
+	public:
+		/**
+		 * \brief Constructor: Empty
+		 * 
+		 */ 
+		visual_objectPositionCallback()
+		{
+		   // nothing
+		}
+	    
+		/**
+		 * \brief This function is executed by the callback during update traversal.
+		 * 
+		 */ 
+		virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
+	};
+
+	osg::Vec3 upVector;
+	
+// Position
+	/**
+	 * Latitude of the object.
+	 */ 
+	double lat;
+
+	/**
+	 * Longitude of the object.
+	 */ 
+	double lon;
+
+	/**
+	 * Altitude of the object over the ellipsoid. 
+	 */ 
+	double alt;
+
+// Attitude
+	/**
+	 * Azimuth angle (Rotation along Z axis, "heading") of the object 
+	 */ 
+	double azimuthAngle_psi;
+
+	/**
+	 * Pitch ("nose relative to horizon") angle of the object 
+	 */ 
+	double pitchAngle_theta;
+
+	/**
+	 * Bank angle of the object.
+	 */ 
+	double bankAngle_phi;
+
+// Scale
+	/**
+	 * Object scale along X axis.
+	 */ 
+	double scaleX;
+
+	/**
+	 * Object scale along Y axis.
+	 */ 
+	double scaleY;
+
+	/**
+	 * Object scale along Z axis.
+	 */ 
+	double scaleZ;
+
+// Camera offset
+	/**
+	 * This is the matrix containing the camera position for the  manipulators
+	 */ 
+	osg::Matrixd cameraMatrix;
+
+	/**
+	 * This is the camera matrix containing offset translation
+	 */ 
+	osg::Matrix cameraTranslationOffset;
+
+	/**
+	 * This is the camera matrix containing offset rotation
+	 */ 
+	osg::Matrix cameraRotationOffset;
+
+	/**
+	 * Geometry offset (If a model's coordinate system has wrong orientation.)
+	 */ 
+	osg::Quat geometry_offset_rotation;	
+
+	/**
+	 * Pointer to the geometry, associated with this object.
+	 */ 
+	osg::ref_ptr<osg::Group> geometry;
+
+	/**
+	 * Pointer to the updater class which updates this visual_object.
+	 */ 
+	osg::ref_ptr<object_updater> updater;
+
+// Labels
+	/**
+	 * Pointer to the labels group which holds all labels associated with this object.
+	 */ 
+	osg::ref_ptr<osg::Geode> labels;
+
+	// Friend classes
+	friend class visual_objectPositionCallback; // To allow the callback access to all member variables.
+	friend class object_updater;	// To allow updater to modify all members.
+
+};
+
+} // END NAMESPACE
Index: /osgVisual/trunk/include/sky_Silverlining/skySilverLining_AtmosphereReference.h
===================================================================
--- /osgVisual/trunk/include/sky_Silverlining/skySilverLining_AtmosphereReference.h	(revision 176)
+++ /osgVisual/trunk/include/sky_Silverlining/skySilverLining_AtmosphereReference.h	(revision 176)
@@ -0,0 +1,58 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+ * 
+ * This file is based on the OSG example of the Silverlining SDK:
+ * Copyright (c) 2008 Sundog Software, LLC. All rights reserved worldwide.
+*/
+
+#include <SilverLining.h>
+#include <osg/Referenced>
+
+
+namespace osgVisual
+{
+
+/**
+ * \brief This class holds the pointer to the atmosphere object and is bound to the rendering camera. 
+ * 
+ * This way all rendered elements can access the atmosphere. It also mirrors the atmosphere's init status 
+ * to prevent crashing by access to the uninitialized object.
+ * 
+ * @author Torben Dannhauer
+ * @date  Sep 2009
+ */ 
+class skySilverLining_atmosphereReference : public osg::Referenced
+{
+	#include <leakDetection.h>
+public:
+	/**
+	 * Pointer to the atmosphere object.
+	 */ 
+	SilverLining::Atmosphere *atmosphere;
+
+	/**
+	 * This flag indicates whether the atmosphere is initialized and the pointer is valid.
+	 */ 
+	bool atmosphereInitialized;
+
+	/**
+	 * \brief Constructor to init the values.
+	 * 
+	 */ 
+	skySilverLining_atmosphereReference() : atmosphereInitialized(false), atmosphere(0) {};
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/sky_Silverlining/skySilverLining_ProjectionMatrixCallback.h
===================================================================
--- /osgVisual/trunk/include/sky_Silverlining/skySilverLining_ProjectionMatrixCallback.h	(revision 176)
+++ /osgVisual/trunk/include/sky_Silverlining/skySilverLining_ProjectionMatrixCallback.h	(revision 176)
@@ -0,0 +1,301 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+ * 
+ * This file is based on the OSG example of the Silverlining SDK:
+ * Copyright (c) 2008 Sundog Software, LLC. All rights reserved worldwide.
+*/
+
+#include <SilverLining.h>
+#include <osg/Camera>
+#include <osg/CullSettings>
+#include <osgAnimation/Animation>
+#include <skySilverLining_skyDrawable.h>
+#include <visual_util.h>
+
+
+
+namespace osgVisual
+{
+
+/**
+ * \brief This class intercepts OSG's method for automatically computing the near and far clip planes, taking into
+    account SilverLining's objects in the scene (sky box, clouds, and possibly an atmospheric limb.)
+ * 
+ * @todo : Create interface to control nearplane while tracking near plane.
+ * 
+ * @author Torben Dannhauer
+ * @date  Sep 2009
+ */ 
+class skySilverLining_projectionMatrixCallback : public osg::CullSettings::ClampProjectionMatrixCallback 
+{
+	#include <leakDetection.h>
+public:
+	/**
+	 * \brief Constructor : Initializes the attributes with valid values.
+	 * 
+	 * @todo : why is CSN required.
+	 * 
+	 * @param atm : Pointer to the atmosphere object.
+	 * @param cam : Pointer to the rendering camera.
+	 * @param csn_ : Pointer to the coordinatesystemode.
+	 */ 
+	skySilverLining_projectionMatrixCallback(SilverLining::Atmosphere *atm, osg::Camera *cam, osg::CoordinateSystemNode *csn_) : osg::CullSettings::ClampProjectionMatrixCallback(),
+        atmosphere(atm), camera(cam), csn(csn_), skyDrawable(0), minFar(90000), maxNear(2)
+    {
+		#include <leakDetection.h>
+
+        stockCullVisitor = osgUtil::CullVisitor::create();
+		//stockCullVisitor->setNearFarRatio( 0.00005 );
+
+		samplerClipPlanes = new osgAnimation::Vec2LinearSampler;
+		keys = samplerClipPlanes->getOrCreateKeyframeContainer();
+
+		//											Flughöhe				near		far
+		keys->push_back(osgAnimation::Vec2Keyframe(      0.0, osg::Vec2(     1.0,     80000.0)));
+		keys->push_back(osgAnimation::Vec2Keyframe(     50.0, osg::Vec2(     5.0,     90000.0)));
+	//keys->push_back(osgAnimation::Vec2Keyframe(    500.0, osg::Vec2(     5.0,    100000.0)));
+	//keys->push_back(osgAnimation::Vec2Keyframe(   1000.0, osg::Vec2(    10.0,    100000.0)));
+	//keys->push_back(osgAnimation::Vec2Keyframe(  10000.0, osg::Vec2(   100.0,   1000000.0)));
+	//keys->push_back(osgAnimation::Vec2Keyframe(1000000.0, osg::Vec2(100000.0, 200000000.0)));
+		keys->push_back(osgAnimation::Vec2Keyframe(    500.0, osg::Vec2(     5.0,    100000.0)));
+		keys->push_back(osgAnimation::Vec2Keyframe(   1000.0, osg::Vec2(    10.0,    100000.0)));
+		keys->push_back(osgAnimation::Vec2Keyframe(  10000.0, osg::Vec2(   50.0,   1000000.0)));
+		keys->push_back(osgAnimation::Vec2Keyframe(1000000.0, osg::Vec2(100.0, 200000000.0)));
+
+    }
+
+	/**
+	 * \brief This functions sets the pointer to the skyDrawable. This pointer is requiered to adjust the skybox size.
+	 * 
+	 * @param sd : Pointer to the skyDrawable to store.
+	 */ 
+	void setSkyDrawable(skySilverLining_skyDrawable *sd) {skyDrawable = sd;}
+
+protected:
+	/**
+	 * \brief Implementation for float values to clamp the projection matrix.
+	 * 
+	 * @param projection : Projection Matrix.
+	 * @param znear : Near value of the projection matrix.
+	 * @param zfar : Far value of the projection matrix.
+	 * @return : True if successful
+	 */ 
+    bool clampProjectionMatrixImplementation(osg::Matrixf& projection, double& znear, double& zfar) const
+    {
+   	   computeNearFar( znear, zfar );
+	   //OSG_NOTIFY( osg::ALWAYS ) << "znear: " << znear << ", zfar: " << zfar << std::endl;
+
+	   if (skyDrawable)
+	   {
+	       skyDrawable->setSkyboxSize(((zfar - znear) * 0.5 + znear) * 2.0);
+	   }
+		
+	   double fovy, ar, zn, zf;
+       camera->getProjectionMatrixAsPerspective(fovy, ar, zn, zf);
+	   camera->setProjectionMatrixAsPerspective(fovy, ar, znear, zfar);
+
+		return true;
+    }
+
+	/**
+	 * \brief Implementation for double values to clamp the projection matrix.
+	 * 
+	 * @param projection : Projection Matrix.
+	 * @param znear : Near value of the projection matrix.
+	 * @param zfar : Far value of the projection matrix.
+	 * @return : True if successful
+	 */ 
+    bool clampProjectionMatrixImplementation(osg::Matrixd& projection, double& znear, double& zfar) const
+    {
+	   computeNearFar( znear, zfar );
+	   //OSG_NOTIFY( osg::ALWAYS ) << "znear: " << znear << ", zfar: " << zfar << std::endl;
+
+	   if (skyDrawable)
+	   {
+	       skyDrawable->setSkyboxSize(((zfar - znear) * 0.5 + znear) * 2.0);
+	   }
+		
+	   double fovy, ar, zn, zf;
+       camera->getProjectionMatrixAsPerspective(fovy, ar, zn, zf);
+	   //OSG_NOTIFY( osg::ALWAYS ) << "znear: " << znear << ", zfar: " << zfar << ", zn: " << zn << std::endl; 
+	   camera->setProjectionMatrixAsPerspective(fovy, ar, znear, zfar);
+
+		return true;
+    }
+
+	/**
+	 * \brief This function computes the near and far value against the cloud objects of silverlining.
+	 * 
+	 * @param znear : Referenced to store the calculated near value into.
+	 * @param zfar : Referenced to store the calculated far value into.
+	 */ 
+    void computeNearFarClouds(double &znear, double &zfar) const
+    {
+		const double fudge = 5000.0;
+        double minDist = 1E10; double maxDist = -1E10;
+
+		// Retrieve all atmosphere objects.
+ 		SL_VECTOR(SilverLining::ObjectHandle) &objects = atmosphere->GetObjects();
+		int size = objects.size();
+		
+		osg::Vec3d eye, dirVector, upVector;
+		camera->getViewMatrixAsLookAt(eye,dirVector,upVector); // Get XYZ from camera
+		//osg::Vec3d camPos = camera->getViewMatrix().getTrans();
+		osg::Vec3d camPos = eye;
+        osg::Vec3d up = camPos;
+        up.normalize();
+        osg::Vec3d down = up * -1.0;
+
+		double dToOrigin = camPos.length();
+
+		// Calculations if atmopshere is rendered from space
+		bool hasLimb = atmosphere->GetConfigOptionBoolean("enable-atmosphere-from-space");
+		OSG_ALWAYS << "has limb " << hasLimb << std::endl;
+		if (hasLimb)
+		{
+			// Compute distance to edge of atmospheric limb
+			double earthRadius = atmosphere->GetConfigOptionDouble("earth-radius-meters");
+			double atmosphereHeight = earthRadius + atmosphere->GetConfigOptionDouble("atmosphere-height");
+			double atmosphereThickness = atmosphere->GetConfigOptionDouble("atmosphere-scale-height-meters") + earthRadius;
+			if (dToOrigin > atmosphereThickness) // Bail if limb not rendered
+			{
+				double dToLimbEdge = sqrt(dToOrigin * dToOrigin + atmosphereHeight * atmosphereHeight);
+				maxDist = dToLimbEdge;
+				double dToLimbBase = sqrt(dToOrigin * dToOrigin + earthRadius * earthRadius);
+				minDist = dToLimbBase;
+			}
+		}
+
+		// Walk through all objects and check if they influence the near plane or far plane
+		SL_VECTOR(SilverLining::ObjectHandle)::iterator it;
+        for (it = objects.begin(); it != objects.end(); it++)
+        {
+            float ox, oy, oz;
+            atmosphere->GetObjectPosition(*it, ox, oy, oz);
+            osg::Vec3d oPos(ox, oy, oz);
+            double oHeight = oPos.length();
+            osg::Vec3d testVec = camPos;
+			// Compare distance to origin of the camera and the object. wenn objecte nah aneinander: 
+			//vertikal shiften, um eine erkennbare Distanz errechnen zu können.
+            if (dToOrigin > oHeight)
+            {
+                testVec = camPos + down * 100.0; // 100 for floating point precision problems
+            }
+            else
+            {
+                testVec = camPos + up * 100.0;
+            }
+            
+            const double farFarAway = 500000;
+
+            double dist = atmosphere->GetObjectDistance(*it, testVec.x(), testVec.y(), testVec.z(),
+				(float)camPos.x(), (float)camPos.y(), (float)camPos.z());
+
+
+            if (dist < farFarAway) // an intersection was found
+            {
+                if (dist < minDist) minDist = dist;
+                if (dist > maxDist) maxDist = dist;
+            }
+        }	// For (all objects) END
+
+        double fovy, ar, zn, zf;
+        camera->getProjectionMatrixAsPerspective(fovy, ar, zn, zf);
+        double halfFovx = (fovy * ar) * 0.5;
+        minDist *= cos(halfFovx * (3.14159265 / 180.0));
+
+        znear = minDist - fudge;
+        zfar = maxDist + fudge;
+
+		//clamp the near plane if low above ground.
+	    double x,y,z,hat;
+	    util::getXYZofCamera( camera, x, y, z );
+		if( util::queryHeightAboveTerrainInWorld( hat, csn, x, y, z ) )
+		{
+			if (hat < 80 )	
+			{
+				znear = maxNear;
+			}
+		}
+	    //OSG_NOTIFY( osg::ALWAYS ) << "Near: " << znear << ", Far: " << zfar << std::endl;
+    }
+
+	void computeNearFar( double& near_, double& far_ ) const
+	{
+		double x,y,z,hat;
+		near_ = 2;
+		far_ = 125000;
+	    util::getXYZofCamera( camera, x, y, z );
+		if( util::queryHeightAboveTerrainInWorld( hat, csn, x, y, z ) )
+		{
+			osg::Vec2 planesNearFar;
+			samplerClipPlanes->getValueAt(hat, planesNearFar);
+
+			near_ = planesNearFar.x();
+			far_  = planesNearFar.y();
+
+			//OSG_NOTIFY( osg::ALWAYS ) << "hat: " << hat << ", near: " << near_ << ", far: " << far_ << std::endl;
+		} // IF HAT END
+		else 
+			OSG_NOTIFY( osg::FATAL ) << "ERROR: Unable to Compute NearFar!" << std::endl;
+
+		if (near_ < 0.5 ) near_ = 0.5;
+	}
+
+    
+	/**
+	 * Pointer to the Cullvisitor which applies the projection matrix.
+	 */ 
+	osg::ref_ptr<osgUtil::CullVisitor> stockCullVisitor;
+
+	/**
+	 * Pointer to silverlinings atmosphere instance.
+	 */ 
+    SilverLining::Atmosphere *atmosphere;
+
+	/**
+	 * Pointer to the camera on which the callback is installed
+	 */ 
+    osg::Camera *camera;
+
+	/**
+	 * Pointer to the skyDrawable
+	 */ 
+	skySilverLining_skyDrawable *skyDrawable;
+
+	/**
+	 * ?
+	 * @todo: wofür ist diese variable nötig?
+	 */ 
+	osg::CoordinateSystemNode *csn;
+
+
+	osg::ref_ptr<osgAnimation::Vec2LinearSampler> samplerClipPlanes;
+	osg::ref_ptr<osgAnimation::Vec2KeyframeContainer> keys;
+
+	/**
+	 * Minimal far distance. The far plane is never nearer than this value.
+	 */ 
+	double minFar;
+
+	/**
+	 * Maximal near distance. The near plane is never farther than this value. 
+	 * It is used to clamp the near plane on a fix near value if the camera is low above ground
+	 */ 
+	double maxNear;
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/sky_Silverlining/skySilverLining_cloudLayerSlot.h
===================================================================
--- /osgVisual/trunk/include/sky_Silverlining/skySilverLining_cloudLayerSlot.h	(revision 176)
+++ /osgVisual/trunk/include/sky_Silverlining/skySilverLining_cloudLayerSlot.h	(revision 176)
@@ -0,0 +1,87 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+ * 
+ * This file is based on the OSG example of the Silverlining SDK:
+ * Copyright (c) 2008 Sundog Software, LLC. All rights reserved worldwide.
+*/
+
+#include <SilverLining.h>
+#include <string>
+
+
+namespace osgVisual
+{
+
+/**
+ * \brief This class represents a single cloudlayer slot which contains a cloud layer and corresponding additional information.
+ * 
+ * @author Torben Dannhauer
+ * @date  Sep 2009
+ */ 
+class cloudLayerSlot
+{
+	#include <leakDetection.h>
+public:
+	/**
+	 * \brief Construtor, which initializes the cloudlayer information with valid default values.
+	 * 
+	 */ 
+	cloudLayerSlot() 
+	{
+		slot_id = -1;
+		used = false;
+		enabled = false;
+		cloudLayerHandle = -1;
+		cloudLayerPointer = NULL;
+		typeName = "";
+	};
+
+	/**
+	 * ID of the cloudlayer slot.
+	 */ 
+	int slot_id;
+
+	/**
+	 * This flag indicates if the cloudlayer slot is in use.
+	 * 
+	 * @todo : Explain diff to 'enabled'.
+	 */ 
+	bool used;
+
+	/**
+	 * This flag indicates if the cloudlayer slot is enabled.
+	 * 
+	 * @todo : Explain diff to 'used'.
+	 */ 
+	bool enabled;
+
+	/**
+	 * This variable contains silverlining's cloudlayer handle-ID.
+	 */ 
+	int cloudLayerHandle;
+
+	/**
+	 * Pointer to the cloudlayer object.
+	 */ 
+	SilverLining::CloudLayer *cloudLayerPointer;
+
+	/**
+	 * Literal name of the cloudlayer type. e.g. CUMULUS_MEDIOCRIS.
+	 */ 
+	std::string typeName;
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/sky_Silverlining/skySilverLining_cloudsDrawable.h
===================================================================
--- /osgVisual/trunk/include/sky_Silverlining/skySilverLining_cloudsDrawable.h	(revision 176)
+++ /osgVisual/trunk/include/sky_Silverlining/skySilverLining_cloudsDrawable.h	(revision 176)
@@ -0,0 +1,104 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+ * 
+ * This file is based on the OSG example of the Silverlining SDK:
+ * Copyright (c) 2008 Sundog Software, LLC. All rights reserved worldwide.
+*/
+
+#include <osg/Drawable>
+#include <osgViewer/Viewer>
+#include <SilverLining.h>
+
+
+
+//class SilverLining::Atmosphere;
+class Atmosphere;
+
+namespace osgVisual
+{
+/**
+ * \brief This class wraps Silverlining's endFrame() function which render clouds, fog and finishes the frame.
+ * 
+ * @author Torben Dannhauer
+ * @date  Sep 2009
+ */ 
+class skySilverLining_cloudsDrawable : public osg::Drawable
+{
+	#include <leakDetection.h>
+public:
+	/**
+	 * \brief Constructor : Initializes attributes.
+	 * 
+	 */ 
+    skySilverLining_cloudsDrawable();
+
+	/**
+	 * \brief Constructor : Initializes attributes.
+	 * 
+	 * @param view : Pointer to the viewer instance.
+	 */ 
+	skySilverLining_cloudsDrawable(osgViewer::Viewer* view);
+
+	/**
+	 * \brief This function checks if this object is the same kind as the specified one.
+	 * 
+	 * This function is required by subclassing osg::Drawable.
+	 * 
+	 * @param obj : object to compare this type to.
+	 * @return : True if it is the same kind.
+	 */ 
+    virtual bool isSameKindAs(const Object* obj) const {
+        return dynamic_cast<const skySilverLining_cloudsDrawable*>(obj)!=NULL;
+    }
+
+	/**
+	 * \brief This function clones this class/type.
+	 * 
+	 * This function is required by subclassing osg::Drawable.
+	 * 
+	 * @return : Cloned instance.
+	 */ 
+    virtual Object* cloneType() const {
+        return new skySilverLining_cloudsDrawable();
+    }
+
+	/**
+	 * \brief This function clones this class/type.
+	 * 
+	 * This function is required by subclassing osg::Drawable.
+	 * 
+	 * @param copyop : Copy operator flag which indicates how to clone.
+	 * @return : Cloned instance.
+	 */ 
+    virtual Object* clone(const osg::CopyOp& copyop) const {
+        return new skySilverLining_cloudsDrawable();
+    }
+
+	/**
+	 * \brief Draw implementation which will be drawn every frame and is the true payload of thes class.
+	 * 
+	 * @param renderInfo : rendering information.. (?)
+	 */ 
+    virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
+
+protected:
+	/**
+	 * Pointer to the viewer instance.
+	 */ 
+    osgViewer::Viewer* _view;
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/sky_Silverlining/skySilverLining_skyDrawable.h
===================================================================
--- /osgVisual/trunk/include/sky_Silverlining/skySilverLining_skyDrawable.h	(revision 176)
+++ /osgVisual/trunk/include/sky_Silverlining/skySilverLining_skyDrawable.h	(revision 176)
@@ -0,0 +1,98 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+ * 
+ * This file is based on the OSG example of the Silverlining SDK:
+ * Copyright (c) 2008 Sundog Software, LLC. All rights reserved worldwide.
+*/
+
+
+
+#include <osg/Drawable>
+#include <osg/CoordinateSystemNode>
+#include <osg/Fog>
+
+#include <osgViewer/Viewer>
+#include <OpenThreads/ScopedLock>
+#include <OpenThreads/Mutex>
+
+#include <skySilverLining_cloudLayerSlot.h>
+#include <visual_util.h>
+
+#include <SilverLining.h>
+#include <iostream>
+
+namespace osgVisual
+{
+
+class skySilverLining_atmosphereReference;
+
+struct cloudlayerOrder 
+{
+	int slot;
+	double lat;
+	double lon;
+	double baseLength;
+	double baseWidth;
+	double thickness;
+	double baseHeight;
+	double density;
+	CloudTypes cloudtype;
+	cloudLayerSlot* assocCloudLayerSlot;	// Pointer to the cloudlayerslot managed by visual_skySilverlining. 
+};
+
+
+class skySilverLining_skyDrawable : public osg::Drawable
+{
+	#include <leakDetection.h>
+public:
+	skySilverLining_skyDrawable();
+	skySilverLining_skyDrawable(osgViewer::Viewer* view, osg::CoordinateSystemNode* csn_);
+
+    virtual bool isSameKindAs(const Object* obj) const {
+        return dynamic_cast<const skySilverLining_skyDrawable*>(obj)!=NULL;
+    }
+    virtual Object* cloneType() const {
+        return new skySilverLining_skyDrawable();
+    }
+    virtual Object* clone(const osg::CopyOp& copyop) const {
+        return new skySilverLining_skyDrawable();
+    }
+
+	void setSkyboxSize(double size) {_skyboxSize = size;}
+
+    virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
+
+	void addCloudLayerOrder(cloudlayerOrder newCL);
+
+	void shutdown();
+
+protected:
+	void setLighting(SilverLining::Atmosphere *atm) const;
+	void setSceneFog(SilverLining::Atmosphere *atmosphere) const;
+	static void initializeSilverLining(skySilverLining_atmosphereReference *ar);
+	void seedAndAddCloudLayers(SilverLining::Atmosphere *atmosphere);
+
+    osgViewer::Viewer* _view;
+	double _skyboxSize;
+
+private:
+	OpenThreads::Mutex cloudLayersToAddMutex;
+	std::vector<cloudlayerOrder> pendingNewCloudLayers;
+	bool newCloudLayersToAdd;
+	osg::ref_ptr<osg::CoordinateSystemNode> sceneRoot;
+};
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/include/sky_Silverlining/visual_skySilverLining.h
===================================================================
--- /osgVisual/trunk/include/sky_Silverlining/visual_skySilverLining.h	(revision 176)
+++ /osgVisual/trunk/include/sky_Silverlining/visual_skySilverLining.h	(revision 176)
@@ -0,0 +1,608 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+ * 
+ * This file is based on the OSG example of the Silverlining SDK:
+ * Copyright (c) 2008 Sundog Software, LLC. All rights reserved worldwide.
+*/
+
+#include <osg/NodeCallback>
+#include <osg/Geode>
+
+#include <SilverLining.h>
+#include <MillisecondTimer.h>
+#ifdef WIN32
+	#include <windows.h>
+#endif
+#include <skySilverLining_skyDrawable.h>
+#include <skySilverLining_cloudsDrawable.h>
+#include <skySilverLining_AtmosphereReference.h>
+#include <skySilverLining_ProjectionMatrixCallback.h> 
+#include <skySilverLining_cloudLayerSlot.h>
+
+#include <visual_util.h>
+
+namespace osgVisual
+{
+
+#define MAX_CLOUDLAYER_SLOTS 5 
+/**
+ * \brief This class is the container class for the sky, stars and clouds
+ * 
+ * This class is the container class for the sky, stars and clouds. It is responsible for initialization and updating of the sky system.
+ * It is realized as Geode that it is possible to install an updateCallback on this class.
+ * This way, the sky position is always updated during update traversal of the scene graph.
+ * 
+ * The NodeCallback class is nested into this class that no external user can use this callback.
+ * 
+ * @todo Add Cloudlayer->set/getalpha() function
+ * @todo Terrain shadows do not exist
+ * @todo Calibrate visual range with test objects. Populate a Lookuptable to use for true visibility ranges.
+ * @todo Implement an abstract sky interface class to allow other sky implementations than silverlining with identical interfaces
+ * 
+ * @author Torben Dannhauer
+ * @date  Jul 2009
+ */ 
+class visual_skySilverLining : public osg::Geode
+{
+	//#include <leakDetection.h>
+public:
+	/**
+	 * \brief Constructor.
+	 * 
+	 * @param viewer_ : Pointer to the applications viewer
+	 * @param configFileName : Filename of the XML configfile to read the configuration from. Currently not used because skySilverlining currently does not need any configuration parameters.
+	 */ 
+	visual_skySilverLining(osgViewer::Viewer* viewer_, std::string configFileName);
+
+	/**
+	 * \brief Destrcutor: The updateCallback is removed and the atmosphere, if instantiated.
+	 * 
+	 */ 
+	virtual ~visual_skySilverLining(void);
+
+	/**
+	 * \brief Returns a Pointer to the atmosphere object.
+	 * 
+	 * @return Pointer to the atmosphere object.
+	 */ 
+	SilverLining::Atmosphere* getAtmosphere() {return atmosphere;};
+
+	/**
+	 * \brief Checks if the sky system is initialized.
+	 * 
+	 * Checks if the sky system is initialized. If not, it makes a deep lookup at the main cameras userdata, if atmosphere is initialized.
+	 * If this returns true, the local variable is updated with ne new initialize status. If this deep lookup returns false, this method returns also false
+	 * asks the cameras user data if initialzed. If that is
+	 * 
+	 * @return : Returns the status of initialization.
+	 */ 
+	bool isInitialized();
+	
+	/**
+	 * \brief This function initializes the sky framework if its used with a PRE_RENDER camera like the distortion module.
+	 * 
+	 * @param distortedRoot : osg::Group* which is the rootNode over distortion and scene
+	 * @param sceneGraphRoot : osg::Group* which is the rootNode and coordinateSystemNode of the scene.
+	 */ 
+	void init(osg::Group *distortedRoot, osg::CoordinateSystemNode *sceneGraphRoot);
+
+	/**
+	 * \brief This function can be called by the updateCallback. If the postInitialization for adding clouds etc. has be called already, this function will skip.
+	 * 
+	 * If this function is called before sky is initalized, all actions are skipped.
+	 * A standart usage is adding objects like clouds and winds, configuring time, location and visibility.
+	 * 
+	 */ 
+	void postInit();
+
+	/**
+	 * \brief This function shuts the sky framework down.
+	 * 
+	 */ 
+	void shutdown();
+
+
+/** @name Time
+ *  The following functions control the simulated time and date. 
+ */
+//@{
+	/**
+	 * \brief Sets the new Date and Time to the sky system. 
+	 * 
+	 * Update is only performed if the sky systme is initialized.
+	 * 
+	 * @param year_ : Year to set. SilverLining can only handle Gregorian calendar years, which means that years before 1582 will not be accurately simulated.
+	 * @param month_ : Month to set. Ranging from 1 (Jan) to 12 (Dec)
+	 * @param day_ : Day to set Ranging from 1 to 31
+	 * @param hour_ : Hour to set. Ranging from 0 to 23
+	 * @param minute_ : Minute to set. Ranging from 0 to 59.
+	 * @param second_ : Second to set. Ranging from 0 to 59.
+	 * @param daylightSaving_ : Configures, if the configured DateTime is in daylight savings or without daylight savings.
+	 * @param timezoneOffset_ : Configures the timezone. Hour offset from GMT, ignoring daylight savings time.
+	 */ 
+	void setDateTime( int year_, int month_, int day_, int hour_, int minute_, int second_, bool daylightSaving_, double timezoneOffset_ );
+
+	/**
+	 * \brief Set time for the sky system.
+	 * 
+	 * @param hour_ : Hour to set. Ranging from 0 to 23
+	 * @param minute_ : Minute to set. Ranging from 0 to 59.
+	 * @param second_ : Second to set. Ranging from 0 to 59.
+	 */ 
+	void setTime( int hour_, int minute_, int second_ );
+
+	/**
+	 * \brief Sets the date for the sky system.
+	 * 
+	 * @param year_ : Year to set. SilverLining can only handle Gregorian calendar years, which means that years before 1582 will not be accurately simulated.
+	 * @param month_ : Month to set. Ranging from 1 (Jan) to 12 (Dec)
+	 * @param day_ : Day to set Ranging from 1 to 31
+	 */ 
+	void setDate( int year_, int month_, int day_ );
+
+	/**
+	 * \brief Configures the date and time by epoche (Seconds elapsed since midnight, January 1, 1970 UTC) 
+	 * 
+	 * This function ignores the daylight savings and timezone.
+	 * 
+	 * @param secondsSince1970_ : Seconds elapsed since midnight, January 1, 1970 UTC
+	 */ 
+	void setDateByEpoch(int secondsSince1970_ );
+
+//@}
+
+/** @name Location
+ *  The following functions control the location to simulate. 
+ */
+//@{
+	/**
+	 * \brief Configures the sky system to simulate a specific location.
+	 * 
+	 * @param lat_ : Latitude in radians
+	 * @param lon_ : Longitude in radians
+	 * @param alt_ : Altimeter in meters above see level.
+	 */ 
+	void setLocation(double lat_, double lon_, double alt_);
+//@}
+
+/** @name Visibility and Haze
+ *  The following functions control the atmosperic effects like visibility range and haze. 
+ */
+//@{
+	/**
+	 * \brief This functions sets the visibility range in meters to simulate.
+	 * 
+	 * @param visibility_ : Visibility range in meters.
+	 */ 
+	void setVisibility(double visibility_);
+
+	/**
+	 * \brief This function returns the visibility range in meters which is simulated. 
+	 * 
+	 * @return : Visibility range in meters.
+	 */ 
+	double getVisibility();
+
+	/**
+	 * \brief This function sets the haze factor to simulate. 
+	 * 
+	 * 1 = Pure air, range 256 km
+	 * 2 = very clear, range 50 km
+	 * 3 = clear, range 15 km
+	 * 7 = light haze, range 8 km
+	 * 20 = haze, range 3 km
+	 * 50 = thin fog, range 2 km
+	 * 
+	 * @param turbidity_ : Haze factor to simulate. 
+	 */ 
+	void setTurbidity(double turbidity_);
+
+	/**
+	 * \brief This function returns the simulated haze factor.
+	 * 
+	 * @return : Haze factor.
+	 */ 
+	double getTurbidity();
+//@}
+
+/** @name Light pollution
+ *  The following functions control the light pollution to simulate at night. 
+ */
+//@{
+	/**
+	 * \brief This functions sets the light pollution in Watt/m2 
+	 * 
+	 * @param lightPollution_ : Light pollution to set.
+	 */ 
+	void setLightPollution(double lightPollution_);
+
+	/**
+	 * \brief This function returns the simulated light pollution in Watt/m2.
+	 * 
+	 * @return : Light pollution in Watt/m2
+	 */ 
+	double getLightPollution();
+//@}
+
+/** @name Clouds
+ *  The following functions control the available slots for cloudLayer. In each slot a cloud layer can be adde and its perscpitation or
+ * baseAltitude updated. All other values are not updateable, therefore a delete and recreation of the cloud layer would be necessary. 
+ */
+//@{
+	/**
+	 * \brief This function adds a Cloudlayer to a sepcified SLOT. If the slot is used, this function returns immediately.
+	 * 
+	 * If the slot number is out of range, nothing happens.
+	 * 
+	 * Currently supported CloudTypes are:
+	 *
+	 * \li CloudTypes::CIRROCUMULUS - High planar cloud puffs.
+	 * \li CloudTypes::CIRRUS_FIBRATUS - High, wispy cirrus clouds.
+     * \li CloudTypes::NIMBOSTRATUS - Low stratus decks.
+     * \li CloudTypes::CUMULONIMBUS_CAPPILATUS - A large thunderhead with lightning and rain.
+     * \li CloudTypes::CUMULUS_MEDIOCRIS - Small, puffy clouds.
+     * \li CloudTypes::CUMULUS_CONGESTUS - Larger cumulus clouds with flattened bottoms.
+     * \li CloudTypes::CUMULUS_MEDIOCRIS_INFINITE - A cumulus mediocris layer where the clouds wrap around
+     *  the camera location at all times, to create the illusion of an infinitely large cloud layer.
+     * \li CloudTypes::CUMULUS_CONGESTUS_INFINITE - A cumulus congestus layer where the clouds wrap around
+     *  the camera location at all times, to create the illusion of an infinitely large cloud layer.
+	 * 
+	 * @param slot_ : Slot to use.
+	 * @param baseLength_ : Baselength in meter of the cloud layer to generate.
+	 * @param baseWidth_ : Basewideth in meter of the cloud layer to generate.
+	 * @param thickness_ : Thicknes of the could layer in meter.
+	 * @param baseHeight_ : Height of the cloud base in WGS84.
+	 * @param density_ : Coverage of the cloud layer in percent (0.0 - 1.0).
+	 * @param cloudtype_ : Type of the cloudlayer to generate.
+	 */ 
+	void addCloudLayer(int slot_, double baseLength_, double baseWidth_, double thickness_, double baseHeight_, double density_, CloudTypes cloudtype_ );
+
+	/**
+	 * \brief This function remove the cloudlayer in the specified slot and marks the slot as free.
+	 * 
+	 * If the slot number is out of range, nothing happens.
+	 * 
+	 * @param slot_ : Slot number to clean 
+	 */ 
+	void removeCloudLayer( int slot_ );
+	
+	/**
+	 * \brief This function removes the cloud layers from all slots
+	 * 
+	 */ 
+	void clearAllSlots();
+
+	/**
+	 * \brief This function returns a pointer to the cloudLayer this slot contains.
+	 * 
+	 * If the slot number is out of range, nothing happens.
+	 * 
+	 * @param slot_ : Slot to query for it's cloudLayer pointer.
+	 * @return : Pointer to the contained cloud layer.
+	 */ 
+	SilverLining::CloudLayer* getCloudLayer( int slot_ );
+	
+	/**
+	 * \brief This function configure the cloud layer als enabled (show clouds) or disabled (hide clouds).
+	 * 
+	 * If the slot number is out of range, nothing happens.
+	 * 
+	 * @param slot_ : Cloudlayer to hide/show.
+	 * @param enabled_ : Control where hide or show should be configured.
+	 */ 
+	void setEnabled(int slot_, bool enabled_ );
+
+	/**
+	 * \brief This function returns if the specified cloud layer is en- or disabled (hidden or shown).
+	 * 
+	 * If the slot number is out of range, nothing happens.
+	 * 
+	 * @param slot_ : Slot zu query.
+	 * @return : true if clouds are visible, false if clouds are hidden.
+	 */ 
+	bool isEnabled( int slot_ );
+
+	/**
+	 * \brief This functions fade the clouds in or out, depending on the visibility tsatus before.
+	 * 
+	 * If the slot number is out of range, nothing happens.
+	 * 
+	 * @param slot_ : Slot to fade.
+	 * @param fadetimeMS_ : Milliseconds to fade the cloud layer.
+	 */ 
+	void fadeVisibility( int slot_, int fadetimeMS_);
+
+	/**
+	 * \brief 
+	 * 
+	 * If the slot number is out of range, nothing happens.
+	 * 
+	 * @param slot_ 
+	 * @return : String with the literal name of the cloud layer type.
+	 */ 
+	std::string getCloudLayerTypeName( int slot_ );
+
+//@}
+
+/** @name Wind
+ *  Description of wind. Attention: Wind volumes are not geocentric: If far enough away from upvector location, the earth will curve away under the wind volume.
+ */
+//@{
+	/**
+	 * \brief This function adds a wind volume to the scene, with the specified characteristics.
+	 * 
+	 * @param bottom_ : Height in WGS84 in metern of the wind volumes bottom. 
+	 * @param top_ : Height in WGS84 in metern of the wind volumes top. 
+	 * @param speed_ : Windspeed in the wind volume in meter per seconds.
+	 * @param direction_ : Wind direction in the wind volume in degree (wind origin, not wind destination).
+	 * 
+	 */ 
+	void addWindVolume(double bottom_, double top_, double speed_, int direction_);
+
+	/**
+	 * \brief This function deletes all wind volumes.
+	 * 
+	 */ 
+	void clearAllWindVolumes();
+
+	/**
+	 * \brief This functions checks wether the specified altitude in MSL is inside a wind volume.
+	 * 
+	 * If multiple wind volumes are nested, this function returns the first matching wind volume.
+	 * Because geocentric wind is not implemented, the altitude information is always base on the location where the wind was added.
+	 * To avoid multiple winds, don't use nested wind volumes.
+	 * 
+	 * @param height_ : Height in meters in WGS84 to check for wind.
+	 * @param bottom_ : If checking altitude is inside a volume, the bottom altitude of the volume in meters above MSL is written into, otherwise -1.
+	 * @param top_ : If checking altitude is inside a volume, the top altitude of the volume in meters above MSL is written into, otherwise -1.
+	 * @param speed_ : If checking altitude is inside a volume, the wind speed in the wind volume is written into, otherwise -1.
+	 * @param direction_ : If checking altitude is inside a volume, the wind direction (0 deg = from north, 90 deg = from east) in the wind volume is written into, otherwise -1.
+	 * @return : True if checking altitude is inside a wind volume, otherwise false.
+	 */ 
+	bool insideWind(double height_, double& bottom_, double& top_, double& speed_, double& direction_);
+
+	
+//@}
+
+/** @name Precipitation
+ *  The following functions control the rate and type of precipitation. It is possible to configure it on an global or a per cloud basis. 
+ */
+//@{
+	// Per SLOT
+	/**
+	 * \brief This functions enables the specified precipitation rate and precipitation type at the specified cloudLayer slot.
+	 * 
+	 * @param slot_ : CloudLayer slot to enable precipitation in.
+	 * @param rate_mmPerHour_rain_ : Precipitation rate in mm/hour of rain.
+	 * @param rate_mmPerHour_drySnow_ : Precipitation rate in mm/hour of dry snow.
+	 * @param rate_mmPerHour_wetSnow_ : Precipitation rate in mm/hour of wet snow.
+	 * @param rate_mmPerHour_sleet_ : Precipitation rate in mm/hour of sleet.
+	 */ 
+	void setSlotPrecipitation( int slot_, double rate_mmPerHour_rain_, double rate_mmPerHour_drySnow_, double rate_mmPerHour_wetSnow_, double rate_mmPerHour_sleet_ );
+
+	/**
+	 * \brief This function retrieves the precipitation of a cloudlayer slot.
+	 * 
+	 * @param slot_ : Slot to check for precipitation. 
+	 * @param rate_mmPerHour_rain : Precipitation rate in mm/hour of rain.
+	 * @param rate_mmPerHour_drySnow : Precipitation rate in mm/hour of dry snow.
+	 * @param rate_mmPerHour_wetSnow : Precipitation rate in mm/hour of wet snow.
+	 * @param rate_mmPerHour_sleet : Precipitation rate in mm/hour of sleet.
+	 * @return : True if cloudLayer has precipitation.
+	 */ 
+	bool getSlotPrecipitation( int slot_, double& rate_mmPerHour_rain, double& rate_mmPerHour_drySnow, double& rate_mmPerHour_wetSnow, double& rate_mmPerHour_sleet );
+	
+	/**
+	 * \brief This function checks a specified location for precipitation at the specified cloudLayer slot.
+	 * 
+	 * @param slot_ : CloudLayer slot to check for specification.
+	 * @param rate_mmPerHour_rain : Precipitation rate in mm/hour of rain.
+	 * @param rate_mmPerHour_drySnow : Precipitation rate in mm/hour of dry snow.
+	 * @param rate_mmPerHour_wetSnow : Precipitation rate in mm/hour of wet snow.
+	 * @param rate_mmPerHour_sleet : Precipitation rate in mm/hour of sleet.
+	 * @param lat_ : Latitude to check for precipitation. If it defaults to -1, the internal sky latitude will be used.
+	 * @param lon_ : Longitude to check for precipitation. If it defaults to -1, the internal sky longitude will be used.
+	 * @param height_ : Height in WGS84 to check for precipitation. If it defaults to -1, the internal sky height will be used.
+	 * @return : Returns true if precipitation at the specified location is true.  
+	 */ 
+	bool getSlotPrecipitationAtLocation( int slot_, double& rate_mmPerHour_rain, double& rate_mmPerHour_drySnow, double& rate_mmPerHour_wetSnow, double& rate_mmPerHour_sleet, double lat_=-1, double lon_=-1, double height_=-1 );
+
+	/**
+	 * \brief This function clears all types of precipitation of the specified slot.
+	 * 
+	 * @param slot_ : Slot toe clear precipitation.
+	 */ 
+	void clearAllPrecipitation( int slot_ );
+
+	// Global
+	/**
+	 * \brief This function clears the global precipitation.
+	 * 
+	 */ 
+	void clearGlobalPrecipitation();
+
+	/**
+	 * \brief This function sets the cloud independent, global precipitation.
+	 * 
+	 * @param rate_mmPerHour_rain_ : Precipitation rate in mm/hour of rain.
+	 * @param rate_mmPerHour_drySnow_ : Precipitation rate in mm/hour of dry snow.
+	 * @param rate_mmPerHour_wetSnow_ : Precipitation rate in mm/hour of wet snow.
+	 * @param rate_mmPerHour_sleet_ : Precipitation rate in mm/hour of sleet.
+	 */ 
+	void setGlobalPrecipitation( double rate_mmPerHour_rain_, double rate_mmPerHour_drySnow_, double rate_mmPerHour_wetSnow_, double rate_mmPerHour_sleet_ );
+	
+	// Misc
+	/**
+	 * \brief This function returns the overall precipitation rate of all cloud dependent precipitation.
+	 * 
+	 * This function adds the precipitation of all cloudLayer seperated for all types of precipitation.
+	 * Global precipitation is ignored, because precipitation without clouds is artificial and only reasonable for visualiszation purposes.
+	 * 
+	 * @param rate_mmPerHour_rain : Precipitation rate in mm/hour of rain.
+	 * @param rate_mmPerHour_drySnow : Precipitation rate in mm/hour of dry snow.
+	 * @param rate_mmPerHour_wetSnow : Precipitation rate in mm/hour of wet snow.
+	 * @param rate_mmPerHour_sleet : Precipitation rate in mm/hour of sleet.
+	 * @param lat_ : Latitude to check for precipitation. If it defaults to -1, the internal sky latitude will be used.
+	 * @param lon_ : Longitude to check for precipitation. If it defaults to -1, the internal sky longitude will be used.
+	 * @param height_ : Height in WGS84 to check for precipitation. If it defaults to -1, the internal sky height will be used.
+	 * @return : True if precipitation lookup was successful.
+	 */ 
+	bool getOverallPrecipitationAtLocation( double& rate_mmPerHour_rain, double& rate_mmPerHour_drySnow, double& rate_mmPerHour_wetSnow, double& rate_mmPerHour_sleet, double lat_=-1, double lon_=-1, double height_=-1 );
+//@}
+
+
+
+
+
+private:
+	/**
+	 * \brief Nested Callback class
+	 * 
+	 * @author Torben Dannhauer
+	 * @date  Jul 2009
+	 */ 
+	class skyUpdateCallback : public osg::NodeCallback
+	{
+	public:
+		/**
+		 * \brief Constructor
+		 * 
+		 * @param csn_ : Pointer to the Coordinate System Node. Necessary to extract lat, lon and height of the camera position.
+		 * @param sceneCamera_ : Pointer to the scene camera (undistorted camera, type PRE_RENDER)
+		 * @param sky_ : Pointer to the sky system.
+		 */ 
+		skyUpdateCallback(osg::CoordinateSystemNode* csn_, osg::Camera* sceneCamera_, visual_skySilverLining* sky_)
+			: csn(csn_), sceneCamera(sceneCamera_), sky(sky_) {};
+
+		/**
+		 * \brief This function is executed as callback during traversal. It updates the skys displayed location.
+		 * 
+		 */ 
+		virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
+	private:
+		/**
+		 * Referenced pointer to the Coordinate System Node. Necessary to extract lat, lon and height of the camera position.
+		 */ 
+		osg::ref_ptr<osg::CoordinateSystemNode> csn;
+		
+		/**
+		 * Referenced pointer to the scene camera (undistorted camera, type PRE_RENDER)
+		 */ 
+		osg::ref_ptr<osg::Camera> sceneCamera;
+
+		/**
+		 * Referenced pointer to the sky system.
+		 */ 
+		osg::ref_ptr<visual_skySilverLining> sky;
+	};	// Nested class END
+
+	/**
+	 * \brief This function updates the atmosphere's upVector, 
+	 * if delta_lat or delta_lon (from the existing location
+	 * and the location of the last upVector update) is larger than N degree.
+	 * If an update is requiered, the existing location is noted as the last update location.
+	 * 
+	 * Iis called by this->setLocation.
+	 * 
+	 */ 
+	void updateUpVector();
+
+	/**
+	 * Pointer to the atmosphere object of Silverlining.
+	 */ 
+	SilverLining::Atmosphere *atmosphere;
+
+	/**
+	 * Referenced Pointer to the viewer
+	 */ 
+	osg::ref_ptr<osgViewer::Viewer> viewer;
+
+	/**
+	 * Referenced Pointer to the camera which pre renders the scene
+	 */ 
+	osg::ref_ptr<osg::Camera> sceneCamera;
+ 
+	/**
+	 * Referenced Pointer to the coordinate system node. Required for WGS84 transformations.
+	 */ 
+	osg::ref_ptr<osg::CoordinateSystemNode> sceneRoot;
+
+	/**
+	 * Referenced Pointer to the updatecallback, which is installed at this node. 
+	 */ 
+	osg::ref_ptr<skyUpdateCallback> updateCallback;
+
+	/**
+	 * Referenced Pointer to the ProjectionMatrix callback.
+	 */ 
+	osg::ref_ptr<skySilverLining_projectionMatrixCallback> cb;
+
+	/**
+	 * Referenced Pointer to the sky Drawable, which renders the skybox.
+	 */ 
+	osg::ref_ptr<skySilverLining_skyDrawable> skyDrawable;
+
+	/**
+	 * Referenced Pointer to the cloudsDrawable, which renders the clouds.
+	 */ 
+	osg::ref_ptr<skySilverLining_cloudsDrawable> cloudsDrawable;
+
+	/**
+	 * Flag which contains if the sky system is initialized. This status is only a local
+	 * copy if the cameras userdata which contain the primary information if the sky system is initialized
+	 */ 
+	bool atmosphereInitialized;
+
+	/**
+	 * This variable indicates whether postinit() was called already.
+	 */ 
+	bool postInitialized;
+
+	/**
+	 * This vector contains all available slots for cloud layer.
+	 */ 
+	std::vector<cloudLayerSlot> cloudLayerSlots;
+
+		/**
+	 * Latitude, which mirrors the latitude of the last sky update. This is neccesary if any weather effect is added to calculate the earth radius on that location for appropriate level above MSL
+	 */ 
+	double lat;
+
+	/**
+	 * Longitude, which mirrors the latitude of the last sky update. This is neccesary if any weather effect is added to calculate the earth radius on that location for appropriate level above MSL
+	 */ 
+	double lon;
+
+	/**
+	 * Height, which mirrors the height of the last sky update.
+	 */ 
+	double height;
+
+};
+
+using namespace SilverLining;
+
+//class MyMillisecondTimer : public SilverLining::MillisecondTimer
+//{
+//public:
+//	virtual unsigned long GetMilliseconds() const
+//        {
+//			return timeGetTime() * 50;
+//        }
+//};
+
+
+} // END NAMESPACE
Index: /osgVisual/trunk/include/util/visual_util.h
===================================================================
--- /osgVisual/trunk/include/util/visual_util.h	(revision 176)
+++ /osgVisual/trunk/include/util/visual_util.h	(revision 176)
@@ -0,0 +1,277 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <string.h>
+#include <iostream>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include <osg/Node>
+#include <osg/Group>
+#include <osg/Geode>
+#include <osg/CoordinateSystemNode>
+#include <osg/ShapeDrawable>
+
+#include <osgViewer/Viewer>
+
+#include <OpenThreads/ReentrantMutex>
+
+#include <osgUtil/LineSegmentIntersector>
+
+#ifdef FUNFUNCTIONS_ENABLED
+#ifdef WIN32
+#include <osgViewer/api/Win32/GraphicsHandleWin32>
+#include "C:\\Program Files/Microsoft SDKs/Windows/v6.1/Include/dwmapi.h"
+#pragma comment ( lib, "C:\\Program Files/Microsoft SDKs/Windows/v6.1/Lib/dwmapi.lib" )
+#endif
+#endif
+
+
+
+namespace osgVisual
+{ 
+
+/**
+ * \brief This class provides utility functions. 
+ * 
+ * The utility functions are implemented as static functions if possible for easy use in other classes.
+ * 
+ * \todo check why lineIntersector is unstable, check if newer and better system is available.
+ * 
+ * @author Torben Dannhauer
+ * @date  Jul 2009
+ */ 
+class util
+{
+	#include <leakDetection.h>
+public:
+	/**
+	 * \brief Construtor
+	 * 
+	 */ 
+	util();
+
+	/**
+	 * \brief Destructor
+	 * 
+	 */ 
+	~util();
+
+	/**
+	 * \brief This functions searches in the scene graph for a node with a name
+	 * 
+	 * This function searches in the scene graph unter the node "currNode" for a node named like the given search name.
+	 * The functions returns the first node with that name.
+	 * 
+	 * @param searchName_ : Nodename to search for
+	 * @param currNode_ : Scene graph to search in.
+	 * @return : if Node found: Pointer to the node. If not found: NULL
+	 */ 
+	static osg::Node* findNamedNode(const std::string& searchName_, osg::Node* currNode_);
+
+	/**
+	 * \brief This function creates a red cylinder of the specified size tor testing purposes.
+	 * 
+	 * @param length_ : Length of the cylinder in meter.
+	 * @param width_ : Diameter of the cylinder in meter.
+	 * @param offset_ : Offset of the cylinder's origin in meter.
+	 * @return : Referenced Pointer off the Geode with the created cylinder.
+	 */ 
+	static osg::ref_ptr<osg::Geode> getDemoCylinder(double length_, double width_, osg::Vec3 offset_ = osg::Vec3(0.0, 0.0, 0.0) );
+	
+	/**
+	 * \brief This function creates a red sphere of the specified size tor testing purposes.
+	 * 
+	 * @param radius_ : Radius of the sphere in meter.
+	 * @param offset_ : Offset of the sphere's origin in meter.
+	 * @return : Referenced Pointer off the Geode with the created cylinder.
+	 */ 
+	static osg::ref_ptr<osg::Geode> getDemoSphere(double radius_, osg::Vec3 offset_ = osg::Vec3(0.0, 0.0, 0.0) );
+
+	/**
+	 * \brief This functions searches the scene graph for intersections of a line between two points and the model.
+	 * 
+	 * @param start_ : Point 1 for the intersection line
+	 * @param end_ : Point 2 for the intersection line
+	 * @param intersection_ : vektor to the intersection point if any is found.
+	 * @param node_ : Node which is the root of the scene graph to check for intersections
+	 * @param intersectTraversalMask_ : Bitwise mask wich controls which nodes should be checked for intersections (e.g. to check only terrain but not clouds or sky)
+	 * @return returns : True if an intersection is found. 
+	 */ 
+	static bool intersect(const osg::Vec3d& start_, const osg::Vec3d& end_, osg::Vec3d& intersection_, osg::Node* node_, osg::Node::NodeMask intersectTraversalMask_=0xffffffff );
+
+	/**
+	 * \brief This function queries the height of terrain (hot) at a specified location.
+	 * 
+	 * @param hot_ : Reference to write the calculated hot into.
+	 * @param rootNode_ : Node which is the root of the scene graph to calculate the hot.
+	 * @param lat_ : Latitude of the position to calculate the hot.
+	 * @param lon_ : Longitude of the position to calculate the hot.
+	 * @param traversalMask_ : Bitwise mask wich controls which nodes should be checked for hot (e.g. to check only terrain but not clouds or sky)
+	 * @return : True if hot calculation successful.
+	 */ 
+	static bool queryHeightOfTerrain(double& hot_, osg::Node* rootNode_, double lat_, double lon_, osg::Node::NodeMask traversalMask_=0xffffffff);
+
+	/**
+	 * \brief This function queries the height above terrain (hat) at a specified location in WGS84 coordinates.
+	 * 
+	 * @param hat_ : Reference to write the calculated hat into.
+	 * @param rootNode_ : Node which is the root of the scene graph to calculate the hat.
+	 * @param lat_ : Latitude of the position to calculate the hat. (e.g. lat of camera)
+	 * @param lon_ : Longitude of the position to calculate the hat.(e.g. lon of camera)
+	 * @param height_ : Height of the position to calculate the hat.(e.g. height of camera).
+	 * @param traversalMask_ : Bitwise mask wich controls which nodes should be checked for hat (e.g. to check only terrain but not clouds or sky)
+	 * @return :  True if hat calculation successful.
+	 */ 
+	static bool queryHeightAboveTerrainInWGS84(double& hat_, osg::Node* rootNode_, double lat_, double lon_, double height_, osg::Node::NodeMask traversalMask_=0xffffffff);
+
+	/**
+	 * \brief This function queries the height above terrain (hat) at a specified location in world coordinates.
+	 * 
+	 * @param hat_ : Reference to write the calculated hat into.
+	 * @param rootNode_ : Node which is the root of the scene graph to calculate the hat.
+	 * @param x_ : First value of the pointer which points to the position to calculate hat for.
+	 * @param y_ : Second value of the pointer which points to the position to calculate hat for. 
+	 * @param z_ : Third value of the pointer which points to the position to calculate hat for.
+	 * @param traversalMask_ : Bitwise mask wich controls which nodes should be checked for hat (e.g. to check only terrain but not clouds or sky)
+	 * @return :  True if hat calculation successful. 
+	 */ 
+	static bool queryHeightAboveTerrainInWorld(double& hat_, osg::Node* rootNode_, double x_, double y_, double z_, osg::Node::NodeMask traversalMask_=0xffffffff);
+
+	/**
+	 * \brief This function calculates the earth readius (vector length in world coordiantes from origin to location) at the specified location.
+	 * 
+	 * @param lat_ : Latitude in radians.
+	 * @param lon_ : Longitude in radians.
+	 * @param rootNode_ : Root node of the scene which coordinate system node should be used.
+	 * @param radius_ : Calculated earth readius in meter.
+	 * @return : True if calculation successful.
+	 */ 
+	static bool calculateEarthRadiusAtWGS84Coordinate(double lat_, double lon_, osg::Node* rootNode_, double& radius_);
+
+	/**
+	 * \brief This function converts a WGS84 position into global OpenGL XYZ coordinates.
+	 * 
+	 * @param lat_ : Latitude of the position to calculate XYZ.
+	 * @param lon_ : Longitude of the position to calculate XYZ.
+	 * @param height_ : Height of the position to calculate XYZ.
+	 * @param rootNode_ : Node which is the root of the scene graph to calculate XYZ.
+	 * @param x_ : X Coordinate in global OpenGL coordinates.
+	 * @param y_ : Y Coordinate in global OpenGL coordinates.
+	 * @param z_ : Z Coordinate in global OpenGL coordinates.
+	 * @return : True if calculation successful.
+	 */ 
+	static bool calculateXYZAtWGS84Coordinate(double lat_, double lon_, double height_, osg::Node* rootNode_, double& x_, double& y_, double& z_);
+
+	/**
+	 * \brief This function calculates lat, lon and height of a specified camera by a specified coordinate system node. 
+	 * 
+	 * @param camera_ : Camera node which position should be calculated.
+	 * @param rootNode_ : rootNode of the scene.
+	 * @param lat_ : Latitude variable to save value in.
+	 * @param lon_ : Longitude variable to save value in.
+	 * @param height_ : Height: variable to save value in.
+	 * @return : True if calculation was successful.
+	 */ 
+	static bool getWGS84ofCamera( osg::Camera* camera_, osg::Node* rootNode_, double& lat_, double& lon_, double& height_ ); 
+
+	/**
+	 * \brief This function returns the global XYZ coordinates of the specified camera.
+	 * 
+	 * @param camera_ : Camera to return the position.
+	 * @param x_ : X coordinate.
+	 * @param y_ : Y coordinate.
+	 * @param z_ : Z coordinate.
+	 */ 
+	static void getXYZofCamera( osg::Camera* camera_, double& x_, double& y_, double& z_ ); 
+
+	/**
+	 * \brief This function disables the close button on the openGL's windowdecoration
+	 * 
+	 * To be honest, this function is only to play, I have found it on http://forum.openscenegraph.org and found it interesting enought to play along ;)
+	 * 
+	 * @param viewer_ : Pointer to the applications viewer
+	 * @return : true if successful
+	 */ 
+	static bool removeClosebuttonOnGLWindow(osgViewer::Viewer* viewer_);
+
+	/**
+	 * \brief This function make the backgroud of the GL window blurred transparent, if an backgroud with alpha is set.
+	 * 
+	 * To be honest, this function is only to play, I have found it on http://forum.openscenegraph.org and found it interesting enought to play along ;)
+	 * 
+	 * @param viewer_ : Pointer to the applications viewer
+	 * @return : true if successful
+	 */ 
+	static bool setTransparentWindowBackground(osgViewer::Viewer* viewer_);
+
+	/**
+	 * \brief Parses for the XML node of the specified module. The caller has to clean up the xmlDoc and the parser, beside it returns NULL because the queried modules is not configured.
+	 * 
+	 * To clean up, call this two functions:
+	 *  xmlFreeDoc(doc);
+	 *  xmlCleanupParser();
+	 * 
+	 * Example to use this function: 
+	 *	xmlDoc* tmpDoc;
+	 *  xmlNode* yourNode = util::getModuleXMLConfig( configFilename, "core", tmpDoc );
+	 *  // use yourNode
+	 *  if(yourNode)
+	 *  {
+	 *     xmlFreeDoc(tmpDoc); xmlCleanupParser();
+	 *  }
+	 * 
+	 * @param configFilename : Config Filename to parse.
+	 * @param moduleName : Module name to search for.
+	 * @param doc : xmlDoc to use. Must be created outside that the caller can clean it up.
+	 * @param disabled : Contains after return if the module was disabled. Only true if valid configuration and definitely disabled.
+	 * @return : NULL on error, otherwise pointer to the xmlNode of the queried module.
+	 */ 
+	static xmlNode* getModuleXMLConfig(std::string configFilename, std::string moduleName, xmlDoc*& doc, bool& disabled);
+
+	/**
+	 * \brief Parses for the XML node of the scenery configuration. The caller has to clean up the xmlDoc and the parser, beside it returns NULL because the queried modules is not configured.
+	 * 
+	 * @param configFilename : Config Filename to parse.
+	 * @param doc : xmlDoc to use. Must be created outside that the caller can clean it up.
+	 * @return : NULL on error, otherwise pointer to the xmlNode of the scenery configuration.
+	 */ 
+	static xmlNode* getSceneryXMLConfig(std::string configFilename, xmlDoc*& doc);
+
+private: 
+	/**
+	 * \brief This functions checks a list of nodes and all of its children for the specified module configuration.
+	 * 
+	 * This function is used by getModuleXMLConfig() and works recursive
+	 * 
+	 * @param node : Node to search in
+	 * @param moduleName :Module name to search for.
+	 * @param disabled : Contains after return if the module was disabled. Only true if valid configuration and definitely disabled.
+	 * @return : NULL if the module configuration was not found, otherwise pointer to the XML Node with the configuration for the specified module. 
+	 */ 
+	static xmlNode* checkXMLNodeChildrenForModule(xmlNode* node, std::string moduleName, bool& disabled);
+
+	/**
+	 * \brief This functions checks a list of nodes and all of its children for the scenery configuration.
+	 * 
+	 * @param node : Node to search in
+	 * @return : NULL if the module configuration was not found, otherwise pointer to the XML Node with the configuration for the specified module. 
+	 */ 
+	static xmlNode* checkXMLNodeChildrenForScenery(xmlNode* node);
+};
+
+} //END NAMESPACE
Index: /osgVisual/trunk/include/vista2D/visual_vista2D.h
===================================================================
--- /osgVisual/trunk/include/vista2D/visual_vista2D.h	(revision 176)
+++ /osgVisual/trunk/include/vista2D/visual_vista2D.h	(revision 176)
@@ -0,0 +1,161 @@
+#pragma once
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+// Vista 2D
+#include "VistaView.h"
+
+// C++ libraries
+#include <string>
+
+// XML Parser
+#include <stdio.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+// OSG Includes
+#include <osg/Drawable>
+#include <osg/Geode>
+#include <osg/Projection>
+#include <osg/MatrixTransform>
+#include <osg/CoordinateSystemNode>
+
+#include <osgDB/FileUtils>
+
+// osgVisual Includes
+#include <visual_util.h>
+
+namespace osgVisual
+{
+
+/**
+ * \brief This class integrates Vista2D by Wetzel Technology into OSG.
+ * 
+ * It wraps vista2D's OpenGL interface to be usable as a standart OSG Node. The Vista2D nodekit performs auto-linking
+ * againt the Vista2D library, therefore only three shared libraries have to be copied to the binary folder of the project.
+ * 
+ * Vista2D ist a software to design HID. This Nodekit enables OSG to display Vista2D project files.
+ * 
+ * Please copy the following files to the binary folder of you application if you intend to use this nodekit:
+ * libView.dll
+ * fontLib.dll
+ * freetype6.dll
+ * 
+ * The implementation of this class is based on osg::Drawable. The drawimplementations contains the Vista2D wrap.
+ *  
+ * @author Torben Dannhauer
+ * @date  Sep 2009
+ */ 
+class visual_vista2D : public osg::Drawable
+{
+public:
+	/**
+	 * \brief Construtor: Creates a Vista2D environment which should be wrapt by this node.
+	 * 
+	 */ 
+	visual_vista2D(void);
+
+	/**
+	 * \brief Empty destructor.
+	 * 
+	 */ 
+	~visual_vista2D(void);
+
+	/**
+	 * \brief This static function must be called to instantiate a vista2D project.
+	 * 
+	 * @param vista2DFilename_ : Vista2D project file to display.
+	 * @param sceneGraphRoot_ : Scenegraph to add the vista2D note as child.
+	 * @return : True if successful.
+	 */ 
+	bool init( osg::CoordinateSystemNode *sceneGraphRoot_, std::string configFileName );
+
+	/**
+	 * \brief This function is requiered by subclassing osg::Drawable.
+	 * 
+	 * @return : Cloned object.
+	 */ 
+	osg::Object* cloneType() const;
+
+	/**
+	 * \brief This function is requiered by subclassing osg::Drawable.
+	 * 
+	 * @param : Copyoperator how to copy the object
+	 * @return : Cloned object.
+	 */ 
+	osg::Object* clone(const osg::CopyOp&) const;
+
+private:
+
+	bool processXMLConfiguration();
+
+	/**
+	 * \brief This function initialized the visual_vista2D object after instantiation by createVistaOverlay()
+	 */ 
+	void startVista2D();
+
+	/**
+	 * \brief This function implements the pure OpenGL draw by calling Vista2D's draw funtion.
+	 * 
+	 * Because Vista2D manipulates OpenGLs stateset, this function saves the
+	 * OSG statset at the beginning and restores it after the drawing of Vista2D 
+	 * 
+	 * @param renderInfo : Renderinfo of the drawing
+	 */ 
+	void drawImplementation(osg::RenderInfo& renderInfo) const;
+	
+	/**
+	 * Pointer to Vista2D's view instance.
+	 */ 
+	Vista2D::VistaView* view;
+
+	/**
+	 * XML config filename
+	 */ 
+	std::string configFileName;
+
+	/**
+	 * Filename of the Vista2D project file.
+	 */
+	std::string vistaProjectfile;
+
+	/**
+	 * Should the background of the Vista2D project be painted?
+	 */
+	bool paintBackground;
+
+	/**
+	 * X-Position to draw.
+	 */
+	int position_x;
+
+	/**
+	 * Y-Position to draw.
+	 */
+	int position_y;
+
+	/**
+	 * Zoom factor to draw the project.
+	 */
+	double zoom;
+
+	/**
+	 * Flag if Vista2D should animate the project according to it's data sources.
+	 */ 
+	bool playanimation;
+}; 
+
+}	// END NAMESPACE
Index: /osgVisual/trunk/models/README.TXT
===================================================================
--- /osgVisual/trunk/models/README.TXT	(revision 176)
+++ /osgVisual/trunk/models/README.TXT	(revision 176)
@@ -0,0 +1,6 @@
+You can use the osgVisual/models subdirectory to store your aircraft models.
+
+Valid model formats are files in any of the osg readable formats.
+A great source of valid aircraft models is flightgear: (www.flightgear.org)
+
+
Index: /osgVisual/trunk/resources/distortion/shader.frag
===================================================================
--- /osgVisual/trunk/resources/distortion/shader.frag	(revision 176)
+++ /osgVisual/trunk/resources/distortion/shader.frag	(revision 176)
@@ -0,0 +1,18 @@
+uniform sampler2D textureImage;
+uniform sampler2D textureDistort;
+uniform sampler2D textureBlend;
+
+void main()
+{
+    vec4 texCoord;
+    vec4 distortColor;
+    vec4 blendColor;
+
+    distortColor = texture2D(textureDistort, gl_TexCoord[0].st);
+    blendColor = texture2D(textureBlend, gl_TexCoord[0].st);
+
+    texCoord.s = (distortColor.b + mod(floor(distortColor.r * 255.5), 16.0)) / 16.0;
+    texCoord.t = 1.0 - (distortColor.g + floor(distortColor.r * 255.5 / 16.0)) / 16.0;
+
+    gl_FragColor = texture2D(textureImage, texCoord.st) * blendColor;
+}
Index: /osgVisual/trunk/resources/distortion/shader.vert
===================================================================
--- /osgVisual/trunk/resources/distortion/shader.vert	(revision 176)
+++ /osgVisual/trunk/resources/distortion/shader.vert	(revision 176)
@@ -0,0 +1,5 @@
+void main()
+{
+	gl_Position = ftransform();
+	gl_TexCoord[0] = gl_MultiTexCoord0;
+}
Index: /osgVisual/trunk/resources/distortion/view_center.cfg
===================================================================
--- /osgVisual/trunk/resources/distortion/view_center.cfg	(revision 176)
+++ /osgVisual/trunk/resources/distortion/view_center.cfg	(revision 176)
@@ -0,0 +1,9 @@
+Camera "center"
+{
+    Lens {
+        Frustum -0.0502217 0.0502217 -0.036397 0.036397 0.1 100;
+    }
+    Offset {
+        Translate 0 1.35 0;
+    }
+}
Index: /osgVisual/trunk/resources/distortion/view_left.cfg
===================================================================
--- /osgVisual/trunk/resources/distortion/view_left.cfg	(revision 176)
+++ /osgVisual/trunk/resources/distortion/view_left.cfg	(revision 176)
@@ -0,0 +1,10 @@
+Camera "left"
+{
+    Lens {
+        Frustum -0.0502217 0.0502217 -0.036397 0.036397 0.1 100;
+    }
+    Offset {
+        Rotate 46 0 1 0;
+        Translate 0 1.35 0;
+    }
+}
Index: /osgVisual/trunk/resources/distortion/view_right.cfg
===================================================================
--- /osgVisual/trunk/resources/distortion/view_right.cfg	(revision 176)
+++ /osgVisual/trunk/resources/distortion/view_right.cfg	(revision 176)
@@ -0,0 +1,10 @@
+Camera "right"
+{
+    Lens {
+        Frustum -0.0502217 0.0502217 -0.036397 0.036397 0.1 100;
+    }
+    Offset {
+        Rotate -46 0 1 0;
+        Translate 0 1.35 0;
+    }
+}
Index: /osgVisual/trunk/resources/osgVisual.svg
===================================================================
--- /osgVisual/trunk/resources/osgVisual.svg	(revision 176)
+++ /osgVisual/trunk/resources/osgVisual.svg	(revision 176)
@@ -0,0 +1,366 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="210mm"
+   height="297mm"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="osgVisual.svg"
+   inkscape:export-filename="D:\osgVisual\osgVisual\resources\osgVisual.png"
+   inkscape:export-xdpi="90.092026"
+   inkscape:export-ydpi="90.092026">
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient3755">
+      <stop
+         style="stop-color:#ffff00;stop-opacity:1;"
+         offset="0"
+         id="stop3757" />
+      <stop
+         style="stop-color:#c3c4c5;stop-opacity:0;"
+         offset="1"
+         id="stop3759" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3745">
+      <stop
+         style="stop-color:#3939e8;stop-opacity:0.60392159;"
+         offset="0"
+         id="stop3747" />
+      <stop
+         style="stop-color:#c3c4c5;stop-opacity:0;"
+         offset="1"
+         id="stop3749" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient3735">
+      <stop
+         style="stop-color:#c3c4c5;stop-opacity:1;"
+         offset="0"
+         id="stop3737" />
+      <stop
+         style="stop-color:#c3c4c5;stop-opacity:0;"
+         offset="1"
+         id="stop3739" />
+    </linearGradient>
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="3.4482759 : 588.25006 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective10" />
+    <inkscape:perspective
+       id="perspective3626"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3658"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3685"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3735"
+       id="linearGradient3741"
+       x1="144.20068"
+       y1="521.10553"
+       x2="204.51643"
+       y2="521.10553"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.7056133,0,0,1.9461714,-29.808136,-447.71593)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3745"
+       id="linearGradient3751"
+       x1="68.278275"
+       y1="516.02405"
+       x2="291.41208"
+       y2="516.02405"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.7056133,0,0,1.9511538,-29.808136,-449.70289)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3755"
+       id="radialGradient3761"
+       cx="260.14559"
+       cy="511.35497"
+       fx="260.14559"
+       fy="511.35497"
+       r="10.22366"
+       gradientTransform="matrix(1.7056133,0,0,5.0224229,-29.808136,-2020.7725)"
+       gradientUnits="userSpaceOnUse" />
+    <inkscape:perspective
+       id="perspective3783"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3807"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.68"
+     inkscape:cx="338.28255"
+     inkscape:cy="553.76555"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:object-nodes="true"
+     inkscape:window-width="1680"
+     inkscape:window-height="988"
+     inkscape:window-x="-8"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="1"
+     inkscape:object-paths="true" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Ebene 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="fill:#ffffff;fill-opacity:1;stroke:none"
+       id="rect3821"
+       width="525.84265"
+       height="549.43823"
+       x="16.853933"
+       y="383.82285"
+       inkscape:export-filename="D:\osgVisual\osgVisual\resources\osgVisual_100.png"
+       inkscape:export-xdpi="17.035583"
+       inkscape:export-ydpi="17.035583" />
+    <a
+       id="a3672"
+       transform="matrix(1.7056133,0,0,1.9461714,-29.808136,-447.71593)"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90"
+       style="stroke-width:2.74434795;stroke-miterlimit:4;stroke-dasharray:none">
+      <path
+         d="m 292.31725,520.08673 c 0,25.90204 -50.32795,46.8998 -112.41062,46.8998 -62.08267,0 -112.41062,-20.99776 -112.41062,-46.8998 0,-25.90204 50.32795,-46.89979 112.41062,-46.89979 62.08267,0 112.41062,20.99775 112.41062,46.89979 z"
+         sodipodi:ry="46.899796"
+         sodipodi:rx="112.41062"
+         sodipodi:cy="520.08673"
+         sodipodi:cx="179.90663"
+         id="path2836"
+         style="fill:none;stroke:#000000;stroke-width:2.74434795;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+         sodipodi:type="arc" />
+    </a>
+    <rect
+       style="fill:none"
+       id="rect3612"
+       width="460.48831"
+       height="143.91515"
+       x="58.226391"
+       y="562.04718"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <rect
+       style="fill:#ffffff;fill-opacity:1"
+       id="rect3616"
+       width="446.94455"
+       height="113.00719"
+       x="42.244297"
+       y="561.64331"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       transform="matrix(1.7056133,0,0,1.9461714,-29.626561,-271.13058)"
+       sodipodi:type="arc"
+       style="fill:none;stroke:#000000;stroke-width:2.74434794999999990;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+       id="path2836-1"
+       sodipodi:cx="179.90663"
+       sodipodi:cy="520.08673"
+       sodipodi:rx="112.41062"
+       sodipodi:ry="46.899796"
+       d="m 292.31725,520.08673 a 112.41062,46.899796 0 1 1 -224.82124,0 112.41062,46.899796 0 1 1 224.82124,0 z"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <rect
+       style="fill:none"
+       id="rect3612-7"
+       width="460.48831"
+       height="143.91515"
+       x="58.407959"
+       y="738.63257"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <rect
+       style="fill:#ffffff;fill-opacity:1"
+       id="rect3616-4"
+       width="446.94455"
+       height="113.00719"
+       x="42.42585"
+       y="738.2287"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+       d="m 85.313954,561.56438 0.181574,176.58535"
+       id="path3648"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+       d="m 468.4547,561.44712 0.18158,176.58535"
+       id="path3648-0"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       style="fill:none;stroke:#ff0000;stroke-width:3.64385271;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="M 84.467456,634.43006 279.06826,882.54771 467.28286,633.46486"
+       id="path3675"
+       sodipodi:nodetypes="ccc"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+       d="M 116.76758,634.14209 C 261.4708,483.7255 166.35398,545.1926 306.05964,595.91383"
+       id="path3691"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+       d="m 85.90203,631.27497 c 11.546371,1.39455 28.67241,-1.21531 35.45042,-1.91141"
+       id="path3699"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+       d="m 293.26144,607.4433 c 56.77894,-55.38741 98.04395,-48.11105 134.08336,16.99938"
+       id="path3705"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 413.11538,602.14363 c 39.50671,-37.53494 15.55853,2.25608 53.93167,42.93221"
+       id="path3711"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+       d="m 211.94823,537.90041 c 43.98641,-8.55169 70.42339,35.10146 109.02738,45.58924"
+       id="path3713"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       style="fill:url(#linearGradient3741);fill-opacity:1;stroke:none"
+       d="M 298.60826,591.60443 C 270.66298,580.6058 248.24617,567.20635 229.8736,550.5189 c -8.12508,-7.37986 -10.90591,-9.67313 -13.182,-10.87092 -1.42545,-0.75014 -0.33963,-0.91147 6.41012,-0.95246 16.9505,-0.10295 27.89123,4.544 56.20666,23.873 16.46426,11.23903 25.58476,16.51644 34.07568,19.71725 l 5.63374,2.12376 -2.92499,1.97126 c -1.60875,1.08419 -4.51184,3.29913 -6.45133,4.92206 -1.93947,1.62295 -3.76789,2.92443 -4.06313,2.89218 -0.29524,-0.0323 -3.43179,-1.198 -6.97009,-2.5906 z"
+       id="path3733"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       style="fill:url(#linearGradient3751);fill-opacity:1;stroke:none"
+       d="m 458.5364,632.93857 c -5.96765,-9.05978 -9.27291,-15.90984 -13.0395,-27.02397 -5.74974,-16.96591 -7.27423,-19.51641 -11.65206,-19.49421 -2.52605,0.0136 -7.98529,3.37731 -14.24182,8.77712 -3.28798,2.83773 -6.12524,5.15951 -6.30504,5.15951 -0.17981,0 -2.78024,-2.80648 -5.77872,-6.23663 -10.91685,-12.48847 -21.82447,-19.82407 -34.08165,-22.92069 -7.64794,-1.93215 -19.62028,-1.6 -27.58495,0.7653 -6.34618,1.88464 -17.56356,6.88289 -21.90729,9.7615 -2.0611,1.36588 -2.18145,1.34978 -9.00588,-1.20445 -8.98082,-3.36132 -16.76857,-7.87198 -35.34832,-20.47369 -23.62242,-16.02188 -33.72242,-20.98255 -47.3679,-23.26501 -5.95788,-0.99657 -20.22863,-0.51883 -20.92697,0.70056 -0.21119,0.36877 -2.00249,1.2799 -3.98066,2.02473 -6.07383,2.28698 -10.27673,6.45099 -46.22477,45.79708 -11.70586,12.81238 -25.57458,27.8404 -30.8194,33.39563 l -9.53604,10.10043 -9.08665,0.89731 c -15.488646,1.52948 -16.31872,1.57372 -20.718145,1.10375 l -4.282447,-0.45747 0,-34.97302 c 0,-38.37328 0.112145,-39.69473 4.13784,-48.75722 10.757512,-24.21696 43.858092,-46.11908 88.975612,-58.87376 53.82284,-15.21564 121.0494,-16.82657 177.76203,-4.25968 32.54863,7.21244 62.26289,19.80359 81.50717,34.53804 8.16431,6.25102 19.37309,18.73049 22.77214,25.35375 1.2993,2.53179 3.04366,6.88934 3.87634,9.68344 1.48515,4.98356 1.51428,5.80302 1.53144,43.08108 l 0.0174,38.00086 -2.28314,2.53148 -2.28313,2.53147 -4.12557,-6.26324 1e-5,0 z"
+       id="path3743"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       style="fill:url(#radialGradient3761);fill-opacity:1;stroke:none"
+       d="m 407.29703,592.96889 c -3.35207,-3.61513 -7.16127,-7.40069 -8.46485,-8.41233 l -2.37016,-1.83934 0.20594,-10.45846 c 0.19231,-9.76587 0.29321,-10.45845 1.52367,-10.45845 1.28486,0 1.31774,-0.81955 1.31774,-32.83969 0,-18.06184 0.14447,-32.8397 0.32097,-32.8397 0.17653,0 2.69058,1.08077 5.5868,2.40169 2.89622,1.32095 5.57059,2.4723 5.94304,2.55857 0.37244,0.0862 2.58177,1.27064 4.90961,2.63195 2.32784,1.36131 4.23243,2.30392 4.23243,2.09466 0,-0.20925 1.41588,0.64411 3.14641,1.89637 1.73053,1.25225 3.40657,2.09336 3.72453,1.86912 0.31798,-0.22423 0.57813,-0.0952 0.57813,0.28658 0,0.38186 0.76185,1.09034 1.69298,1.57443 l 1.69297,0.88018 0,24.74292 0,24.74292 -2.37017,0 -2.37015,0 0,13.35889 0,13.35889 -4.73248,3.83367 c -2.60285,2.1085 -4.736,4.09443 -4.74031,4.41317 -0.005,0.31873 -0.36478,0.57952 -0.80102,0.57952 -0.43623,0 -1.27425,0.49442 -1.86226,1.09871 -0.94546,0.97162 -1.77403,0.33847 -7.16382,-5.47427 l 0,0 z"
+       id="path3753"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+       d="m 437.50822,587.00891 c 13.29764,4.18314 21.96163,19.42388 31.00411,30.4787"
+       id="path3767"
+       sodipodi:nodetypes="cc"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       style="fill:#c3c4c5;fill-opacity:1;stroke:none"
+       d="m 459.72204,634.19528 c -6.66069,-9.30346 -11.06399,-18.4731 -15.54835,-32.37855 -1.44648,-4.4854 -2.97744,-8.92195 -3.4021,-9.859 -0.42468,-0.93706 -0.65588,-1.83638 -0.51378,-1.99852 0.57197,-0.65265 6.47445,3.57864 10.17139,7.29151 2.16242,2.17175 6.83913,7.67595 10.39267,12.23159 l 6.46099,8.28296 0,7.84979 0,7.8498 -2.24333,2.51218 -2.24332,2.51215 -3.07417,-4.29391 0,0 z"
+       id="path3771"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       style="fill:none;stroke:#00ff00;stroke-width:25;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="M 227.11466,902.98611 42.42585,803.23589 41.195132,593.72789"
+       id="path3773-9"
+       sodipodi:nodetypes="ccc"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       sodipodi:nodetypes="ccc"
+       id="path3797"
+       d="m 333.95117,905.13875 184.68881,-99.75022 1.23072,-209.508"
+       style="fill:none;stroke:#0000ff;stroke-width:25;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <path
+       style="fill:none;stroke:#ff0000;stroke-width:25;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="M 71.905724,497.90823 280.26964,409.99803 485.7714,502.87931"
+       id="path3773-9-4"
+       sodipodi:nodetypes="ccc"
+       inkscape:export-filename="D:\EigeneDateien\Dokumente\osgVisual.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+  </g>
+</svg>
Index: /osgVisual/trunk/resources/osgVisual_incl_Text.svg
===================================================================
--- /osgVisual/trunk/resources/osgVisual_incl_Text.svg	(revision 176)
+++ /osgVisual/trunk/resources/osgVisual_incl_Text.svg	(revision 176)
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="210mm"
+   height="297mm"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="osgVisual_incl_Text.svg">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective10" />
+    <inkscape:perspective
+       id="perspective2824"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.16"
+     inkscape:cx="393.2693"
+     inkscape:cy="733.19627"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1680"
+     inkscape:window-height="988"
+     inkscape:window-x="-8"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Ebene 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="fill:#ffffff;fill-opacity:1;stroke:none"
+       id="rect3606"
+       width="573.27588"
+       height="155.17241"
+       x="119.82758"
+       y="192.87944"
+       inkscape:export-filename="D:\DA\osgVisual\resources\osgvisual_incl_Text.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <image
+       y="196.72917"
+       x="551.90149"
+       id="image2826"
+       height="144.86337"
+       width="138.79443"
+       xlink:href="file:///D:/osgVisual/osgVisual/resources/osgVisual.png"
+       inkscape:export-filename="D:\DA\osgVisual\resources\osgvisual_incl_Text.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <text
+       xml:space="preserve"
+       style="font-size:80px;font-style:normal;font-weight:normal;fill:#668dbf;fill-opacity:1;stroke:#000000;stroke-width:1.20000005;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;font-family:Bitstream Vera Sans"
+       x="132.96553"
+       y="299.05182"
+       id="text2830"
+       inkscape:export-filename="D:\DA\osgVisual\resources\osgvisual_incl_Text.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90"><tspan
+         sodipodi:role="line"
+         id="tspan2832"
+         x="132.96553"
+         y="299.05182"
+         style="font-size:90px;fill:#668dbf;fill-opacity:1;stroke:#000000;stroke-width:1.20000005;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;font-family:Aharoni;-inkscape-font-specification:Aharoni">osgVisual</tspan></text>
+  </g>
+</svg>
Index: /osgVisual/trunk/resources/sky_silverlining/README.TXT
===================================================================
--- /osgVisual/trunk/resources/sky_silverlining/README.TXT	(revision 176)
+++ /osgVisual/trunk/resources/sky_silverlining/README.TXT	(revision 176)
@@ -0,0 +1,1 @@
+Please copy the content of the Resource directory from the silverlining SDK into this directory.
Index: /osgVisual/trunk/src/cluster/ENET_LICENSE
===================================================================
--- /osgVisual/trunk/src/cluster/ENET_LICENSE	(revision 176)
+++ /osgVisual/trunk/src/cluster/ENET_LICENSE	(revision 176)
@@ -0,0 +1,7 @@
+Copyright (c) 2002-2010 Lee Salzman
+
+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: /osgVisual/trunk/src/cluster/dataIO_clusterAsioTcpIostream.cpp
===================================================================
--- /osgVisual/trunk/src/cluster/dataIO_clusterAsioTcpIostream.cpp	(revision 176)
+++ /osgVisual/trunk/src/cluster/dataIO_clusterAsioTcpIostream.cpp	(revision 176)
@@ -0,0 +1,118 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include "dataIO_clusterAsioTcpIostream.h"
+
+using namespace osgVisual;
+
+using boost::asio::ip::tcp;
+
+dataIO_clusterAsioTcpIostream::dataIO_clusterAsioTcpIostream() 
+{
+	OSG_NOTIFY(osg::ALWAYS) << "dataIO_clusterAsioTcpIostream constructed" << std::endl;
+
+	port = 5678;
+	initialized = false;
+}
+
+dataIO_clusterAsioTcpIostream::~dataIO_clusterAsioTcpIostream()
+{
+	OSG_NOTIFY(osg::ALWAYS) << "dataIO_clusterAsioTcpIostream destructed" << std::endl;
+}
+
+void dataIO_clusterAsioTcpIostream::init( osg::ArgumentParser& arguments_, clustermode clusterMode_, osgVisual::dataIO_transportContainer* sendContainer_, bool compressionEnabled_, bool asAscii_ )
+{
+	OSG_NOTIFY(osg::ALWAYS) << "dataIO_clusterAsioTcpIostream initialized" << std::endl;
+
+	clusterMode = clusterMode_;
+
+	if(clusterMode == osgVisual::dataIO_cluster::MASTER)
+	{
+		
+
+		tcp::endpoint endpoint(tcp::v4(), port);
+		tcp::acceptor acceptor(io_service, endpoint);
+
+										tcp::iostream stream;
+									
+										acceptor.accept(*stream.rdbuf());
+										tcp::no_delay option(true);
+										boost::system::error_code ec;
+										stream.rdbuf()->set_option(option, ec);
+										if (ec)
+										{
+											OSG_NOTIFY(osg::WARN) << "Error: Unable to set TCP_NODELAY option" << ec << std::endl;
+											// An error occurred.
+										}
+	}
+
+	if(clusterMode == osgVisual::dataIO_cluster::SLAVE)
+	{
+
+	}
+
+	initialized = true;
+}
+
+void dataIO_clusterAsioTcpIostream::shutdown()
+{
+	OSG_NOTIFY(osg::ALWAYS) << "dataIO_clusterAsioTcpIostream shut down" << std::endl;
+
+	if(initialized)
+	{
+
+	}
+}
+
+bool dataIO_clusterAsioTcpIostream::sendTO_OBJvaluesToSlaves()
+{
+	OSG_NOTIFY(osg::INFO) << "dataIO_clusterAsioTcpIostream::sendTO_OBJvaluesToSlaves()" << std::endl;
+
+	return true;
+}
+
+bool dataIO_clusterAsioTcpIostream::readTO_OBJvaluesFromMaster()
+{
+	OSG_NOTIFY(osg::INFO) << "dataIO_clusterAsioTcpIostream::readTO_OBJvaluesFromMaster()" << std::endl;
+
+	return true;
+}
+
+void dataIO_clusterAsioTcpIostream::reportAsReadyToSwap()
+{
+	OSG_NOTIFY(osg::INFO) << "dataIO_clusterAsioTcpIostream::reportAsReadyToSwap()" << std::endl;
+}
+
+bool dataIO_clusterAsioTcpIostream::waitForSwap()
+{
+	OSG_NOTIFY(osg::INFO) << "dataIO_clusterAsioTcpIostream::waitForAllReadyToSwap()" << std::endl;
+
+	return true;
+}
+
+bool dataIO_clusterAsioTcpIostream::waitForAllReadyToSwap()
+{
+	OSG_NOTIFY(osg::INFO) << "dataIO_clusterAsioTcpIostream::waitForAllReadyToSwap()" << std::endl;
+
+	return true;
+}
+
+bool dataIO_clusterAsioTcpIostream::sendSwapCommand()
+{
+	OSG_NOTIFY(osg::INFO) << "dataIO_clusterAsioTcpIostream::sendSwapCommand()" << std::endl;
+
+	return true;
+}
Index: /osgVisual/trunk/src/cluster/dataIO_clusterDummy.cpp
===================================================================
--- /osgVisual/trunk/src/cluster/dataIO_clusterDummy.cpp	(revision 176)
+++ /osgVisual/trunk/src/cluster/dataIO_clusterDummy.cpp	(revision 176)
@@ -0,0 +1,80 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include "dataIO_clusterDummy.h"
+
+using namespace osgVisual;
+
+dataIO_clusterDummy::dataIO_clusterDummy()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "clusterDummy constructed" << std::endl;
+}
+
+dataIO_clusterDummy::~dataIO_clusterDummy(void)
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "clusterDummy destructed" << std::endl;
+}
+
+void dataIO_clusterDummy::init( osg::ArgumentParser& arguments_, clustermode clusterMode_, osgVisual::dataIO_transportContainer* sendContainer_, bool compressionEnabled_, bool asAscii_ )
+{
+	sendContainer = sendContainer_;
+	OSG_NOTIFY( osg::ALWAYS ) << "clusterDummy init();" << std::endl;
+}
+
+void dataIO_clusterDummy::shutdown()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "clusterDummy shutdown();" << std::endl;
+}
+
+bool dataIO_clusterDummy::sendTO_OBJvaluesToSlaves()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "clusterDummy sendTO_OBJvaluesToSlaves()" << std::endl;
+
+	return true;
+}
+
+bool dataIO_clusterDummy::readTO_OBJvaluesFromMaster()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "clusterDummy readTO_OBJvaluesFromMaster()" << std::endl;
+
+	return true;
+}
+
+void dataIO_clusterDummy::reportAsReadyToSwap()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "clusterDummy reportAsReadyToSwap()" << std::endl;
+}
+
+bool dataIO_clusterDummy::waitForSwap()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "clusterDummy waitForSwap()" << std::endl;
+
+	return true;
+}
+
+bool dataIO_clusterDummy::waitForAllReadyToSwap()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "clusterDummy waitForAllReadyToSwap()" << std::endl;
+
+	return true;
+}
+
+bool dataIO_clusterDummy::sendSwapCommand()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "clusterDummy sendSwapCommand()" << std::endl;
+
+	return true;
+}
Index: /osgVisual/trunk/src/cluster/dataIO_clusterENet.cpp
===================================================================
--- /osgVisual/trunk/src/cluster/dataIO_clusterENet.cpp	(revision 176)
+++ /osgVisual/trunk/src/cluster/dataIO_clusterENet.cpp	(revision 176)
@@ -0,0 +1,240 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include "dataIO_clusterENet.h"
+
+using namespace osgVisual;
+
+dataIO_clusterENet::dataIO_clusterENet()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "clusterENet constructed" << std::endl;
+
+	serverToConnect = "unknown";
+	hardSync = false;	// integrate into init()
+	port = 12345;	// integrate into init()
+}
+
+
+dataIO_clusterENet::~dataIO_clusterENet(void)
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "clusterENet destructed" << std::endl;
+}
+
+
+void dataIO_clusterENet::init( osg::ArgumentParser& arguments_, osgViewer::Viewer* viewer_, clustermode clusterMode_, osgVisual::dataIO_transportContainer* sendContainer_, bool compressionEnabled_, bool asAscii_ )
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "clusterENet init();" << std::endl;
+	
+	// Store viewer
+	viewer = viewer_;
+
+	// Configure the clustermode
+	clusterMode = clusterMode_;
+
+	// store sendContainer
+	sendContainer = sendContainer_;
+
+	// Configure Compression and instantiate read/write-options
+	std::string readOptionString = "";
+	std::string writeOptionString = "";
+	if(asAscii_)
+	{
+		readOptionString = "Ascii";
+		writeOptionString = "Ascii";
+	}
+	if (compressionEnabled_)
+		writeOptionString+=" Compressor=zlib";
+	readOptions = new osgDB::Options( readOptionString.c_str() );
+	writeOptions = new osgDB::Options( writeOptionString.c_str() );
+
+	// Get ReaderWriter
+	rw = osgDB::Registry::instance()->getReaderWriterForExtension("osgb");	
+	
+	// create ENet implementation object.
+	enet_impl = new osgVisual::dataIO_clusterENet_implementation(receivedTransportContainer);
+
+	// initialize ENet implementation
+	if(clusterMode == MASTER)
+	{
+		std::cout << "Init dataIO_cluster_ENet as Server on port " << port << std::endl;
+		enet_impl->init(dataIO_clusterENet_implementation::SERVER, port);
+
+		initialized = true;
+	}
+	if(clusterMode == SLAVE)
+	{
+		// Get the server IP
+		if(!arguments_.read("--server",serverToConnect, port))
+		{
+			// try server discovery
+			//discoverServer(serverToConnect,port);
+			/* todo : implement a udp server discovery based on ASIO */
+		}
+
+		// Init ENet
+		enet_impl->init(dataIO_clusterENet_implementation::CLIENT, port);
+
+		// Connect to server with 5 retries:
+		bool connected = false;
+		for(int i=0; i<5; i++)
+		{
+			std::cout << "Try to connect to server " << serverToConnect << std::endl;
+			if( enet_impl->connectTo( serverToConnect.c_str(), 5000 ) )
+			{
+				// Connect successful.
+				initialized = true;
+				connected = true;
+				break;
+			}
+		}	// For END
+		if(!connected)
+		{
+			initialized = false;
+			std::cout << "Finally failed to establish connection to server " << serverToConnect << std::endl;
+			exit(-1);
+		}
+	}	// IF SLAVE END
+}
+
+
+void dataIO_clusterENet::shutdown()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "clusterENet shutdown();" << std::endl;
+}
+
+
+bool dataIO_clusterENet::sendTO_OBJvaluesToSlaves(osg::Matrixd viewMatrix_) 
+{
+	//OSG_NOTIFY( osg::ALWAYS ) << "clusterENet sendTO_OBJvaluesToSlaves()" << std::endl;
+	
+	if(sendContainer.valid())
+	{
+		// Pack FrameID & Viewmatrix
+		sendContainer->setFrameID(viewer->getFrameStamp()->getFrameNumber());
+		sendContainer->setViewMatrix(viewMatrix_);
+
+		// Writing node to stream
+		std::stringstream myOstream;
+		if ( rw )
+		{
+			osgDB::ReaderWriter::WriteResult wr = rw->writeObject( *sendContainer.get(), myOstream, writeOptions );
+			if (wr.success() )			
+			{
+				// Send Data via ENet:
+				//OSG_NOTIFY( osg::ALWAYS ) << "dataIO_clusterUDP::sendTO_OBJvaluesToSlaves() - Bytes to send: " << myOstream.str().length() << std::endl;
+				//OSG_NOTIFY( osg::ALWAYS ) << "Send: " << myOstream.str() << std::endl;
+				//OSG_NOTIFY( osg::ALWAYS ) << "Sent Framenumber: " << viewer->getFrameStamp()->getFrameNumber() << std::endl;
+				ENetPacket * packet = enet_packet_create (myOstream.str().c_str(), 
+												  myOstream.str().size(), 
+												  ENET_PACKET_FLAG_RELIABLE);
+		
+				// Send data
+				enet_impl->sendPacket( packet, 0, 0, true);
+			}
+			else OSG_NOTIFY( osg::WARN ) << "ERROR: dataIO_clusterENet::sendTO_OBJvaluesToSlaves() :: Save failed: " << wr.message() << std::endl;
+		}
+		else OSG_NOTIFY( osg::WARN ) << "ERROR: dataIO_clusterENet::sendTO_OBJvaluesToSlaves() :: Unable to get readerWriter for osgb" << std::endl;
+	}
+	else OSG_NOTIFY( osg::WARN ) << "ERROR: dataIO_clusterENet::sendTO_OBJvaluesToSlaves() :: Invalid transportContainer" << std::endl;
+
+
+	enet_impl->processEvents();	// As Master: process events AFTER doing anything to have up to have the "sent" commands in queue.
+	return true;
+}
+
+
+bool dataIO_clusterENet::readTO_OBJvaluesFromMaster()
+{
+	//OSG_NOTIFY( osg::ALWAYS ) << "clusterENet readTO_OBJvaluesFromMaster()" << std::endl;
+	enet_impl->processEvents();	// As Slave: process events BEFORE doing anything to have up to date values.
+
+	int bytes_received = receivedTransportContainer.size();
+	if (bytes_received > 0 )
+	{
+		//OSG_NOTIFY( osg::ALWAYS ) << "dataIO_clusterENet::readTO_OBJvaluesFromMaster() - Bytes received: " << bytes_received << std::endl;
+		//OSG_NOTIFY( osg::ALWAYS ) << "Received: " << std::endl << receivedTransportContainer << std::endl;
+		
+
+		// Unserialize data
+		if ( rw )
+		{
+			std::stringstream tmp;
+			tmp  << receivedTransportContainer;
+			osgDB::ReaderWriter::ReadResult rr = rw->readObject( tmp, readOptions );
+			if (rr.success())
+			{
+				sendContainer = dynamic_cast<osgVisual::dataIO_transportContainer*>(rr.takeObject());
+				if (sendContainer)
+				{
+					OSG_NOTIFY( osg::ALWAYS ) << "Received:: Settings Viewmatrix...FrameID is: " << sendContainer->getFrameID() << std::endl;
+					// Restore Viewmatrix 
+					viewer->getCamera()->setViewMatrix(sendContainer->getViewMatrix());
+				}
+				else
+					OSG_NOTIFY( osg::WARN ) << "ERROR: dataIO_clusterENet::readTO_OBJvaluesFromMaster() - Unable to cast converted node to transportContainer" << std::endl;
+			}
+			else
+				OSG_NOTIFY( osg::WARN ) << "ERROR: dataIO_clusterENet::readTO_OBJvaluesFromMaster() - Unable to convert stream to node" << std::endl;
+		}
+		else
+			OSG_NOTIFY( osg::WARN ) << "ERROR: dataIO_clusterENet::readTO_OBJvaluesFromMaster() - Unable to get readerWriter for osgb" << std::endl;
+	}	// IF bytes recv > 0 END
+
+
+
+	return true;
+}
+
+
+void dataIO_clusterENet::reportAsReadyToSwap()
+{
+	if(!hardSync)
+		return;
+
+	OSG_NOTIFY( osg::ALWAYS ) << "clusterENet reportAsReadyToSwap()" << std::endl;
+}
+
+bool dataIO_clusterENet::waitForSwap()
+{
+	if(!hardSync)
+		return true;
+
+	OSG_NOTIFY( osg::ALWAYS ) << "clusterENet waitForSwap()" << std::endl;
+
+	return true;
+}
+
+
+bool dataIO_clusterENet::waitForAllReadyToSwap()
+{
+	if(!hardSync)
+		return true;
+
+	OSG_NOTIFY( osg::ALWAYS ) << "clusterENet waitForAllReadyToSwap()" << std::endl;
+
+	return true;
+}
+
+
+bool dataIO_clusterENet::sendSwapCommand()
+{
+	if(!hardSync)
+		return true;
+
+	OSG_NOTIFY( osg::ALWAYS ) << "clusterENet sendSwapCommand()" << std::endl;
+
+	return true;
+}
Index: /osgVisual/trunk/src/cluster/dataIO_clusterENet_implementation.cpp
===================================================================
--- /osgVisual/trunk/src/cluster/dataIO_clusterENet_implementation.cpp	(revision 176)
+++ /osgVisual/trunk/src/cluster/dataIO_clusterENet_implementation.cpp	(revision 176)
@@ -0,0 +1,315 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include "dataIO_clusterENet_implementation.h"
+
+using namespace osgVisual;
+
+int dataIO_clusterENet_implementation::activeENetInstances = 0;
+
+dataIO_clusterENet_implementation::dataIO_clusterENet_implementation(std::string& receivedTransportContainer_)
+: receivedTransportContainer(receivedTransportContainer_)
+{
+	std::cout << "Instantiated server class# "<< activeENetInstances << std::endl;
+
+	enetInitialized = false;
+	host = NULL;
+	// Start ENet
+	if (activeENetInstances++ == 0)
+	{
+		if( enet_initialize() != 0)
+		{
+			std::cout <<  "An error occurred while initializing ENet." << std::endl;
+		}
+		else
+		{
+			std::cout << "Starting ENet subsystem successful" << std::endl;
+		}
+	}
+}
+
+dataIO_clusterENet_implementation::~dataIO_clusterENet_implementation()
+{
+	// Delete Host Object if instantiated
+	if(host)
+		enet_host_destroy(host);
+
+	// Stop ENet if it is the last element.
+	if(--activeENetInstances == 0)
+	{
+		std::cout << "Close ENet subsystem" << std::endl;
+		enet_deinitialize();
+	}
+	std::cout << "Destroyed server class# "<< activeENetInstances << std::endl;
+}
+
+bool dataIO_clusterENet_implementation::init(dataIO_clusterENet_implementation::role role_, unsigned short port_, int maxClients_, int maxChannels_, int maxInBandwidth_, int maxOutBandwidth_)
+{
+	port = port_;
+	currentRole = role_;
+
+	if(currentRole == dataIO_clusterENet_implementation::SERVER)
+	{
+		/* Bind the server to the default localhost.     */
+		/* A specific host address can be specified by   */
+		/* enet_address_set_host (& address, "x.x.x.x"); */
+
+		address.host = ENET_HOST_ANY;
+		/* Bind the server to port. */
+		address.port = port;
+
+		host = enet_host_create (& address /* the address to bind the server host to */, 
+									 maxClients_      /* allow up to 32 clients and/or outgoing connections */,
+									 maxChannels_      /* allow up to 2 channels to be used, 0 and 1 */,
+									 maxInBandwidth_      /* assume any amount of incoming bandwidth */,
+									 maxOutBandwidth_      /* assume any amount of outgoing bandwidth */);
+		if (host == NULL)
+		{
+			std::cout <<  "An error occurred while trying to create an ENet server." << std::endl;
+			return false;
+		}
+	}	// IF SERVER END
+
+	if(currentRole == dataIO_clusterENet_implementation::CLIENT)
+	{
+		 host = enet_host_create (NULL /* create a client host */,
+									 maxClients_      /* allow up to 32 clients and/or outgoing connections */,
+									 maxChannels_      /* allow up to 2 channels to be used, 0 and 1 */,
+									 maxInBandwidth_      /* assume any amount of incoming bandwidth */,
+									 maxOutBandwidth_      /* assume any amount of outgoing bandwidth */);
+		 if (host == NULL)
+		{
+			std::cout <<  "An error occurred while trying to create an ENet client." << std::endl;
+			return false;
+		}
+
+	}	// IF CLIENT END
+
+	enetInitialized = true;
+	return true;
+}
+
+void dataIO_clusterENet_implementation::processEvents(int timeout_ms_)
+{
+	if(!enetInitialized)
+		return;
+
+	ENetEvent event;
+	while(enet_host_service (host, & event, timeout_ms_) > 0)
+	{
+		switch (event.type)
+		{
+			case ENET_EVENT_TYPE_CONNECT:
+				onConnect(&event);
+				break;
+
+			case ENET_EVENT_TYPE_RECEIVE:
+				onReceivePacket(&event);
+			
+				/* Clean up the packet now that we're done using it. */
+				enet_packet_destroy (event.packet);
+				break;
+
+			case ENET_EVENT_TYPE_DISCONNECT:
+				onDisconnect(&event);
+				break;
+			
+			case ENET_EVENT_TYPE_NONE:
+				// nothing to do
+				break;
+
+			default: 
+				std::cout << "Unknown Eventtype" << std::endl;
+		}	// SWITCH CASE END
+	}	// WHILE EVENT END
+
+}
+
+void dataIO_clusterENet_implementation::sendPacket( ENetPacket* packet_, enet_uint8 channelID_, unsigned int peerID_, bool autoFlush_ )
+{
+	// are connected peers available?
+	if( peerList.size() == 0 )
+	{
+		//std::cout << "dataIO_clusterENet_implementation::sendPacket() - ERROR: No connected peer available!" << std::endl;
+		
+		// If we can't send the packet, we have to destroy it to free it's memory (In a case of send ENet takes ownership and frees after sending.).
+		enet_packet_destroy (packet_);
+
+		return;
+	}
+
+	// Client
+	if(currentRole == dataIO_clusterENet_implementation::CLIENT)
+	{
+		enet_peer_send (peerList[0], channelID_, packet_);
+	}
+
+	// Server
+	if(currentRole == dataIO_clusterENet_implementation::SERVER)
+	{
+		if(peerID_ < peerList.size())
+			enet_peer_send (peerList[peerID_], channelID_, packet_);
+		else
+			std::cout << "dataIO_clusterENet_implementation::sendPacket() - ERROR: Peer #"<<peerID_<<" is not available, only peers 0-"<<(peerList.size()-1)<<" are connected!" << std::endl;
+	}
+
+	if(autoFlush_)
+		enet_host_flush( host );
+}
+
+void dataIO_clusterENet_implementation::sendPacket( ENetPacket* packet_, enet_uint8 channelID_, std::string peerName_, bool autoFlush_ )
+{
+		// are connected peers available?
+	if( peerList.size() == 0 )
+	{
+		std::cout << "dataIO_clusterENet_implementation::sendPacket() - ERROR: No connected peer available!" << std::endl;
+		return;
+	}
+
+	// Client
+	if(currentRole == dataIO_clusterENet_implementation::CLIENT)
+	{
+		enet_peer_send (peerList[0], channelID_, packet_);
+	}
+
+	// Server
+	if(currentRole == dataIO_clusterENet_implementation::SERVER)
+	{
+		int peerID_=-1;
+		for(unsigned int i=0;i<peerList.size();i++)	// Search peer
+		{
+			if( *((std::string*)peerList[i]->data) == peerName_ )
+			{
+				peerID_ = i;
+				break;
+			}
+		}
+		if( peerID_ >= 0 && peerID_ < (int)peerList.size())
+			enet_peer_send (peerList[peerID_], channelID_, packet_);
+		else
+			std::cout << "dataIO_clusterENet_implementation::sendPacket() - ERROR: Peer #"<<peerID_<<" is not available, only peers 0-"<<(peerList.size()-1)<<" are connected!" << std::endl;
+	}
+
+	if(autoFlush_)
+		enet_host_flush( host );
+}
+
+void dataIO_clusterENet_implementation::broadcastPacket( enet_uint8 channelID_, ENetPacket* packet_, bool autoFlush_ )
+{
+	if(currentRole != dataIO_clusterENet_implementation::SERVER)
+		return;
+
+	enet_host_broadcast( host, channelID_, packet_ );
+	if(autoFlush_)
+		enet_host_flush( host );
+}
+
+bool dataIO_clusterENet_implementation::connectTo( const char* remoteAddr_, int connectTimeout_ms_, int clientInfo_,  int channelToAlloc_ )
+{
+	if(currentRole != dataIO_clusterENet_implementation::CLIENT)
+	{
+		std::cout << "dataIO_clusterENet_implementation::connectTo() : ERROR: ENet does not work as client - ignoring to connect!" << std::endl;
+		return false;
+	}
+
+	ENetAddress address;
+	enet_address_set_host (& address, remoteAddr_);
+    address.port = port;
+
+	
+	ENetPeer* tmpPeer = enet_host_connect( host, &address, channelToAlloc_, clientInfo_ );    // host, remote address, number of channels, describing data.
+   
+    if (tmpPeer == NULL)
+    {
+		std::cout << "No available peers for initiating an ENet connection." << std::endl;
+       return false;
+    }
+    
+    /* Wait up to 5 seconds for the connection attempt to succeed. */
+    if (enet_host_service (host, & event, connectTimeout_ms_) > 0
+		&& event.type == ENET_EVENT_TYPE_CONNECT)
+    {
+		peerList.push_back( tmpPeer );
+		std::cout << "Connection to " << remoteAddr_ << ":"<<port<<" succeeded." << std::endl;
+		// Note down peers remote IP.
+		char *hostIP = new char[20];
+		enet_address_get_host_ip( &address, hostIP, 20 );
+		tmpPeer->data = hostIP;
+
+		return true;
+    }
+    else
+    {
+        /* Either the n seconds are up or a disconnect event was */
+        /* received. Reset the peer in the event the n seconds   */
+        /* had run out without any significant event.            */
+        enet_peer_reset (tmpPeer);
+
+		std::cout << "Connection to " << remoteAddr_ << ":"<<port<<" failed." << std::endl;
+		return false;
+    }
+}
+
+void dataIO_clusterENet_implementation::onReceivePacket(ENetEvent* event_)
+{
+		receivedTransportContainer.assign((char*)(event_->packet->data), event_->packet->dataLength);
+		enet_packet_destroy(event_->packet);   
+		//std::cout << "A packet of length "<<receivedTransportContainer.size()<<" containing "<<receivedTransportContainer<<" was received from "<<receivedTransportContainer<<" on channel "<<(int)(event_->channelID)<<std::endl;
+}
+
+void dataIO_clusterENet_implementation::onConnect(ENetEvent* event_)
+{
+	/* Get connect remote IP */
+	char *hostIP = new char[20];
+	enet_address_get_host_ip(&(event_->peer->address), hostIP, 20);
+
+	/* debug output */
+	std::cout << "A new client connected from "<<hostIP<<"." << std::endl; 
+		
+	/* Store any relevant client information here. */
+	event_->peer ->data = hostIP;	
+
+	/* note peer for duplex usage of the connection */
+	peerList.push_back(event_->peer);	
+}
+
+void dataIO_clusterENet_implementation::onDisconnect(ENetEvent* event_)
+{
+	// remove peer pionter from peerList
+	int foundOn = -1;
+	for(unsigned int i=0;i<peerList.size();i++)
+	{
+		if(peerList[0] == event_->peer)
+		{
+			peerList.erase(peerList.begin()+i);
+			break;
+		}
+	}
+
+
+	if(currentRole == dataIO_clusterENet_implementation::SERVER)
+	{
+		std::cout << "Client " << (char*)event_->peer->data << " disconnected." << std::endl;
+	}
+
+	if(currentRole == dataIO_clusterENet_implementation::CLIENT)
+	{
+		std::cout << "Server "<< (char*)event_->peer->data<<"disconnected." << std::endl;
+	}
+
+	// Reset the peer information
+	event_->peer->data = NULL;
+}
Index: /osgVisual/trunk/src/cluster/enet/callbacks.c
===================================================================
--- /osgVisual/trunk/src/cluster/enet/callbacks.c	(revision 176)
+++ /osgVisual/trunk/src/cluster/enet/callbacks.c	(revision 176)
@@ -0,0 +1,47 @@
+/** 
+ @file callbacks.c
+ @brief ENet callback functions
+*/
+#define ENET_BUILDING_LIB 1
+#include "enet/enet.h"
+
+static ENetCallbacks callbacks = { malloc, free, abort };
+
+int
+enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits)
+{
+   if (version < ENET_VERSION_CREATE (1, 3, 0))
+     return -1;
+
+   if (inits -> malloc != NULL || inits -> free != NULL)
+   {
+      if (inits -> malloc == NULL || inits -> free == NULL)
+        return -1;
+
+      callbacks.malloc = inits -> malloc;
+      callbacks.free = inits -> free;
+   }
+      
+   if (inits -> no_memory != NULL)
+     callbacks.no_memory = inits -> no_memory;
+
+   return enet_initialize ();
+}
+           
+void *
+enet_malloc (size_t size)
+{
+   void * memory = callbacks.malloc (size);
+
+   if (memory == NULL)
+     callbacks.no_memory ();
+
+   return memory;
+}
+
+void
+enet_free (void * memory)
+{
+   callbacks.free (memory);
+}
+
Index: /osgVisual/trunk/src/cluster/enet/compress.c
===================================================================
--- /osgVisual/trunk/src/cluster/enet/compress.c	(revision 176)
+++ /osgVisual/trunk/src/cluster/enet/compress.c	(revision 176)
@@ -0,0 +1,658 @@
+#if _MSC_VER > 1000
+	#pragma warning(disable:4146)
+#endif // _MSC_VER > 1000
+
+/** 
+ @file compress.c
+ @brief An adaptive order-2 PPM range coder
+*/
+#define ENET_BUILDING_LIB 1
+#include <string.h>
+#include "enet/enet.h"
+
+typedef struct _ENetSymbol
+{
+    /* binary indexed tree of symbols */
+    enet_uint8 value;
+    enet_uint8 count;
+    enet_uint16 under;
+    enet_uint16 left, right;
+
+    /* context defined by this symbol */
+    enet_uint16 symbols;
+    enet_uint16 escapes;
+    enet_uint16 total;
+    enet_uint16 parent; 
+} ENetSymbol;
+
+/* adaptation constants tuned aggressively for small packet sizes rather than large file compression */
+enum
+{
+    ENET_RANGE_CODER_TOP    = 1<<24,
+    ENET_RANGE_CODER_BOTTOM = 1<<16,
+
+    ENET_CONTEXT_SYMBOL_DELTA = 3,
+    ENET_CONTEXT_SYMBOL_MINIMUM = 1,
+    ENET_CONTEXT_ESCAPE_MINIMUM = 1,
+
+    ENET_SUBCONTEXT_ORDER = 2,
+    ENET_SUBCONTEXT_SYMBOL_DELTA = 2,
+    ENET_SUBCONTEXT_ESCAPE_DELTA = 5
+};
+
+/* context exclusion roughly halves compression speed, so disable for now */
+#undef ENET_CONTEXT_EXCLUSION
+
+typedef struct _ENetRangeCoder
+{
+    /* only allocate enough symbols for reasonable MTUs, would need to be larger for large file compression */
+    ENetSymbol symbols[4096];
+} ENetRangeCoder;
+
+void *
+enet_range_coder_create (void)
+{
+    ENetRangeCoder * rangeCoder = (ENetRangeCoder *) enet_malloc (sizeof (ENetRangeCoder));
+    if (rangeCoder == NULL)
+      return NULL;
+
+    return rangeCoder;
+}
+
+void
+enet_range_coder_destroy (void * context)
+{
+    ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
+    if (rangeCoder == NULL)
+      return;
+
+    enet_free (rangeCoder);
+}
+
+#define ENET_SYMBOL_CREATE(symbol, value_, count_) \
+{ \
+    symbol = & rangeCoder -> symbols [nextSymbol ++]; \
+    symbol -> value = value_; \
+    symbol -> count = count_; \
+    symbol -> under = count_; \
+    symbol -> left = 0; \
+    symbol -> right = 0; \
+    symbol -> symbols = 0; \
+    symbol -> escapes = 0; \
+    symbol -> total = 0; \
+    symbol -> parent = 0; \
+}
+
+#define ENET_CONTEXT_CREATE(context, escapes_, minimum) \
+{ \
+    ENET_SYMBOL_CREATE (context, 0, 0); \
+    (context) -> escapes = escapes_; \
+    (context) -> total = escapes_ + 256*minimum; \
+    (context) -> symbols = 0; \
+}
+
+static enet_uint16
+enet_symbol_rescale (ENetSymbol * symbol)
+{
+    enet_uint16 total = 0;
+    for (;;)
+    {
+        symbol -> count -= symbol->count >> 1;
+        symbol -> under = symbol -> count;
+        if (symbol -> left)
+          symbol -> under += enet_symbol_rescale (symbol + symbol -> left);
+        total += symbol -> under;
+        if (! symbol -> right) break;
+        symbol += symbol -> right;
+    } 
+    return total;
+}
+
+#define ENET_CONTEXT_RESCALE(context, minimum) \
+{ \
+    (context) -> total = (context) -> symbols ? enet_symbol_rescale ((context) + (context) -> symbols) : 0; \
+    (context) -> escapes -= (context) -> escapes >> 1; \
+    (context) -> total += (context) -> escapes + 256*minimum; \
+}
+
+#define ENET_RANGE_CODER_OUTPUT(value) \
+{ \
+    if (outData >= outEnd) \
+      return 0; \
+    * outData ++ = value; \
+}
+
+#define ENET_RANGE_CODER_ENCODE(under, count, total) \
+{ \
+    encodeRange /= (total); \
+    encodeLow += (under) * encodeRange; \
+    encodeRange *= (count); \
+    for (;;) \
+    { \
+        if((encodeLow ^ (encodeLow + encodeRange)) >= ENET_RANGE_CODER_TOP) \
+        { \
+            if(encodeRange >= ENET_RANGE_CODER_BOTTOM) break; \
+            encodeRange = -encodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \
+        } \
+        ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \
+        encodeRange <<= 8; \
+        encodeLow <<= 8; \
+    } \
+}
+
+#define ENET_RANGE_CODER_FLUSH \
+{ \
+    while (encodeLow) \
+    { \
+        ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \
+        encodeLow <<= 8; \
+    } \
+}
+
+#define ENET_RANGE_CODER_FREE_SYMBOLS \
+{ \
+    if (nextSymbol >= sizeof (rangeCoder -> symbols) / sizeof (ENetSymbol) - ENET_SUBCONTEXT_ORDER ) \
+    { \
+        nextSymbol = 0; \
+        ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); \
+        predicted = 0; \
+        order = 0; \
+    } \
+}
+
+#define ENET_CONTEXT_ENCODE(context, symbol_, value_, under_, count_, update, minimum) \
+{ \
+    under_ = value*minimum; \
+    count_ = minimum; \
+    if (! (context) -> symbols) \
+    { \
+        ENET_SYMBOL_CREATE (symbol_, value_, update); \
+        (context) -> symbols = symbol_ - (context); \
+    } \
+    else \
+    { \
+        ENetSymbol * node = (context) + (context) -> symbols; \
+        for (;;) \
+        { \
+            if (value_ < node -> value) \
+            { \
+                node -> under += update; \
+                if (node -> left) { node += node -> left; continue; } \
+                ENET_SYMBOL_CREATE (symbol_, value_, update); \
+                node -> left = symbol_ - node; \
+            } \
+            else \
+            if (value_ > node -> value) \
+            { \
+                under_ += node -> under; \
+                if (node -> right) { node += node -> right; continue; } \
+                ENET_SYMBOL_CREATE (symbol_, value_, update); \
+                node -> right = symbol_ - node; \
+            } \
+            else \
+            { \
+                count_ += node -> count; \
+                under_ += node -> under - node -> count; \
+                node -> under += update; \
+                node -> count += update; \
+                symbol_ = node; \
+            } \
+            break; \
+        } \
+    } \
+}
+
+#ifdef ENET_CONTEXT_EXCLUSION
+static const ENetSymbol emptyContext = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+#define ENET_CONTEXT_WALK(context, body) \
+{ \
+    const ENetSymbol * node = (context) + (context) -> symbols; \
+    const ENetSymbol * stack [256]; \
+    size_t stackSize = 0; \
+    while (node -> left) \
+    { \
+        stack [stackSize ++] = node; \
+        node += node -> left; \
+    } \
+    for (;;) \
+    { \
+        body; \
+        if (node -> right) \
+        { \
+            node += node -> right; \
+            while (node -> left) \
+            { \
+                stack [stackSize ++] = node; \
+                node += node -> left; \
+            } \
+        } \
+        else \
+        if (stackSize <= 0) \
+            break; \
+        else \
+            node = stack [-- stackSize]; \
+    } \
+}
+
+#define ENET_CONTEXT_ENCODE_EXCLUDE(context, value_, under, total, minimum) \
+ENET_CONTEXT_WALK(context, { \
+    if (node -> value != value_) \
+    { \
+        enet_uint16 parentCount = rangeCoder -> symbols [node -> parent].count + minimum; \
+        if (node -> value < value_) \
+          under -= parentCount; \
+        total -= parentCount; \
+    } \
+})
+#endif
+
+size_t
+enet_range_coder_compress (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit)
+{
+    ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
+    enet_uint8 * outStart = outData, * outEnd = & outData [outLimit];
+    const enet_uint8 * inData, * inEnd;
+    enet_uint32 encodeLow = 0, encodeRange = ~0;
+    ENetSymbol * root;
+    enet_uint16 predicted = 0;
+    size_t order = 0, nextSymbol = 0;
+
+    if (rangeCoder == NULL || inBufferCount <= 0 || inLimit <= 0)
+      return 0;
+
+    inData = (const enet_uint8 *) inBuffers -> data;
+    inEnd = & inData [inBuffers -> dataLength];
+    inBuffers ++;
+    inBufferCount --;
+
+    ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM);
+
+    for (;;)
+    {
+        ENetSymbol * subcontext, * symbol;
+#ifdef ENET_CONTEXT_EXCLUSION
+        const ENetSymbol * childContext = & emptyContext;
+#endif
+        enet_uint8 value;
+        enet_uint16 count, under, * parent = & predicted, total;
+        if (inData >= inEnd)
+        {
+            if (inBufferCount <= 0)
+              break;
+            inData = (const enet_uint8 *) inBuffers -> data;
+            inEnd = & inData [inBuffers -> dataLength];
+            inBuffers ++;
+            inBufferCount --;
+        }
+        value = * inData ++;
+    
+        for (subcontext = & rangeCoder -> symbols [predicted]; 
+             subcontext != root; 
+#ifdef ENET_CONTEXT_EXCLUSION
+             childContext = subcontext, 
+#endif
+                subcontext = & rangeCoder -> symbols [subcontext -> parent])
+        {
+            ENET_CONTEXT_ENCODE (subcontext, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0);
+            * parent = symbol - rangeCoder -> symbols;
+            parent = & symbol -> parent;
+            total = subcontext -> total;
+#ifdef ENET_CONTEXT_EXCLUSION
+            if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA)
+              ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, 0);
+#endif
+            if (count > 0)
+            {
+                ENET_RANGE_CODER_ENCODE (subcontext -> escapes + under, count, total);
+            }
+            else
+            {
+                if (subcontext -> escapes > 0 && subcontext -> escapes < total) 
+                    ENET_RANGE_CODER_ENCODE (0, subcontext -> escapes, total); 
+                subcontext -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA;
+                subcontext -> total += ENET_SUBCONTEXT_ESCAPE_DELTA;
+            }
+            subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA;
+            if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
+              ENET_CONTEXT_RESCALE (subcontext, 0);
+            if (count > 0) goto nextInput;
+        }
+
+        ENET_CONTEXT_ENCODE (root, symbol, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM);
+        * parent = symbol - rangeCoder -> symbols;
+        parent = & symbol -> parent;
+        total = root -> total;
+#ifdef ENET_CONTEXT_EXCLUSION
+        if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA)
+          ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, ENET_CONTEXT_SYMBOL_MINIMUM); 
+#endif
+        ENET_RANGE_CODER_ENCODE (root -> escapes + under, count, total);
+        root -> total += ENET_CONTEXT_SYMBOL_DELTA; 
+        if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
+          ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM);
+
+    nextInput:
+        if (order >= ENET_SUBCONTEXT_ORDER) 
+          predicted = rangeCoder -> symbols [predicted].parent;
+        else 
+          order ++;
+        ENET_RANGE_CODER_FREE_SYMBOLS;
+    }
+
+    ENET_RANGE_CODER_FLUSH;
+
+    return (size_t) (outData - outStart);
+}
+
+#define ENET_RANGE_CODER_SEED \
+{ \
+    if (inData < inEnd) decodeCode |= * inData ++ << 24; \
+    if (inData < inEnd) decodeCode |= * inData ++ << 16; \
+    if (inData < inEnd) decodeCode |= * inData ++ << 8; \
+    if (inData < inEnd) decodeCode |= * inData ++; \
+}
+
+#define ENET_RANGE_CODER_READ(total) ((decodeCode - decodeLow) / (decodeRange /= (total)))
+
+#define ENET_RANGE_CODER_DECODE(under, count, total) \
+{ \
+    decodeLow += (under) * decodeRange; \
+    decodeRange *= (count); \
+    for (;;) \
+    { \
+        if((decodeLow ^ (decodeLow + decodeRange)) >= ENET_RANGE_CODER_TOP) \
+        { \
+            if(decodeRange >= ENET_RANGE_CODER_BOTTOM) break; \
+            decodeRange = -decodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \
+        } \
+        decodeCode <<= 8; \
+        if (inData < inEnd) \
+          decodeCode |= * inData ++; \
+        decodeRange <<= 8; \
+        decodeLow <<= 8; \
+    } \
+}
+
+#define ENET_CONTEXT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, createRoot, visitNode, createRight, createLeft) \
+{ \
+    under_ = 0; \
+    count_ = minimum; \
+    if (! (context) -> symbols) \
+    { \
+        createRoot; \
+    } \
+    else \
+    { \
+        ENetSymbol * node = (context) + (context) -> symbols; \
+        for (;;) \
+        { \
+            enet_uint16 after = under_ + node -> under + (node -> value + 1)*minimum, before = node -> count + minimum; \
+            visitNode; \
+            if (code >= after) \
+            { \
+                under_ += node -> under; \
+                if (node -> right) { node += node -> right; continue; } \
+                createRight; \
+            } \
+            else \
+            if (code < after - before) \
+            { \
+                node -> under += update; \
+                if (node -> left) { node += node -> left; continue; } \
+                createLeft; \
+            } \
+            else \
+            { \
+                value_ = node -> value; \
+                count_ += node -> count; \
+                under_ = after - before; \
+                node -> under += update; \
+                node -> count += update; \
+                symbol_ = node; \
+            } \
+            break; \
+        } \
+    } \
+}
+
+#define ENET_CONTEXT_TRY_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \
+ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, return 0, exclude (node -> value, after, before), return 0, return 0)
+
+#define ENET_CONTEXT_ROOT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \
+ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, \
+    { \
+        value_ = code / minimum; \
+        under_ = code - code%minimum; \
+        ENET_SYMBOL_CREATE (symbol_, value_, update); \
+        (context) -> symbols = symbol_ - (context); \
+    }, \
+    exclude (node -> value, after, before), \
+    { \
+        value_ = node->value + 1 + (code - after)/minimum; \
+        under_ = code - (code - after)%minimum; \
+        ENET_SYMBOL_CREATE (symbol_, value_, update); \
+        node -> right = symbol_ - node; \
+    }, \
+    { \
+        value_ = node->value - 1 - (after - before - code - 1)/minimum; \
+        under_ = code - (after - before - code - 1)%minimum; \
+        ENET_SYMBOL_CREATE (symbol_, value_, update); \
+        node -> left = symbol_ - node; \
+    }) \
+
+#ifdef ENET_CONTEXT_EXCLUSION
+typedef struct _ENetExclude
+{
+    enet_uint8 value;
+    enet_uint16 under;
+} ENetExclude;
+
+#define ENET_CONTEXT_DECODE_EXCLUDE(context, total, minimum) \
+{ \
+    enet_uint16 under = 0; \
+    nextExclude = excludes; \
+    ENET_CONTEXT_WALK (context, { \
+        under += rangeCoder -> symbols [node -> parent].count + minimum; \
+        nextExclude -> value = node -> value; \
+        nextExclude -> under = under; \
+        nextExclude ++; \
+    }); \
+    total -= under; \
+}
+
+#define ENET_CONTEXT_EXCLUDED(value_, after, before) \
+{ \
+    size_t low = 0, high = nextExclude - excludes; \
+    for(;;) \
+    { \
+        size_t mid = (low + high) >> 1; \
+        const ENetExclude * exclude = & excludes [mid]; \
+        if (value_ < exclude -> value) \
+        { \
+            if (low + 1 < high) \
+            { \
+                high = mid; \
+                continue; \
+            } \
+            if (exclude > excludes) \
+              after -= exclude [-1].under; \
+        } \
+        else \
+        { \
+            if (value_ > exclude -> value) \
+            { \
+                if (low + 1 < high) \
+                { \
+                    low = mid; \
+                    continue; \
+                } \
+            } \
+            else \
+              before = 0; \
+            after -= exclude -> under; \
+        } \
+        break; \
+    } \
+}
+#endif
+
+#define ENET_CONTEXT_NOT_EXCLUDED(value_, after, before)
+
+size_t
+enet_range_coder_decompress (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit)
+{
+    ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
+    enet_uint8 * outStart = outData, * outEnd = & outData [outLimit];
+    const enet_uint8 * inEnd = & inData [inLimit];
+    enet_uint32 decodeLow = 0, decodeCode = 0, decodeRange = ~0;
+    ENetSymbol * root;
+    enet_uint16 predicted = 0;
+    size_t order = 0, nextSymbol = 0;
+#ifdef ENET_CONTEXT_EXCLUSION
+    ENetExclude excludes [256];
+    ENetExclude * nextExclude = excludes;
+#endif
+  
+    if (rangeCoder == NULL || inLimit <= 0)
+      return 0;
+
+    ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM);
+
+    ENET_RANGE_CODER_SEED;
+
+    for (;;)
+    {
+        ENetSymbol * subcontext, * symbol, * patch;
+#ifdef ENET_CONTEXT_EXCLUSION
+        const ENetSymbol * childContext = & emptyContext;
+#endif
+        enet_uint8 value = 0;
+        enet_uint16 code, under, count, bottom, * parent = & predicted, total;
+
+        for (subcontext = & rangeCoder -> symbols [predicted];
+             subcontext != root;
+#ifdef ENET_CONTEXT_EXCLUSION
+             childContext = subcontext, 
+#endif
+                subcontext = & rangeCoder -> symbols [subcontext -> parent])
+        {
+            if (subcontext -> escapes <= 0)
+              continue;
+            total = subcontext -> total;
+#ifdef ENET_CONTEXT_EXCLUSION
+            if (childContext -> total > 0) 
+              ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, 0); 
+#endif
+            if (subcontext -> escapes >= total)
+              continue;
+            code = ENET_RANGE_CODER_READ (total);
+            if (code < subcontext -> escapes) 
+            {
+                ENET_RANGE_CODER_DECODE (0, subcontext -> escapes, total); 
+                continue;
+            }
+            code -= subcontext -> escapes;
+#ifdef ENET_CONTEXT_EXCLUSION
+            if (childContext -> total > 0)
+            {
+                ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_EXCLUDED); 
+            }
+            else
+#endif
+            {
+                ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_NOT_EXCLUDED); 
+            }
+            bottom = symbol - rangeCoder -> symbols;
+            ENET_RANGE_CODER_DECODE (subcontext -> escapes + under, count, total);
+            subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA;
+            if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
+              ENET_CONTEXT_RESCALE (subcontext, 0);
+            goto patchContexts;
+        }
+
+        total = root -> total;
+#ifdef ENET_CONTEXT_EXCLUSION
+        if (childContext -> total > 0)
+          ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, ENET_CONTEXT_SYMBOL_MINIMUM);  
+#endif
+        code = ENET_RANGE_CODER_READ (total);
+        if (code < root -> escapes)
+        {
+            ENET_RANGE_CODER_DECODE (0, root -> escapes, total);
+            break;
+        }
+        code -= root -> escapes;
+#ifdef ENET_CONTEXT_EXCLUSION
+        if (childContext -> total > 0)
+        {
+            ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_EXCLUDED); 
+        }
+        else
+#endif
+        {
+            ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_NOT_EXCLUDED); 
+        }
+        bottom = symbol - rangeCoder -> symbols;
+        ENET_RANGE_CODER_DECODE (root -> escapes + under, count, total);
+        root -> total += ENET_CONTEXT_SYMBOL_DELTA;
+        if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
+          ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM);
+
+    patchContexts:
+        for (patch = & rangeCoder -> symbols [predicted];
+             patch != subcontext;
+             patch = & rangeCoder -> symbols [patch -> parent])
+        {
+            ENET_CONTEXT_ENCODE (patch, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0);
+            * parent = symbol - rangeCoder -> symbols;
+            parent = & symbol -> parent;
+            if (count <= 0)
+            {
+                patch -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA;
+                patch -> total += ENET_SUBCONTEXT_ESCAPE_DELTA;
+            }
+            patch -> total += ENET_SUBCONTEXT_SYMBOL_DELTA; 
+            if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || patch -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
+              ENET_CONTEXT_RESCALE (patch, 0);
+        }
+        * parent = bottom;
+
+        ENET_RANGE_CODER_OUTPUT (value);
+
+        if (order >= ENET_SUBCONTEXT_ORDER)
+          predicted = rangeCoder -> symbols [predicted].parent;
+        else
+          order ++;
+        ENET_RANGE_CODER_FREE_SYMBOLS;
+    }
+                        
+    return (size_t) (outData - outStart);
+}
+
+/** @defgroup host ENet host functions
+    @{
+*/
+
+/** Sets the packet compressor the host should use to the default range coder.
+    @param host host to enable the range coder for
+    @returns 0 on success, < 0 on failure
+*/
+int
+enet_host_compress_with_range_coder (ENetHost * host)
+{
+    ENetCompressor compressor;
+    memset (& compressor, 0, sizeof (compressor));
+    compressor.context = enet_range_coder_create();
+    if (compressor.context == NULL)
+      return -1;
+    compressor.compress = enet_range_coder_compress;
+    compressor.decompress = enet_range_coder_decompress;
+    compressor.destroy = enet_range_coder_destroy;
+    enet_host_compress (host, & compressor);
+    return 0;
+}
+    
+/** @} */
+    
+     
Index: /osgVisual/trunk/src/cluster/enet/host.c
===================================================================
--- /osgVisual/trunk/src/cluster/enet/host.c	(revision 176)
+++ /osgVisual/trunk/src/cluster/enet/host.c	(revision 176)
@@ -0,0 +1,479 @@
+/** 
+ @file host.c
+ @brief ENet host management functions
+*/
+#define ENET_BUILDING_LIB 1
+#include <string.h>
+#include <time.h>
+#include "enet/enet.h"
+
+/** @defgroup host ENet host functions
+    @{
+*/
+
+/** Creates a host for communicating to peers.  
+
+    @param address   the address at which other peers may connect to this host.  If NULL, then no peers may connect to the host.
+    @param peerCount the maximum number of peers that should be allocated for the host.
+    @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
+    @param incomingBandwidth downstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
+    @param outgoingBandwidth upstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
+
+    @returns the host on success and NULL on failure
+
+    @remarks ENet will strategically drop packets on specific sides of a connection between hosts
+    to ensure the host's bandwidth is not overwhelmed.  The bandwidth parameters also determine
+    the window size of a connection which limits the amount of reliable packets that may be in transit
+    at any given time.
+*/
+ENetHost *
+enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
+{
+    ENetHost * host;
+    ENetPeer * currentPeer;
+
+    if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID)
+      return NULL;
+
+    host = (ENetHost *) enet_malloc (sizeof (ENetHost));
+    if (host == NULL)
+      return NULL;
+
+    host -> peers = (ENetPeer *) enet_malloc (peerCount * sizeof (ENetPeer));
+    if (host -> peers == NULL)
+    {
+       enet_free (host);
+
+       return NULL;
+    }
+    memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
+
+    host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
+    if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
+    {
+       if (host -> socket != ENET_SOCKET_NULL)
+         enet_socket_destroy (host -> socket);
+
+       enet_free (host -> peers);
+       enet_free (host);
+
+       return NULL;
+    }
+
+    enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
+    enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1);
+    enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
+    enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
+
+    if (address != NULL)
+      host -> address = * address;
+
+    if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
+      channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
+    else
+    if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
+      channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
+
+    host -> randomSeed = (enet_uint32) time(NULL) + (enet_uint32) (size_t) host;
+    host -> randomSeed = (host -> randomSeed << 16) | (host -> randomSeed >> 16);
+    host -> channelLimit = channelLimit;
+    host -> incomingBandwidth = incomingBandwidth;
+    host -> outgoingBandwidth = outgoingBandwidth;
+    host -> bandwidthThrottleEpoch = 0;
+    host -> recalculateBandwidthLimits = 0;
+    host -> mtu = ENET_HOST_DEFAULT_MTU;
+    host -> peerCount = peerCount;
+    host -> commandCount = 0;
+    host -> bufferCount = 0;
+    host -> checksum = NULL;
+    host -> receivedAddress.host = ENET_HOST_ANY;
+    host -> receivedAddress.port = 0;
+    host -> receivedData = NULL;
+    host -> receivedDataLength = 0;
+     
+    host -> totalSentData = 0;
+    host -> totalSentPackets = 0;
+    host -> totalReceivedData = 0;
+    host -> totalReceivedPackets = 0;
+
+    host -> compressor.context = NULL;
+    host -> compressor.compress = NULL;
+    host -> compressor.decompress = NULL;
+    host -> compressor.destroy = NULL;
+
+    enet_list_clear (& host -> dispatchQueue);
+
+    for (currentPeer = host -> peers;
+         currentPeer < & host -> peers [host -> peerCount];
+         ++ currentPeer)
+    {
+       currentPeer -> host = host;
+       currentPeer -> incomingPeerID = currentPeer - host -> peers;
+       currentPeer -> outgoingSessionID = currentPeer -> incomingSessionID = 0xFF;
+       currentPeer -> data = NULL;
+
+       enet_list_clear (& currentPeer -> acknowledgements);
+       enet_list_clear (& currentPeer -> sentReliableCommands);
+       enet_list_clear (& currentPeer -> sentUnreliableCommands);
+       enet_list_clear (& currentPeer -> outgoingReliableCommands);
+       enet_list_clear (& currentPeer -> outgoingUnreliableCommands);
+       enet_list_clear (& currentPeer -> dispatchedCommands);
+
+       enet_peer_reset (currentPeer);
+    }
+
+    return host;
+}
+
+/** Destroys the host and all resources associated with it.
+    @param host pointer to the host to destroy
+*/
+void
+enet_host_destroy (ENetHost * host)
+{
+    ENetPeer * currentPeer;
+
+    enet_socket_destroy (host -> socket);
+
+    for (currentPeer = host -> peers;
+         currentPeer < & host -> peers [host -> peerCount];
+         ++ currentPeer)
+    {
+       enet_peer_reset (currentPeer);
+    }
+
+    if (host -> compressor.context != NULL && host -> compressor.destroy)
+      (* host -> compressor.destroy) (host -> compressor.context);
+
+    enet_free (host -> peers);
+    enet_free (host);
+}
+
+/** Initiates a connection to a foreign host.
+    @param host host seeking the connection
+    @param address destination for the connection
+    @param channelCount number of channels to allocate
+    @param data user data supplied to the receiving host 
+    @returns a peer representing the foreign host on success, NULL on failure
+    @remarks The peer returned will have not completed the connection until enet_host_service()
+    notifies of an ENET_EVENT_TYPE_CONNECT event for the peer.
+*/
+ENetPeer *
+enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount, enet_uint32 data)
+{
+    ENetPeer * currentPeer;
+    ENetChannel * channel;
+    ENetProtocol command;
+
+    if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
+      channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
+    else
+    if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
+      channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
+
+    for (currentPeer = host -> peers;
+         currentPeer < & host -> peers [host -> peerCount];
+         ++ currentPeer)
+    {
+       if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
+         break;
+    }
+
+    if (currentPeer >= & host -> peers [host -> peerCount])
+      return NULL;
+
+    currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
+    if (currentPeer -> channels == NULL)
+      return NULL;
+    currentPeer -> channelCount = channelCount;
+    currentPeer -> state = ENET_PEER_STATE_CONNECTING;
+    currentPeer -> address = * address;
+    currentPeer -> connectID = ++ host -> randomSeed;
+
+    if (host -> outgoingBandwidth == 0)
+      currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+    else
+      currentPeer -> windowSize = (host -> outgoingBandwidth /
+                                    ENET_PEER_WINDOW_SIZE_SCALE) * 
+                                      ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+
+    if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
+      currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+    else
+    if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
+      currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+         
+    for (channel = currentPeer -> channels;
+         channel < & currentPeer -> channels [channelCount];
+         ++ channel)
+    {
+        channel -> outgoingReliableSequenceNumber = 0;
+        channel -> outgoingUnreliableSequenceNumber = 0;
+        channel -> incomingReliableSequenceNumber = 0;
+
+        enet_list_clear (& channel -> incomingReliableCommands);
+        enet_list_clear (& channel -> incomingUnreliableCommands);
+
+        channel -> usedReliableWindows = 0;
+        memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows));
+    }
+        
+    command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+    command.header.channelID = 0xFF;
+    command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
+    command.connect.incomingSessionID = currentPeer -> incomingSessionID;
+    command.connect.outgoingSessionID = currentPeer -> outgoingSessionID;
+    command.connect.mtu = ENET_HOST_TO_NET_32 (currentPeer -> mtu);
+    command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize);
+    command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
+    command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
+    command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
+    command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
+    command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
+    command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);
+    command.connect.connectID = currentPeer -> connectID;
+    command.connect.data = ENET_HOST_TO_NET_32 (data);
+ 
+    enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0);
+
+    return currentPeer;
+}
+
+/** Queues a packet to be sent to all peers associated with the host.
+    @param host host on which to broadcast the packet
+    @param channelID channel on which to broadcast
+    @param packet packet to broadcast
+*/
+void
+enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet)
+{
+    ENetPeer * currentPeer;
+
+    for (currentPeer = host -> peers;
+         currentPeer < & host -> peers [host -> peerCount];
+         ++ currentPeer)
+    {
+       if (currentPeer -> state != ENET_PEER_STATE_CONNECTED)
+         continue;
+
+       enet_peer_send (currentPeer, channelID, packet);
+    }
+
+    if (packet -> referenceCount == 0)
+      enet_packet_destroy (packet);
+}
+
+/** Sets the packet compressor the host should use to compress and decompress packets.
+    @param host host to enable or disable compression for
+    @param compressor callbacks for for the packet compressor; if NULL, then compression is disabled
+*/
+void
+enet_host_compress (ENetHost * host, const ENetCompressor * compressor)
+{
+    if (host -> compressor.context != NULL && host -> compressor.destroy)
+      (* host -> compressor.destroy) (host -> compressor.context);
+
+    if (compressor)
+      host -> compressor = * compressor;
+    else
+      host -> compressor.context = NULL;
+}
+
+/** Limits the maximum allowed channels of future incoming connections.
+    @param host host to limit
+    @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
+*/
+void
+enet_host_channel_limit (ENetHost * host, size_t channelLimit)
+{
+    if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
+      channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
+    else
+    if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
+      channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
+
+    host -> channelLimit = channelLimit;
+}
+
+
+/** Adjusts the bandwidth limits of a host.
+    @param host host to adjust
+    @param incomingBandwidth new incoming bandwidth
+    @param outgoingBandwidth new outgoing bandwidth
+    @remarks the incoming and outgoing bandwidth parameters are identical in function to those
+    specified in enet_host_create().
+*/
+void
+enet_host_bandwidth_limit (ENetHost * host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
+{
+    host -> incomingBandwidth = incomingBandwidth;
+    host -> outgoingBandwidth = outgoingBandwidth;
+    host -> recalculateBandwidthLimits = 1;
+}
+
+void
+enet_host_bandwidth_throttle (ENetHost * host)
+{
+    enet_uint32 timeCurrent = enet_time_get (),
+           elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch,
+           peersTotal = 0,
+           dataTotal = 0,
+           peersRemaining,
+           bandwidth,
+           throttle = 0,
+           bandwidthLimit = 0;
+    int needsAdjustment;
+    ENetPeer * peer;
+    ENetProtocol command;
+
+    if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
+      return;
+
+    for (peer = host -> peers;
+         peer < & host -> peers [host -> peerCount];
+         ++ peer)
+    {
+        if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
+          continue;
+
+        ++ peersTotal;
+        dataTotal += peer -> outgoingDataTotal;
+    }
+
+    if (peersTotal == 0)
+      return;
+
+    peersRemaining = peersTotal;
+    needsAdjustment = 1;
+
+    if (host -> outgoingBandwidth == 0)
+      bandwidth = ~0;
+    else
+      bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000;
+
+    while (peersRemaining > 0 && needsAdjustment != 0)
+    {
+        needsAdjustment = 0;
+        
+        if (dataTotal < bandwidth)
+          throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
+        else
+          throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
+
+        for (peer = host -> peers;
+             peer < & host -> peers [host -> peerCount];
+             ++ peer)
+        {
+            enet_uint32 peerBandwidth;
+            
+            if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
+                peer -> incomingBandwidth == 0 ||
+                peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
+              continue;
+
+            peerBandwidth = (peer -> incomingBandwidth * elapsedTime) / 1000;
+            if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth)
+              continue;
+
+            peer -> packetThrottleLimit = (peerBandwidth * 
+                                            ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal;
+            
+            if (peer -> packetThrottleLimit == 0)
+              peer -> packetThrottleLimit = 1;
+            
+            if (peer -> packetThrottle > peer -> packetThrottleLimit)
+              peer -> packetThrottle = peer -> packetThrottleLimit;
+
+            peer -> outgoingBandwidthThrottleEpoch = timeCurrent;
+
+            
+            needsAdjustment = 1;
+            -- peersRemaining;
+            bandwidth -= peerBandwidth;
+            dataTotal -= peerBandwidth;
+        }
+    }
+
+    if (peersRemaining > 0)
+    for (peer = host -> peers;
+         peer < & host -> peers [host -> peerCount];
+         ++ peer)
+    {
+        if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
+            peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
+          continue;
+
+        peer -> packetThrottleLimit = throttle;
+
+        if (peer -> packetThrottle > peer -> packetThrottleLimit)
+          peer -> packetThrottle = peer -> packetThrottleLimit;
+    }
+    
+    if (host -> recalculateBandwidthLimits)
+    {
+       host -> recalculateBandwidthLimits = 0;
+
+       peersRemaining = peersTotal;
+       bandwidth = host -> incomingBandwidth;
+       needsAdjustment = 1;
+
+       if (bandwidth == 0)
+         bandwidthLimit = 0;
+       else
+       while (peersRemaining > 0 && needsAdjustment != 0)
+       {
+           needsAdjustment = 0;
+           bandwidthLimit = bandwidth / peersRemaining;
+
+           for (peer = host -> peers;
+                peer < & host -> peers [host -> peerCount];
+                ++ peer)
+           {
+               if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
+                   peer -> incomingBandwidthThrottleEpoch == timeCurrent)
+                 continue;
+
+               if (peer -> outgoingBandwidth > 0 &&
+                   peer -> outgoingBandwidth >= bandwidthLimit)
+                 continue;
+
+               peer -> incomingBandwidthThrottleEpoch = timeCurrent;
+ 
+               needsAdjustment = 1;
+               -- peersRemaining;
+               bandwidth -= peer -> outgoingBandwidth;
+           }
+       }
+
+       for (peer = host -> peers;
+            peer < & host -> peers [host -> peerCount];
+            ++ peer)
+       {
+           if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
+             continue;
+
+           command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+           command.header.channelID = 0xFF;
+           command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
+
+           if (peer -> incomingBandwidthThrottleEpoch == timeCurrent)
+             command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth);
+           else
+             command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit);
+
+           enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+       } 
+    }
+
+    host -> bandwidthThrottleEpoch = timeCurrent;
+
+    for (peer = host -> peers;
+         peer < & host -> peers [host -> peerCount];
+         ++ peer)
+    {
+        peer -> incomingDataTotal = 0;
+        peer -> outgoingDataTotal = 0;
+    }
+}
+    
+/** @} */
Index: /osgVisual/trunk/src/cluster/enet/list.c
===================================================================
--- /osgVisual/trunk/src/cluster/enet/list.c	(revision 176)
+++ /osgVisual/trunk/src/cluster/enet/list.c	(revision 176)
@@ -0,0 +1,75 @@
+/** 
+ @file list.c
+ @brief ENet linked list functions
+*/
+#define ENET_BUILDING_LIB 1
+#include "enet/list.h"
+
+/** 
+    @defgroup list ENet linked list utility functions
+    @ingroup private
+    @{
+*/
+void
+enet_list_clear (ENetList * list)
+{
+   list -> sentinel.next = & list -> sentinel;
+   list -> sentinel.previous = & list -> sentinel;
+}
+
+ENetListIterator
+enet_list_insert (ENetListIterator position, void * data)
+{
+   ENetListIterator result = (ENetListIterator) data;
+
+   result -> previous = position -> previous;
+   result -> next = position;
+
+   result -> previous -> next = result;
+   position -> previous = result;
+
+   return result;
+}
+
+void *
+enet_list_remove (ENetListIterator position)
+{
+   position -> previous -> next = position -> next;
+   position -> next -> previous = position -> previous;
+
+   return position;
+}
+
+ENetListIterator
+enet_list_move (ENetListIterator position, void * dataFirst, void * dataLast)
+{
+   ENetListIterator first = (ENetListIterator) dataFirst,
+                    last = (ENetListIterator) dataLast;
+
+   first -> previous -> next = last -> next;
+   last -> next -> previous = first -> previous;
+
+   first -> previous = position -> previous;
+   last -> next = position;
+
+   first -> previous -> next = first;
+   position -> previous = last;
+    
+   return first;
+}
+
+size_t
+enet_list_size (ENetList * list)
+{
+   size_t size = 0;
+   ENetListIterator position;
+
+   for (position = enet_list_begin (list);
+        position != enet_list_end (list);
+        position = enet_list_next (position))
+     ++ size;
+   
+   return size;
+}
+
+/** @} */
Index: /osgVisual/trunk/src/cluster/enet/packet.c
===================================================================
--- /osgVisual/trunk/src/cluster/enet/packet.c	(revision 176)
+++ /osgVisual/trunk/src/cluster/enet/packet.c	(revision 176)
@@ -0,0 +1,157 @@
+/** 
+ @file  packet.c
+ @brief ENet packet management functions
+*/
+#include <string.h>
+#define ENET_BUILDING_LIB 1
+#include "enet/enet.h"
+
+/** @defgroup Packet ENet packet functions 
+    @{ 
+*/
+
+/** Creates a packet that may be sent to a peer.
+    @param dataContents initial contents of the packet's data; the packet's data will remain uninitialized if dataContents is NULL.
+    @param dataLength   size of the data allocated for this packet
+    @param flags        flags for this packet as described for the ENetPacket structure.
+    @returns the packet on success, NULL on failure
+*/
+ENetPacket *
+enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags)
+{
+    ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket));
+    if (packet == NULL)
+      return NULL;
+
+    if (flags & ENET_PACKET_FLAG_NO_ALLOCATE)
+      packet -> data = (enet_uint8 *) data;
+    else
+    {
+       packet -> data = (enet_uint8 *) enet_malloc (dataLength);
+       if (packet -> data == NULL)
+       {
+          enet_free (packet);
+          return NULL;
+       }
+
+       if (data != NULL)
+         memcpy (packet -> data, data, dataLength);
+    }
+
+    packet -> referenceCount = 0;
+    packet -> flags = flags;
+    packet -> dataLength = dataLength;
+    packet -> freeCallback = NULL;
+
+    return packet;
+}
+
+/** Destroys the packet and deallocates its data.
+    @param packet packet to be destroyed
+*/
+void
+enet_packet_destroy (ENetPacket * packet)
+{
+    if (packet -> freeCallback != NULL)
+      (* packet -> freeCallback) (packet);
+    if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
+      enet_free (packet -> data);
+    enet_free (packet);
+}
+
+/** Attempts to resize the data in the packet to length specified in the 
+    dataLength parameter 
+    @param packet packet to resize
+    @param dataLength new size for the packet data
+    @returns 0 on success, < 0 on failure
+*/
+int
+enet_packet_resize (ENetPacket * packet, size_t dataLength)
+{
+    enet_uint8 * newData;
+   
+    if (dataLength <= packet -> dataLength || (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
+    {
+       packet -> dataLength = dataLength;
+
+       return 0;
+    }
+
+    newData = (enet_uint8 *) enet_malloc (dataLength);
+    if (newData == NULL)
+      return -1;
+
+    memcpy (newData, packet -> data, packet -> dataLength);
+    enet_free (packet -> data);
+    
+    packet -> data = newData;
+    packet -> dataLength = dataLength;
+
+    return 0;
+}
+
+static int initializedCRC32 = 0;
+static enet_uint32 crcTable [256];
+
+static enet_uint32 
+reflect_crc (int val, int bits)
+{
+    int result = 0, bit;
+
+    for (bit = 0; bit < bits; bit ++)
+    {
+        if(val & 1) result |= 1 << (bits - 1 - bit); 
+        val >>= 1;
+    }
+
+    return result;
+}
+
+static void 
+initialize_crc32 ()
+{
+    int byte;
+
+    for (byte = 0; byte < 256; ++ byte)
+    {
+        enet_uint32 crc = reflect_crc (byte, 8) << 24;
+        int offset;
+
+        for(offset = 0; offset < 8; ++ offset)
+        {
+            if (crc & 0x80000000)
+                crc = (crc << 1) ^ 0x04c11db7;
+            else
+                crc <<= 1;
+        }
+
+        crcTable [byte] = reflect_crc (crc, 32);
+    }
+
+    initializedCRC32 = 1;
+}
+    
+enet_uint32
+enet_crc32 (const ENetBuffer * buffers, size_t bufferCount)
+{
+    enet_uint32 crc = 0xFFFFFFFF;
+    
+    if (! initializedCRC32) initialize_crc32 ();
+
+    while (bufferCount -- > 0)
+    {
+        const enet_uint8 * data = (const enet_uint8 *) buffers -> data,
+                         * dataEnd = & data [buffers -> dataLength];
+
+        while (data < dataEnd)
+        {
+            crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++];        
+        }
+
+        ++ buffers;
+    }
+
+    return ENET_HOST_TO_NET_32 (~ crc);
+}
+
+/** @} */
Index: /osgVisual/trunk/src/cluster/enet/peer.c
===================================================================
--- /osgVisual/trunk/src/cluster/enet/peer.c	(revision 176)
+++ /osgVisual/trunk/src/cluster/enet/peer.c	(revision 176)
@@ -0,0 +1,816 @@
+/** 
+ @file  peer.c
+ @brief ENet peer management functions
+*/
+#include <string.h>
+#define ENET_BUILDING_LIB 1
+#include "enet/enet.h"
+
+/** @defgroup peer ENet peer functions 
+    @{
+*/
+
+/** Configures throttle parameter for a peer.
+
+    Unreliable packets are dropped by ENet in response to the varying conditions
+    of the Internet connection to the peer.  The throttle represents a probability
+    that an unreliable packet should not be dropped and thus sent by ENet to the peer.
+    The lowest mean round trip time from the sending of a reliable packet to the
+    receipt of its acknowledgement is measured over an amount of time specified by
+    the interval parameter in milliseconds.  If a measured round trip time happens to
+    be significantly less than the mean round trip time measured over the interval, 
+    then the throttle probability is increased to allow more traffic by an amount
+    specified in the acceleration parameter, which is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE
+    constant.  If a measured round trip time happens to be significantly greater than
+    the mean round trip time measured over the interval, then the throttle probability
+    is decreased to limit traffic by an amount specified in the deceleration parameter, which
+    is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE constant.  When the throttle has
+    a value of ENET_PEER_PACKET_THROTTLE_SCALE, on unreliable packets are dropped by 
+    ENet, and so 100% of all unreliable packets will be sent.  When the throttle has a
+    value of 0, all unreliable packets are dropped by ENet, and so 0% of all unreliable
+    packets will be sent.  Intermediate values for the throttle represent intermediate
+    probabilities between 0% and 100% of unreliable packets being sent.  The bandwidth
+    limits of the local and foreign hosts are taken into account to determine a 
+    sensible limit for the throttle probability above which it should not raise even in
+    the best of conditions.
+
+    @param peer peer to configure 
+    @param interval interval, in milliseconds, over which to measure lowest mean RTT; the default value is ENET_PEER_PACKET_THROTTLE_INTERVAL.
+    @param acceleration rate at which to increase the throttle probability as mean RTT declines
+    @param deceleration rate at which to decrease the throttle probability as mean RTT increases
+*/
+void
+enet_peer_throttle_configure (ENetPeer * peer, enet_uint32 interval, enet_uint32 acceleration, enet_uint32 deceleration)
+{
+    ENetProtocol command;
+
+    peer -> packetThrottleInterval = interval;
+    peer -> packetThrottleAcceleration = acceleration;
+    peer -> packetThrottleDeceleration = deceleration;
+
+    command.header.command = ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+    command.header.channelID = 0xFF;
+
+    command.throttleConfigure.packetThrottleInterval = ENET_HOST_TO_NET_32 (interval);
+    command.throttleConfigure.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (acceleration);
+    command.throttleConfigure.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (deceleration);
+
+    enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+}
+
+int
+enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
+{
+    if (peer -> lastRoundTripTime <= peer -> lastRoundTripTimeVariance)
+    {
+        peer -> packetThrottle = peer -> packetThrottleLimit;
+    }
+    else
+    if (rtt < peer -> lastRoundTripTime)
+    {
+        peer -> packetThrottle += peer -> packetThrottleAcceleration;
+
+        if (peer -> packetThrottle > peer -> packetThrottleLimit)
+          peer -> packetThrottle = peer -> packetThrottleLimit;
+
+        return 1;
+    }
+    else
+    if (rtt > peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance)
+    {
+        if (peer -> packetThrottle > peer -> packetThrottleDeceleration)
+          peer -> packetThrottle -= peer -> packetThrottleDeceleration;
+        else
+          peer -> packetThrottle = 0;
+
+        return -1;
+    }
+
+    return 0;
+}
+
+/** Queues a packet to be sent.
+    @param peer destination for the packet
+    @param channelID channel on which to send
+    @param packet packet to send
+    @retval 0 on success
+    @retval < 0 on failure
+*/
+int
+enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
+{
+   ENetChannel * channel = & peer -> channels [channelID];
+   ENetProtocol command;
+   size_t fragmentLength;
+
+   if (peer -> state != ENET_PEER_STATE_CONNECTED ||
+       channelID >= peer -> channelCount)
+     return -1;
+
+   fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);
+
+   if (packet -> dataLength > fragmentLength)
+   {
+      enet_uint16 startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1);
+      enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength),
+             fragmentNumber,
+             fragmentOffset;
+      ENetList fragments;
+      ENetOutgoingCommand * fragment;
+
+      enet_list_clear (& fragments);
+
+      for (fragmentNumber = 0,
+             fragmentOffset = 0;
+           fragmentOffset < packet -> dataLength;
+           ++ fragmentNumber,
+             fragmentOffset += fragmentLength)
+      {
+         if (packet -> dataLength - fragmentOffset < fragmentLength)
+           fragmentLength = packet -> dataLength - fragmentOffset;
+
+         fragment = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
+         if (fragment == NULL)
+         {
+            while (! enet_list_empty (& fragments))
+            {
+               fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments));
+               
+               enet_free (fragment);
+            }
+            
+            return -1;
+         }
+         
+         fragment -> fragmentOffset = fragmentOffset;
+         fragment -> fragmentLength = fragmentLength;
+         fragment -> packet = packet;
+         fragment -> command.header.command = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+         fragment -> command.header.channelID = channelID;
+         fragment -> command.sendFragment.startSequenceNumber = startSequenceNumber;
+         fragment -> command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength);
+         fragment -> command.sendFragment.fragmentCount = fragmentCount;
+         fragment -> command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber);
+         fragment -> command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength);
+         fragment -> command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset);
+        
+         enet_list_insert (enet_list_end (& fragments), fragment);
+      }
+
+      packet -> referenceCount += fragmentNumber;
+
+      while (! enet_list_empty (& fragments))
+      {
+         fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments));
+ 
+         enet_peer_setup_outgoing_command (peer, fragment);
+      }
+
+      return 0;
+   }
+
+   command.header.channelID = channelID;
+
+   if (packet -> flags & ENET_PACKET_FLAG_RELIABLE)
+   {
+      command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+      command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
+   }
+   else
+   if (packet -> flags & ENET_PACKET_FLAG_UNSEQUENCED)
+   {
+      command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
+      command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup + 1);
+      command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
+   }
+   else 
+   if (channel -> outgoingUnreliableSequenceNumber >= 0xFFFF)
+   {
+      command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+      command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
+   }
+   else
+   {
+      command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE;
+      command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingUnreliableSequenceNumber + 1);
+      command.sendUnreliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
+   }
+
+   if (enet_peer_queue_outgoing_command (peer, & command, packet, 0, packet -> dataLength) == NULL)
+     return -1;
+
+   return 0;
+}
+
+/** Attempts to dequeue any incoming queued packet.
+    @param peer peer to dequeue packets from
+    @param channelID holds the channel ID of the channel the packet was received on success
+    @returns a pointer to the packet, or NULL if there are no available incoming queued packets
+*/
+ENetPacket *
+enet_peer_receive (ENetPeer * peer, enet_uint8 * channelID)
+{
+   ENetIncomingCommand * incomingCommand;
+   ENetPacket * packet;
+   
+   if (enet_list_empty (& peer -> dispatchedCommands))
+     return NULL;
+
+   incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (& peer -> dispatchedCommands));
+
+   if (channelID != NULL)
+     * channelID = incomingCommand -> command.header.channelID;
+
+   packet = incomingCommand -> packet;
+
+   -- packet -> referenceCount;
+
+   if (incomingCommand -> fragments != NULL)
+     enet_free (incomingCommand -> fragments);
+
+   enet_free (incomingCommand);
+
+   return packet;
+}
+
+static void
+enet_peer_reset_outgoing_commands (ENetList * queue)
+{
+    ENetOutgoingCommand * outgoingCommand;
+
+    while (! enet_list_empty (queue))
+    {
+       outgoingCommand = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (queue));
+
+       if (outgoingCommand -> packet != NULL)
+       {
+          -- outgoingCommand -> packet -> referenceCount;
+
+          if (outgoingCommand -> packet -> referenceCount == 0)
+            enet_packet_destroy (outgoingCommand -> packet);
+       }
+
+       enet_free (outgoingCommand);
+    }
+}
+
+static void
+enet_peer_reset_incoming_commands (ENetList * queue)
+{
+    ENetIncomingCommand * incomingCommand;
+
+    while (! enet_list_empty (queue))
+    {
+       incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (queue));
+
+       if (incomingCommand -> packet != NULL)
+       {
+          -- incomingCommand -> packet -> referenceCount;
+
+          if (incomingCommand -> packet -> referenceCount == 0)
+            enet_packet_destroy (incomingCommand -> packet);
+       }
+
+       if (incomingCommand -> fragments != NULL)
+         enet_free (incomingCommand -> fragments);
+
+       enet_free (incomingCommand);
+    }
+}
+
+void
+enet_peer_reset_queues (ENetPeer * peer)
+{
+    ENetChannel * channel;
+
+    if (peer -> needsDispatch)
+    {
+       enet_list_remove (& peer -> dispatchList);
+
+       peer -> needsDispatch = 0;
+    }
+
+    while (! enet_list_empty (& peer -> acknowledgements))
+      enet_free (enet_list_remove (enet_list_begin (& peer -> acknowledgements)));
+
+    enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands);
+    enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands);
+    enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands);
+    enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands);
+    enet_peer_reset_incoming_commands (& peer -> dispatchedCommands);
+
+    if (peer -> channels != NULL && peer -> channelCount > 0)
+    {
+        for (channel = peer -> channels;
+             channel < & peer -> channels [peer -> channelCount];
+             ++ channel)
+        {
+            enet_peer_reset_incoming_commands (& channel -> incomingReliableCommands);
+            enet_peer_reset_incoming_commands (& channel -> incomingUnreliableCommands);
+        }
+
+        enet_free (peer -> channels);
+    }
+
+    peer -> channels = NULL;
+    peer -> channelCount = 0;
+}
+
+/** Forcefully disconnects a peer.
+    @param peer peer to forcefully disconnect
+    @remarks The foreign host represented by the peer is not notified of the disconnection and will timeout
+    on its connection to the local host.
+*/
+void
+enet_peer_reset (ENetPeer * peer)
+{
+    peer -> outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID;
+    peer -> connectID = 0;
+
+    peer -> state = ENET_PEER_STATE_DISCONNECTED;
+
+    peer -> incomingBandwidth = 0;
+    peer -> outgoingBandwidth = 0;
+    peer -> incomingBandwidthThrottleEpoch = 0;
+    peer -> outgoingBandwidthThrottleEpoch = 0;
+    peer -> incomingDataTotal = 0;
+    peer -> outgoingDataTotal = 0;
+    peer -> lastSendTime = 0;
+    peer -> lastReceiveTime = 0;
+    peer -> nextTimeout = 0;
+    peer -> earliestTimeout = 0;
+    peer -> packetLossEpoch = 0;
+    peer -> packetsSent = 0;
+    peer -> packetsLost = 0;
+    peer -> packetLoss = 0;
+    peer -> packetLossVariance = 0;
+    peer -> packetThrottle = ENET_PEER_DEFAULT_PACKET_THROTTLE;
+    peer -> packetThrottleLimit = ENET_PEER_PACKET_THROTTLE_SCALE;
+    peer -> packetThrottleCounter = 0;
+    peer -> packetThrottleEpoch = 0;
+    peer -> packetThrottleAcceleration = ENET_PEER_PACKET_THROTTLE_ACCELERATION;
+    peer -> packetThrottleDeceleration = ENET_PEER_PACKET_THROTTLE_DECELERATION;
+    peer -> packetThrottleInterval = ENET_PEER_PACKET_THROTTLE_INTERVAL;
+    peer -> lastRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
+    peer -> lowestRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
+    peer -> lastRoundTripTimeVariance = 0;
+    peer -> highestRoundTripTimeVariance = 0;
+    peer -> roundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
+    peer -> roundTripTimeVariance = 0;
+    peer -> mtu = peer -> host -> mtu;
+    peer -> reliableDataInTransit = 0;
+    peer -> outgoingReliableSequenceNumber = 0;
+    peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+    peer -> incomingUnsequencedGroup = 0;
+    peer -> outgoingUnsequencedGroup = 0;
+    peer -> eventData = 0;
+
+    memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
+    
+    enet_peer_reset_queues (peer);
+}
+
+/** Sends a ping request to a peer.
+    @param peer destination for the ping request
+    @remarks ping requests factor into the mean round trip time as designated by the 
+    roundTripTime field in the ENetPeer structure.  Enet automatically pings all connected
+    peers at regular intervals, however, this function may be called to ensure more
+    frequent ping requests.
+*/
+void
+enet_peer_ping (ENetPeer * peer)
+{
+    ENetProtocol command;
+
+    if (peer -> state != ENET_PEER_STATE_CONNECTED)
+      return;
+
+    command.header.command = ENET_PROTOCOL_COMMAND_PING | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+    command.header.channelID = 0xFF;
+   
+    enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+}
+
+/** Force an immediate disconnection from a peer.
+    @param peer peer to disconnect
+    @param data data describing the disconnection
+    @remarks No ENET_EVENT_DISCONNECT event will be generated. The foreign peer is not
+    guarenteed to receive the disconnect notification, and is reset immediately upon
+    return from this function.
+*/
+void
+enet_peer_disconnect_now (ENetPeer * peer, enet_uint32 data)
+{
+    ENetProtocol command;
+
+    if (peer -> state == ENET_PEER_STATE_DISCONNECTED)
+      return;
+
+    if (peer -> state != ENET_PEER_STATE_ZOMBIE &&
+        peer -> state != ENET_PEER_STATE_DISCONNECTING)
+    {
+        enet_peer_reset_queues (peer);
+
+        command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
+        command.header.channelID = 0xFF;
+        command.disconnect.data = ENET_HOST_TO_NET_32 (data);
+
+        enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+
+        enet_host_flush (peer -> host);
+    }
+
+    enet_peer_reset (peer);
+}
+
+/** Request a disconnection from a peer.
+    @param peer peer to request a disconnection
+    @param data data describing the disconnection
+    @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service()
+    once the disconnection is complete.
+*/
+void
+enet_peer_disconnect (ENetPeer * peer, enet_uint32 data)
+{
+    ENetProtocol command;
+
+    if (peer -> state == ENET_PEER_STATE_DISCONNECTING ||
+        peer -> state == ENET_PEER_STATE_DISCONNECTED ||
+        peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT ||
+        peer -> state == ENET_PEER_STATE_ZOMBIE)
+      return;
+
+    enet_peer_reset_queues (peer);
+
+    command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT;
+    command.header.channelID = 0xFF;
+    command.disconnect.data = ENET_HOST_TO_NET_32 (data);
+
+    if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
+      command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+    else
+      command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;      
+    
+    enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+
+    if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
+      peer -> state = ENET_PEER_STATE_DISCONNECTING;
+    else
+    {
+        enet_host_flush (peer -> host);
+        enet_peer_reset (peer);
+    }
+}
+
+/** Request a disconnection from a peer, but only after all queued outgoing packets are sent.
+    @param peer peer to request a disconnection
+    @param data data describing the disconnection
+    @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service()
+    once the disconnection is complete.
+*/
+void
+enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data)
+{   
+    if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) && 
+        ! (enet_list_empty (& peer -> outgoingReliableCommands) &&
+           enet_list_empty (& peer -> outgoingUnreliableCommands) && 
+           enet_list_empty (& peer -> sentReliableCommands)))
+    {
+        peer -> state = ENET_PEER_STATE_DISCONNECT_LATER;
+        peer -> eventData = data;
+    }
+    else
+      enet_peer_disconnect (peer, data);
+}
+
+ENetAcknowledgement *
+enet_peer_queue_acknowledgement (ENetPeer * peer, const ENetProtocol * command, enet_uint16 sentTime)
+{
+    ENetAcknowledgement * acknowledgement;
+
+    if (command -> header.channelID < peer -> channelCount)
+    {
+        ENetChannel * channel = & peer -> channels [command -> header.channelID];
+        enet_uint16 reliableWindow = command -> header.reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE,
+                    currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
+
+        if (command -> header.reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
+           reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
+
+        if (reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1 && reliableWindow <= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS)
+          return NULL;
+    }
+
+    acknowledgement = (ENetAcknowledgement *) enet_malloc (sizeof (ENetAcknowledgement));
+    if (acknowledgement == NULL)
+      return NULL;
+
+    peer -> outgoingDataTotal += sizeof (ENetProtocolAcknowledge);
+
+    acknowledgement -> sentTime = sentTime;
+    acknowledgement -> command = * command;
+    
+    enet_list_insert (enet_list_end (& peer -> acknowledgements), acknowledgement);
+    
+    return acknowledgement;
+}
+
+void
+enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoingCommand)
+{
+    ENetChannel * channel = & peer -> channels [outgoingCommand -> command.header.channelID];
+
+    peer -> outgoingDataTotal += enet_protocol_command_size (outgoingCommand -> command.header.command) + outgoingCommand -> fragmentLength;
+
+    if (outgoingCommand -> command.header.channelID == 0xFF)
+    {
+       ++ peer -> outgoingReliableSequenceNumber;
+
+       outgoingCommand -> reliableSequenceNumber = peer -> outgoingReliableSequenceNumber;
+       outgoingCommand -> unreliableSequenceNumber = 0;
+    }
+    else
+    if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
+    {
+       ++ channel -> outgoingReliableSequenceNumber;
+       channel -> outgoingUnreliableSequenceNumber = 0;
+
+       outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
+       outgoingCommand -> unreliableSequenceNumber = 0;
+    }
+    else
+    if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED)
+    {
+       ++ peer -> outgoingUnsequencedGroup;
+
+       outgoingCommand -> reliableSequenceNumber = 0;
+       outgoingCommand -> unreliableSequenceNumber = 0;
+    }
+    else
+    {
+       ++ channel -> outgoingUnreliableSequenceNumber;
+        
+       outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
+       outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber;
+    }
+   
+    outgoingCommand -> sendAttempts = 0;
+    outgoingCommand -> sentTime = 0;
+    outgoingCommand -> roundTripTimeout = 0;
+    outgoingCommand -> roundTripTimeoutLimit = 0;
+    outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> reliableSequenceNumber);
+
+    if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
+      enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
+    else
+      enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand);
+}
+
+ENetOutgoingCommand *
+enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 offset, enet_uint16 length)
+{
+    ENetOutgoingCommand * outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
+    if (outgoingCommand == NULL)
+      return NULL;
+
+    outgoingCommand -> command = * command;
+    outgoingCommand -> fragmentOffset = offset;
+    outgoingCommand -> fragmentLength = length;
+    outgoingCommand -> packet = packet;
+    if (packet != NULL)
+      ++ packet -> referenceCount;
+
+    enet_peer_setup_outgoing_command (peer, outgoingCommand);
+
+    return outgoingCommand;
+}
+
+void
+enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel)
+{
+    ENetListIterator currentCommand;
+
+    for (currentCommand = enet_list_begin (& channel -> incomingUnreliableCommands);
+         currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
+         currentCommand = enet_list_next (currentCommand))
+    {
+       ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
+
+       if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE &&
+           incomingCommand -> reliableSequenceNumber != channel -> incomingReliableSequenceNumber)
+         break;
+    }
+
+    if (currentCommand == enet_list_begin (& channel -> incomingUnreliableCommands))
+      return;
+
+    enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingUnreliableCommands), enet_list_previous (currentCommand));
+
+    if (! peer -> needsDispatch)
+    {
+       enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
+
+       peer -> needsDispatch = 1;
+    }
+}
+
+void
+enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel)
+{
+    ENetListIterator currentCommand;
+
+    for (currentCommand = enet_list_begin (& channel -> incomingReliableCommands);
+         currentCommand != enet_list_end (& channel -> incomingReliableCommands);
+         currentCommand = enet_list_next (currentCommand))
+    {
+       ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
+         
+       if (incomingCommand -> fragmentsRemaining > 0 ||
+           incomingCommand -> reliableSequenceNumber != (enet_uint16) (channel -> incomingReliableSequenceNumber + 1))
+         break;
+
+       channel -> incomingReliableSequenceNumber = incomingCommand -> reliableSequenceNumber;
+
+       if (incomingCommand -> fragmentCount > 0)
+         channel -> incomingReliableSequenceNumber += incomingCommand -> fragmentCount - 1;
+    } 
+
+    if (currentCommand == enet_list_begin (& channel -> incomingReliableCommands))
+      return;
+
+    enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingReliableCommands), enet_list_previous (currentCommand));
+
+    if (! peer -> needsDispatch)
+    {
+       enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
+
+       peer -> needsDispatch = 1;
+    }
+
+    enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
+}
+
+ENetIncomingCommand *
+enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 fragmentCount)
+{
+    static ENetIncomingCommand dummyCommand;
+
+    ENetChannel * channel = & peer -> channels [command -> header.channelID];
+    enet_uint32 unreliableSequenceNumber = 0, reliableSequenceNumber;
+    enet_uint16 reliableWindow, currentWindow;
+    ENetIncomingCommand * incomingCommand;
+    ENetListIterator currentCommand;
+
+    if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
+      goto freePacket;
+
+    if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED)
+    {
+        reliableSequenceNumber = command -> header.reliableSequenceNumber;
+        reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
+        currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
+
+        if (reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
+           reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
+
+        if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1)
+          goto freePacket;
+    }
+                    
+    switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
+    {
+    case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
+    case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
+       if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber)
+           goto freePacket;
+       
+       for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
+            currentCommand != enet_list_end (& channel -> incomingReliableCommands);
+            currentCommand = enet_list_previous (currentCommand))
+       {
+          incomingCommand = (ENetIncomingCommand *) currentCommand;
+
+          if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
+          {
+             if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
+               continue;
+          }
+          else
+          if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
+            break;
+
+          if (incomingCommand -> reliableSequenceNumber <= reliableSequenceNumber)
+          {
+             if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
+               break;
+
+             goto freePacket;
+          }
+       }
+       break;
+
+    case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE:
+       unreliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendUnreliable.unreliableSequenceNumber);
+
+       for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands));
+            currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
+            currentCommand = enet_list_previous (currentCommand))
+       {
+          incomingCommand = (ENetIncomingCommand *) currentCommand;
+
+          if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE)
+            continue;
+
+          if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
+          {
+             if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
+               continue;
+          }
+          else
+          if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
+            break;
+
+          if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
+            break;
+
+          if (incomingCommand -> reliableSequenceNumber > reliableSequenceNumber)
+            continue;
+
+          if (incomingCommand -> unreliableSequenceNumber <= unreliableSequenceNumber)
+          {
+             if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber)
+               break;
+
+             goto freePacket;
+          }
+       }
+       break;
+
+    case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED:
+       currentCommand = enet_list_end (& channel -> incomingUnreliableCommands);
+       break;
+
+    default:
+       goto freePacket;
+    }
+
+    incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand));
+    if (incomingCommand == NULL)
+      goto notifyError;
+
+    incomingCommand -> reliableSequenceNumber = command -> header.reliableSequenceNumber;
+    incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber & 0xFFFF;
+    incomingCommand -> command = * command;
+    incomingCommand -> fragmentCount = fragmentCount;
+    incomingCommand -> fragmentsRemaining = fragmentCount;
+    incomingCommand -> packet = packet;
+    incomingCommand -> fragments = NULL;
+    
+    if (fragmentCount > 0)
+    { 
+       incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32));
+       if (incomingCommand -> fragments == NULL)
+       {
+          enet_free (incomingCommand);
+
+          goto notifyError;
+       }
+       memset (incomingCommand -> fragments, 0, (fragmentCount + 31) / 32 * sizeof (enet_uint32));
+    }
+
+    if (packet != NULL)
+      ++ packet -> referenceCount;
+
+    enet_list_insert (enet_list_next (currentCommand), incomingCommand);
+
+    switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
+    {
+    case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
+    case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
+       enet_peer_dispatch_incoming_reliable_commands (peer, channel);
+       break;
+
+    default:
+       enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
+       break;
+    }
+
+    return incomingCommand;
+
+freePacket:
+    if (fragmentCount > 0)
+      goto notifyError;
+
+    if (packet != NULL && packet -> referenceCount == 0)
+      enet_packet_destroy (packet);
+
+    return & dummyCommand;
+
+notifyError:
+    if (packet != NULL && packet -> referenceCount == 0)
+      enet_packet_destroy (packet);
+
+    return NULL;
+}
+
+/** @} */
Index: /osgVisual/trunk/src/cluster/enet/protocol.c
===================================================================
--- /osgVisual/trunk/src/cluster/enet/protocol.c	(revision 176)
+++ /osgVisual/trunk/src/cluster/enet/protocol.c	(revision 176)
@@ -0,0 +1,1671 @@
+/** 
+ @file  protocol.c
+ @brief ENet protocol functions
+*/
+#include <stdio.h>
+#include <string.h>
+#define ENET_BUILDING_LIB 1
+#include "enet/utility.h"
+#include "enet/time.h"
+#include "enet/enet.h"
+
+static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
+{
+    0,
+    sizeof (ENetProtocolAcknowledge),
+    sizeof (ENetProtocolConnect),
+    sizeof (ENetProtocolVerifyConnect),
+    sizeof (ENetProtocolDisconnect),
+    sizeof (ENetProtocolPing),
+    sizeof (ENetProtocolSendReliable),
+    sizeof (ENetProtocolSendUnreliable),
+    sizeof (ENetProtocolSendFragment),
+    sizeof (ENetProtocolSendUnsequenced),
+    sizeof (ENetProtocolBandwidthLimit),
+    sizeof (ENetProtocolThrottleConfigure),
+};
+
+size_t
+enet_protocol_command_size (enet_uint8 commandNumber)
+{
+    return commandSizes [commandNumber & ENET_PROTOCOL_COMMAND_MASK];
+}
+
+static int
+enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
+{
+    while (! enet_list_empty (& host -> dispatchQueue))
+    {
+       ENetPeer * peer = (ENetPeer *) enet_list_remove (enet_list_begin (& host -> dispatchQueue));
+
+       peer -> needsDispatch = 0;
+
+       switch (peer -> state)
+       {
+       case ENET_PEER_STATE_CONNECTION_PENDING:
+       case ENET_PEER_STATE_CONNECTION_SUCCEEDED:
+           peer -> state = ENET_PEER_STATE_CONNECTED;
+
+           event -> type = ENET_EVENT_TYPE_CONNECT;
+           event -> peer = peer;
+           event -> data = peer -> eventData;
+
+           return 1;
+           
+       case ENET_PEER_STATE_ZOMBIE:
+           host -> recalculateBandwidthLimits = 1;
+
+           event -> type = ENET_EVENT_TYPE_DISCONNECT;
+           event -> peer = peer;
+           event -> data = peer -> eventData;
+
+           enet_peer_reset (peer);
+
+           return 1;
+
+       case ENET_PEER_STATE_CONNECTED:
+           if (enet_list_empty (& peer -> dispatchedCommands))
+             continue;
+
+           event -> packet = enet_peer_receive (peer, & event -> channelID);
+           if (event -> packet == NULL)
+             continue;
+             
+           event -> type = ENET_EVENT_TYPE_RECEIVE;
+           event -> peer = peer;
+
+           if (! enet_list_empty (& peer -> dispatchedCommands))
+           {
+              peer -> needsDispatch = 1;
+         
+              enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
+           }
+
+           return 1;
+       }
+    }
+
+    return 0;
+}
+
+static void
+enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState state)
+{
+    peer -> state = state;
+
+    if (! peer -> needsDispatch)
+    {
+       enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
+
+       peer -> needsDispatch = 1;
+    }    
+}
+    
+static void
+enet_protocol_notify_connect (ENetHost * host, ENetPeer * peer, ENetEvent * event)
+{
+    host -> recalculateBandwidthLimits = 1;
+
+    if (event != NULL)
+    {
+        peer -> state = ENET_PEER_STATE_CONNECTED;
+
+        event -> type = ENET_EVENT_TYPE_CONNECT;
+        event -> peer = peer;
+        event -> data = peer -> eventData;
+    }
+    else 
+        enet_protocol_dispatch_state (host, peer, peer -> state == ENET_PEER_STATE_CONNECTING ? ENET_PEER_STATE_CONNECTION_SUCCEEDED : ENET_PEER_STATE_CONNECTION_PENDING);
+}
+
+static void
+enet_protocol_notify_disconnect (ENetHost * host, ENetPeer * peer, ENetEvent * event)
+{
+    if (peer -> state >= ENET_PEER_STATE_CONNECTION_PENDING)
+       host -> recalculateBandwidthLimits = 1;
+
+    if (peer -> state != ENET_PEER_STATE_CONNECTING && peer -> state < ENET_PEER_STATE_CONNECTION_SUCCEEDED)
+        enet_peer_reset (peer);
+    else
+    if (event != NULL)
+    {
+        event -> type = ENET_EVENT_TYPE_DISCONNECT;
+        event -> peer = peer;
+        event -> data = 0;
+
+        enet_peer_reset (peer);
+    }
+    else 
+    {
+        peer -> eventData = 0;
+
+        enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
+    }
+}
+
+static void
+enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer)
+{
+    ENetOutgoingCommand * outgoingCommand;
+
+    while (! enet_list_empty (& peer -> sentUnreliableCommands))
+    {
+        outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentUnreliableCommands);
+        
+        enet_list_remove (& outgoingCommand -> outgoingCommandList);
+
+        if (outgoingCommand -> packet != NULL)
+        {
+           -- outgoingCommand -> packet -> referenceCount;
+
+           if (outgoingCommand -> packet -> referenceCount == 0)
+             enet_packet_destroy (outgoingCommand -> packet);
+        }
+
+        enet_free (outgoingCommand);
+    }
+}
+
+static ENetProtocolCommand
+enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliableSequenceNumber, enet_uint8 channelID)
+{
+    ENetOutgoingCommand * outgoingCommand;
+    ENetListIterator currentCommand;
+    ENetProtocolCommand commandNumber;
+
+    for (currentCommand = enet_list_begin (& peer -> sentReliableCommands);
+         currentCommand != enet_list_end (& peer -> sentReliableCommands);
+         currentCommand = enet_list_next (currentCommand))
+    {
+       outgoingCommand = (ENetOutgoingCommand *) currentCommand;
+        
+       if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber &&
+           outgoingCommand -> command.header.channelID == channelID)
+         break;
+    }
+
+    if (currentCommand == enet_list_end (& peer -> sentReliableCommands))
+    {
+       for (currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
+            currentCommand != enet_list_end (& peer -> outgoingReliableCommands);
+            currentCommand = enet_list_next (currentCommand))
+       {
+          outgoingCommand = (ENetOutgoingCommand *) currentCommand;
+
+          if (outgoingCommand -> sendAttempts < 1) return ENET_PROTOCOL_COMMAND_NONE;
+
+          if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber &&
+              outgoingCommand -> command.header.channelID == channelID)
+            break;
+       }
+
+       if (currentCommand == enet_list_end (& peer -> outgoingReliableCommands))
+         return ENET_PROTOCOL_COMMAND_NONE;
+    }
+
+    if (channelID < peer -> channelCount)
+    {
+       ENetChannel * channel = & peer -> channels [channelID];
+       enet_uint16 reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
+       if (channel -> reliableWindows [reliableWindow] > 0)
+       {
+          -- channel -> reliableWindows [reliableWindow];
+          if (! channel -> reliableWindows [reliableWindow])
+            channel -> usedReliableWindows &= ~ (1 << reliableWindow);
+       }
+    }
+
+    commandNumber = (ENetProtocolCommand) (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK);
+    
+    enet_list_remove (& outgoingCommand -> outgoingCommandList);
+
+    if (outgoingCommand -> packet != NULL)
+    {
+       peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength;
+
+       -- outgoingCommand -> packet -> referenceCount;
+
+       if (outgoingCommand -> packet -> referenceCount == 0)
+         enet_packet_destroy (outgoingCommand -> packet);
+    }
+
+    enet_free (outgoingCommand);
+
+    if (enet_list_empty (& peer -> sentReliableCommands))
+      return commandNumber;
+    
+    outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentReliableCommands);
+    
+    peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout;
+
+    return commandNumber;
+} 
+
+static ENetPeer *
+enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENetProtocol * command)
+{
+    enet_uint8 incomingSessionID, outgoingSessionID;
+    enet_uint32 mtu, windowSize;
+    ENetChannel * channel;
+    size_t channelCount;
+    ENetPeer * currentPeer;
+    ENetProtocol verifyCommand;
+
+    channelCount = ENET_NET_TO_HOST_32 (command -> connect.channelCount);
+
+    if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT ||
+        channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
+      return NULL;
+
+    for (currentPeer = host -> peers;
+         currentPeer < & host -> peers [host -> peerCount];
+         ++ currentPeer)
+    {
+        if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED &&
+            currentPeer -> address.host == host -> receivedAddress.host &&
+            currentPeer -> address.port == host -> receivedAddress.port &&
+            currentPeer -> connectID == command -> connect.connectID)
+          return NULL;
+    }
+
+    for (currentPeer = host -> peers;
+         currentPeer < & host -> peers [host -> peerCount];
+         ++ currentPeer)
+    {
+        if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
+          break;
+    }
+
+    if (currentPeer >= & host -> peers [host -> peerCount])
+      return NULL;
+
+    if (channelCount > host -> channelLimit)
+      channelCount = host -> channelLimit;
+    currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
+    if (currentPeer -> channels == NULL)
+      return NULL;
+    currentPeer -> channelCount = channelCount;
+    currentPeer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT;
+    currentPeer -> connectID = command -> connect.connectID;
+    currentPeer -> address = host -> receivedAddress;
+    currentPeer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID);
+    currentPeer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth);
+    currentPeer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth);
+    currentPeer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleInterval);
+    currentPeer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleAcceleration);
+    currentPeer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleDeceleration);
+    currentPeer -> eventData = ENET_NET_TO_HOST_32 (command -> connect.data);
+
+    incomingSessionID = command -> connect.incomingSessionID == 0xFF ? currentPeer -> outgoingSessionID : command -> connect.incomingSessionID;
+    incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
+    if (incomingSessionID == currentPeer -> outgoingSessionID)
+      incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
+    currentPeer -> outgoingSessionID = incomingSessionID;
+
+    outgoingSessionID = command -> connect.outgoingSessionID == 0xFF ? currentPeer -> incomingSessionID : command -> connect.outgoingSessionID;
+    outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
+    if (outgoingSessionID == currentPeer -> incomingSessionID)
+      outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT);
+    currentPeer -> incomingSessionID = outgoingSessionID;
+
+    for (channel = currentPeer -> channels;
+         channel < & currentPeer -> channels [channelCount];
+         ++ channel)
+    {
+        channel -> outgoingReliableSequenceNumber = 0;
+        channel -> outgoingUnreliableSequenceNumber = 0;
+        channel -> incomingReliableSequenceNumber = 0;
+
+        enet_list_clear (& channel -> incomingReliableCommands);
+        enet_list_clear (& channel -> incomingUnreliableCommands);
+
+        channel -> usedReliableWindows = 0;
+        memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows));
+    }
+
+    mtu = ENET_NET_TO_HOST_32 (command -> connect.mtu);
+
+    if (mtu < ENET_PROTOCOL_MINIMUM_MTU)
+      mtu = ENET_PROTOCOL_MINIMUM_MTU;
+    else
+    if (mtu > ENET_PROTOCOL_MAXIMUM_MTU)
+      mtu = ENET_PROTOCOL_MAXIMUM_MTU;
+
+    currentPeer -> mtu = mtu;
+
+    if (host -> outgoingBandwidth == 0 &&
+        currentPeer -> incomingBandwidth == 0)
+      currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+    else
+    if (host -> outgoingBandwidth == 0 ||
+        currentPeer -> incomingBandwidth == 0)
+      currentPeer -> windowSize = (ENET_MAX (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) /
+                                    ENET_PEER_WINDOW_SIZE_SCALE) *
+                                      ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+    else
+      currentPeer -> windowSize = (ENET_MIN (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) /
+                                    ENET_PEER_WINDOW_SIZE_SCALE) * 
+                                      ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+
+    if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
+      currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+    else
+    if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
+      currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+
+    if (host -> incomingBandwidth == 0)
+      windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+    else
+      windowSize = (host -> incomingBandwidth / ENET_PEER_WINDOW_SIZE_SCALE) *
+                     ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+
+    if (windowSize > ENET_NET_TO_HOST_32 (command -> connect.windowSize))
+      windowSize = ENET_NET_TO_HOST_32 (command -> connect.windowSize);
+
+    if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
+      windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+    else
+    if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
+      windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+
+    verifyCommand.header.command = ENET_PROTOCOL_COMMAND_VERIFY_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+    verifyCommand.header.channelID = 0xFF;
+    verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
+    verifyCommand.verifyConnect.incomingSessionID = incomingSessionID;
+    verifyCommand.verifyConnect.outgoingSessionID = outgoingSessionID;
+    verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_16 (currentPeer -> mtu);
+    verifyCommand.verifyConnect.windowSize = ENET_HOST_TO_NET_32 (windowSize);
+    verifyCommand.verifyConnect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
+    verifyCommand.verifyConnect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
+    verifyCommand.verifyConnect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
+    verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
+    verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
+    verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);
+    verifyCommand.verifyConnect.connectID = currentPeer -> connectID;
+
+    enet_peer_queue_outgoing_command (currentPeer, & verifyCommand, NULL, 0, 0);
+
+    return currentPeer;
+}
+
+static int
+enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
+{
+    ENetPacket * packet;
+    size_t dataLength;
+
+    if (command -> header.channelID >= peer -> channelCount ||
+        (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
+      return -1;
+
+    dataLength = ENET_NET_TO_HOST_16 (command -> sendReliable.dataLength);
+    * currentData += dataLength;
+    if (* currentData > & host -> receivedData [host -> receivedDataLength])
+      return -1;
+
+    packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendReliable),
+                                 dataLength,
+                                 ENET_PACKET_FLAG_RELIABLE);
+    if (packet == NULL ||
+        enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL)
+      return -1;
+
+    return 0;
+}
+
+static int
+enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
+{
+    ENetPacket * packet;
+    enet_uint32 unsequencedGroup, index;
+    size_t dataLength;
+
+    if (command -> header.channelID >= peer -> channelCount ||
+        (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
+      return -1;
+
+    dataLength = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.dataLength);
+    * currentData += dataLength;
+    if (* currentData > & host -> receivedData [host -> receivedDataLength])
+      return -1; 
+
+    unsequencedGroup = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.unsequencedGroup);
+    index = unsequencedGroup % ENET_PEER_UNSEQUENCED_WINDOW_SIZE;
+   
+    if (unsequencedGroup < peer -> incomingUnsequencedGroup)
+      unsequencedGroup += 0x10000;
+
+    if (unsequencedGroup >= (enet_uint32) peer -> incomingUnsequencedGroup + ENET_PEER_FREE_UNSEQUENCED_WINDOWS * ENET_PEER_UNSEQUENCED_WINDOW_SIZE)
+      return 0;
+
+    unsequencedGroup &= 0xFFFF;
+
+    if (unsequencedGroup - index != peer -> incomingUnsequencedGroup)
+    {
+        peer -> incomingUnsequencedGroup = unsequencedGroup - index;
+
+        memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
+    }
+    else
+    if (peer -> unsequencedWindow [index / 32] & (1 << (index % 32)))
+      return 0;
+      
+    packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnsequenced),
+                                 dataLength,
+                                 ENET_PACKET_FLAG_UNSEQUENCED);
+    if (packet == NULL ||
+        enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL)
+      return -1;
+   
+    peer -> unsequencedWindow [index / 32] |= 1 << (index % 32);
+ 
+    return 0;
+}
+
+static int
+enet_protocol_handle_send_unreliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
+{
+    ENetPacket * packet;
+    size_t dataLength;
+
+    if (command -> header.channelID >= peer -> channelCount ||
+        (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
+      return -1;
+
+    dataLength = ENET_NET_TO_HOST_16 (command -> sendUnreliable.dataLength);
+    * currentData += dataLength;
+    if (* currentData > & host -> receivedData [host -> receivedDataLength])
+      return -1;
+
+    packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnreliable),
+                                 dataLength,
+                                 0);
+    if (packet == NULL ||
+        enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL)
+      return -1;
+
+    return 0;
+}
+
+static int
+enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData)
+{
+    enet_uint32 fragmentNumber,
+           fragmentCount,
+           fragmentOffset,
+           fragmentLength,
+           startSequenceNumber,
+           totalLength;
+    ENetChannel * channel;
+    enet_uint16 startWindow, currentWindow;
+    ENetListIterator currentCommand;
+    ENetIncomingCommand * startCommand = NULL;
+
+    if (command -> header.channelID >= peer -> channelCount ||
+        (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER))
+      return -1;
+
+    fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength);
+    * currentData += fragmentLength;
+    if (* currentData > & host -> receivedData [host -> receivedDataLength])
+      return -1;
+
+    channel = & peer -> channels [command -> header.channelID];
+    startSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendFragment.startSequenceNumber);
+    startWindow = startSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
+    currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
+
+    if (startSequenceNumber < channel -> incomingReliableSequenceNumber)
+      startWindow += ENET_PEER_RELIABLE_WINDOWS;
+
+    if (startWindow < currentWindow || startWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1)
+      return 0;
+
+    fragmentNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentNumber);
+    fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount);
+    fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset);
+    totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength);
+    
+    if (fragmentOffset >= totalLength ||
+        fragmentOffset + fragmentLength > totalLength ||
+        fragmentNumber >= fragmentCount)
+      return -1;
+ 
+    for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
+         currentCommand != enet_list_end (& channel -> incomingReliableCommands);
+         currentCommand = enet_list_previous (currentCommand))
+    {
+       ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
+
+       if (startSequenceNumber >= channel -> incomingReliableSequenceNumber)
+       {
+          if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
+            continue;
+       }
+       else
+       if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
+         break;
+
+       if (incomingCommand -> reliableSequenceNumber <= startSequenceNumber)
+       {
+          if (incomingCommand -> reliableSequenceNumber < startSequenceNumber)
+            break;
+        
+          if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_FRAGMENT ||
+              totalLength != incomingCommand -> packet -> dataLength ||
+              fragmentCount != incomingCommand -> fragmentCount)
+            return -1;
+
+          startCommand = incomingCommand;
+          break;
+       }
+    }
+ 
+    if (startCommand == NULL)
+    {
+       ENetProtocol hostCommand = * command;
+       ENetPacket * packet = enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_RELIABLE);
+       if (packet == NULL)
+         return -1;
+
+       hostCommand.header.reliableSequenceNumber = startSequenceNumber;
+       hostCommand.sendFragment.startSequenceNumber = startSequenceNumber;
+       hostCommand.sendFragment.dataLength = fragmentLength;
+       hostCommand.sendFragment.fragmentNumber = fragmentNumber;
+       hostCommand.sendFragment.fragmentCount = fragmentCount;
+       hostCommand.sendFragment.fragmentOffset = fragmentOffset;
+       hostCommand.sendFragment.totalLength = totalLength;
+
+       startCommand = enet_peer_queue_incoming_command (peer, & hostCommand, packet, fragmentCount);
+       if (startCommand == NULL)
+         return -1;
+    }
+    
+    if ((startCommand -> fragments [fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0)
+    {
+       -- startCommand -> fragmentsRemaining;
+
+       startCommand -> fragments [fragmentNumber / 32] |= (1 << (fragmentNumber % 32));
+
+       if (fragmentOffset + fragmentLength > startCommand -> packet -> dataLength)
+         fragmentLength = startCommand -> packet -> dataLength - fragmentOffset;
+
+       memcpy (startCommand -> packet -> data + fragmentOffset,
+               (enet_uint8 *) command + sizeof (ENetProtocolSendFragment),
+               fragmentLength);
+
+        if (startCommand -> fragmentsRemaining <= 0)
+          enet_peer_dispatch_incoming_reliable_commands (peer, channel);
+    }
+
+    return 0;
+}
+
+static int
+enet_protocol_handle_ping (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
+{
+    return 0;
+}
+
+static int
+enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
+{
+    peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.incomingBandwidth);
+    peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.outgoingBandwidth);
+
+    if (peer -> incomingBandwidth == 0 && host -> outgoingBandwidth == 0)
+      peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+    else
+      peer -> windowSize = (ENET_MIN (peer -> incomingBandwidth, host -> outgoingBandwidth) /
+                             ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+
+    if (peer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
+      peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+    else
+    if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
+      peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+
+    return 0;
+}
+
+static int
+enet_protocol_handle_throttle_configure (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
+{
+    peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleInterval);
+    peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleAcceleration);
+    peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleDeceleration);
+
+    return 0;
+}
+
+static int
+enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetProtocol * command)
+{
+    if (peer -> state == ENET_PEER_STATE_ZOMBIE || peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT)
+      return 0;
+
+    enet_peer_reset_queues (peer);
+
+    if (peer -> state == ENET_PEER_STATE_CONNECTION_SUCCEEDED)
+        enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
+    else
+    if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
+    {
+        if (peer -> state == ENET_PEER_STATE_CONNECTION_PENDING) host -> recalculateBandwidthLimits = 1;
+
+        enet_peer_reset (peer);
+    }
+    else
+    if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
+      peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT;
+    else
+      enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
+
+    if (peer -> state != ENET_PEER_STATE_DISCONNECTED)
+      peer -> eventData = ENET_NET_TO_HOST_32 (command -> disconnect.data);
+
+    return 0;
+}
+
+static int
+enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command)
+{
+    enet_uint32 roundTripTime,
+           receivedSentTime,
+           receivedReliableSequenceNumber;
+    ENetProtocolCommand commandNumber;
+
+    receivedSentTime = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedSentTime);
+    receivedSentTime |= host -> serviceTime & 0xFFFF0000;
+    if ((receivedSentTime & 0x8000) > (host -> serviceTime & 0x8000))
+        receivedSentTime -= 0x10000;
+
+    if (ENET_TIME_LESS (host -> serviceTime, receivedSentTime))
+      return 0;
+
+    peer -> lastReceiveTime = host -> serviceTime;
+    peer -> earliestTimeout = 0;
+
+    roundTripTime = ENET_TIME_DIFFERENCE (host -> serviceTime, receivedSentTime);
+
+    enet_peer_throttle (peer, roundTripTime);
+
+    peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4;
+
+    if (roundTripTime >= peer -> roundTripTime)
+    {
+       peer -> roundTripTime += (roundTripTime - peer -> roundTripTime) / 8;
+       peer -> roundTripTimeVariance += (roundTripTime - peer -> roundTripTime) / 4;
+    }
+    else
+    {
+       peer -> roundTripTime -= (peer -> roundTripTime - roundTripTime) / 8;
+       peer -> roundTripTimeVariance += (peer -> roundTripTime - roundTripTime) / 4;
+    }
+
+    if (peer -> roundTripTime < peer -> lowestRoundTripTime)
+      peer -> lowestRoundTripTime = peer -> roundTripTime;
+
+    if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance) 
+      peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
+
+    if (peer -> packetThrottleEpoch == 0 ||
+        ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval)
+    {
+        peer -> lastRoundTripTime = peer -> lowestRoundTripTime;
+        peer -> lastRoundTripTimeVariance = peer -> highestRoundTripTimeVariance;
+        peer -> lowestRoundTripTime = peer -> roundTripTime;
+        peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
+        peer -> packetThrottleEpoch = host -> serviceTime;
+    }
+
+    receivedReliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedReliableSequenceNumber);
+
+    commandNumber = enet_protocol_remove_sent_reliable_command (peer, receivedReliableSequenceNumber, command -> header.channelID);
+
+    switch (peer -> state)
+    {
+    case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT:
+       if (commandNumber != ENET_PROTOCOL_COMMAND_VERIFY_CONNECT)
+         return -1;
+
+       enet_protocol_notify_connect (host, peer, event);
+       break;
+
+    case ENET_PEER_STATE_DISCONNECTING:
+       if (commandNumber != ENET_PROTOCOL_COMMAND_DISCONNECT)
+         return -1;
+
+       enet_protocol_notify_disconnect (host, peer, event);
+       break;
+
+    case ENET_PEER_STATE_DISCONNECT_LATER:
+       if (enet_list_empty (& peer -> outgoingReliableCommands) &&
+           enet_list_empty (& peer -> outgoingUnreliableCommands) &&   
+           enet_list_empty (& peer -> sentReliableCommands))
+         enet_peer_disconnect (peer, peer -> eventData);
+       break;
+    }
+   
+    return 0;
+}
+
+static int
+enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command)
+{
+    enet_uint32 mtu, windowSize;
+    size_t channelCount;
+
+    if (peer -> state != ENET_PEER_STATE_CONNECTING)
+      return 0;
+
+    channelCount = ENET_NET_TO_HOST_32 (command -> verifyConnect.channelCount);
+
+    if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT ||
+        ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleInterval) != peer -> packetThrottleInterval ||
+        ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleAcceleration) != peer -> packetThrottleAcceleration ||
+        ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleDeceleration) != peer -> packetThrottleDeceleration ||
+        command -> verifyConnect.connectID != peer -> connectID)
+    {
+        peer -> eventData = 0;
+
+        enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
+
+        return -1;
+    }
+
+    enet_protocol_remove_sent_reliable_command (peer, 1, 0xFF);
+    
+    if (channelCount < peer -> channelCount)
+      peer -> channelCount = channelCount;
+
+    peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> verifyConnect.outgoingPeerID);
+    peer -> incomingSessionID = command -> verifyConnect.incomingSessionID;
+    peer -> outgoingSessionID = command -> verifyConnect.outgoingSessionID;
+
+    mtu = ENET_NET_TO_HOST_32 (command -> verifyConnect.mtu);
+
+    if (mtu < ENET_PROTOCOL_MINIMUM_MTU)
+      mtu = ENET_PROTOCOL_MINIMUM_MTU;
+    else 
+    if (mtu > ENET_PROTOCOL_MAXIMUM_MTU)
+      mtu = ENET_PROTOCOL_MAXIMUM_MTU;
+
+    if (mtu < peer -> mtu)
+      peer -> mtu = mtu;
+
+    windowSize = ENET_NET_TO_HOST_32 (command -> verifyConnect.windowSize);
+
+    if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
+      windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+
+    if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
+      windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+
+    if (windowSize < peer -> windowSize)
+      peer -> windowSize = windowSize;
+
+    peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.incomingBandwidth);
+    peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.outgoingBandwidth);
+
+    enet_protocol_notify_connect (host, peer, event);
+    return 0;
+}
+
+static int
+enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
+{
+    ENetProtocolHeader * header;
+    ENetProtocol * command;
+    ENetPeer * peer;
+    enet_uint8 * currentData;
+    size_t headerSize;
+    enet_uint16 peerID, flags;
+    enet_uint8 sessionID;
+
+    if (host -> receivedDataLength < (size_t) & ((ENetProtocolHeader *) 0) -> sentTime)
+      return 0;
+
+    header = (ENetProtocolHeader *) host -> receivedData;
+
+    peerID = ENET_NET_TO_HOST_16 (header -> peerID);
+    sessionID = (peerID & ENET_PROTOCOL_HEADER_SESSION_MASK) >> ENET_PROTOCOL_HEADER_SESSION_SHIFT;
+    flags = peerID & ENET_PROTOCOL_HEADER_FLAG_MASK;
+    peerID &= ~ (ENET_PROTOCOL_HEADER_FLAG_MASK | ENET_PROTOCOL_HEADER_SESSION_MASK);
+
+    headerSize = (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME ? sizeof (ENetProtocolHeader) : (size_t) & ((ENetProtocolHeader *) 0) -> sentTime);
+    if (host -> checksum != NULL)
+      headerSize += sizeof (enet_uint32);
+
+    if (peerID == ENET_PROTOCOL_MAXIMUM_PEER_ID)
+      peer = NULL;
+    else
+    if (peerID >= host -> peerCount)
+      return 0;
+    else
+    {
+       peer = & host -> peers [peerID];
+
+       if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
+           peer -> state == ENET_PEER_STATE_ZOMBIE ||
+           (host -> receivedAddress.host != peer -> address.host &&
+             peer -> address.host != ENET_HOST_BROADCAST) ||
+           (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
+            sessionID != peer -> incomingSessionID))
+         return 0;
+    }
+ 
+    if (flags & ENET_PROTOCOL_HEADER_FLAG_COMPRESSED)
+    {
+        size_t originalSize;
+        if (host -> compressor.context == NULL || host -> compressor.decompress == NULL)
+          return 0;
+
+        originalSize = host -> compressor.decompress (host -> compressor.context,
+                                    host -> receivedData + headerSize, 
+                                    host -> receivedDataLength - headerSize, 
+                                    host -> packetData [1] + headerSize, 
+                                    sizeof (host -> packetData [1]) - headerSize);
+        if (originalSize <= 0 || originalSize > sizeof (host -> packetData [1]) - headerSize)
+          return 0;
+
+        memcpy (host -> packetData [1], header, headerSize);
+        host -> receivedData = host -> packetData [1];
+        host -> receivedDataLength = headerSize + originalSize;
+    }
+
+    if (host -> checksum != NULL)
+    {
+        enet_uint32 * checksum = (enet_uint32 *) & host -> receivedData [headerSize - sizeof (enet_uint32)],
+                    desiredChecksum = * checksum;
+        ENetBuffer buffer;
+
+        * checksum = peer != NULL ? peer -> connectID : 0;
+
+        buffer.data = host -> receivedData;
+        buffer.dataLength = host -> receivedDataLength;
+
+        if (host -> checksum (& buffer, 1) != desiredChecksum)
+          return 0;
+    }
+       
+    if (peer != NULL)
+    {
+       peer -> address.host = host -> receivedAddress.host;
+       peer -> address.port = host -> receivedAddress.port;
+       peer -> incomingDataTotal += host -> receivedDataLength;
+    }
+    
+    currentData = host -> receivedData + headerSize;
+  
+    while (currentData < & host -> receivedData [host -> receivedDataLength])
+    {
+       enet_uint8 commandNumber;
+       size_t commandSize;
+
+       command = (ENetProtocol *) currentData;
+
+       if (currentData + sizeof (ENetProtocolCommandHeader) > & host -> receivedData [host -> receivedDataLength])
+         break;
+
+       commandNumber = command -> header.command & ENET_PROTOCOL_COMMAND_MASK;
+       if (commandNumber >= ENET_PROTOCOL_COMMAND_COUNT) 
+         break;
+       
+       commandSize = commandSizes [commandNumber];
+       if (commandSize == 0 || currentData + commandSize > & host -> receivedData [host -> receivedDataLength])
+         break;
+
+       currentData += commandSize;
+
+       if (peer == NULL && commandNumber != ENET_PROTOCOL_COMMAND_CONNECT)
+         break;
+         
+       command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> header.reliableSequenceNumber);
+
+       switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
+       {
+       case ENET_PROTOCOL_COMMAND_ACKNOWLEDGE:
+          if (enet_protocol_handle_acknowledge (host, event, peer, command))
+            goto commandError;
+          break;
+
+       case ENET_PROTOCOL_COMMAND_CONNECT:
+          peer = enet_protocol_handle_connect (host, header, command);
+          if (peer == NULL)
+            goto commandError;
+          break;
+
+       case ENET_PROTOCOL_COMMAND_VERIFY_CONNECT:
+          if (enet_protocol_handle_verify_connect (host, event, peer, command))
+            goto commandError;
+          break;
+
+       case ENET_PROTOCOL_COMMAND_DISCONNECT:
+          if (enet_protocol_handle_disconnect (host, peer, command))
+            goto commandError;
+          break;
+
+       case ENET_PROTOCOL_COMMAND_PING:
+          if (enet_protocol_handle_ping (host, peer, command))
+            goto commandError;
+          break;
+
+       case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
+          if (enet_protocol_handle_send_reliable (host, peer, command, & currentData))
+            goto commandError;
+          break;
+
+       case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE:
+          if (enet_protocol_handle_send_unreliable (host, peer, command, & currentData))
+            goto commandError;
+          break;
+
+       case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED:
+          if (enet_protocol_handle_send_unsequenced (host, peer, command, & currentData))
+            goto commandError;
+          break;
+
+       case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
+          if (enet_protocol_handle_send_fragment (host, peer, command, & currentData))
+            goto commandError;
+          break;
+
+       case ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT:
+          if (enet_protocol_handle_bandwidth_limit (host, peer, command))
+            goto commandError;
+          break;
+
+       case ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE:
+          if (enet_protocol_handle_throttle_configure (host, peer, command))
+            goto commandError;
+          break;
+
+       default:
+          goto commandError;
+       }
+
+       if (peer != NULL &&
+           (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) != 0)
+       {
+           enet_uint16 sentTime;
+
+           if (! (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME))
+             break;
+
+           sentTime = ENET_NET_TO_HOST_16 (header -> sentTime);
+
+           switch (peer -> state)
+           {
+           case ENET_PEER_STATE_DISCONNECTING:
+           case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT:
+              break;
+
+           case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT:
+              if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT)
+                enet_peer_queue_acknowledgement (peer, command, sentTime);
+              break;
+
+           default:   
+              enet_peer_queue_acknowledgement (peer, command, sentTime);        
+              break;
+           }
+       }
+    }
+
+commandError:
+    if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE)
+      return 1;
+
+    return 0;
+}
+ 
+static int
+enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
+{
+    for (;;)
+    {
+       int receivedLength;
+       ENetBuffer buffer;
+
+       buffer.data = host -> packetData [0];
+       buffer.dataLength = sizeof (host -> packetData [0]);
+
+       receivedLength = enet_socket_receive (host -> socket,
+                                             & host -> receivedAddress,
+                                             & buffer,
+                                             1);
+
+       if (receivedLength < 0)
+         return -1;
+
+       if (receivedLength == 0)
+         return 0;
+
+       host -> receivedData = host -> packetData [0];
+       host -> receivedDataLength = receivedLength;
+      
+       host -> totalReceivedData += receivedLength;
+       host -> totalReceivedPackets ++;
+ 
+       switch (enet_protocol_handle_incoming_commands (host, event))
+       {
+       case 1:
+          return 1;
+       
+       case -1:
+          return -1;
+
+       default:
+          break;
+       }
+    }
+
+    return -1;
+}
+
+static void
+enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer)
+{
+    ENetProtocol * command = & host -> commands [host -> commandCount];
+    ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
+    ENetAcknowledgement * acknowledgement;
+    ENetListIterator currentAcknowledgement;
+  
+    currentAcknowledgement = enet_list_begin (& peer -> acknowledgements);
+         
+    while (currentAcknowledgement != enet_list_end (& peer -> acknowledgements))
+    {
+       if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
+           buffer >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
+           peer -> mtu - host -> packetSize < sizeof (ENetProtocolAcknowledge))
+       {
+          host -> continueSending = 1;
+
+          break;
+       }
+
+       acknowledgement = (ENetAcknowledgement *) currentAcknowledgement;
+ 
+       currentAcknowledgement = enet_list_next (currentAcknowledgement);
+
+       buffer -> data = command;
+       buffer -> dataLength = sizeof (ENetProtocolAcknowledge);
+
+       host -> packetSize += buffer -> dataLength;
+ 
+       command -> header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE;
+       command -> header.channelID = acknowledgement -> command.header.channelID;
+       command -> acknowledge.receivedReliableSequenceNumber = ENET_HOST_TO_NET_16 (acknowledgement -> command.header.reliableSequenceNumber);
+       command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_16 (acknowledgement -> sentTime);
+  
+       if ((acknowledgement -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT)
+         enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE);
+
+       enet_list_remove (& acknowledgement -> acknowledgementList);
+       enet_free (acknowledgement);
+
+       ++ command;
+       ++ buffer;
+    }
+
+    host -> commandCount = command - host -> commands;
+    host -> bufferCount = buffer - host -> buffers;
+}
+
+static void
+enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
+{
+    ENetProtocol * command = & host -> commands [host -> commandCount];
+    ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
+    ENetOutgoingCommand * outgoingCommand;
+    ENetListIterator currentCommand;
+
+    currentCommand = enet_list_begin (& peer -> outgoingUnreliableCommands);
+    
+    while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands))
+    {
+       size_t commandSize;
+
+       outgoingCommand = (ENetOutgoingCommand *) currentCommand;
+       commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
+
+       if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
+           buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
+           peer -> mtu - host -> packetSize < commandSize ||
+           (outgoingCommand -> packet != NULL &&
+             peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> packet -> dataLength))
+       {
+          host -> continueSending = 1;
+
+          break;
+       }
+
+       currentCommand = enet_list_next (currentCommand);
+
+       if (outgoingCommand -> packet != NULL)
+       {
+          peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER;
+          peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE;
+          
+          if (peer -> packetThrottleCounter > peer -> packetThrottle)
+          {
+             -- outgoingCommand -> packet -> referenceCount;
+
+             if (outgoingCommand -> packet -> referenceCount == 0)
+               enet_packet_destroy (outgoingCommand -> packet);
+         
+             enet_list_remove (& outgoingCommand -> outgoingCommandList);
+             enet_free (outgoingCommand);
+           
+             continue;
+          }
+       }
+
+       buffer -> data = command;
+       buffer -> dataLength = commandSize;
+      
+       host -> packetSize += buffer -> dataLength;
+
+       * command = outgoingCommand -> command;
+       
+       enet_list_remove (& outgoingCommand -> outgoingCommandList);
+
+       if (outgoingCommand -> packet != NULL)
+       {
+          ++ buffer;
+          
+          buffer -> data = outgoingCommand -> packet -> data;
+          buffer -> dataLength = outgoingCommand -> packet -> dataLength;
+
+          host -> packetSize += buffer -> dataLength;
+
+          enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand);
+       }
+       else
+         enet_free (outgoingCommand);
+
+       ++ command;
+       ++ buffer;
+    } 
+
+    host -> commandCount = command - host -> commands;
+    host -> bufferCount = buffer - host -> buffers;
+
+    if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER && 
+        enet_list_empty (& peer -> outgoingReliableCommands) &&
+        enet_list_empty (& peer -> outgoingUnreliableCommands) && 
+        enet_list_empty (& peer -> sentReliableCommands))
+      enet_peer_disconnect (peer, peer -> eventData);
+}
+
+static int
+enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event)
+{
+    ENetOutgoingCommand * outgoingCommand;
+    ENetListIterator currentCommand, insertPosition;
+
+    currentCommand = enet_list_begin (& peer -> sentReliableCommands);
+    insertPosition = enet_list_begin (& peer -> outgoingReliableCommands);
+
+    while (currentCommand != enet_list_end (& peer -> sentReliableCommands))
+    {
+       outgoingCommand = (ENetOutgoingCommand *) currentCommand;
+
+       currentCommand = enet_list_next (currentCommand);
+
+       if (ENET_TIME_DIFFERENCE (host -> serviceTime, outgoingCommand -> sentTime) < outgoingCommand -> roundTripTimeout)
+         continue;
+
+       if (peer -> earliestTimeout == 0 ||
+           ENET_TIME_LESS (outgoingCommand -> sentTime, peer -> earliestTimeout))
+         peer -> earliestTimeout = outgoingCommand -> sentTime;
+
+       if (peer -> earliestTimeout != 0 &&
+             (ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= ENET_PEER_TIMEOUT_MAXIMUM ||
+               (outgoingCommand -> roundTripTimeout >= outgoingCommand -> roundTripTimeoutLimit &&
+                 ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= ENET_PEER_TIMEOUT_MINIMUM)))
+       {
+          enet_protocol_notify_disconnect (host, peer, event);
+
+          return 1;
+       }
+
+       if (outgoingCommand -> packet != NULL)
+         peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength;
+          
+       ++ peer -> packetsLost;
+
+       outgoingCommand -> roundTripTimeout *= 2;
+
+       enet_list_insert (insertPosition, enet_list_remove (& outgoingCommand -> outgoingCommandList));
+
+       if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) &&
+           ! enet_list_empty (& peer -> sentReliableCommands))
+       {
+          outgoingCommand = (ENetOutgoingCommand *) currentCommand;
+
+          peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout;
+       }
+    }
+    
+    return 0;
+}
+
+static void
+enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer)
+{
+    ENetProtocol * command = & host -> commands [host -> commandCount];
+    ENetBuffer * buffer = & host -> buffers [host -> bufferCount];
+    ENetOutgoingCommand * outgoingCommand;
+    ENetListIterator currentCommand;
+    ENetChannel *channel;
+    enet_uint16 reliableWindow;
+    size_t commandSize;
+
+    currentCommand = enet_list_begin (& peer -> outgoingReliableCommands);
+    
+    while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands))
+    {
+       outgoingCommand = (ENetOutgoingCommand *) currentCommand;
+
+       channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL;
+       reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
+       if (channel != NULL && 
+           outgoingCommand -> sendAttempts < 1 && 
+           ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) &&
+           (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE ||
+             channel -> usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) | 
+               (((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOW_SIZE - reliableWindow)))))
+         break;
+  
+       commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK];
+       if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] ||
+           buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] ||
+           peer -> mtu - host -> packetSize < commandSize)
+       {
+          host -> continueSending = 1;
+          
+          break;
+       }
+
+       if (outgoingCommand -> packet != NULL)
+       {
+          if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > peer -> windowSize)
+            break;
+
+          if ((enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength))
+          {
+             host -> continueSending = 1;
+
+             break;
+          }
+       }
+      
+       currentCommand = enet_list_next (currentCommand);
+
+       if (channel != NULL && outgoingCommand -> sendAttempts < 1)
+       {
+          channel -> usedReliableWindows |= 1 << reliableWindow;
+          ++ channel -> reliableWindows [reliableWindow];
+       }
+
+       ++ outgoingCommand -> sendAttempts;
+ 
+       if (outgoingCommand -> roundTripTimeout == 0)
+       {
+          outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance;
+          outgoingCommand -> roundTripTimeoutLimit = ENET_PEER_TIMEOUT_LIMIT * outgoingCommand -> roundTripTimeout;
+       }
+
+       if (enet_list_empty (& peer -> sentReliableCommands))
+         peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout;
+
+       enet_list_insert (enet_list_end (& peer -> sentReliableCommands),
+                         enet_list_remove (& outgoingCommand -> outgoingCommandList));
+
+       outgoingCommand -> sentTime = host -> serviceTime;
+
+       buffer -> data = command;
+       buffer -> dataLength = commandSize;
+
+       host -> packetSize += buffer -> dataLength;
+       host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME;
+
+       * command = outgoingCommand -> command;
+
+       if (outgoingCommand -> packet != NULL)
+       {
+          ++ buffer;
+          
+          buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset;
+          buffer -> dataLength = outgoingCommand -> fragmentLength;
+
+          host -> packetSize += outgoingCommand -> fragmentLength;
+
+          peer -> reliableDataInTransit += outgoingCommand -> fragmentLength;
+       }
+
+       ++ peer -> packetsSent;
+        
+       ++ command;
+       ++ buffer;
+    }
+
+    host -> commandCount = command - host -> commands;
+    host -> bufferCount = buffer - host -> buffers;
+}
+
+static int
+enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int checkForTimeouts)
+{
+    enet_uint8 headerData [sizeof (ENetProtocolHeader) + sizeof (enet_uint32)];
+    ENetProtocolHeader * header = (ENetProtocolHeader *) headerData;
+    ENetPeer * currentPeer;
+    int sentLength;
+    size_t shouldCompress = 0;
+ 
+    host -> continueSending = 1;
+
+    while (host -> continueSending)
+    for (host -> continueSending = 0,
+           currentPeer = host -> peers;
+         currentPeer < & host -> peers [host -> peerCount];
+         ++ currentPeer)
+    {
+        if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED ||
+            currentPeer -> state == ENET_PEER_STATE_ZOMBIE)
+          continue;
+
+        host -> headerFlags = 0;
+        host -> commandCount = 0;
+        host -> bufferCount = 1;
+        host -> packetSize = sizeof (ENetProtocolHeader);
+
+        if (! enet_list_empty (& currentPeer -> acknowledgements))
+          enet_protocol_send_acknowledgements (host, currentPeer);
+
+        if (checkForTimeouts != 0 &&
+            ! enet_list_empty (& currentPeer -> sentReliableCommands) &&
+            ENET_TIME_GREATER_EQUAL (host -> serviceTime, currentPeer -> nextTimeout) &&
+            enet_protocol_check_timeouts (host, currentPeer, event) == 1)
+          return 1;
+
+        if (! enet_list_empty (& currentPeer -> outgoingReliableCommands))
+          enet_protocol_send_reliable_outgoing_commands (host, currentPeer);
+        else
+        if (enet_list_empty (& currentPeer -> sentReliableCommands) &&
+            ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= ENET_PEER_PING_INTERVAL &&
+            currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing))
+        { 
+            enet_peer_ping (currentPeer);
+            enet_protocol_send_reliable_outgoing_commands (host, currentPeer);
+        }
+                      
+        if (! enet_list_empty (& currentPeer -> outgoingUnreliableCommands))
+          enet_protocol_send_unreliable_outgoing_commands (host, currentPeer);
+
+        if (host -> commandCount == 0)
+          continue;
+
+        if (currentPeer -> packetLossEpoch == 0)
+          currentPeer -> packetLossEpoch = host -> serviceTime;
+        else
+        if (ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> packetLossEpoch) >= ENET_PEER_PACKET_LOSS_INTERVAL &&
+            currentPeer -> packetsSent > 0)
+        {
+           enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent;
+
+#ifdef ENET_DEBUG
+#ifdef WIN32
+           printf (
+#else
+           fprintf (stderr, 
+#endif
+                    "peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0);
+#endif
+          
+           currentPeer -> packetLossVariance -= currentPeer -> packetLossVariance / 4;
+
+           if (packetLoss >= currentPeer -> packetLoss)
+           {
+              currentPeer -> packetLoss += (packetLoss - currentPeer -> packetLoss) / 8;
+              currentPeer -> packetLossVariance += (packetLoss - currentPeer -> packetLoss) / 4;
+           }
+           else
+           {
+              currentPeer -> packetLoss -= (currentPeer -> packetLoss - packetLoss) / 8;
+              currentPeer -> packetLossVariance += (currentPeer -> packetLoss - packetLoss) / 4;
+           }
+
+           currentPeer -> packetLossEpoch = host -> serviceTime;
+           currentPeer -> packetsSent = 0;
+           currentPeer -> packetsLost = 0;
+        }
+
+        host -> buffers -> data = headerData;
+        if (host -> headerFlags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME)
+        {
+            header -> sentTime = ENET_HOST_TO_NET_16 (host -> serviceTime & 0xFFFF);
+
+            host -> buffers -> dataLength = sizeof (ENetProtocolHeader);
+        }
+        else
+          host -> buffers -> dataLength = (size_t) & ((ENetProtocolHeader *) 0) -> sentTime;
+
+        shouldCompress = 0;
+        if (host -> compressor.context != NULL && host -> compressor.compress != NULL)
+        {
+            size_t originalSize = host -> packetSize - sizeof(ENetProtocolHeader),
+                   compressedSize = host -> compressor.compress (host -> compressor.context,
+                                        & host -> buffers [1], host -> bufferCount - 1,
+                                        originalSize,
+                                        host -> packetData [1],
+                                        originalSize);
+            if (compressedSize > 0 && compressedSize < originalSize)
+            {
+                host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_COMPRESSED;
+                shouldCompress = compressedSize;
+#ifdef ENET_DEBUG_COMPRESS
+#ifdef WIN32
+           printf (
+#else
+           fprintf (stderr,
+#endif
+                    "peer %u: compressed %u -> %u (%u%%)\n", currentPeer -> incomingPeerID, originalSize, compressedSize, (compressedSize * 100) / originalSize);
+#endif
+            }
+        }
+
+        if (currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID)
+          host -> headerFlags |= currentPeer -> outgoingSessionID << ENET_PROTOCOL_HEADER_SESSION_SHIFT;
+        header -> peerID = ENET_HOST_TO_NET_16 (currentPeer -> outgoingPeerID | host -> headerFlags);
+        if (host -> checksum != NULL)
+        {
+            enet_uint32 * checksum = (enet_uint32 *) & headerData [host -> buffers -> dataLength];
+            * checksum = currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID ? currentPeer -> connectID : 0;
+            host -> buffers -> dataLength += sizeof (enet_uint32);
+            * checksum = host -> checksum (host -> buffers, host -> bufferCount);
+        }
+
+        if (shouldCompress > 0)
+        {
+            host -> buffers [1].data = host -> packetData [1];
+            host -> buffers [1].dataLength = shouldCompress;
+            host -> bufferCount = 2;
+        }
+
+        currentPeer -> lastSendTime = host -> serviceTime;
+
+        sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount);
+
+        enet_protocol_remove_sent_unreliable_commands (currentPeer);
+
+        if (sentLength < 0)
+          return -1;
+
+        host -> totalSentData += sentLength;
+        host -> totalSentPackets ++;
+    }
+   
+    return 0;
+}
+
+/** Sends any queued packets on the host specified to its designated peers.
+
+    @param host   host to flush
+    @remarks this function need only be used in circumstances where one wishes to send queued packets earlier than in a call to enet_host_service().
+    @ingroup host
+*/
+void
+enet_host_flush (ENetHost * host)
+{
+    host -> serviceTime = enet_time_get ();
+
+    enet_protocol_send_outgoing_commands (host, NULL, 0);
+}
+
+/** Checks for any queued events on the host and dispatches one if available.
+
+    @param host    host to check for events
+    @param event   an event structure where event details will be placed if available
+    @retval > 0 if an event was dispatched
+    @retval 0 if no events are available
+    @retval < 0 on failure
+    @ingroup host
+*/
+int
+enet_host_check_events (ENetHost * host, ENetEvent * event)
+{
+    if (event == NULL) return -1;
+
+    event -> type = ENET_EVENT_TYPE_NONE;
+    event -> peer = NULL;
+    event -> packet = NULL;
+
+    return enet_protocol_dispatch_incoming_commands (host, event);
+}
+
+/** Waits for events on the host specified and shuttles packets between
+    the host and its peers.
+
+    @param host    host to service
+    @param event   an event structure where event details will be placed if one occurs
+                   if event == NULL then no events will be delivered
+    @param timeout number of milliseconds that ENet should wait for events
+    @retval > 0 if an event occurred within the specified time limit
+    @retval 0 if no event occurred
+    @retval < 0 on failure
+    @remarks enet_host_service should be called fairly regularly for adequate performance
+    @ingroup host
+*/
+int
+enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout)
+{
+    enet_uint32 waitCondition;
+
+    if (event != NULL)
+    {
+        event -> type = ENET_EVENT_TYPE_NONE;
+        event -> peer = NULL;
+        event -> packet = NULL;
+
+        switch (enet_protocol_dispatch_incoming_commands (host, event))
+        {
+        case 1:
+            return 1;
+
+        case -1:
+            perror ("Error dispatching incoming packets");
+
+            return -1;
+
+        default:
+            break;
+        }
+    }
+
+    host -> serviceTime = enet_time_get ();
+    
+    timeout += host -> serviceTime;
+
+    do
+    {
+       if (ENET_TIME_DIFFERENCE (host -> serviceTime, host -> bandwidthThrottleEpoch) >= ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
+         enet_host_bandwidth_throttle (host);
+
+       switch (enet_protocol_send_outgoing_commands (host, event, 1))
+       {
+       case 1:
+          return 1;
+
+       case -1:
+          perror ("Error sending outgoing packets");
+
+          return -1;
+
+       default:
+          break;
+       }
+
+       switch (enet_protocol_receive_incoming_commands (host, event))
+       {
+       case 1:
+          return 1;
+
+       case -1:
+          perror ("Error receiving incoming packets");
+
+          return -1;
+
+       default:
+          break;
+       }
+
+       switch (enet_protocol_send_outgoing_commands (host, event, 1))
+       {
+       case 1:
+          return 1;
+
+       case -1:
+          perror ("Error sending outgoing packets");
+
+          return -1;
+
+       default:
+          break;
+       }
+
+       if (event != NULL)
+       {
+          switch (enet_protocol_dispatch_incoming_commands (host, event))
+          {
+          case 1:
+             return 1;
+
+          case -1:
+             perror ("Error dispatching incoming packets");
+
+             return -1;
+
+          default:
+             break;
+          }
+       }
+
+       host -> serviceTime = enet_time_get ();
+
+       if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout))
+         return 0;
+
+       waitCondition = ENET_SOCKET_WAIT_RECEIVE;
+
+       if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0)
+         return -1;
+       
+       host -> serviceTime = enet_time_get ();
+    } while (waitCondition == ENET_SOCKET_WAIT_RECEIVE);
+
+    return 0; 
+}
+
Index: /osgVisual/trunk/src/cluster/enet/unix.c
===================================================================
--- /osgVisual/trunk/src/cluster/enet/unix.c	(revision 176)
+++ /osgVisual/trunk/src/cluster/enet/unix.c	(revision 176)
@@ -0,0 +1,440 @@
+/** 
+ @file  unix.c
+ @brief ENet Unix system specific functions
+*/
+#ifndef WIN32
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+#define ENET_BUILDING_LIB 1
+#include "enet/enet.h"
+
+#ifdef HAS_FCNTL
+#include <fcntl.h>
+#endif
+
+#ifdef __APPLE__
+#undef HAS_POLL
+#endif
+
+#ifdef HAS_POLL
+#include <sys/poll.h>
+#endif
+
+#ifndef HAS_SOCKLEN_T
+// todo check if new solution works
+//typedef int socklen_t;
+typedef __socklen_t socklen_t;
+#endif
+
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+
+static enet_uint32 timeBase = 0;
+
+int
+enet_initialize (void)
+{
+    return 0;
+}
+
+void
+enet_deinitialize (void)
+{
+}
+
+enet_uint32
+enet_time_get (void)
+{
+    struct timeval timeVal;
+
+    gettimeofday (& timeVal, NULL);
+
+    return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase;
+}
+
+void
+enet_time_set (enet_uint32 newTimeBase)
+{
+    struct timeval timeVal;
+
+    gettimeofday (& timeVal, NULL);
+    
+    timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
+}
+
+int
+enet_address_set_host (ENetAddress * address, const char * name)
+{
+    struct hostent * hostEntry = NULL;
+#ifdef HAS_GETHOSTBYNAME_R
+    struct hostent hostData;
+    char buffer [2048];
+    int errnum;
+
+#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+    gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
+#else
+    hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
+#endif
+#else
+    hostEntry = gethostbyname (name);
+#endif
+
+    if (hostEntry == NULL ||
+        hostEntry -> h_addrtype != AF_INET)
+    {
+#ifdef HAS_INET_PTON
+        if (! inet_pton (AF_INET, name, & address -> host))
+#else
+        if (! inet_aton (name, (struct in_addr *) & address -> host))
+#endif
+            return -1;
+        return 0;
+    }
+
+    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
+
+    return 0;
+}
+
+int
+enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
+{
+#ifdef HAS_INET_NTOP
+    if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL)
+#else
+    char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
+    if (addr != NULL)
+        strncpy (name, addr, nameLength);
+    else
+#endif
+        return -1;
+    return 0;
+}
+
+int
+enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
+{
+    struct in_addr in;
+    struct hostent * hostEntry = NULL;
+#ifdef HAS_GETHOSTBYADDR_R
+    struct hostent hostData;
+    char buffer [2048];
+    int errnum;
+
+    in.s_addr = address -> host;
+
+#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+    gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
+#else
+    hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
+#endif
+#else
+    in.s_addr = address -> host;
+
+    hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
+#endif
+
+    if (hostEntry == NULL)
+      return enet_address_get_host_ip (address, name, nameLength);
+
+    strncpy (name, hostEntry -> h_name, nameLength);
+
+    return 0;
+}
+
+int
+enet_socket_bind (ENetSocket socket, const ENetAddress * address)
+{
+    struct sockaddr_in sin;
+
+    memset (& sin, 0, sizeof (struct sockaddr_in));
+
+    sin.sin_family = AF_INET;
+
+    if (address != NULL)
+    {
+       sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+       sin.sin_addr.s_addr = address -> host;
+    }
+    else
+    {
+       sin.sin_port = 0;
+       sin.sin_addr.s_addr = INADDR_ANY;
+    }
+
+    return bind (socket,
+                 (struct sockaddr *) & sin,
+                 sizeof (struct sockaddr_in)); 
+}
+
+int 
+enet_socket_listen (ENetSocket socket, int backlog)
+{
+    return listen (socket, backlog < 0 ? SOMAXCONN : backlog);
+}
+
+ENetSocket
+enet_socket_create (ENetSocketType type)
+{
+    return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
+}
+
+int
+enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
+{
+    int result = -1;
+    switch (option)
+    {
+        case ENET_SOCKOPT_NONBLOCK:
+#ifdef HAS_FCNTL
+            result = fcntl (socket, F_SETFL, O_NONBLOCK | fcntl (socket, F_GETFL));
+#else
+            result = ioctl (socket, FIONBIO, & value);
+#endif
+            break;
+
+        case ENET_SOCKOPT_BROADCAST:
+            result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
+            break;
+
+        case ENET_SOCKOPT_REUSEADDR:
+            result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
+            break;
+
+        case ENET_SOCKOPT_RCVBUF:
+            result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
+            break;
+
+        case ENET_SOCKOPT_SNDBUF:
+            result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
+            break;
+
+        default:
+            break;
+    }
+    return result == -1 ? -1 : 0;
+}
+
+int
+enet_socket_connect (ENetSocket socket, const ENetAddress * address)
+{
+    struct sockaddr_in sin;
+
+    memset (& sin, 0, sizeof (struct sockaddr_in));
+
+    sin.sin_family = AF_INET;
+    sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+    sin.sin_addr.s_addr = address -> host;
+
+    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
+}
+
+ENetSocket
+enet_socket_accept (ENetSocket socket, ENetAddress * address)
+{
+    int result;
+    struct sockaddr_in sin;
+    socklen_t sinLength = sizeof (struct sockaddr_in);
+
+    result = accept (socket, 
+                     address != NULL ? (struct sockaddr *) & sin : NULL, 
+                     address != NULL ? & sinLength : NULL);
+    
+    if (result == -1)
+      return ENET_SOCKET_NULL;
+
+    if (address != NULL)
+    {
+        address -> host = (enet_uint32) sin.sin_addr.s_addr;
+        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+    }
+
+    return result;
+} 
+    
+void
+enet_socket_destroy (ENetSocket socket)
+{
+    close (socket);
+}
+
+int
+enet_socket_send (ENetSocket socket,
+                  const ENetAddress * address,
+                  const ENetBuffer * buffers,
+                  size_t bufferCount)
+{
+    struct msghdr msgHdr;
+    struct sockaddr_in sin;
+    int sentLength;
+
+    memset (& msgHdr, 0, sizeof (struct msghdr));
+
+    if (address != NULL)
+    {
+        memset (& sin, 0, sizeof (struct sockaddr_in));
+
+        sin.sin_family = AF_INET;
+        sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+        sin.sin_addr.s_addr = address -> host;
+
+        msgHdr.msg_name = & sin;
+        msgHdr.msg_namelen = sizeof (struct sockaddr_in);
+    }
+
+    msgHdr.msg_iov = (struct iovec *) buffers;
+    msgHdr.msg_iovlen = bufferCount;
+
+    sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
+    
+    if (sentLength == -1)
+    {
+       if (errno == EWOULDBLOCK)
+         return 0;
+
+       return -1;
+    }
+
+    return sentLength;
+}
+
+int
+enet_socket_receive (ENetSocket socket,
+                     ENetAddress * address,
+                     ENetBuffer * buffers,
+                     size_t bufferCount)
+{
+    struct msghdr msgHdr;
+    struct sockaddr_in sin;
+    int recvLength;
+
+    memset (& msgHdr, 0, sizeof (struct msghdr));
+
+    if (address != NULL)
+    {
+        msgHdr.msg_name = & sin;
+        msgHdr.msg_namelen = sizeof (struct sockaddr_in);
+    }
+
+    msgHdr.msg_iov = (struct iovec *) buffers;
+    msgHdr.msg_iovlen = bufferCount;
+
+    recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
+
+    if (recvLength == -1)
+    {
+       if (errno == EWOULDBLOCK)
+         return 0;
+
+       return -1;
+    }
+
+#ifdef HAS_MSGHDR_FLAGS
+    if (msgHdr.msg_flags & MSG_TRUNC)
+      return -1;
+#endif
+
+    if (address != NULL)
+    {
+        address -> host = (enet_uint32) sin.sin_addr.s_addr;
+        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+    }
+
+    return recvLength;
+}
+
+int
+enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
+{
+    struct timeval timeVal;
+
+    timeVal.tv_sec = timeout / 1000;
+    timeVal.tv_usec = (timeout % 1000) * 1000;
+
+    return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
+}
+
+int
+enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
+{
+#ifdef HAS_POLL
+    struct pollfd pollSocket;
+    int pollCount;
+    
+    pollSocket.fd = socket;
+    pollSocket.events = 0;
+
+    if (* condition & ENET_SOCKET_WAIT_SEND)
+      pollSocket.events |= POLLOUT;
+
+    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
+      pollSocket.events |= POLLIN;
+
+    pollCount = poll (& pollSocket, 1, timeout);
+
+    if (pollCount < 0)
+      return -1;
+
+    * condition = ENET_SOCKET_WAIT_NONE;
+
+    if (pollCount == 0)
+      return 0;
+
+    if (pollSocket.revents & POLLOUT)
+      * condition |= ENET_SOCKET_WAIT_SEND;
+    
+    if (pollSocket.revents & POLLIN)
+      * condition |= ENET_SOCKET_WAIT_RECEIVE;
+
+    return 0;
+#else
+    fd_set readSet, writeSet;
+    struct timeval timeVal;
+    int selectCount;
+
+    timeVal.tv_sec = timeout / 1000;
+    timeVal.tv_usec = (timeout % 1000) * 1000;
+
+    FD_ZERO (& readSet);
+    FD_ZERO (& writeSet);
+
+    if (* condition & ENET_SOCKET_WAIT_SEND)
+      FD_SET (socket, & writeSet);
+
+    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
+      FD_SET (socket, & readSet);
+
+    selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
+
+    if (selectCount < 0)
+      return -1;
+
+    * condition = ENET_SOCKET_WAIT_NONE;
+
+    if (selectCount == 0)
+      return 0;
+
+    if (FD_ISSET (socket, & writeSet))
+      * condition |= ENET_SOCKET_WAIT_SEND;
+
+    if (FD_ISSET (socket, & readSet))
+      * condition |= ENET_SOCKET_WAIT_RECEIVE;
+
+    return 0;
+#endif
+}
+
+#endif
+
Index: /osgVisual/trunk/src/cluster/enet/win32.c
===================================================================
--- /osgVisual/trunk/src/cluster/enet/win32.c	(revision 176)
+++ /osgVisual/trunk/src/cluster/enet/win32.c	(revision 176)
@@ -0,0 +1,348 @@
+/** 
+ @file  win32.c
+ @brief ENet Win32 system specific functions
+*/
+#ifdef WIN32
+
+#include <time.h>
+#define ENET_BUILDING_LIB 1
+#include "enet/enet.h"
+
+static enet_uint32 timeBase = 0;
+
+int
+enet_initialize (void)
+{
+    WORD versionRequested = MAKEWORD (1, 1);
+    WSADATA wsaData;
+   
+    if (WSAStartup (versionRequested, & wsaData))
+       return -1;
+
+    if (LOBYTE (wsaData.wVersion) != 1||
+        HIBYTE (wsaData.wVersion) != 1)
+    {
+       WSACleanup ();
+       
+       return -1;
+    }
+
+    timeBeginPeriod (1);
+
+    return 0;
+}
+
+void
+enet_deinitialize (void)
+{
+    timeEndPeriod (1);
+
+    WSACleanup ();
+}
+
+enet_uint32
+enet_time_get (void)
+{
+    return (enet_uint32) timeGetTime () - timeBase;
+}
+
+void
+enet_time_set (enet_uint32 newTimeBase)
+{
+    timeBase = (enet_uint32) timeGetTime () - newTimeBase;
+}
+
+int
+enet_address_set_host (ENetAddress * address, const char * name)
+{
+    struct hostent * hostEntry;
+
+    hostEntry = gethostbyname (name);
+    if (hostEntry == NULL ||
+        hostEntry -> h_addrtype != AF_INET)
+    {
+        unsigned long host = inet_addr (name);
+        if (host == INADDR_NONE)
+            return -1;
+        address -> host = host;
+        return 0;
+    }
+
+    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
+
+    return 0;
+}
+
+int
+enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
+{
+    char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
+    if (addr == NULL)
+        return -1;
+    strncpy (name, addr, nameLength);
+    return 0;
+}
+
+int
+enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
+{
+    struct in_addr in;
+    struct hostent * hostEntry;
+    
+    in.s_addr = address -> host;
+    
+    hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
+    if (hostEntry == NULL)
+      return enet_address_get_host_ip (address, name, nameLength);
+
+    strncpy (name, hostEntry -> h_name, nameLength);
+
+    return 0;
+}
+
+int
+enet_socket_bind (ENetSocket socket, const ENetAddress * address)
+{
+    struct sockaddr_in sin;
+
+    memset (& sin, 0, sizeof (struct sockaddr_in));
+
+    sin.sin_family = AF_INET;
+
+    if (address != NULL)
+    {
+       sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+       sin.sin_addr.s_addr = address -> host;
+    }
+    else
+    {
+       sin.sin_port = 0;
+       sin.sin_addr.s_addr = INADDR_ANY;
+    }
+
+    return bind (socket,
+                 (struct sockaddr *) & sin,
+                 sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
+}
+
+int
+enet_socket_listen (ENetSocket socket, int backlog)
+{
+    return listen (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0;
+}
+
+ENetSocket
+enet_socket_create (ENetSocketType type)
+{
+    return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
+}
+
+int
+enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
+{
+    int result = SOCKET_ERROR;
+    switch (option)
+    {
+        case ENET_SOCKOPT_NONBLOCK:
+        {
+            u_long nonBlocking = (u_long) value;
+            result = ioctlsocket (socket, FIONBIO, & nonBlocking);
+            break;
+        }
+
+        case ENET_SOCKOPT_BROADCAST:
+            result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
+            break;
+
+        case ENET_SOCKOPT_REUSEADDR:
+            result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
+            break;
+
+        case ENET_SOCKOPT_RCVBUF:
+            result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
+            break;
+
+        case ENET_SOCKOPT_SNDBUF:
+            result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
+            break;
+
+        default:
+            break;
+    }
+    return result == SOCKET_ERROR ? -1 : 0;
+}
+
+int
+enet_socket_connect (ENetSocket socket, const ENetAddress * address)
+{
+    struct sockaddr_in sin;
+
+    memset (& sin, 0, sizeof (struct sockaddr_in));
+
+    sin.sin_family = AF_INET;
+    sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+    sin.sin_addr.s_addr = address -> host;
+
+    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
+}
+
+ENetSocket
+enet_socket_accept (ENetSocket socket, ENetAddress * address)
+{
+    SOCKET result;
+    struct sockaddr_in sin;
+    int sinLength = sizeof (struct sockaddr_in);
+
+    result = accept (socket, 
+                     address != NULL ? (struct sockaddr *) & sin : NULL, 
+                     address != NULL ? & sinLength : NULL);
+
+    if (result == INVALID_SOCKET)
+      return ENET_SOCKET_NULL;
+
+    if (address != NULL)
+    {
+        address -> host = (enet_uint32) sin.sin_addr.s_addr;
+        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+    }
+
+    return result;
+}
+
+void
+enet_socket_destroy (ENetSocket socket)
+{
+    closesocket (socket);
+}
+
+int
+enet_socket_send (ENetSocket socket,
+                  const ENetAddress * address,
+                  const ENetBuffer * buffers,
+                  size_t bufferCount)
+{
+    struct sockaddr_in sin;
+    DWORD sentLength;
+
+    if (address != NULL)
+    {
+        memset (& sin, 0, sizeof (struct sockaddr_in));
+
+        sin.sin_family = AF_INET;
+        sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+        sin.sin_addr.s_addr = address -> host;
+    }
+
+    if (WSASendTo (socket, 
+                   (LPWSABUF) buffers,
+                   (DWORD) bufferCount,
+                   & sentLength,
+                   0,
+                   address != NULL ? (struct sockaddr *) & sin : 0,
+                   address != NULL ? sizeof (struct sockaddr_in) : 0,
+                   NULL,
+                   NULL) == SOCKET_ERROR)
+    {
+       if (WSAGetLastError () == WSAEWOULDBLOCK)
+         return 0;
+
+       return -1;
+    }
+
+    return (int) sentLength;
+}
+
+int
+enet_socket_receive (ENetSocket socket,
+                     ENetAddress * address,
+                     ENetBuffer * buffers,
+                     size_t bufferCount)
+{
+    INT sinLength = sizeof (struct sockaddr_in);
+    DWORD flags = 0,
+          recvLength;
+    struct sockaddr_in sin;
+
+    if (WSARecvFrom (socket,
+                     (LPWSABUF) buffers,
+                     (DWORD) bufferCount,
+                     & recvLength,
+                     & flags,
+                     address != NULL ? (struct sockaddr *) & sin : NULL,
+                     address != NULL ? & sinLength : NULL,
+                     NULL,
+                     NULL) == SOCKET_ERROR)
+    {
+       switch (WSAGetLastError ())
+       {
+       case WSAEWOULDBLOCK:
+       case WSAECONNRESET:
+          return 0;
+       }
+
+       return -1;
+    }
+
+    if (flags & MSG_PARTIAL)
+      return -1;
+
+    if (address != NULL)
+    {
+        address -> host = (enet_uint32) sin.sin_addr.s_addr;
+        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+    }
+
+    return (int) recvLength;
+}
+
+int
+enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
+{
+    struct timeval timeVal;
+
+    timeVal.tv_sec = timeout / 1000;
+    timeVal.tv_usec = (timeout % 1000) * 1000;
+
+    return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
+}
+
+int
+enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
+{
+    fd_set readSet, writeSet;
+    struct timeval timeVal;
+    int selectCount;
+    
+    timeVal.tv_sec = timeout / 1000;
+    timeVal.tv_usec = (timeout % 1000) * 1000;
+    
+    FD_ZERO (& readSet);
+    FD_ZERO (& writeSet);
+
+    if (* condition & ENET_SOCKET_WAIT_SEND)
+      FD_SET (socket, & writeSet);
+
+    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
+      FD_SET (socket, & readSet);
+
+    selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
+
+    if (selectCount < 0)
+      return -1;
+
+    * condition = ENET_SOCKET_WAIT_NONE;
+
+    if (selectCount == 0)
+      return 0;
+
+    if (FD_ISSET (socket, & writeSet))
+      * condition |= ENET_SOCKET_WAIT_SEND;
+    
+    if (FD_ISSET (socket, & readSet))
+      * condition |= ENET_SOCKET_WAIT_RECEIVE;
+
+    return 0;
+} 
+
+#endif
+
Index: /osgVisual/trunk/src/core/osgVisual.cpp
===================================================================
--- /osgVisual/trunk/src/core/osgVisual.cpp	(revision 176)
+++ /osgVisual/trunk/src/core/osgVisual.cpp	(revision 176)
@@ -0,0 +1,87 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+const unsigned int MAX_NUM_EVENTS = 10;
+
+#ifdef _DEBUG
+	#ifdef WIN32
+		// Declare this in header.
+		#define _CRTDBG_MAP_ALLOC
+		#include <stdlib.h>
+		#include <crtdbg.h>
+	#endif 
+#endif 
+
+
+//#include <windows.h>
+
+#include <osg/ArgumentParser>
+#include <osg/Referenced>
+#include <osgDB/Registry>
+
+#include <visual_core.h>
+
+
+
+
+int main(int argc, char** argv)
+{
+	
+#ifdef _DEBUG
+	#ifdef WIN32
+		#include <leakDetection.h>	// for main: must be inside function. In classes: headerfile inside calss is sufficient
+		int tmp_flag;
+
+		HANDLE log_file = CreateFile("mem_log.txt", GENERIC_WRITE,FILE_SHARE_WRITE,
+			NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+
+		_CrtSetReportMode(_CRT_ASSERT,_CRTDBG_MODE_FILE | _CRTDBG_MODE_WNDW |
+			_CRTDBG_MODE_DEBUG);
+		_CrtSetReportMode(_CRT_WARN,_CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
+		_CrtSetReportMode(_CRT_ERROR,_CRTDBG_MODE_FILE | _CRTDBG_MODE_WNDW |
+			_CRTDBG_MODE_DEBUG);
+
+		// output to the file
+		_CrtSetReportFile(_CRT_ASSERT, log_file);
+		_CrtSetReportFile(_CRT_WARN, log_file);
+		_CrtSetReportFile(_CRT_ERROR, log_file);
+
+		tmp_flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+		tmp_flag |= _CRTDBG_ALLOC_MEM_DF;
+		tmp_flag |= _CRTDBG_DELAY_FREE_MEM_DF;
+		tmp_flag |= _CRTDBG_LEAK_CHECK_DF;
+
+		_CrtSetDbgFlag(tmp_flag);
+	#endif 
+#endif 
+
+    // Use an ArgumentParser object to manage the program arguments.
+	osg::ArgumentParser arguments(&argc,argv);
+
+    // Instantiate osgVisual main class
+	osg::ref_ptr<osgVisual::visual_core> core = new osgVisual::visual_core(arguments);
+
+    // Visual initialisieren
+    core->initialize();
+
+	// Shut osgVisual down
+	core->shutdown();
+
+	// Set Pointer to null to destroy the objects before this function ends
+	core = NULL;
+
+	return 0;
+}
Index: /osgVisual/trunk/src/core/visual_core.cpp
===================================================================
--- /osgVisual/trunk/src/core/visual_core.cpp	(revision 176)
+++ /osgVisual/trunk/src/core/visual_core.cpp	(revision 176)
@@ -0,0 +1,515 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+
+#include <visual_core.h>
+
+using namespace osgVisual;
+
+visual_core::visual_core(osg::ArgumentParser& arguments_) : arguments(arguments_)
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "visual_core instantiated." << std::endl;
+}
+
+visual_core::~visual_core(void)
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "visual_core destroyed." << std::endl;
+}
+
+void visual_core::initialize()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "Initialize visual_core..." << std::endl;
+
+	// Check for config file to provide it to all modules during initialization.
+	if( arguments.read("-c", configFilename) || arguments.read("--config", configFilename) )
+	{
+		if( !osgDB::fileExists(configFilename) )
+			configFilename = "";
+		else
+			OSG_ALWAYS << "Using configuration file: " << configFilename << std::endl;
+	}
+
+	// Configure osg to use KdTrees
+	osgDB::Registry::instance()->setBuildKdTreesHint(osgDB::ReaderWriter::Options::BUILD_KDTREES);
+
+	// Setup pathes
+	osgDB::Registry::instance()->getDataFilePathList().push_back( "D:\\DA\\osgVisual\\models" );
+	
+	// Setup viewer
+	viewer = new osgViewer::Viewer(arguments);
+
+	// Setup coordinate system node
+	rootNode = new osg::CoordinateSystemNode;	// todo memleakf
+	rootNode->setEllipsoidModel(new osg::EllipsoidModel());
+
+	// Test memory leak (todo)
+	double* test = new double[1000];
+
+	#ifdef USE_SPACENAVIGATOR
+		mouse = NULL;
+	#endif
+
+	//osg::DisplaySettings::instance()->setNumOfDatabaseThreadsHint( 8 );
+
+	// Show model
+	viewer->setSceneData( rootNode );
+
+	osg::Group* distortedSceneGraph = NULL;
+#ifdef USE_DISTORTION
+	// Initialize distortion
+	distortion = new visual_distortion( viewer, arguments, configFilename );
+	distortedSceneGraph = distortion->initialize( rootNode, viewer->getCamera()->getClearColor() );
+#endif
+
+#ifdef USE_SKY_SILVERLINING
+	// Initialize sky
+	sky = new visual_skySilverLining( viewer, configFilename );
+	sky->init(distortedSceneGraph, rootNode);	// Without distortion: distortedSceneGraph=NULL
+#endif
+
+	// Initialize DataIO interface
+	visual_dataIO::getInstance()->init(viewer, arguments, configFilename);
+
+	// Add manipulators for user interaction - after dataIO to be able to skip it in slaves rendering machines.
+	addManipulators();
+
+	loadTerrain(arguments);
+
+	// create the windows and run the threads.
+	viewer->realize();
+
+	// parse Configuration file
+	parseConfigFile(arguments);
+
+	// All modules are initialized - now check arguments for any unused parameter.
+	checkCommandlineArgumentsForFinalErrors();
+
+	// Run visual main loop
+	mainLoop();
+}
+
+void visual_core::mainLoop()
+{
+	int framestoScenerySetup = 5;
+	// run main loop
+	while( !viewer->done() )
+    {
+		// setup scenery
+		if(framestoScenerySetup-- == 0)
+			setupScenery();
+
+		// next frame please....
+        viewer->advance();
+
+		/*double hat, hot, lat, lon, height;
+		util::getWGS84ofCamera( viewer->getCamera(), rootNode, lat, lon, height);
+		if (util::queryHeightOfTerrain( hot, rootNode, lat, lon) && util::queryHeightAboveTerrainInWGS84( hat, rootNode, lat, lon, height ) )
+			OSG_NOTIFY( osg::ALWAYS ) << "HOT is: " << hot << ", HAT is: " << hat << std::endl;*/
+	
+		// perform all queued events
+		viewer->eventTraversal();
+
+		// update the scene by traversing it with the the update visitor which will
+        // call all node update callbacks and animations.
+        viewer->updateTraversal();
+		
+        // Render the Frame.
+        viewer->renderingTraversals();
+
+    }	// END WHILE
+}
+
+void visual_core::shutdown()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "Shutdown visual_core..." << std::endl;
+
+	// Shutdown Dbug HUD
+	if(hud.valid())
+		hud->shutdown();
+	// Unset scene data
+	viewer->setSceneData( NULL );
+
+#ifdef USE_SKY_SILVERLINING
+	// Shutdown sky
+	if( sky.valid() )
+		sky->shutdown();
+#endif
+
+#ifdef USE_DISTORTION
+	// Shutdown distortion
+	if( distortion.valid() )
+		distortion->shutdown();
+#endif
+
+	// Shutdown data
+	rootNode = NULL;
+
+	// Shutdown dataIO
+	visual_dataIO::getInstance()->shutdown();
+
+	
+#ifdef USE_SPACENAVIGATOR
+	//Delete SpaceMouse driver
+	if(mouse)
+	{
+		mouse->shutdown();
+		delete mouse;
+	}
+#endif
+
+	// Destroy osgViewer
+	viewer = NULL;
+}
+
+bool visual_core::loadTerrain(osg::ArgumentParser& arguments_)
+{
+	osg::ref_ptr<osg::Node> model = osgDB::readNodeFiles(arguments_);
+	if( model.valid() )
+	{
+        rootNode->addChild( model.get() );
+		return true;
+	}
+	else
+	{
+        OSG_NOTIFY( osg::FATAL ) << "Load terrain: No data loaded" << std::endl;
+        return false;
+    }    
+
+	return false;
+}
+
+void visual_core::addManipulators()
+{
+	if(!visual_dataIO::getInstance()->isSlave()) // set up the camera manipulators if not slave.
+    {
+        osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
+
+        keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
+        keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
+        keyswitchManipulator->addMatrixManipulator( '3', "Terrain", new osgGA::TerrainManipulator() );
+		nt = new osgGA::NodeTrackerManipulator();
+		keyswitchManipulator->addMatrixManipulator( '4', "NodeTrackerManipulator", nt );
+		
+#ifdef USE_SPACENAVIGATOR
+		// SpaceNavigator manipulator
+		mouse = new SpaceMouse();
+		mouse->initialize();
+		mouseTrackerManip = new NodeTrackerSpaceMouse(mouse);
+		mouseTrackerManip->setTrackerMode(NodeTrackerSpaceMouse::NODE_CENTER);
+		mouseTrackerManip->setRotationMode(NodeTrackerSpaceMouse::ELEVATION_AZIM);
+		mouseTrackerManip->setAutoComputeHomePosition( true );
+		keyswitchManipulator->addMatrixManipulator( '5', "Spacemouse Node Tracker", mouseTrackerManip );
+		keyswitchManipulator->addMatrixManipulator( '6', "Spacemouse Free (Airplane)", new FreeManipulator(mouse) );
+#endif
+
+		// objectMounted Manipulator for Camera control by Nodes
+		objectMountedCameraManip = new objectMountedManipulator();
+		keyswitchManipulator->addMatrixManipulator( '7', "Object mounted Camera", objectMountedCameraManip );
+
+		// Animation path manipulator
+        std::string pathfile;
+        char keyForAnimationPath = '8';
+        while (arguments.read("-p",pathfile))
+        {
+            osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
+            if (apm || !apm->valid()) 
+            {
+                unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
+                keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
+                keyswitchManipulator->selectMatrixManipulator(num);
+                ++keyForAnimationPath;
+            }
+        }
+
+        viewer->setCameraManipulator( keyswitchManipulator.get() );
+    }	// If not Slave END
+
+    // add the state manipulator
+    viewer->addEventHandler( new osgGA::StateSetManipulator(rootNode->getOrCreateStateSet()) );
+    
+    // add the thread model handler
+    viewer->addEventHandler(new osgViewer::ThreadingHandler);
+
+    // add the window size toggle handler
+    viewer->addEventHandler(new osgViewer::WindowSizeHandler);
+        
+    // add the stats handler
+    viewer->addEventHandler(new osgViewer::StatsHandler);
+
+    // add the help handler
+    viewer->addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage()));
+
+    // add the record camera path handler
+    viewer->addEventHandler(new osgViewer::RecordCameraPathHandler);
+
+    // add the LOD Scale handler
+    viewer->addEventHandler(new osgViewer::LODScaleHandler);
+
+    // add the screen capture handler
+    viewer->addEventHandler(new osgViewer::ScreenCaptureHandler);
+}
+
+void visual_core::parseConfigFile(osg::ArgumentParser& arguments_)
+{
+	if( configFilename != "" )
+	{
+		xmlDoc *doc = NULL;
+		xmlNode *root_element = NULL;
+	  	
+		doc = xmlReadFile(configFilename.c_str(), NULL, 0);
+		if (doc == NULL)
+		{
+			OSG_ALWAYS << "visual_core::parseConfigFile() - ERROR: could not parse osgVisual config file" << configFilename  << std::endl;
+		}
+		else
+		{
+			//  Get the root element node
+			root_element = xmlDocGetRootElement(doc);
+
+			// Parse the XML document.
+			checkXMLNode(root_element);
+
+			// free the document
+			xmlFreeDoc(doc);;
+		}
+		// Free the global variables that may have been allocated by the parser.
+		xmlCleanupParser();
+
+	}	// IF configfile exists
+}
+
+void visual_core::checkXMLNode(xmlNode * a_node)
+{
+  for (xmlNode *cur_node = a_node; cur_node; cur_node = cur_node->next)
+	{
+		std::string node_name=reinterpret_cast<const char*>(cur_node->name);
+		if(cur_node->type == XML_ELEMENT_NODE && node_name == "osgvisualconfiguration")
+		{
+			OSG_DEBUG << "XML node osgvisualconfiguration found" << std::endl;
+
+			// Iterate to the next nodes to configure modules and scenery.
+			checkXMLNode(cur_node->children);		
+		}
+
+        if (cur_node->type == XML_ELEMENT_NODE && node_name == "module")
+		{
+			OSG_DEBUG << "XML node module found" << std::endl;
+
+			parseModule(cur_node);
+	
+            //OSG_DEBUG << "node type=Element, name:" << cur_node->name << std::endl;
+			//OSG_DEBUG << "Processing children at " << cur_node->children << std::endl;
+        }	// IF(module) END
+
+		if (cur_node->type == XML_ELEMENT_NODE && node_name == "scenery")
+		{
+			OSG_DEBUG << "XML node scenery found" << std::endl;
+
+			parseScenery(cur_node);
+	
+            //OSG_DEBUG << "node type=Element, name:" << cur_node->name << std::endl;
+			//OSG_DEBUG << "Processing children at " << cur_node->children << std::endl;
+        }	// IF(scenery) END
+    }	// FOR END
+}
+
+void visual_core::parseModule(xmlNode * a_node)
+{
+	OSG_ALWAYS << "parseModule()" << std::endl;
+
+// Extract infos
+	std::string name = "";
+	bool enabled = false;
+
+	xmlAttr  *attr = a_node->properties;
+	while ( attr ) 
+	{ 
+		std::string attr_name=reinterpret_cast<const char*>(attr->name);
+		std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
+		if( attr_name == "name" )
+			name = reinterpret_cast<const char*>(attr->children->content);
+		if( attr_name == "enabled" && attr_value== "yes" )
+			enabled = true;
+		if( attr_name == "enabled" && attr_value== "no" )
+			enabled = false;
+
+		attr = attr->next; 
+	} 
+	OSG_ALWAYS << "Module '" << name << "' found. Enabled = " << enabled << std::endl;
+
+	// Pass the nodes to the corresponding modules...
+	if(name == "core") this->config(a_node);
+}
+
+void visual_core::parseScenery(xmlNode * a_node)
+{
+	OSG_ALWAYS << "parseScenery()" << std::endl;
+}
+
+void visual_core::config(xmlNode * a_node)
+{
+	// Currently no configuration options fpr the core module are available.
+}
+
+bool visual_core::checkCommandlineArgumentsForFinalErrors()
+{
+	// Setup Application Usage
+	arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
+	arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the new FSD visualization tool, written by Torben Dannhauer");
+    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] Terrain_filename");
+	arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
+
+    // if user request help write it out to cout.
+    if (arguments.read("-h") || arguments.read("--help"))
+    {
+        arguments.getApplicationUsage()->write(std::cout);
+		//cause the viewer to exit and shut down clean.
+        viewer->setDone(true);
+    }
+
+    // report any errors if they have occurred when parsing the program arguments.
+    if (arguments.errors())
+    {
+        arguments.writeErrorMessages(std::cout);
+		//cause the viewer to exit and shut down clean.
+        viewer->setDone(true);
+    }
+
+	 // any option left unread are converted into errors to write out later.
+    arguments.reportRemainingOptionsAsUnrecognized();
+
+    // report any errors if they have occurred when parsing the program arguments.
+    if (arguments.errors())
+    {
+        arguments.writeErrorMessages(std::cout);
+        return false;
+    }
+	return true;
+}
+
+void visual_core::setupScenery()
+{
+
+	// Sky settings: 	
+	sky->setTime(15,30,00);
+	sky->setVisibility(50000);
+	sky->addWindVolume( 0.0, 15000.0, 25.0, 90.0 );
+	
+	//sky->addCloudLayer( 0, 20000, 20000, 600.0, 1000.0, 0.5, CUMULONIMBUS_CAPPILATUS );
+	//sky->addCloudLayer( 1, 5000000, 5000000, 600.0, 7351.0, 0.2, CIRRUS_FIBRATUS );
+	//sky->addCloudLayer( 2, 50000, 50000, 600.0, 7351.0, 0.2, CIRROCUMULUS );
+	///sky->addCloudLayer( 2, 100000, 100000, 600.0, 2351.0, 0.75, STRATUS );
+	sky->addCloudLayer( 3, 50000, 50000, 1300.0, 700.0, 0.07, CUMULUS_CONGESTUS );
+	//sky->addCloudLayer( 1, 100000, 100000, 3500.0, 2000.0, 0.30, STRATOCUMULUS );
+
+	//sky->setSlotPrecipitation( 1, 0.0, 0.0, 0.0, 25.0 );
+
+
+	//testObj = new visual_object( rootNode, "testStab", objectMountedCameraManip );
+	//testObj->setNewPosition( osg::DegreesToRadians(47.7123), osg::DegreesToRadians(12.84088), 600 );
+	///* using a huge cylinder to test position & orientation */
+	//testObj->setGeometry( util::getDemoCylinder(5000.0, 20.0 ) );
+	//testObj->addUpdater( new object_updater(testObj) );
+
+	//osg::ref_ptr<visual_object> testObj2 = new visual_object( rootNode, "neuschwanstein" );	// todo memleak
+	////testObj2->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 );
+	//testObj2->setNewPosition( osg::DegreesToRadians(47.557523564234), osg::DegreesToRadians(10.749646398595), 950 );
+	//testObj2->loadGeometry( "../models/neuschwanstein.osgb" );
+	////testObj2->addUpdater( new object_updater(testObj2) );	// todo memleak
+
+	osg::ref_ptr<visual_object> testObj3 = new visual_object( rootNode, "SAENGER1" );	// todo memleak
+	testObj3->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 );
+	testObj3->loadGeometry( "../models/saenger1.flt" );
+	testObj3->addUpdater( new object_updater(testObj3) );	// todo memleak
+	
+
+	osg::ref_ptr<visual_object> testObj4 = new visual_object( rootNode, "SAENGER2" );	// todo memleak
+	testObj4->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 650 );
+	testObj4->loadGeometry( "../models/saenger2.flt" );
+	testObj4->addUpdater( new object_updater(testObj4) );	// todo memleak
+	testObj4->addLabel("testLabel", "LabelTest!!\nnächste Zeile :)",osg::Vec4(1.0f,0.25f,1.0f,1.0f));
+
+	osg::ref_ptr<visual_object> testObj5 = new visual_object( rootNode, "SAENGER" );	// todo memleak
+	testObj5->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 550 );
+	testObj5->loadGeometry( "../models/saengerCombine.flt" );
+	//testObj5->setScale( 2 );
+	testObj5->addUpdater( new object_updater(testObj5) );	// todo memleak
+
+#ifdef USE_SPACENAVIGATOR
+	// Manipulatoren auf dieses Objekt binden (Primärobjekt)
+	if (objectMountedCameraManip.valid())
+		objectMountedCameraManip->setAttachedObject( testObj4 );
+	if (mouseTrackerManip.valid())
+	{
+		mouseTrackerManip->setTrackNode( testObj4->getGeometry() );
+		mouseTrackerManip->setMinimumDistance( 100 );
+	}
+#endif
+
+	if(nt.valid())
+	{
+		osgGA::NodeTrackerManipulator::TrackerMode trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER;
+		osgGA::NodeTrackerManipulator::RotationMode rotationMode = osgGA::NodeTrackerManipulator::ELEVATION_AZIM;
+		nt->setTrackerMode(trackerMode);
+		nt->setRotationMode(rotationMode);
+		//nt->setAutoComputeHomePosition( true );
+		nt->setMinimumDistance( 100 );
+		nt->setTrackNode(testObj4->getGeometry());
+		//nt->computeHomePosition();
+		nt->setAutoComputeHomePosition( true );
+		nt->setDistance( 250 );
+	}
+
+
+	// Load EDDF
+	//std::string filename = "D:\\DA\\EDDF_test\\eddf.ive";
+	//if( !osgDB::fileExists(filename) )
+	//{
+	//	OSG_NOTIFY(osg::ALWAYS) << "Warning: EDDF Model not loaded. File '" << filename << "' does not exist. Skipping.";
+	//}
+	//// read model
+	//osg::ref_ptr<osg::Node> tmpModel = osgDB::readNodeFile( filename );
+	//if (tmpModel.valid())
+	//	rootNode->addChild( tmpModel );
+	
+ 
+	visual_draw2D::getInstance()->init( rootNode, viewer );
+	//osg::ref_ptr<visual_hud> hud = new visual_hud();
+	hud = new visual_debug_hud();
+	hud->init( viewer, rootNode );
+	
+	
+
+	//osg::ref_ptr<visual_draw3D> test = new visual_draw3D();
+	//test->init( rootNode, viewer );
+
+	//// Creating Testclasses
+	//osg::ref_ptr<osgVisual::dataIO_transportContainer> test = new osgVisual::dataIO_transportContainer();
+	//osg::ref_ptr<osgVisual::dataIO_executer> testEx = new osgVisual::dataIO_executer();
+	//osg::ref_ptr<osgVisual::dataIO_slot> testSlot = new osgVisual::dataIO_slot();
+	//test->setFrameID( 22 );
+	//test->setName("ugamoep");
+	//testEx->setexecuterID( osgVisual::dataIO_executer::IS_COLLISION );
+	//testSlot->setVariableName(std::string("HalloName"));
+	//testSlot->setdataDirection( osgVisual::dataIO_slot::TO_OBJ );
+	//testSlot->setvarType( osgVisual::dataIO_slot::DOUBLE );
+	//testSlot->setValue( 0.12345 );
+	//test->addExecuter( testEx );
+	//test->addSlot( testSlot );
+
+	visual_dataIO::getInstance()->setSlotData("TestSlot1", osgVisual::dataIO_slot::TO_OBJ, 0.12345);
+
+}
Index: /osgVisual/trunk/src/dataIO/dataIO_executer.cpp
===================================================================
--- /osgVisual/trunk/src/dataIO/dataIO_executer.cpp	(revision 176)
+++ /osgVisual/trunk/src/dataIO/dataIO_executer.cpp	(revision 176)
@@ -0,0 +1,38 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include "dataIO_executer.h"
+
+REGISTER_OBJECT_WRAPPER( dataIO_executer,                 // The unique wrapper name
+						new osgVisual::dataIO_executer,             // The proto
+                         osgVisual::dataIO_executer,                 // The class typename
+						 "osg::Node osgVisual::dataIO_executer" )  // The inheritance relations
+{
+    // Serializers for different members    
+	BEGIN_ENUM_SERIALIZER( executerID, DO_NOTHING );
+		ADD_ENUM_VALUE( GET_HAT );
+		ADD_ENUM_VALUE( GET_HOT );
+		ADD_ENUM_VALUE( GET_LAT );
+		ADD_ENUM_VALUE( GET_LON );
+		ADD_ENUM_VALUE( IS_COLLISION );
+		ADD_ENUM_VALUE( IS_INSIDE_CLOUD );
+		ADD_ENUM_VALUE( IS_WIND );
+		ADD_ENUM_VALUE( IS_PRECIPITATION );
+		ADD_ENUM_VALUE( DO_NOTHING );
+		END_ENUM_SERIALIZER();
+		ADD_LIST_SERIALIZER( DoubleParameter, osgVisual::dataIO_executer::parameterList );
+	ADD_STRING_SERIALIZER( StringParameter, "" );	
+}
Index: /osgVisual/trunk/src/dataIO/dataIO_slot.cpp
===================================================================
--- /osgVisual/trunk/src/dataIO/dataIO_slot.cpp	(revision 176)
+++ /osgVisual/trunk/src/dataIO/dataIO_slot.cpp	(revision 176)
@@ -0,0 +1,36 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include "dataIO_slot.h"
+
+REGISTER_OBJECT_WRAPPER( dataIO_slot,                 // The unique wrapper name
+                         new osgVisual::dataIO_slot,             // The proto
+                         osgVisual::dataIO_slot,                 // The class typename
+						 "osg::Object osgVisual::dataIO_slot" )  // The inheritance relations
+{
+    // Serializers for different members    
+	BEGIN_ENUM_SERIALIZER( dataDirection, TO_OBJ );
+		ADD_ENUM_VALUE( TO_OBJ );
+		ADD_ENUM_VALUE( FROM_OBJ );
+		END_ENUM_SERIALIZER();
+	BEGIN_ENUM_SERIALIZER( varType, DOUBLE );
+		ADD_ENUM_VALUE( DOUBLE );
+		ADD_ENUM_VALUE( STRING );
+		END_ENUM_SERIALIZER();
+	ADD_STRING_SERIALIZER( VariableName, "" );
+	ADD_DOUBLE_SERIALIZER( Value, 0.0 );
+	ADD_STRING_SERIALIZER( SValue, "" );	
+}
Index: /osgVisual/trunk/src/dataIO/dataIO_transportContainer.cpp
===================================================================
--- /osgVisual/trunk/src/dataIO/dataIO_transportContainer.cpp	(revision 176)
+++ /osgVisual/trunk/src/dataIO/dataIO_transportContainer.cpp	(revision 176)
@@ -0,0 +1,31 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include "dataIO_transportContainer.h"
+#include <osgDB/ObjectWrapper>
+#include <osgDB/InputStream>
+#include <osgDB/OutputStream>
+
+REGISTER_OBJECT_WRAPPER( dataIO_transportContainer,                      // The unique wrapper name
+                         new osgVisual::dataIO_transportContainer,             // The proto
+                         osgVisual::dataIO_transportContainer,                 // The class typename
+						 "osg::Object osgVisual::dataIO_transportContainer" )  // The inheritance relations
+{
+	ADD_INT_SERIALIZER( FrameID, 0 );
+	ADD_MATRIXD_SERIALIZER( ViewMatrix, osg::Matrixd() );
+	ADD_LIST_SERIALIZER( Executer, osgVisual::dataIO_transportContainer::executerList );
+	ADD_LIST_SERIALIZER( IOSlots, osgVisual::dataIO_transportContainer::slotList );
+}
Index: /osgVisual/trunk/src/dataIO/visual_dataIO.cpp
===================================================================
--- /osgVisual/trunk/src/dataIO/visual_dataIO.cpp	(revision 176)
+++ /osgVisual/trunk/src/dataIO/visual_dataIO.cpp	(revision 176)
@@ -0,0 +1,388 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include "visual_dataIO.h"
+
+using namespace osgVisual;
+
+visual_dataIO::visual_dataIO()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "visual_dataIO constructed" << std::endl;
+
+	initialized = false;
+	clusterMode = osgVisual::dataIO_cluster::STANDALONE;
+	// Create Transport-Container:
+	slotContainer = new osgVisual::dataIO_transportContainer();
+}
+
+visual_dataIO::~visual_dataIO()
+{
+	// Delete all slots:
+	for(unsigned int i=0;i<dataSlots.size();i++)
+	{
+		delete dataSlots[i];
+	}
+	dataSlots.clear();
+	
+	OSG_NOTIFY( osg::ALWAYS ) << "visual_dataIO destructed" << std::endl;
+}
+
+visual_dataIO* visual_dataIO::getInstance()
+{
+	static visual_dataIO instance; 
+	return &instance; 
+};
+
+void visual_dataIO::init(osgViewer::Viewer* viewer_, osg::ArgumentParser& arguments_, std::string configFileName)
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "visual_dataIO initialize.." << std::endl;
+
+	// Init variables
+	viewer = viewer_;
+
+	// Process XML configuration
+	this->configFileName = configFileName;
+	if(!processXMLConfiguration())
+		OSG_FATAL << "ERROR: visual_dataIO::init() - Failed to initialize dataIO via XML configuration!";
+
+
+	// Create Cluster.
+	#ifdef USE_CLUSTER_ASIO_TCP_IOSTREAM
+		cluster = new dataIO_clusterAsioTcpIostream();
+	#endif 
+	#ifdef USE_CLUSTER_ENET
+		cluster = new dataIO_clusterENet();
+		cluster->enableHardSync( false );	/** \todo : rebuild this structure in cluster.h and move it this way to a general implementation. */
+	#endif
+	#ifdef USE_CLUSTER_DUMMY
+		cluster = new dataIO_clusterDummy();
+	#endif
+	if(cluster.valid())
+		//cluster->init(arguments_, clusterMode, slotContainer, true, false);
+		cluster->init(arguments_, viewer_, clusterMode, slotContainer, false, false);
+
+	// Create extLink.
+	#ifdef USE_EXTLINK_DUMMY
+		extLink = new dataIO_extLinkDummy( dataSlots );
+	#endif
+	#ifdef USE_EXTLINK_VCL
+		extLink = new dataIO_extLinkVCL( dataSlots );
+	#endif
+	extLink->init();
+
+	
+
+	// Install callbacks to perform DataIO activities every frame:
+	//// EventCallback at the absolute beginning of the frame
+	eventCallback = new dataIO_eventCallback(this);
+	viewer->getCamera()->setEventCallback( eventCallback );
+	//// FinalDrawCallback at the end of event and update handling, but BEFORE rendering the frame
+	finalDrawCallback = new dataIO_finalDrawCallback(this);
+	viewer->getCamera()->setFinalDrawCallback( finalDrawCallback );
+
+	initialized = true;
+}
+
+bool visual_dataIO::processXMLConfiguration()
+{
+	// Init XML
+	xmlDoc* tmpDoc;
+	bool disabled;
+	xmlNode* config = util::getModuleXMLConfig( configFileName, "dataio", tmpDoc, disabled );
+
+	if( disabled)
+		OSG_NOTIFY( osg::ALWAYS ) << "..disabled by XML configuration file. dataIO can't be disabled. Ignoring." << std::endl;
+
+	// extract configuration values
+	if(config)
+	{
+		xmlNode* a_node = config->children;
+
+		for (xmlNode *cur_node = a_node; cur_node; cur_node = cur_node->next)
+		{
+			std::string node_name=reinterpret_cast<const char*>(cur_node->name);
+			//OSG_ALWAYS << "----visual_distortion::processXMLConfiguration() - node type="<< cur_node->type <<", name=" << cur_node->name << std::endl;
+
+			// Check for dataio node
+			if(cur_node->type == XML_ELEMENT_NODE && node_name == "dataio")
+			{
+				// Extract cluster role
+				xmlAttr  *attr = cur_node->properties;
+				while ( attr ) 
+				{ 
+					std::string attr_name=reinterpret_cast<const char*>(attr->name);
+					std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
+					if( attr_name == "clusterrole" )
+					{
+						if(attr_value == "master")
+						{
+							OSG_NOTIFY( osg::ALWAYS ) << "Configure osgVisual as MASTER" << std::endl;
+							clusterMode = osgVisual::dataIO_cluster::MASTER;
+						}
+						else if(attr_value == "slave")
+						{
+							OSG_NOTIFY( osg::ALWAYS ) << "Configure osgVisual as SLAVE" << std::endl;
+							clusterMode = osgVisual::dataIO_cluster::SLAVE;
+							slotContainer = NULL;	// Slave only recieves container, therefor set this Pointer NULL (created instance will be deleted because it is an auto pointer).
+						}
+						else if(attr_value == "standalone")
+						{
+							OSG_NOTIFY( osg::ALWAYS ) << "Configure osgVisual as STANDALONE" << std::endl;
+							clusterMode = osgVisual::dataIO_cluster::STANDALONE;
+						}
+					}
+					attr = attr->next; 
+				}	// WHILE attrib END
+			}
+
+			// Check for cluster node
+			if(cur_node->type == XML_ELEMENT_NODE && node_name == "cluster")
+			{
+				// Check Attributes to determine if the dummy implementation or any other implementation must be instantiated
+
+				// Pass XML attributes to cluster to analyse and configure it by cluster itself
+			}
+
+			// Check for extLink node
+			if(cur_node->type == XML_ELEMENT_NODE && node_name == "extlink")
+			{
+				// Check Attributes to determine if the dummy implementation or any other implementation must be instantiated
+
+				// Pass XML attributes to extlink to analyse and configure it by extLink itself
+			}
+
+		}	// FOR all nodes END
+
+		// clean up
+		xmlFreeDoc(tmpDoc); xmlCleanupParser();
+		return true;
+	}	// IF Config valid END
+	else
+	{
+		OSG_WARN << "ERROR: visual_data::processXMLConfiguration() - Module configuration not found" << std::endl;
+		return false;
+	}
+
+	return true;
+}
+
+void visual_dataIO::shutdown()
+{
+	if(initialized)
+	{
+		OSG_NOTIFY( osg::ALWAYS ) << "Shutdown visual_dataIO..." << std::endl;
+
+		viewer->getCamera()->removeEventCallback( eventCallback );
+		eventCallback = NULL;
+		viewer->getCamera()->setFinalDrawCallback( NULL );
+		finalDrawCallback = NULL;
+		
+		viewer = NULL;
+		
+
+		if(cluster.valid())
+			cluster->shutdown();
+		if(extLink.valid())
+		extLink->shutdown();
+	}
+}
+
+void visual_dataIO::dataIO_eventCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
+{
+	// perform all actions for the eventDrawCallback.
+	OSG_NOTIFY( osg::INFO ) << "---- Executing EventCallback.." <<  std::endl;
+
+	switch( dataIO->clusterMode )
+	{
+		case osgVisual::dataIO_cluster::MASTER : 
+			{
+				dataIO->extLink->readTO_OBJvalues();
+				dataIO->cluster->sendTO_OBJvaluesToSlaves(dataIO->calcViewMatrix());
+			}
+			break;
+		case osgVisual::dataIO_cluster::SLAVE : 
+			{
+				dataIO->cluster->readTO_OBJvaluesFromMaster();
+			}
+			break;
+		case osgVisual::dataIO_cluster::STANDALONE : 
+			{
+				dataIO->extLink->readTO_OBJvalues();
+			}
+			break;
+		default:
+			OSG_NOTIFY( osg::FATAL ) << "ERROR: Unkown clustermode!" <<  std::endl;
+			break;
+	};
+	traverse(node, nv);
+}
+
+void visual_dataIO::dataIO_finalDrawCallback::operator() (const osg::Camera& camera) const
+{
+	// perform all actions for the initialDrawCallback.
+	OSG_NOTIFY( osg::INFO ) << "---- Executing InitialDrawCallback.." << std::endl;
+
+	switch( dataIO->clusterMode )
+	{
+		case osgVisual::dataIO_cluster::MASTER : 
+			{
+				dataIO->extLink->writebackFROM_OBJvalues();
+				dataIO->cluster->waitForAllReadyToSwap();
+				dataIO->cluster->sendSwapCommand();
+			}
+			break;
+		case osgVisual::dataIO_cluster::SLAVE : 
+			{
+				dataIO->cluster->reportAsReadyToSwap();
+				dataIO->cluster->waitForSwap();
+			}
+			break;
+		case osgVisual::dataIO_cluster::STANDALONE : 
+			{
+				dataIO->extLink->writebackFROM_OBJvalues();
+			}
+			break;
+		default:
+			OSG_NOTIFY( osg::FATAL ) << "ERROR: visual_dataIO::dataIO_finalDrawCallback::operator() - Unkown clustermode!" <<  std::endl;
+			break;
+	};
+}
+
+void* visual_dataIO::getSlotPointer(std::string variableName_, osgVisual::dataIO_slot::dataDirection direction_, osgVisual::dataIO_slot::varType variableTyp_ )
+{
+	// iterate through slotlist. If found, return pointer, else add slot to list and return pointer
+	for (unsigned int i=0; i<dataSlots.size(); i++)
+	{
+		// Check if this variable name&-type already exists
+		if( dataSlots[i]->variableName == variableName_ && dataSlots[i]->direction == direction_  && dataSlots[i]->variableType ==  variableTyp_)
+		{
+			//OSG_NOTIFY( osg::INFO ) << "visual_dataIO::getSlotPointer() - Slot found at position " << i << std::endl;
+			// Return pointer to the value
+			return dataSlots[i];
+		}
+	}
+
+	// Slot does not exist -> add it to slot list
+	//OSG_NOTIFY( osg::INFO ) << "visual_dataIO::getSlotPointer() - Slot not found, will add as new slot " << std::endl;
+	dataIO_slot* newSlot = new dataIO_slot();
+	newSlot->variableName = variableName_;
+	newSlot->variableType = variableTyp_;
+	newSlot->value = 0;
+	newSlot->sValue = "";
+	dataSlots.push_back( newSlot );
+	return dataSlots.back();
+}
+
+double visual_dataIO::getSlotDataAsDouble(std::string variableName_, osgVisual::dataIO_slot::dataDirection direction_ )
+{
+	// iterate through slotlist. If found, return value
+	for (unsigned int i=0; i<dataSlots.size(); i++)
+	{
+		// Check if this variable name&-type already exists
+		if( dataSlots[i]->variableName == variableName_ && dataSlots[i]->direction == direction_  && dataSlots[i]->variableType == osgVisual::dataIO_slot::DOUBLE )
+		{
+			//OSG_NOTIFY( osg::INFO ) << "visual_dataIO::getSlotDataAsDouble() - Slot found at position " << i << std::endl;
+			return dataSlots[i]->value;
+		}
+	}
+	return 0;
+}
+
+std::string visual_dataIO::getSlotDataAsString(std::string variableName_, osgVisual::dataIO_slot::dataDirection direction_ )
+{
+	// iterate through slotlist. If found, return value
+	for (unsigned int i=0; i<dataSlots.size(); i++)
+	{
+		// Check if this variable name&-type already exists
+		if( dataSlots[i]->variableName == variableName_ && dataSlots[i]->direction == direction_  && dataSlots[i]->variableType == osgVisual::dataIO_slot::STRING )
+		{
+			//OSG_NOTIFY( osg::INFO ) << "visual_dataIO::getSlotDataAsDouble() - Slot found at position " << i << std::endl;
+			return dataSlots[i]->sValue;
+		}
+	}
+	return "";
+}
+
+osgVisual::dataIO_slot* visual_dataIO::setSlotData(std::string variableName_, osgVisual::dataIO_slot::dataDirection direction_, std::string sValue_ )
+{
+	bool slotFound = false;
+	// iterate through slotlist. If found, return pointer, else add slot to list
+	for (unsigned int i=0; i<dataSlots.size(); i++)
+	{
+		// Check if this variable name&-type already exists
+		if( dataSlots[i]->variableName == variableName_ && dataSlots[i]->direction == direction_ && dataSlots[i]->variableType ==  osgVisual::dataIO_slot::STRING)
+		{
+			// Update value
+			dataSlots[i]->sValue = sValue_;
+			slotFound = true;
+			return dataSlots[i];
+		}
+		
+	}
+
+	if (!slotFound)
+	{
+		// Slot does not exist -> add it to slot list
+		dataIO_slot* newSlot = new dataIO_slot();
+		newSlot->variableName = variableName_;
+		newSlot->direction = direction_;
+		newSlot->variableType = osgVisual::dataIO_slot::STRING;
+		newSlot->value = 0;
+		newSlot->sValue = sValue_;
+		dataSlots.push_back( newSlot );
+		return dataSlots.back();
+	}
+
+	return NULL;
+}
+
+osgVisual::dataIO_slot* visual_dataIO::setSlotData(std::string variableName_, osgVisual::dataIO_slot::dataDirection direction_, double value_ )
+{
+	// iterate through slotlist. If found, return pointer, else add slot to list
+	bool slotFound = false;
+	for (unsigned int i=0; i<dataSlots.size(); i++)
+	{
+		// Check if this variableName & -type already exists
+		if( dataSlots[i]->variableName == variableName_ && dataSlots[i]->direction == direction_ && dataSlots[i]->variableType ==  osgVisual::dataIO_slot::DOUBLE)
+		{
+			// Update value
+			//OSG_NOTIFY( osg::ALWAYS ) << "setSlotData: " << variableName_ << " - value: " << value_ << std::endl;
+			dataSlots[i]->value = value_;
+			slotFound = true;
+			return dataSlots[i];
+		}	
+	}
+
+	if (!slotFound)
+	{
+		// Slot does not exist -> add it to slot list
+		dataIO_slot* newSlot = new dataIO_slot();
+		newSlot->variableName = variableName_;
+		newSlot->direction = direction_;
+		newSlot->variableType = osgVisual::dataIO_slot::DOUBLE;
+		newSlot->value = value_;
+		newSlot->sValue = "";
+		dataSlots.push_back( newSlot );
+		return dataSlots.back();
+	}
+
+	return NULL;
+}
+
+osg::Matrixd visual_dataIO::calcViewMatrix()
+{
+	return viewer->getCameraManipulator()->getInverseMatrix();
+}
Index: /osgVisual/trunk/src/distortion/visual_distortion.cpp
===================================================================
--- /osgVisual/trunk/src/distortion/visual_distortion.cpp	(revision 176)
+++ /osgVisual/trunk/src/distortion/visual_distortion.cpp	(revision 176)
@@ -0,0 +1,547 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <visual_distortion.h>
+
+using namespace osgVisual;
+
+visual_distortion::visual_distortion(osgViewer::Viewer* viewer_, osg::ArgumentParser& arguments_, std::string configFileName) : viewer(viewer_), arguments(arguments_)
+{
+	OSG_NOTIFY (osg::ALWAYS ) << "visual_distortion instantiated." << std::endl;
+
+	this->configFileName = configFileName;
+	initialized = false;
+	distortionEnabled = false;
+	parser = new CameraConfigParser();
+
+	distortedGraph = NULL;
+	cleanGraph = NULL;
+
+	distortMapTexture = NULL;
+	blendMapTexture = NULL;
+}
+
+visual_distortion::~visual_distortion(void)
+{
+	OSG_NOTIFY (osg::ALWAYS ) << "visual_distortion destroyed." << std::endl;
+}
+
+bool visual_distortion::processXMLConfiguration()
+{
+	// Init XML
+	xmlDoc* tmpDoc;
+	bool disabled;
+	xmlNode* config = util::getModuleXMLConfig( configFileName, "distortion", tmpDoc, disabled );
+
+	if( disabled)
+	{
+		OSG_NOTIFY( osg::ALWAYS ) << "..disabled by XML configuration file." << std::endl;
+		return false;
+	}
+	
+	// extract configuration values
+	if(config)
+	{
+		OSG_NOTIFY( osg::ALWAYS ) << "..using distortion." << std::endl;
+
+		xmlNode* a_node = config->children;
+
+		for (xmlNode *cur_node = a_node; cur_node; cur_node = cur_node->next)
+		{
+			std::string node_name=reinterpret_cast<const char*>(cur_node->name);
+			//OSG_ALWAYS << "----visual_distortion::processXMLConfiguration() - node type="<< cur_node->type <<", name=" << cur_node->name << std::endl;
+
+			// Check for distortion node
+			if(cur_node->type == XML_ELEMENT_NODE && node_name == "distortion")
+			{
+				xmlAttr  *attr = cur_node->properties;
+				while ( attr ) 
+				{ 
+					std::string attr_name=reinterpret_cast<const char*>(attr->name);
+					std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
+					if( attr_name == "channelname" )
+					{
+						std::string  channelname = attr_value;
+						OSG_NOTIFY(osg::ALWAYS) << "visual_distortion: Channelname:" << channelname << std::endl;
+
+						std::string pre_cfg("..\\resources\\distortion\\view_");
+						std::string pre_distortion("..\\resources\\distortion\\distort_");
+						std::string pre_blend("..\\resources\\distortion\\blend_");
+						std::string post_cfg(".cfg");
+						std::string post_distortion(".bmp");
+						std::string post_blend(".bmp");
+
+						// load channel config
+						parser->parseConfigFile((pre_cfg+channelname+post_cfg).data());
+						// load channel blendmap
+						blendMapFileName = (pre_blend+channelname+post_blend).data();
+						// load channel distortionmap
+						distortMapFileName = (pre_distortion+channelname+post_distortion).data(); 
+						// set channel frustum
+						if( parser->isConfigParsed())
+ 							viewer->getCamera()->setProjectionMatrixAsFrustum((parser->getFrustumDataset())[0], (parser->getFrustumDataset())[1], (parser->getFrustumDataset())[2], (parser->getFrustumDataset())[3], (parser->getFrustumDataset())[4], (parser->getFrustumDataset())[5]);
+						else
+							OSG_NOTIFY(osg::WARN) << "WARNING: Unable to parse Frustum values from '" << pre_cfg<<channelname<<post_cfg << "' -- continue without valid frustum values." << std::endl;
+					}
+					if( attr_name == "renderimplemmentation" )
+					{
+						if(attr_value=="fbo")
+							renderImplementation = osg::Camera::FRAME_BUFFER_OBJECT;
+						if(attr_value=="pbuffer")
+							renderImplementation = osg::Camera::PIXEL_BUFFER;
+						if(attr_value=="pbuffer-rtt")
+							renderImplementation = osg::Camera::PIXEL_BUFFER_RTT;
+						if(attr_value=="fb")
+							renderImplementation = osg::Camera::FRAME_BUFFER;
+						if(attr_value=="window")
+							renderImplementation = osg::Camera::SEPERATE_WINDOW;           
+					}
+					if( attr_name == "width" )
+					{
+						std::stringstream sstr(attr_value);
+						sstr >> tex_width;
+					}
+					if( attr_name == "height" )
+					{
+						std::stringstream sstr(attr_value);
+						sstr >> tex_height;
+					}
+					if( attr_name == "useshader" )
+						useShaderDistortion = (attr_value == "yes") ? true : false;
+					if( attr_name == "hdr" )
+						useHDR = (attr_value == "yes") ? true : false;
+					if( attr_name == "usetexturerectangle" )
+						useTextureRectangle = (attr_value == "yes") ? true : false;
+
+
+					attr = attr->next; 
+				}	// WHILE attrib END
+			}	// IF Node == distortion END
+
+			// Check for distortionmap node
+			if(cur_node->type == XML_ELEMENT_NODE && node_name == "distortionmap")
+			{
+				xmlAttr  *attr = cur_node->properties;
+				while ( attr ) 
+				{ 
+					std::string attr_name=reinterpret_cast<const char*>(attr->name);
+					std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
+					if( attr_name == "filename" )
+					{
+						distortMapFileName = attr_value;
+					}
+					attr = attr->next; 
+				}
+			}
+
+			// Check for distortionmap node
+			if(cur_node->type == XML_ELEMENT_NODE && node_name == "blendmap")
+			{
+				xmlAttr  *attr = cur_node->properties;
+				while ( attr ) 
+				{ 
+					std::string attr_name=reinterpret_cast<const char*>(attr->name);
+					std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
+					if( attr_name == "filename" )
+					{
+						blendMapFileName = attr_value;
+					}
+					attr = attr->next; 
+				}
+			}
+		}	// FOR all nodes END
+
+		// clean up
+		xmlFreeDoc(tmpDoc); xmlCleanupParser();
+		return true;
+	}	// IF Config valid END
+	else
+	{
+		OSG_WARN << "ERROR: visual_distortion::processXMLConfiguration() - Module configuration not found" << std::endl;
+		return false;
+	}
+
+	return true;
+}
+
+osg::Group* visual_distortion::initialize(osg::Group* subgraph, const osg::Vec4& clearColor )
+{
+	OSG_NOTIFY (osg::ALWAYS ) << "visual_distortion initialize..";  // The sentence is finished by the init result...
+
+	// Initialize variables:
+	tex_width = 2048;
+    tex_height = 2048;
+	renderImplementation = osg::Camera::FRAME_BUFFER_OBJECT;
+	useTextureRectangle = false;
+	useShaderDistortion = false;
+	useHDR = false; 
+	distortMapFileName = "..\\resources\\distortion\\distort_distDisabled.bmp";
+	blendMapFileName = "..\\resources\\distortion\\blend_distDisabled.bmp";
+
+	// Process XML configuration
+	if(!processXMLConfiguration())
+		return NULL;	// Abort distortion initialization.
+
+	// Add this node to the scenegraph to get updated during update traversal.
+	subgraph->addChild( this );
+
+	// add the keyboard handler for toggle distortion
+	arguments.getApplicationUsage()->addKeyboardMouseBinding("d", "Toggle Distortion.");
+	kBEventHandler = new ToggleDistortionKBEventHandler( this );
+	viewer->addEventHandler( kBEventHandler );
+
+	cleanGraph = subgraph;
+	distortedGraph = createPreRenderSubGraph( subgraph, clearColor );
+
+	// Create and install updateCallback (to get called for copying the main cameras view matrixes to the PRE_RENDER camera)
+	// -- must be called _AFTER_ createPreRenderSubGraph() (necessary because sceneCamera is set by createPreRenderSubGraph())
+	updateCallback = new distortionUpdateCallback( viewer, sceneCamera );
+	this->setUpdateCallback( updateCallback );
+
+	// Note down state flags..
+	initialized = true;
+	distortionEnabled = true;
+
+	distortionEnabled = true;
+	viewer->setSceneData( distortedGraph );
+	
+	return distortedGraph;
+}
+
+void visual_distortion::shutdown()
+{
+	if(initialized)
+	{
+		// Remove this Node from scenegraph
+		cleanGraph->removeChild( this );
+
+		// Remove update callback
+		this->removeUpdateCallback( updateCallback );
+		updateCallback = NULL;
+
+		OSG_NOTIFY (osg::ALWAYS ) << "visual_distortion shutdown complete." << std::endl;
+	}
+}
+
+void visual_distortion::distortionUpdateCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
+{
+	// Copy Main Camera's matrixes to the PRE_RENDER Camera.
+	//std::cout << "distortion updatecallback" << std::endl;
+	sceneCamera->setViewMatrix( viewer->getCamera()->getViewMatrix() );
+	sceneCamera->setProjectionMatrix( viewer->getCamera()->getProjectionMatrix() );
+}
+
+void visual_distortion::toggleDistortion()
+{
+	// Toggle
+	//// If not Distorted: enabled distortion
+	if( !distortionEnabled )
+	{
+		distortionEnabled = true;
+		viewer->setSceneData( distortedGraph );
+	}
+	else	// .. otherwise disable distortion
+	{
+		distortionEnabled = false;
+		viewer->setSceneData( cleanGraph );
+	}
+}
+
+
+osg::Group* visual_distortion::createPreRenderSubGraph(osg::Group* subgraph, const osg::Vec4& clearColor )
+{
+    if (!subgraph) return 0;
+
+    // create a group to contain the flag and the pre rendering camera.
+    osg::Group* parent = new osg::Group;
+
+    // texture to render to and to use for rendering of flag.
+    osg::Texture* texture = 0;
+    if (useTextureRectangle)
+    {
+        osg::TextureRectangle* textureRect = new osg::TextureRectangle;
+        textureRect->setTextureSize(tex_width, tex_height);
+        textureRect->setInternalFormat(GL_RGBA);
+        textureRect->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
+        textureRect->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
+        
+        texture = textureRect;
+    }
+    else
+    {
+        osg::Texture2D* texture2D = new osg::Texture2D;
+        texture2D->setTextureSize(tex_width, tex_height);
+        texture2D->setInternalFormat(GL_RGBA);
+        texture2D->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
+        texture2D->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
+        
+        texture = texture2D;
+    } 
+
+    if (useHDR)
+    {
+        texture->setInternalFormat(GL_RGBA16F_ARB);
+        texture->setSourceFormat(GL_RGBA);
+        texture->setSourceType(GL_FLOAT);
+    }
+
+    // load a distortion map texture file
+	if ( osgDB::fileExists( distortMapFileName ) )
+		distortMapTexture = loadTexture(distortMapFileName);
+	else
+	{
+		OSG_NOTIFY(osg::FATAL) << "ERROR: Distortionmap file'" << distortMapFileName << "' not found! Please change the channelname, filename or copy the desired file to the applications root folder!" << std::endl;
+		exit(-1);
+	}
+
+    // load a blend map texture file
+	if ( osgDB::fileExists( blendMapFileName ) )
+		blendMapTexture = loadTexture(blendMapFileName);
+	else
+	{
+		OSG_NOTIFY(osg::FATAL) << "ERROR: Blendmap file'" << blendMapFileName << "' not found! Please change the channelname, filename or copy the desired file to the applications root folder!" << std::endl;
+		exit(-1);
+	}
+
+    // set up the plane to render the rendered view.
+    {
+        // create the quad to visualize.
+        osg::Geometry* polyGeom = new osg::Geometry();
+
+        polyGeom->setSupportsDisplayList(false);
+
+        osg::Vec3 origin(0.0f,0.0f,0.0f);
+        osg::Vec3 xAxis(1.0f,0.0f,0.0f);
+        osg::Vec3 yAxis(0.0f,1.0f,0.0f);
+        osg::Vec3 zAxis(0.0f,0.0f,1.0f);
+        float height = 1024.0f;
+        float width = 1280.0f;
+        int noSteps = 128;
+        if (useShaderDistortion)
+            noSteps = 2;
+
+        osg::Vec3Array* vertices = new osg::Vec3Array;
+        osg::Vec2Array* texcoords = new osg::Vec2Array;
+        osg::Vec2Array* texcoords2 = useShaderDistortion?NULL:(new osg::Vec2Array);
+        osg::Vec4Array* colors = new osg::Vec4Array;
+
+        osg::Vec3 bottom = origin;
+        osg::Vec3 dx = xAxis*(width/((float)(noSteps-1)));
+        osg::Vec3 dy = yAxis*(height/((float)(noSteps-1)));
+
+        osg::Vec2 bottom_texcoord(0.0f,0.0f);
+        osg::Vec2 dx_texcoord(1.0f/(float)(noSteps-1),0.0f);
+        osg::Vec2 dy_texcoord(0.0f,1.0f/(float)(noSteps-1));
+
+        osg::Vec3 cursor = bottom;
+        osg::Vec2 texcoord = bottom_texcoord;
+        int i,j;
+        for(i=0;i<noSteps;++i)
+        {
+            osg::Vec3 cursor = bottom+dy*(float)i;
+            osg::Vec2 texcoord = bottom_texcoord+dy_texcoord*(float)i;
+            for(j=0;j<noSteps;++j)
+            {
+                vertices->push_back(cursor);
+                if (distortMapTexture && !useShaderDistortion)
+                {
+                    osg::Vec2 imgcoord = osg::Vec2((distortMapTexture->getImage(0)->s()-1) * texcoord.x(),
+                                                   (distortMapTexture->getImage(0)->t()-1) * texcoord.y());
+                    unsigned char* pPixel = &distortMapTexture->getImage(0)->data()[(int)imgcoord.y()*distortMapTexture->getImage(0)->getRowSizeInBytes()+
+                                                                                    (int)imgcoord.x()*distortMapTexture->getImage(0)->getPixelSizeInBits()/8];
+                    texcoords->push_back(osg::Vec2(((float)pPixel[2] / 255.0f + (pPixel[0] % 16)) / 16.0f,
+                                                   1.0f - ((float)pPixel[1] / 255.0f + (pPixel[0] / 16)) / 16.0f));
+                    texcoords2->push_back(osg::Vec2(texcoord.x(), texcoord.y()));
+                }
+                else
+                    texcoords->push_back(osg::Vec2(texcoord.x(), texcoord.y()));
+                colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
+
+                cursor += dx;
+                texcoord += dx_texcoord;
+            }
+        }
+
+        // pass the created vertex array to the points geometry object.
+        polyGeom->setVertexArray(vertices);
+
+        polyGeom->setColorArray(colors);
+        polyGeom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
+        polyGeom->setTexCoordArray(0,texcoords);
+        if (!useShaderDistortion)
+            polyGeom->setTexCoordArray(2,texcoords2);
+
+        for(i=0;i<noSteps-1;++i)
+        {
+            osg::DrawElementsUShort* elements = new osg::DrawElementsUShort(osg::PrimitiveSet::QUAD_STRIP);
+            for(j=0;j<noSteps;++j)
+            {
+                elements->push_back(j+(i+1)*noSteps);
+                elements->push_back(j+(i)*noSteps);
+            }
+            polyGeom->addPrimitiveSet(elements);
+        }
+
+        // new we need to add the texture to the Drawable, we do so by creating a 
+        // StateSet to contain the Texture StateAttribute.
+        osg::StateSet* stateset = polyGeom->getOrCreateStateSet();
+        stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
+        stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
+        stateset->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
+
+        osg::Geode* geode = new osg::Geode();
+        geode->addDrawable(polyGeom);
+
+        if (useShaderDistortion)
+        {
+            // apply the distortion map texture
+            if (distortMapTexture)
+                geode->getOrCreateStateSet()->setTextureAttributeAndModes(1, distortMapTexture, osg::StateAttribute::ON);
+        }
+
+        // apply the blend map texture
+        if (blendMapTexture)
+            geode->getOrCreateStateSet()->setTextureAttributeAndModes(2, blendMapTexture, osg::StateAttribute::ON);
+
+        // set up the camera to render the textured quad
+        osg::Camera* camera = new osg::Camera;
+
+        // just inherit the main cameras view
+        camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
+        camera->setViewMatrix(osg::Matrix::identity());
+        //sceneCamera->setProjectionMatrixAsOrtho2D(0,viewer->getCamera()->getViewport()->width(),0,viewer->getCamera()->getViewport()->height());
+		camera->setProjectionMatrixAsOrtho2D(0,1280,0,1024);
+		/** \todo: use screen size dynamically */
+
+        // set the camera to render before the main camera.
+        camera->setRenderOrder(osg::Camera::POST_RENDER, 200);
+
+        // only clear the depth buffer
+        camera->setClearMask(0);
+
+        // add subgraph to render
+        camera->addChild(geode);
+
+        if (useShaderDistortion)
+        {
+            // create shaders for distortion
+            osg::StateSet* ss = geode->getOrCreateStateSet();
+
+            osg::Program* distortProgram = new osg::Program;
+            distortProgram->setName( "distortion" );
+            osg::Shader* distortVertObj = new osg::Shader( osg::Shader::VERTEX );
+            osg::Shader* distortFragObj = new osg::Shader( osg::Shader::FRAGMENT );
+
+            if (loadShaderSource( distortVertObj, "../resources/distortion/shader.vert" ) &&
+                loadShaderSource( distortFragObj, "../resources/distortion/shader.frag" ) &&
+                distortMapTexture)
+            {
+                distortProgram->addShader( distortFragObj );
+                distortProgram->addShader( distortVertObj );
+                ss->addUniform( new osg::Uniform("textureImage", 0) );
+                ss->addUniform( new osg::Uniform("textureDistort", 1) );
+                ss->addUniform( new osg::Uniform("textureBlend", 2) );
+                ss->setAttributeAndModes(distortProgram, osg::StateAttribute::ON);
+            }
+			else
+			{
+				OSG_NOTIFY(osg::FATAL) << "##################################" << std::endl << "## Unable to activate ShaderDistortion!" << std::endl << "## ABORT" << std::endl << "##################################" << std::endl;
+				exit(0);
+			}
+        }
+
+        parent->addChild(camera);
+    }
+
+    // then create the camera node to do the render to texture
+    {    
+        osg::Camera* camera = new osg::Camera;
+
+        // set up the background color and clear mask.
+        camera->setClearColor(clearColor);
+        camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+
+        // just inherit the main cameras view
+		/* ABSOLUTE_RF required to make intersections possible.
+		Disadvantage of ABOLUTE_RF : the maincameras view matrix and projection
+		matrix has to copied to the PRE_RENDER camera by our self.
+		Therefore an update callback is installed.
+		*/
+		camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);	
+        camera->setProjectionMatrix(osg::Matrixd::identity());
+        camera->setViewMatrix(osg::Matrixd::identity());
+
+        // set viewport
+        camera->setViewport(0,0,tex_width,tex_height);
+
+        // set the camera to render before the main camera.
+        camera->setRenderOrder(osg::Camera::PRE_RENDER, 0);
+
+		sceneCamera = camera;
+
+        // tell the camera to use OpenGL frame buffer object where supported.
+        camera->setRenderTargetImplementation(renderImplementation);
+
+        // attach the texture and use it as the color buffer.
+        camera->attach(osg::Camera::COLOR_BUFFER, texture);	// No Multisampling/Antialiasing
+		//camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, 0, false, 4, 4); // 4x Multisampling/Antialiasing
+
+        // add subgraph to render
+        camera->addChild(subgraph);
+
+        parent->addChild(camera);
+    }    
+    return parent;
+}
+
+
+bool visual_distortion::loadShaderSource( osg::Shader* shader, const std::string& fileName )
+{
+    std::string foundFileName = osgDB::findDataFile(fileName);
+    if (foundFileName.length() != 0 )
+    {
+        return shader->loadShaderSourceFromFile( foundFileName.c_str() );
+    }
+
+    OSG_NOTIFY(osg::WARN) << "File \"" << fileName << "\" not found." << std::endl;
+
+    return false;
+}
+
+osg::Texture* visual_distortion::loadTexture( const std::string& fileName )
+{
+    std::string foundFileName = osgDB::findDataFile(fileName);
+    if (foundFileName.length() != 0 )
+    {
+        // load distortion map texture file
+        osg::Image* image = osgDB::readImageFile(foundFileName);
+        if (image)
+        {
+			osg::Texture2D* texture = new osg::Texture2D;
+            texture->setImage(image);
+            texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST);
+            texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST);
+            texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE);
+            texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE);
+            return texture;
+        }
+    }
+
+    OSG_NOTIFY(osg::WARN) << "File \"" << fileName << "\" not found." << std::endl;
+
+    return NULL;
+}
Index: /osgVisual/trunk/src/draw2D/visual_debug_hud.cpp
===================================================================
--- /osgVisual/trunk/src/draw2D/visual_debug_hud.cpp	(revision 176)
+++ /osgVisual/trunk/src/draw2D/visual_debug_hud.cpp	(revision 176)
@@ -0,0 +1,177 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <visual_debug_hud.h>
+
+using namespace osgVisual;
+
+visual_debug_hud::visual_debug_hud(void)
+{
+}
+
+visual_debug_hud::~visual_debug_hud(void)
+{
+}
+
+bool visual_debug_hud::init( osgViewer::Viewer *viewer_, osg::CoordinateSystemNode* rootNode_  )
+{	
+
+
+
+    screen_width = viewer_->getCamera()->getViewport()->width();
+    screen_height = viewer_->getCamera()->getViewport()->height();
+   	
+	visual_draw2D::getInstance()->addDrawContent( addContent(), "HUD" );
+
+	// Set callback.
+	updateCallback = new HudUpdateCallback( rootNode_, viewer_->getCamera() );
+	this->setEventCallback( updateCallback );
+
+	isInitialized = true;
+
+	return true;
+}
+
+void visual_debug_hud::shutdown()
+{
+	if (isInitialized)
+	{	
+		// Remove Draw Content 
+		visual_draw2D::getInstance()->removeDrawContent("HUD");
+
+		// Remove updatecallback
+		this->removeEventCallback( updateCallback );
+		updateCallback = NULL;
+	}
+}
+
+osg::ref_ptr<osg::Geode> visual_debug_hud::addContent()
+{
+	osg::ref_ptr<osg::Geode> hudGeode = this;
+
+	// turn lighting off
+	osg::ref_ptr<osg::StateSet> stateset = hudGeode->getOrCreateStateSet();
+    stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
+
+
+    
+	// Add Text: 
+	osg::Vec3 position(screen_width-180.0f,120.0f,0.0f);
+	osg::Vec3 delta(0.0f,-25.0f,0.0f);
+	std::string timesFont("fonts/arial.ttf");
+	{
+		textLat = new osgText::Text;
+		hudGeode->addDrawable( textLat );
+		textLat->setFont(timesFont);
+		textLat->setPosition(position);
+		textLat->setCharacterSize(21);
+		textLat->setDataVariance(osg::Object::DYNAMIC); 
+
+		position += delta;
+
+		textLon = new osgText::Text;
+		hudGeode->addDrawable( textLon );
+		textLon->setFont(timesFont);
+		textLon->setPosition(position);
+		textLon->setCharacterSize(21);
+		textLon->setDataVariance(osg::Object::DYNAMIC); 
+
+		position += delta;
+
+		textAlt = new osgText::Text;
+		hudGeode->addDrawable( textAlt );
+		textAlt->setFont(timesFont);
+		textAlt->setPosition(position);
+		textAlt->setCharacterSize(21);
+		textAlt->setDataVariance(osg::Object::DYNAMIC); 
+
+		position += delta;
+
+		textHat = new osgText::Text;
+		hudGeode->addDrawable( textHat );
+		textHat->setFont(timesFont);
+		textHat->setPosition(position);
+		textHat->setCharacterSize(21);
+		textHat->setDataVariance(osg::Object::DYNAMIC); 
+
+		position += delta;
+
+		textHot = new osgText::Text;
+		hudGeode->addDrawable( textHot );
+		textHot->setFont(timesFont);
+		textHot->setPosition(position);
+		textHot->setCharacterSize(21);
+		textHot->setDataVariance(osg::Object::DYNAMIC); 
+
+		position += delta;
+	}
+
+	return hudGeode.get();
+}
+
+void visual_debug_hud::HudUpdateCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
+{
+	visual_debug_hud* hud = dynamic_cast<visual_debug_hud*>(node);
+	if ( !hud )
+	{
+		OSG_NOTIFY(osg::FATAL) << "ERROR : No object found. Unable to apply this callback!" << std::endl;
+		return;
+	}
+
+	// Retrieving new HUD values
+
+	double lat = 0;
+	double lon = 0;
+	double hat = 0;
+	double hot = 0;
+	double alt = 0;
+
+	util::getWGS84ofCamera( sceneCamera, csn, lat, lon, alt ); 
+	util::queryHeightAboveTerrainInWGS84(hat, csn, lat, lon, alt);
+	util::queryHeightOfTerrain(hot, csn, lat, lon);
+
+
+	// Updating Display Elements:
+	std::ostringstream valuestring;
+	
+	valuestring.str("");
+	valuestring << osg::RadiansToDegrees( lat );
+	hud->textLat->setText("LAT: "+valuestring.str());
+
+	valuestring.str("");
+	valuestring << osg::RadiansToDegrees( lon );
+	hud->textLon->setText("LON: "+valuestring.str());
+
+	valuestring << std::fixed;
+	valuestring.precision(2);
+	valuestring.fill('0');
+
+	valuestring.width(8);
+	valuestring.str("");
+	valuestring << alt;
+	hud->textAlt->setText("ALT: "+valuestring.str());
+
+
+	valuestring.width(8);
+	valuestring.str("");
+	valuestring << hat;
+	hud->textHat->setText("HAT: "+valuestring.str());
+
+	valuestring.width(8);
+	valuestring.str("");
+	valuestring << hot;
+	hud->textHot->setText("HOT: "+valuestring.str());
+}
Index: /osgVisual/trunk/src/draw2D/visual_draw2D.cpp
===================================================================
--- /osgVisual/trunk/src/draw2D/visual_draw2D.cpp	(revision 176)
+++ /osgVisual/trunk/src/draw2D/visual_draw2D.cpp	(revision 176)
@@ -0,0 +1,142 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <visual_draw2D.h>
+
+using namespace osgVisual;
+
+visual_draw2D::visual_draw2D(void)
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "visual_draw2D constructed" << std::endl;
+	initialized = false;
+}
+
+visual_draw2D::~visual_draw2D(void)
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "visual_draw2D destroyed: " << std::endl;
+}
+
+visual_draw2D* visual_draw2D::getInstance()
+{
+	static visual_draw2D instance; 
+	return &instance; 
+};
+
+bool visual_draw2D::init( osg::CoordinateSystemNode *sceneGraphRoot_, osgViewer::Viewer *viewer_ )
+{
+    screen_width = viewer_->getCamera()->getViewport()->width();
+    screen_height = viewer_->getCamera()->getViewport()->height();
+ 
+   // Projection node for defining view frustrum for the HUD:
+	draw2DProjectionMatrix = new osg::Projection;
+
+   // Initialize the projection matrix for viewing everything we
+   // will add as descendants of this node. Use screen coordinates
+   // to define the horizontal and vertical extent of the projection
+   // matrix. Positions described under this node will equate to
+   // pixel coordinates.
+   draw2DProjectionMatrix->setMatrix(osg::Matrix::ortho2D(0,screen_width,0,screen_height));
+
+   // For the HUD model view matrix use an identity matrix:
+   draw2DModelViewMatrix = new osg::MatrixTransform;
+   draw2DModelViewMatrix->setMatrix(osg::Matrix::identity());
+
+   // Make sure the model view matrix is not affected by any transforms
+   // above it in the scene graph:
+   draw2DModelViewMatrix->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
+   
+
+   // Add the HUD projection matrix as a child of the root node
+   // and the HUD model view matrix as a child of the projection matrix
+   // Anything under this node will be viewed using this projection matrix
+   // and positioned with this model view matrix.
+   draw2DProjectionMatrix->addChild(draw2DModelViewMatrix);
+   sceneGraphRoot_->addChild( draw2DProjectionMatrix );
+
+   initialized = true;
+   return true;
+}
+
+void visual_draw2D::shutdown()
+{
+	if (!initialized)
+		return;
+
+	// Remove all Drawcontens
+	removeAllDrawContents();
+
+	// Remove Projectionmatrix
+	draw2DProjectionMatrix->removeChild( draw2DModelViewMatrix );
+	draw2DProjectionMatrix = NULL;
+
+	initialized = false;
+}
+
+bool visual_draw2D::addDrawContent( osg::Geode* content_, std::string name_,int renderBinDetail_ )
+{
+	if (!initialized)
+		return false;
+
+	// Add the Geometry node to contain HUD geometry as a child of the
+    // HUD model view matrix.
+	draw2DModelViewMatrix->addChild( content_ );
+	content_->setName( name_ );
+	
+	osg::StateSet* stateSet = content_->getOrCreateStateSet();
+	stateSet->setRenderBinDetails( renderBinDetail_, "RenderBin");
+	// disable depth test to ensure that it is always drawn.
+	stateSet->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
+
+	return true;
+}
+
+osg::Geode* visual_draw2D::getDrawContent( std::string name_ )
+{
+	osg::Node* tmp = util::findNamedNode(name_, draw2DModelViewMatrix);
+	if(tmp)
+	{
+		osg::Geode* tmp2 = tmp->asGeode();
+		if (tmp2)
+			return tmp2;
+		else
+			return NULL;
+	}
+	else 
+		return NULL;
+}
+
+bool visual_draw2D::removeDrawContent( std::string name_ )
+{
+	osg::Node* tmp = util::findNamedNode(name_, draw2DModelViewMatrix);
+	if(tmp)
+	{
+		draw2DModelViewMatrix->removeChild( tmp );
+		return true;
+	}
+	else
+		return false;
+}
+	
+void visual_draw2D::removeAllDrawContents()
+{
+	if (getDrawContentNum() > 0)
+		draw2DModelViewMatrix->removeChildren(0, getDrawContentNum() );
+}
+
+int visual_draw2D::getDrawContentNum()
+{
+	return draw2DModelViewMatrix->getNumChildren();
+}
Index: /osgVisual/trunk/src/draw2D/visual_hud.cpp
===================================================================
--- /osgVisual/trunk/src/draw2D/visual_hud.cpp	(revision 176)
+++ /osgVisual/trunk/src/draw2D/visual_hud.cpp	(revision 176)
@@ -0,0 +1,106 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <visual_hud.h>
+
+using namespace osgVisual;
+
+visual_hud::visual_hud(void)
+{
+}
+
+visual_hud::~visual_hud(void)
+{
+}
+
+bool visual_hud::init( osgViewer::Viewer *viewer_ )
+{	
+    screen_width = viewer_->getCamera()->getViewport()->width();
+    screen_height = viewer_->getCamera()->getViewport()->height();
+   	
+	visual_draw2D::getInstance()->addDrawContent( addContent(), "HUD" );
+
+	return true;
+}
+
+osg::ref_ptr<osg::Geode> visual_hud::addContent()
+{
+	osg::ref_ptr<osg::Geode> hudGeode = this;
+
+	// turn lighting off
+    osg::StateSet* stateset = hudGeode->getOrCreateStateSet();
+    stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
+
+    // create background
+	{
+		// configuring background shape
+		float depth = -0.1; // Paint background behind text. 
+		osg::Vec4f bgColor_rgba = osg::Vec4(1.0f,1.0,0.8f,0.2f);
+		osg::Vec3 hudCenter = osg::Vec3((float)(screen_width/2), (float)(screen_height/2), 0.0);
+		float baseSize = 200;
+		float addSize = 70;
+
+
+		osg::Geometry* hudBackground = new osg::Geometry;
+
+		osg::Vec3Array* vertices = new osg::Vec3Array;
+		vertices->push_back(hudCenter+osg::Vec3(baseSize+addSize, baseSize, depth));
+		vertices->push_back(hudCenter+osg::Vec3(baseSize, baseSize+addSize, depth));
+		vertices->push_back(hudCenter+osg::Vec3(-baseSize , baseSize+addSize, depth));
+		vertices->push_back(hudCenter+osg::Vec3(-baseSize-addSize, baseSize,depth));
+		vertices->push_back(hudCenter+osg::Vec3(-baseSize-addSize, -baseSize,depth));
+		vertices->push_back(hudCenter+osg::Vec3(-baseSize , -baseSize-addSize, depth));
+		vertices->push_back(hudCenter+osg::Vec3(baseSize, -baseSize-addSize, depth));
+		vertices->push_back(hudCenter+osg::Vec3(baseSize+addSize, -baseSize, depth));
+		hudBackground->setVertexArray(vertices);
+		
+		osg::Vec3Array* normals = new osg::Vec3Array;
+		normals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
+		hudBackground->setNormalArray(normals);
+		hudBackground->setNormalBinding(osg::Geometry::BIND_OVERALL);
+		
+		osg::Vec4Array* colors = new osg::Vec4Array;
+		colors->push_back( bgColor_rgba );
+		hudBackground->setColorArray(colors);
+		hudBackground->setColorBinding(osg::Geometry::BIND_OVERALL);
+		
+		hudBackground->addPrimitiveSet(new osg::DrawArrays(GL_POLYGON,0,8));
+		
+		osg::StateSet* stateset = hudBackground->getOrCreateStateSet();
+		stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
+		stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
+
+		hudGeode->addDrawable(hudBackground);    
+	}
+    
+	// Add Text: 
+	//osg::Vec3 position(550.0f,450.0f,0.0f);
+	osg::Vec3 position(100.0f,100.0f,0.0f);
+	osg::Vec3 delta(0.0f,-120.0f,0.0f);
+	std::string timesFont("fonts/arial.ttf");
+	{
+		osgText::Text* text = new  osgText::Text;
+		hudGeode->addDrawable( text );
+
+		text->setFont(timesFont);
+		text->setPosition(position);
+		text->setText("Head Up Displays\nare simple ;-)");
+
+		position += delta;
+	}
+
+	return hudGeode.get();
+}
Index: /osgVisual/trunk/src/draw3D/visual_draw3D.cpp
===================================================================
--- /osgVisual/trunk/src/draw3D/visual_draw3D.cpp	(revision 176)
+++ /osgVisual/trunk/src/draw3D/visual_draw3D.cpp	(revision 176)
@@ -0,0 +1,78 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <visual_draw3D.h>
+
+using namespace osgVisual;
+
+visual_draw3D::visual_draw3D(void)
+{
+}
+
+visual_draw3D::~visual_draw3D(void)
+{
+}
+
+void visual_draw3D::init( osg::CoordinateSystemNode* rootNode_, osgViewer::Viewer *viewer_ )
+{
+	osg::Matrix testmatrix = viewer_->getCamera()->getViewMatrix();
+
+	testmatrix.makeTranslate( 2.0, 2.0, 2.0 );
+	//testmatrix.
+	osg::ref_ptr<osg::Geode> hudGeode = new osg::Geode();
+	rootNode_->addChild( hudGeode );
+
+
+    // create background
+	
+	// configuring background shape
+	float depth = -0.1; // Paint background behind text. 
+	osg::Vec4f bgColor_rgba = osg::Vec4(1.0f,1.0,0.8f,0.2f);
+	osg::Vec3 hudCenter = osg::Vec3(0.0, 0.0, 0.0);
+	float baseSize = 200;
+	float addSize = 70;
+
+
+	osg::Geometry* hudBackground = new osg::Geometry;
+
+	osg::Vec3Array* vertices = new osg::Vec3Array;
+	vertices->push_back(hudCenter+osg::Vec3(baseSize+addSize, baseSize, depth));
+	vertices->push_back(hudCenter+osg::Vec3(baseSize, baseSize+addSize, depth));
+	vertices->push_back(hudCenter+osg::Vec3(-baseSize , baseSize+addSize, depth));
+	vertices->push_back(hudCenter+osg::Vec3(-baseSize-addSize, baseSize,depth));
+	vertices->push_back(hudCenter+osg::Vec3(-baseSize-addSize, -baseSize,depth));
+	vertices->push_back(hudCenter+osg::Vec3(-baseSize , -baseSize-addSize, depth));
+	vertices->push_back(hudCenter+osg::Vec3(baseSize, -baseSize-addSize, depth));
+	vertices->push_back(hudCenter+osg::Vec3(baseSize+addSize, -baseSize, depth));
+	hudBackground->setVertexArray(vertices);
+	
+	osg::Vec3Array* normals = new osg::Vec3Array;
+	normals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
+	hudBackground->setNormalArray(normals);
+	hudBackground->setNormalBinding(osg::Geometry::BIND_OVERALL);
+	
+	osg::Vec4Array* colors = new osg::Vec4Array;
+	colors->push_back( bgColor_rgba );
+	hudBackground->setColorArray(colors);
+	hudBackground->setColorBinding(osg::Geometry::BIND_OVERALL);
+	
+	hudBackground->addPrimitiveSet(new osg::DrawArrays(GL_POLYGON,0,8));
+	
+	osg::StateSet* stateset = hudBackground->getOrCreateStateSet();
+	stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
+	stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
+
+}
Index: /osgVisual/trunk/src/extLink/dataIO_extLinkDummy.cpp
===================================================================
--- /osgVisual/trunk/src/extLink/dataIO_extLinkDummy.cpp	(revision 176)
+++ /osgVisual/trunk/src/extLink/dataIO_extLinkDummy.cpp	(revision 176)
@@ -0,0 +1,61 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <dataIO_extLinkDummy.h>
+
+#include <visual_dataIO.h>	// include in.cpp to avoid circular inclusion (visual_dataIO <-> extLinkDummy)
+
+
+using namespace osgVisual;
+
+dataIO_extLinkDummy::dataIO_extLinkDummy(std::vector<dataIO_slot *>& dataSlots_) : dataIO_extLink(dataSlots_)
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "extLinkDummy constructed" << std::endl;
+}
+
+dataIO_extLinkDummy::~dataIO_extLinkDummy(void)
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "extLinkDummy destroyed" << std::endl;
+}
+
+void dataIO_extLinkDummy::init()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "extLinkDummy init()" << std::endl;
+}
+
+void dataIO_extLinkDummy::shutdown()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "extLinkDummy shutdown()" << std::endl;
+}
+
+bool dataIO_extLinkDummy::readTO_OBJvalues()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "extLinkDummy readTO_OBJvalues()" << std::endl;
+
+	return true;
+}
+
+bool dataIO_extLinkDummy::writebackFROM_OBJvalues()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "extLinkDummy writebackFROM_OBJvalues()" << std::endl;
+
+	return true;
+}
+
+void dataIO_extLinkDummy::provideSlots()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "extLinkDummy provideSlots()" << std::endl;
+}
Index: /osgVisual/trunk/src/extLink/dataIO_extLinkVCL.cpp
===================================================================
--- /osgVisual/trunk/src/extLink/dataIO_extLinkVCL.cpp	(revision 176)
+++ /osgVisual/trunk/src/extLink/dataIO_extLinkVCL.cpp	(revision 176)
@@ -0,0 +1,212 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <dataIO_extLinkVCL.h>
+
+#include <visual_dataIO.h>	// include in.cpp to avoid circular inclusion (visual_dataIO <-> extLinkVCL)
+
+using namespace osgVisual;
+
+dataIO_extLinkVCL::dataIO_extLinkVCL(std::vector<dataIO_slot *>& dataSlots_) : dataIO_extLink(dataSlots_)
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "extLinkVCL constructed" << std::endl;
+}
+
+dataIO_extLinkVCL::~dataIO_extLinkVCL(void)
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "extLinkVCL destroyed" << std::endl;
+}
+
+void dataIO_extLinkVCL::init()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "extLinkVCL init()" << std::endl;
+
+	VCLConfigFilename = "osgVisual.xml";
+	
+	if ( osgDB::fileExists( VCLConfigFilename ) )
+	{
+		CVCLIO::GetInstance().LoadProject(VCLConfigFilename.c_str());
+
+		parseVCLConfig();
+		
+		initialized = true;
+	}
+	else
+	{
+		OSG_NOTIFY( osg::FATAL ) << "ERROR: Could not find VCL Configuration file " << VCLConfigFilename << std::endl;
+		exit(-1);
+	}
+
+}
+
+void dataIO_extLinkVCL::shutdown()
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "extLinkVCL shutdown()" << std::endl;
+}
+
+bool dataIO_extLinkVCL::readTO_OBJvalues()
+{
+	OSG_NOTIFY( osg::INFO ) << "extLinkVCL readTO_OBJvalues()" << std::endl;
+
+	// perform external data exchange
+	CVCLIO::GetInstance().DoDataExchange();
+
+	// read TO_OBJ values from VCL
+	for(unsigned int i=0;i<extLinkChannels.size();i++)
+	{
+		if(extLinkSlots[i]->getdataDirection() == osgVisual::dataIO_slot::TO_OBJ)
+		{
+			//Copy data from VCL to slot. IMPORTANT: Due to VCL's string incapability only double slots are filled.
+			osgVisual::visual_dataIO::getInstance()->setSlotData( extLinkSlots[i]->getVariableName(), osgVisual::dataIO_slot::TO_OBJ, extLinkChannels[i]->GetValue() );
+		}	// IF (TO_OBJ) END
+	}
+
+	return true;
+}
+
+bool dataIO_extLinkVCL::writebackFROM_OBJvalues()
+{
+	OSG_NOTIFY( osg::INFO ) << "extLinkVCL writebackFROM_OBJvalues()" << std::endl;
+
+	// write FROM_OBJ values into VCL
+	for(unsigned int i=0;i<extLinkChannels.size();i++)
+	{
+		if(extLinkSlots[i]->getdataDirection() == osgVisual::dataIO_slot::FROM_OBJ && extLinkSlots[i]->getvarType() == osgVisual::dataIO_slot::DOUBLE)
+		{
+			//Copy data from slot to VCL. IMPORTANT: Due to VCL's string incapability only double slots are filled.
+			extLinkChannels[i]->SetValue( osgVisual::visual_dataIO::getInstance()->getSlotDataAsDouble( extLinkSlots[i]->getVariableName(), osgVisual::dataIO_slot::FROM_OBJ ) );
+		}	// IF (FROM_OBJ) END
+	}
+
+	/* In VCL no VCL dataexchange is performed, 
+	it is postponed until the next frame beginning,
+	where TO_OBJ exchange calls CVCLIO::GetInstance().DoDataExchange();.
+	*/
+	return true;
+}
+
+bool dataIO_extLinkVCL::parseVCLConfig()
+{
+	configFileValid = false;
+	xmlDoc *doc = NULL;
+    xmlNode *root_element = NULL;
+  	
+	doc = xmlReadFile(VCLConfigFilename.c_str(), NULL, 0);
+	if (doc == NULL)
+	{
+		configFileValid = false;
+		std::cout << "error: could not parse file" << VCLConfigFilename;
+	}
+	else
+	{
+		//  Get the root element node
+		root_element = xmlDocGetRootElement(doc);
+
+		// Parse the XML document.
+		checkXMLNode(root_element);
+
+		// free the document
+		xmlFreeDoc(doc);;
+	}
+	// Free the global variables that may have been allocated by the parser.
+	xmlCleanupParser();
+
+	if(!configFileValid)
+		OSG_ALWAYS << "ERROR: XML file seems not to be a valid VCL configuration file!" << std::endl;
+
+	return true;
+}
+
+void dataIO_extLinkVCL::checkXMLNode(xmlNode * a_node)
+{
+    for (xmlNode *cur_node = a_node; cur_node; cur_node = cur_node->next)
+	{
+		std::string node_name=reinterpret_cast<const char*>(cur_node->name);
+		if(cur_node->type == XML_ELEMENT_NODE && node_name == "CONFIGURATION")
+		{
+			//OSG_DEBUG << "XML node CONFIGURATION found" << std::endl;
+			configFileValid = true;
+		}
+
+        if (cur_node->type == XML_ELEMENT_NODE && node_name == "CHANNEL")
+		{
+			//OSG_DEBUG << "XML node CHANNEL found" << std::endl;
+
+			// Extract channel infos like name, direction and extract channels
+			std::string name;
+			dataIO_slot::dataDirection direction;
+			xmlAttr  *attr = cur_node->properties;
+			while ( attr ) 
+			{ 
+				std::string attr_name=reinterpret_cast<const char*>(attr->name);
+				if( attr_name == "name" )
+					name = reinterpret_cast<const char*>(attr->children->content);
+				if( attr_name == "multicast_in_group" )
+					direction = dataIO_slot::TO_OBJ;
+				if( attr_name == "multicast_out_group" )
+					direction = dataIO_slot::FROM_OBJ;
+				//std::cout << "Attribute name: " << attr->name << " value: " << attr->children->content << std::endl;
+				attr = attr->next; 
+			} 
+			addChannels(cur_node->children, name, direction );
+	
+            //OSG_DEBUG << "node type=Element, name:" << cur_node->name << std::endl;
+			//OSG_DEBUG << "Processing children at " << cur_node->children << std::endl;
+        }	// IF(CHANNEL) END
+
+		// Iterate to the next nodes to find channels.
+        checkXMLNode(cur_node->children);		
+    }	// FOR END
+}
+
+void dataIO_extLinkVCL::addChannels(xmlNode * a_node, std::string channelName_, dataIO_slot::dataDirection direction_ )
+{
+	if(!a_node)
+		return;
+
+	OSG_ALWAYS << "dataIO_extL) : Processing entries for channel " << channelName_ << " with the direction " << direction_ << std::endl;
+
+	for (xmlNode *cur_node = a_node; cur_node; cur_node = cur_node->next)
+	{
+		if (cur_node->type != XML_ELEMENT_NODE)	// only emelent nodes are relevant entries. otherwise skip this iteration. VCL files only contain text nodes in comments or as untrimmed element nodes.
+			continue;		
+
+		// Extract ENTRY - name (from the Channel <ENTRY> in the XML file
+		std::string entryName;
+		xmlAttr  *attr = cur_node->properties;
+		while ( attr ) 
+		{ 
+			std::string attr_name=reinterpret_cast<const char*>(attr->name);
+			if( attr_name == "name" )
+				entryName = reinterpret_cast<const char*>(attr->children->content);
+			//OSG_DEBUG << "Attribute name: " << attr->name << " value: " << attr->children->content << std::endl;
+			attr = attr->next; 
+		} 
+
+		// Store VCL variable
+		CVCLVariable<double>* tmp = new CVCLVariable<double>;
+		extLinkChannels.push_back(tmp);
+
+		// Attach VCL variable to channel:
+		//OSG_DEBUG << "attaching.... name: " << channelName_ << ", entryName: " << entryName << std::endl;
+		if( !tmp->Attach(channelName_.c_str(), entryName.c_str() ) )
+			OSG_ALWAYS << "ERROR - dataIO_extLinkVCL::addChannels(): unable to attach VCL variable entryName: " << entryName << " to channel: " << channelName_ << std::endl;
+
+		// Set SLOT data and store SLOT pointer 
+		osgVisual::dataIO_slot* tmpSlot = osgVisual::visual_dataIO::getInstance()->setSlotData( entryName, direction_, 0 );
+		extLinkSlots.push_back( tmpSlot );
+	}	// FOR each ENTRY END
+}
Index: /osgVisual/trunk/src/extLink/manip_extLink.cpp
===================================================================
--- /osgVisual/trunk/src/extLink/manip_extLink.cpp	(revision 176)
+++ /osgVisual/trunk/src/extLink/manip_extLink.cpp	(revision 176)
@@ -0,0 +1,70 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+#include <manip_extLink.h>
+
+
+
+using namespace osg;
+using namespace osgGA;
+using namespace osgVisual;
+
+extLinkManipulator::extLinkManipulator()
+{
+}
+
+extLinkManipulator::~extLinkManipulator()
+{
+}
+
+void extLinkManipulator::init(const GUIEventAdapter& ,GUIActionAdapter& )
+{
+}
+
+void extLinkManipulator::getUsage(osg::ApplicationUsage& usage) const
+{
+}
+
+bool extLinkManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& us)
+{
+    switch(ea.getEventType())
+    {
+    case(GUIEventAdapter::FRAME):
+        if (attachedObject.valid())
+		{
+			setByMatrix( attachedObject->getCameraMatrix() );
+		}
+        return false;
+    default:
+        break;
+    }
+
+    return false;
+}
+
+void extLinkManipulator::setByMatrix(const osg::Matrixd& matrix)
+{
+    manipMatrix = matrix;
+}
+
+osg::Matrixd extLinkManipulator::getMatrix() const
+{
+    return manipMatrix;
+}
+
+osg::Matrixd extLinkManipulator::getInverseMatrix() const
+{
+	return osg::Matrixd::inverse(manipMatrix);
+}
Index: /osgVisual/trunk/src/manip_ObjectMounted/manip_objectMounted.cpp
===================================================================
--- /osgVisual/trunk/src/manip_ObjectMounted/manip_objectMounted.cpp	(revision 176)
+++ /osgVisual/trunk/src/manip_ObjectMounted/manip_objectMounted.cpp	(revision 176)
@@ -0,0 +1,71 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <manip_objectMounted.h>
+
+
+
+using namespace osg;
+using namespace osgGA;
+using namespace osgVisual;
+
+objectMountedManipulator::objectMountedManipulator()
+{
+}
+
+objectMountedManipulator::~objectMountedManipulator()
+{
+}
+
+void objectMountedManipulator::init(const GUIEventAdapter& ,GUIActionAdapter& )
+{
+}
+
+void objectMountedManipulator::getUsage(osg::ApplicationUsage& usage) const
+{
+}
+
+bool objectMountedManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& us)
+{
+    switch(ea.getEventType())
+    {
+    case(GUIEventAdapter::FRAME):
+        if (attachedObject.valid())
+		{
+			setByMatrix( attachedObject->getCameraMatrix() );
+		}
+        return false;
+    default:
+        break;
+    }
+
+    return false;
+}
+
+void objectMountedManipulator::setByMatrix(const osg::Matrixd& matrix)
+{
+    manipMatrix = matrix;
+}
+
+osg::Matrixd objectMountedManipulator::getMatrix() const
+{
+    return manipMatrix;
+}
+
+osg::Matrixd objectMountedManipulator::getInverseMatrix() const
+{
+	return osg::Matrixd::inverse(manipMatrix);
+}
Index: /osgVisual/trunk/src/manip_Spacemouse/manip_freeSpaceMouse.cpp
===================================================================
--- /osgVisual/trunk/src/manip_Spacemouse/manip_freeSpaceMouse.cpp	(revision 176)
+++ /osgVisual/trunk/src/manip_Spacemouse/manip_freeSpaceMouse.cpp	(revision 176)
@@ -0,0 +1,208 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <manip_freeSpaceMouse.h>
+
+
+
+using namespace osg;
+using namespace osgGA;
+using namespace osgVisual;
+
+FreeManipulator::FreeManipulator(SpaceMouse* spacemouse) : _spaceMouse(spacemouse)
+{
+}
+
+FreeManipulator::~FreeManipulator()
+{
+}
+
+void FreeManipulator::init(const GUIEventAdapter& ,GUIActionAdapter& )
+{
+}
+
+void FreeManipulator::getUsage(osg::ApplicationUsage& usage) const
+{
+}
+
+bool FreeManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& us)
+{
+    switch(ea.getEventType())
+    {
+    case(GUIEventAdapter::FRAME):
+        if (calcMovement())
+            us.requestRedraw();
+        return false;
+    default:
+        break;
+    }
+
+    return false;
+}
+
+void FreeManipulator::setByMatrix(const osg::Matrixd& matrix)
+{
+    _position = matrix.getTrans();
+    _attitude = matrix.getRotate();
+}
+
+osg::Matrixd FreeManipulator::getMatrix() const
+{
+    return osg::Matrixd::rotate(_attitude)*osg::Matrixd::translate(_position);
+}
+
+osg::Matrixd FreeManipulator::getInverseMatrix() const
+{
+    return osg::Matrixd::translate(-_position)*osg::Matrixd::rotate(_attitude.inverse());
+}
+
+bool FreeManipulator::calcMovement()
+{
+    double dTX, dTY, dTZ;
+    _spaceMouse->getTranslations(dTX, dTY, dTZ);
+
+    double dRX, dRY, dRZ;
+    _spaceMouse->getRotations(dRX, dRY, dRZ);
+
+    osg::Matrix rotation_matrix;
+    rotation_matrix.makeRotate(_attitude);
+
+    osg::Vec3d lookVector = -getUpVector(rotation_matrix);
+    osg::Vec3d sideVector = getSideVector(rotation_matrix);
+    osg::Vec3d upVector = getFrontVector(rotation_matrix);
+
+    lookVector.normalize();
+    sideVector.normalize();
+    upVector.normalize();
+
+    // POSITION
+    _position -= lookVector * dTZ;
+    _position += upVector   * dTY;
+    _position += sideVector * dTX;
+	//std::cout << "Translation: "<< dTX * 1000000.0<< ", " << dTY * 1000000.0<< ", " << dTZ * 1000000.0<< std::endl;
+
+    // ATTITUDE
+    _attitude *= osg::Quat( dRY, osg::Vec3(0.0, 0.0, 1.0));		//Yaw
+    _attitude *= osg::Quat( dRX, sideVector);					// Pitch
+	_attitude *= osg::Quat( -dRZ, lookVector);					// Bank
+
+
+    if (!_trackNodePath.empty())
+    {
+        osg::Vec3 trackNodeCenter = getTrackNodeCenter();
+
+        osg::Matrix matrixLookAt;
+        matrixLookAt.makeLookAt(_position, trackNodeCenter, osg::Vec3(0.0, 0.0, 1.0));
+
+        osg::Quat attitude = matrixLookAt.getRotate().inverse();
+        _attitude = attitude;
+    }
+
+    return true;
+}
+
+osg::Vec3 FreeManipulator::getTrackNodeCenter()
+{
+    osg::Matrixd localToWorld, worldToLocal;
+    computeNodeLocalToWorld(localToWorld);
+    computeNodeWorldToLocal(worldToLocal);
+
+    osg::Vec3 center(0.0, 0.0, 0.0);
+    if (validateNodePath())
+        center = osg::Vec3d(_trackNodePath.back()->getBound().center())*localToWorld;
+    else
+        center = osg::Vec3d(0.0f,0.0f,0.0f)*localToWorld;
+
+    return(center);
+}
+
+void FreeManipulator::computeNodeWorldToLocal(osg::Matrixd& worldToLocal) const
+{
+    if (validateNodePath())
+    {
+        worldToLocal = osg::computeWorldToLocal(getNodePath());
+    }
+}
+
+void FreeManipulator::computeNodeLocalToWorld(osg::Matrixd& localToWorld) const
+{
+    if (validateNodePath())
+    {
+        localToWorld = osg::computeLocalToWorld(getNodePath());
+    }
+
+}
+
+bool FreeManipulator::validateNodePath() const
+{
+    for(ObserverNodePath::const_iterator itr = _trackNodePath.begin();
+        itr != _trackNodePath.begin();
+        ++itr)
+    {
+        if (*itr==0) 
+        {
+            OSG_NOTIFY(osg::NOTICE)<<"Warning: tracked node path has been invalidated by changes in the scene graph."<<std::endl;
+            const_cast<ObserverNodePath&>(_trackNodePath).clear();
+            return false;
+        }
+    }
+    return true;
+}
+
+osg::NodePath FreeManipulator::getNodePath() const
+{
+    osg::NodePath nodePath;
+    for(ObserverNodePath::const_iterator itr = _trackNodePath.begin();
+        itr != _trackNodePath.end();
+        ++itr)
+    {
+        nodePath.push_back(const_cast<osg::Node*>(itr->get()));
+    }
+    return nodePath;
+}
+
+void FreeManipulator::setTrackNode(osg::Node* node)
+{
+    if (!node)
+    {
+        OSG_NOTIFY(osg::NOTICE)<<"NodeTrackerManipulator::setTrackNode(Node*):  Unable to set tracked node due to null Node*"<<std::endl;
+        return;
+    }
+
+    osg::NodePathList nodePaths = node->getParentalNodePaths();
+    if (!nodePaths.empty())
+    {
+        if (nodePaths.size()>1)
+        {
+            OSG_NOTIFY(osg::NOTICE)<<"osgGA::NodeTrackerManipualtor::setTrackNode(..) taking first parent path, ignoring others."<<std::endl;
+        }
+
+        OSG_NOTIFY(osg::INFO)<<"NodeTrackerManipulator::setTrackNode(Node*"<<node<<" "<<node->getName()<<"): Path set"<<std::endl;
+        _trackNodePath.clear();
+        setTrackNodePath( nodePaths.front() );
+    }
+    else
+    {
+        OSG_NOTIFY(osg::NOTICE)<<"NodeTrackerManipulator::setTrackNode(Node*): Unable to set tracked node due to empty parental path."<<std::endl;
+    }
+    
+    OSG_NOTIFY(osg::INFO)<<"setTrackNode("<<node->getName()<<")"<<std::endl;
+    for(unsigned int i=0; i<_trackNodePath.size(); ++i)
+    {
+        OSG_NOTIFY(osg::INFO)<<"  "<<_trackNodePath[i]->className()<<" '"<<_trackNodePath[i]->getName()<<"'"<<std::endl;
+    }
+
+}
Index: /osgVisual/trunk/src/manip_Spacemouse/manip_nodeTrackerSpaceMouse.cpp
===================================================================
--- /osgVisual/trunk/src/manip_Spacemouse/manip_nodeTrackerSpaceMouse.cpp	(revision 176)
+++ /osgVisual/trunk/src/manip_Spacemouse/manip_nodeTrackerSpaceMouse.cpp	(revision 176)
@@ -0,0 +1,723 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <manip_nodeTrackerSpaceMouse.h>
+
+
+
+using namespace osg;
+using namespace osgVisual;
+
+
+NodeTrackerSpaceMouse::NodeTrackerSpaceMouse(SpaceMouse* spacemouse) : _spaceMouse(spacemouse)
+{
+    _trackerMode = NODE_CENTER_AND_ROTATION; 
+    _rotationMode = TRACKBALL; 
+
+    _distance = 1.0;
+
+    _thrown = false;
+	_autohoming = false;
+	_ah_init = false;
+	_distanceDependendAV = false;
+
+	TZ=0;
+	RX=0;
+	RY=0;
+	RZ=0;
+
+}
+
+
+NodeTrackerSpaceMouse::~NodeTrackerSpaceMouse()
+{
+}
+
+void NodeTrackerSpaceMouse::setTrackNode(osg::Node* node)
+{
+    if (!node)
+    {
+        osg::notify(osg::NOTICE)<<"NodeTrackerSpaceMouse::setTrackNode(Node*):  Unable to set tracked node due to null Node*"<<std::endl;
+        return;
+    }
+
+    osg::NodePathList parentNodePaths = node->getParentalNodePaths();
+
+    if (!parentNodePaths.empty())
+    {
+        osg::notify(osg::INFO)<<"NodeTrackerSpaceMouse::setTrackNode(Node*): Path set"<<std::endl;
+        setTrackNodePath(parentNodePaths[0]);
+    }
+    else
+    {
+        osg::notify(osg::NOTICE)<<"NodeTrackerSpaceMouse::setTrackNode(Node*): Unable to set tracked node due to empty parental path."<<std::endl;
+    }
+}
+
+osg::Node* NodeTrackerSpaceMouse::getTrackNode()
+{
+    osg::NodePath nodePath;
+    if (_trackNodePath.getNodePath(nodePath)) return nodePath.back();
+    else return 0;
+}
+
+const osg::Node* NodeTrackerSpaceMouse::getTrackNode() const
+{
+    osg::NodePath nodePath;
+    if (_trackNodePath.getNodePath(nodePath)) return nodePath.back();
+    else return 0;
+}
+
+void NodeTrackerSpaceMouse::setTrackerMode(TrackerMode mode)
+{
+    _trackerMode = mode;
+}
+
+void NodeTrackerSpaceMouse::setRotationMode(RotationMode mode)
+{
+    _rotationMode = mode;
+    if (getAutoComputeHomePosition()) computeHomePosition();    
+}
+
+void NodeTrackerSpaceMouse::setNode(osg::Node* node)
+{
+    _node = node;
+    
+    if (_node.get())
+    {
+        const osg::BoundingSphere& boundingSphere=_node->getBound();
+        const float minimumDistanceScale = 0.001f;
+        _minimumDistance = osg::clampBetween(
+            float(boundingSphere._radius) * minimumDistanceScale,
+            0.00001f,1.0f);
+            
+        osg::notify(osg::INFO)<<"Setting Tracker manipulator _minimumDistance to "<<_minimumDistance<<std::endl;
+    }
+    if (getAutoComputeHomePosition()) computeHomePosition();    
+}
+
+const osg::Node* NodeTrackerSpaceMouse::getNode() const
+{
+    return _node.get();
+}
+
+
+osg::Node* NodeTrackerSpaceMouse::getNode()
+{
+    return _node.get();
+}
+
+
+void NodeTrackerSpaceMouse::home(const GUIEventAdapter& ,GUIActionAdapter& us)
+{
+    if (getAutoComputeHomePosition()) computeHomePosition();
+
+    computePosition(_homeEye, _homeCenter, _homeUp);
+    us.requestRedraw();
+}
+
+void NodeTrackerSpaceMouse::computeHomePosition()
+{
+    osg::NodePath nodePath;
+    _trackNodePath.getNodePath(nodePath);
+
+    osg::Node* node = nodePath.empty() ? getNode() : nodePath.back();
+    
+    if(node)
+    {
+        const osg::BoundingSphere& boundingSphere=node->getBound();
+
+        setHomePosition(boundingSphere._center+osg::Vec3( 0.0,-3.5f * boundingSphere._radius,0.0f),
+                        boundingSphere._center,
+                        osg::Vec3(0.0f,0.0f,1.0f),
+                        _autoComputeHomePosition);
+    }
+}
+
+
+
+void NodeTrackerSpaceMouse::init(const GUIEventAdapter& ,GUIActionAdapter& )
+{
+    flushMouseEventStack();
+}
+
+
+void NodeTrackerSpaceMouse::getUsage(osg::ApplicationUsage& usage) const
+{
+    usage.addKeyboardMouseBinding("SN Tracker: Space","Toggle camera auto homing");
+	usage.addKeyboardMouseBinding("SN Tracker: m","Toggle Nodetracker Mode");
+	usage.addKeyboardMouseBinding("SN Tracker: n","Toggle distance dependend angular velocity");
+    usage.addKeyboardMouseBinding("SN Tracker: +","When in stereo, increase the fusion distance");
+    usage.addKeyboardMouseBinding("SN Tracker: -","When in stereo, reduce the fusion distance");
+}
+
+bool NodeTrackerSpaceMouse::handle(const GUIEventAdapter& ea,GUIActionAdapter& us)
+{
+    switch(ea.getEventType())
+    {
+        case(GUIEventAdapter::PUSH):
+        {
+            flushMouseEventStack();
+            addMouseEvent(ea);
+            if (calcMovement()) us.requestRedraw();
+            us.requestContinuousUpdate(false);
+            _thrown = false;
+            return true;
+        }
+
+        case(GUIEventAdapter::RELEASE):
+        {
+            if (ea.getButtonMask()==0)
+            {
+
+                double timeSinceLastRecordEvent = _ga_t0.valid() ? (ea.getTime() - _ga_t0->getTime()) : DBL_MAX;
+                if (timeSinceLastRecordEvent>0.02) flushMouseEventStack();
+
+                if (isMouseMoving())
+                {
+                    if (calcMovement())
+                    {
+                        us.requestRedraw();
+                        us.requestContinuousUpdate(true);
+                        _thrown = true;
+                    }
+                }
+                else
+                {
+                    flushMouseEventStack();
+                    addMouseEvent(ea);
+                    if (calcMovement()) us.requestRedraw();
+                    us.requestContinuousUpdate(false);
+                    _thrown = false;
+                }
+
+            }
+            else
+            {
+                flushMouseEventStack();
+                addMouseEvent(ea);
+                if (calcMovement()) us.requestRedraw();
+                us.requestContinuousUpdate(false);
+                _thrown = false;
+            }
+            return true;
+        }
+
+        case(GUIEventAdapter::DRAG):
+        {
+            addMouseEvent(ea);
+            if (calcMovement()) us.requestRedraw();
+            us.requestContinuousUpdate(false);
+            _thrown = false;
+            return true;
+        }
+
+        case(GUIEventAdapter::MOVE):
+        {
+            return false;
+        }
+
+        case(GUIEventAdapter::KEYDOWN):
+            if (ea.getKey()==' ')
+            {
+				if (_autohoming)
+					_autohoming=false;
+				else
+					_autohoming=true;
+                return true;
+            }
+			if (ea.getKey()=='m')
+            {
+				switch(_trackerMode)
+				{
+					case NODE_CENTER: _trackerMode=NODE_CENTER_AND_AZIM;
+						break;
+					case NODE_CENTER_AND_AZIM: _trackerMode=NODE_CENTER_AND_ROTATION;
+						break;
+					case  NODE_CENTER_AND_ROTATION: _trackerMode=NODE_CENTER;
+						break;
+					default: _trackerMode = NODE_CENTER;
+						break;
+				};
+                return true;
+            }
+			if (ea.getKey()=='n')
+            {
+				if (_distanceDependendAV)
+					_distanceDependendAV=false;
+				else
+					_distanceDependendAV=true;
+                return true;
+            }
+            return false;
+        case(GUIEventAdapter::FRAME):
+            if (_thrown)
+            {
+                if (calcMovement()) us.requestRedraw();
+            }
+
+			computeHomePosition();
+			computePosition(_homeEye, _homeCenter, _homeUp);
+			if (calcMovementSpaceMouse())
+				us.requestRedraw();
+
+            return false;
+        default:
+            return false;
+    }
+}
+
+
+bool NodeTrackerSpaceMouse::isMouseMoving()
+{
+    if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;
+
+    static const float velocity = 0.1f;
+
+    float dx = _ga_t0->getXnormalized()-_ga_t1->getXnormalized();
+    float dy = _ga_t0->getYnormalized()-_ga_t1->getYnormalized();
+    float len = sqrtf(dx*dx+dy*dy);
+    float dt = _ga_t0->getTime()-_ga_t1->getTime();
+
+    return (len>dt*velocity);
+}
+
+
+void NodeTrackerSpaceMouse::flushMouseEventStack()
+{
+    _ga_t1 = NULL;
+    _ga_t0 = NULL;
+}
+
+
+void NodeTrackerSpaceMouse::addMouseEvent(const GUIEventAdapter& ea)
+{
+    _ga_t1 = _ga_t0;
+    _ga_t0 = &ea;
+}
+
+void NodeTrackerSpaceMouse::setByMatrix(const osg::Matrixd& matrix)
+{
+    osg::Vec3d eye,center,up;
+    matrix.getLookAt(eye,center,up,_distance);
+    computePosition(eye,center,up);
+}
+
+void NodeTrackerSpaceMouse::computeNodeCenterAndRotation(osg::Vec3d& nodeCenter, osg::Quat& nodeRotation) const
+{
+    osg::Matrixd localToWorld, worldToLocal;
+    osg::NodePath nodePath;
+    if (_trackNodePath.getNodePath(nodePath))
+    {
+        worldToLocal = osg::computeWorldToLocal(nodePath);
+        localToWorld = osg::computeLocalToWorld(nodePath);
+        nodeCenter = osg::Vec3d(nodePath.back()->getBound().center())*localToWorld;
+    }
+    else
+    {
+        nodeCenter = osg::Vec3d(0.0f,0.0f,0.0f)*localToWorld;
+    }
+
+
+    switch(_trackerMode)
+    {
+        case(NODE_CENTER_AND_AZIM):
+        {
+            CoordinateFrame coordinateFrame = getCoordinateFrame(nodeCenter);
+            osg::Matrixd localToFrame(localToWorld*osg::Matrixd::inverse(coordinateFrame));
+
+            double azim = atan2(-localToFrame(0,1),localToFrame(0,0));
+            osg::Quat nodeRotationRelToFrame, rotationOfFrame;
+            nodeRotationRelToFrame.makeRotate(-azim,0.0,0.0,1.0);
+            rotationOfFrame = coordinateFrame.getRotate();
+            nodeRotation = nodeRotationRelToFrame*rotationOfFrame;
+            break;
+        }
+        case(NODE_CENTER_AND_ROTATION):
+        {
+            // scale the matrix to get rid of any scales before we extract the rotation.
+            double sx = 1.0/sqrt(localToWorld(0,0)*localToWorld(0,0) + localToWorld(1,0)*localToWorld(1,0) + localToWorld(2,0)*localToWorld(2,0));
+            double sy = 1.0/sqrt(localToWorld(0,1)*localToWorld(0,1) + localToWorld(1,1)*localToWorld(1,1) + localToWorld(2,1)*localToWorld(2,1));
+            double sz = 1.0/sqrt(localToWorld(0,2)*localToWorld(0,2) + localToWorld(1,2)*localToWorld(1,2) + localToWorld(2,2)*localToWorld(2,2));
+            localToWorld = localToWorld*osg::Matrixd::scale(sx,sy,sz);
+
+            nodeRotation = localToWorld.getRotate();
+            break;
+        }
+        case(NODE_CENTER):
+        default:
+        {
+            CoordinateFrame coordinateFrame = getCoordinateFrame(nodeCenter);
+            nodeRotation = coordinateFrame.getRotate();
+            break;
+        }
+    }
+
+}
+
+
+osg::Matrixd NodeTrackerSpaceMouse::getMatrix() const
+{
+    osg::Vec3d nodeCenter;
+    osg::Quat nodeRotation;
+    computeNodeCenterAndRotation(nodeCenter,nodeRotation);
+    return osg::Matrixd::translate(0.0,0.0,_distance)*osg::Matrixd::rotate(_rotation)*osg::Matrixd::rotate(nodeRotation)*osg::Matrix::translate(nodeCenter);
+}
+
+osg::Matrixd NodeTrackerSpaceMouse::getInverseMatrix() const
+{
+    osg::Vec3d nodeCenter;
+    osg::Quat nodeRotation;
+    computeNodeCenterAndRotation(nodeCenter,nodeRotation);
+    return osg::Matrixd::translate(-nodeCenter)*osg::Matrixd::rotate(nodeRotation.inverse())*osg::Matrixd::rotate(_rotation.inverse())*osg::Matrixd::translate(0.0,0.0,-_distance);
+}
+
+void NodeTrackerSpaceMouse::computePosition(const osg::Vec3d& eye,const osg::Vec3d& center,const osg::Vec3d& up)
+{
+    if (!_node) return;
+
+    // compute rotation matrix
+    osg::Vec3 lv(center-eye);
+    _distance = lv.length();
+    
+    osg::Matrixd lookat;
+    lookat.makeLookAt(eye,center,up);
+    
+    _rotation = lookat.getRotate().inverse();
+}
+
+bool NodeTrackerSpaceMouse::calcMovement()
+{
+    // return if less then two events have been added.
+    if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;
+
+    double dx = _ga_t0->getXnormalized()-_ga_t1->getXnormalized();
+    double dy = _ga_t0->getYnormalized()-_ga_t1->getYnormalized();
+
+
+    float distance = sqrtf(dx*dx + dy*dy);
+    // return if movement is too fast, indicating an error in event values or change in screen.
+    if (distance>0.5)
+    {
+        return false;
+    }
+    
+    // return if there is no movement.
+    if (distance==0.0f)
+    {
+        return false;
+    }
+
+    osg::Vec3d nodeCenter;
+    osg::Quat nodeRotation;
+    computeNodeCenterAndRotation(nodeCenter, nodeRotation);
+
+    unsigned int buttonMask = _ga_t1->getButtonMask();
+
+    if (buttonMask==GUIEventAdapter::LEFT_MOUSE_BUTTON)
+    {
+
+        if (_rotationMode==TRACKBALL)
+        {
+
+            // rotate camera.
+            osg::Vec3 axis;
+            double angle;
+
+            double px0 = _ga_t0->getXnormalized();
+            double py0 = _ga_t0->getYnormalized();
+
+            double px1 = _ga_t1->getXnormalized();
+            double py1 = _ga_t1->getYnormalized();
+
+
+            trackball(axis,angle,px1,py1,px0,py0);
+
+            osg::Quat new_rotate;
+            new_rotate.makeRotate(angle,axis);
+
+            _rotation = _rotation*new_rotate;
+        }
+        else
+        {
+            osg::Matrix rotation_matrix;
+            rotation_matrix.makeRotate(_rotation);
+
+            osg::Vec3d lookVector = -getUpVector(rotation_matrix);
+            osg::Vec3d sideVector = getSideVector(rotation_matrix);
+            osg::Vec3d upVector = getFrontVector(rotation_matrix);
+            
+            osg::Vec3d localUp(0.0f,0.0f,1.0f);
+
+            osg::Vec3d forwardVector = localUp^sideVector;
+            sideVector = forwardVector^localUp;
+
+            forwardVector.normalize();
+            sideVector.normalize();
+            
+            osg::Quat rotate_elevation;
+            rotate_elevation.makeRotate(dy,sideVector);
+
+            osg::Quat rotate_azim;
+            rotate_azim.makeRotate(-dx,localUp);
+            
+            _rotation = _rotation * rotate_elevation * rotate_azim;
+            
+        }
+        
+        return true;
+
+    }
+    else if (buttonMask==GUIEventAdapter::MIDDLE_MOUSE_BUTTON ||
+        buttonMask==(GUIEventAdapter::LEFT_MOUSE_BUTTON|GUIEventAdapter::RIGHT_MOUSE_BUTTON))
+    {
+        return true;
+    }
+    else if (buttonMask==GUIEventAdapter::RIGHT_MOUSE_BUTTON)
+    {
+
+        // zoom model.
+
+        double fd = _distance;
+        double scale = 1.0f+dy;
+        if (fd*scale>_minimumDistance)
+        {
+
+            _distance *= scale;
+
+        } else
+        {
+            _distance = _minimumDistance;
+        }
+        
+        return true;
+
+    }
+
+    return false;
+}
+
+bool NodeTrackerSpaceMouse::calcMovementSpaceMouse()
+{
+	// TRACKBALL mode is not possible, because it uses the mouseevent, which does not happen with Spacemouse.
+
+   double dTX, dTY, dTZ;	// Only TZ is used later.
+    _spaceMouse->getTranslations(dTX, dTY, dTZ);
+
+    double dRX, dRY, dRZ;
+    _spaceMouse->getRotations(dRX, dRY, dRZ);
+
+	//OSG_NOTIFY( osg::INFO ) << "Recieved Spacemousevalues: dRX:" << dRX << ", dRY:" << dRY << ", dRZ:" << dRZ << ", dTX:" << dTX << std::endl;
+
+	if(!_ah_init)
+	{
+		TZ=dTZ;
+		RX=dRX;
+		RY=dRY;
+		RZ=dRZ;
+		_ah_init=true;
+	}
+
+	if (_autohoming)	// The factors are required to allow macroscopic movements.
+	{
+		TZ=dTZ*5;
+		if (!_distanceDependendAV)
+		{
+			RX=dRX*100;
+			RY=dRY*100;
+			RZ=dRZ*100;
+		}
+	}
+	else		// NOT Autohoming
+	{
+		TZ+=dTZ;
+		//OSG_NOTIFY( osg::INFO ) << "Stored Spacemousevalues: RX:" << RX << ", RY:" << RY << ", RZ:" << RZ << ", TX:" << TX << std::endl;
+		if (_distanceDependendAV)
+		{
+			RX+=(dRX*800/TZ);
+			RY+=(dRY*800/TZ);
+			RZ+=(dRZ*800/TZ);
+		}
+		else
+		{
+			RX+=dRX;
+			RY+=dRY;
+			RZ+=dRZ;
+		}
+	}
+
+    osg::Vec3d nodeCenter;
+    osg::Quat nodeRotation;
+    computeNodeCenterAndRotation(nodeCenter, nodeRotation);
+
+    // ROTATION PART
+    if (_rotationMode==TRACKBALL)
+    {
+		// return if less then two events have been added.
+		if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;
+
+        // rotate camera.
+        osg::Vec3 axis;
+        double angle;
+
+        double px0 = _ga_t0->getXnormalized();
+        double py0 = _ga_t0->getYnormalized();
+
+        double px1 = _ga_t1->getXnormalized();
+        double py1 = _ga_t1->getYnormalized();
+
+
+        trackball(axis,angle,px1,py1,px0,py0);
+
+        osg::Quat new_rotate;
+        new_rotate.makeRotate(angle,axis);
+
+        _rotation = _rotation*new_rotate;
+    }
+    else
+    {
+        osg::Matrix rotation_matrix;
+        rotation_matrix.makeRotate(_rotation);
+
+        osg::Vec3d lookVector = -getUpVector(rotation_matrix);
+        osg::Vec3d sideVector = getSideVector(rotation_matrix);
+        osg::Vec3d upVector = getFrontVector(rotation_matrix);
+        
+        osg::Vec3d localUp(0.0f,0.0f,1.0f);
+
+        osg::Vec3d forwardVector = localUp^sideVector;
+        sideVector = forwardVector^localUp;
+
+        forwardVector.normalize();
+        sideVector.normalize();
+        
+        osg::Quat rotate_elevation;
+		rotate_elevation.makeRotate(osg::DegreesToRadians(RX*90), sideVector);
+
+        osg::Quat rotate_azim;
+		rotate_azim.makeRotate(osg::DegreesToRadians(RY*90), localUp);
+        
+        _rotation = _rotation * rotate_elevation * rotate_azim;
+        
+    }
+
+    // TRANSLATION PART
+    double scale = 1.0f+TZ/100;
+	if (_distance*scale>_minimumDistance)
+    {
+
+        _distance *= scale;
+
+    } else
+    {
+		TZ = (_minimumDistance/_distance - 1)*100;	// Reset TZ to the value f(_minimalDistance, _distance, scale-function). 
+        _distance = _minimumDistance;
+    }
+    return true;
+}
+
+void NodeTrackerSpaceMouse::clampOrientation()
+{
+}
+
+
+/*
+ * This size should really be based on the distance from the center of
+ * rotation to the point on the object underneath the mouse.  That
+ * point would then track the mouse as closely as possible.  This is a
+ * simple example, though, so that is left as an Exercise for the
+ * Programmer.
+ */
+const float TRACKBALLSIZE = 0.8f;
+
+/*
+ * Ok, simulate a track-ball.  Project the points onto the virtual
+ * trackball, then figure out the axis of rotation, which is the cross
+ * product of P1 P2 and O P1 (O is the center of the ball, 0,0,0)
+ * Note:  This is a deformed trackball-- is a trackball in the center,
+ * but is deformed into a hyperbolic sheet of rotation away from the
+ * center.  This particular function was chosen after trying out
+ * several variations.
+ *
+ * It is assumed that the arguments to this routine are in the range
+ * (-1.0 ... 1.0)
+ */
+void NodeTrackerSpaceMouse::trackball(osg::Vec3& axis,double & angle, double  p1x, double  p1y, double  p2x, double  p2y)
+{
+    /*
+     * First, figure out z-coordinates for projection of P1 and P2 to
+     * deformed sphere
+     */
+
+    osg::Matrix rotation_matrix(_rotation);
+
+
+    osg::Vec3d uv = osg::Vec3d(0.0,1.0,0.0)*rotation_matrix;
+    osg::Vec3d sv = osg::Vec3d(1.0,0.0,0.0)*rotation_matrix;
+    osg::Vec3d lv = osg::Vec3d(0.0,0.0,-1.0)*rotation_matrix;
+
+    osg::Vec3d p1 = sv*p1x+uv*p1y-lv*tb_project_to_sphere(TRACKBALLSIZE,p1x,p1y);
+    osg::Vec3d p2 = sv*p2x+uv*p2y-lv*tb_project_to_sphere(TRACKBALLSIZE,p2x,p2y);
+
+    /*
+     *  Now, we want the cross product of P1 and P2
+     */
+
+// Robert,
+//
+// This was the quick 'n' dirty  fix to get the trackball doing the right 
+// thing after fixing the Quat rotations to be right-handed.  You may want
+// to do something more elegant.
+//   axis = p1^p2;
+axis = p2^p1;
+    axis.normalize();
+
+    /*
+     *  Figure out how much to rotate around that axis.
+     */
+    double t = (p2-p1).length() / (2.0*TRACKBALLSIZE);
+
+    /*
+     * Avoid problems with out-of-control values...
+     */
+    if (t > 1.0) t = 1.0;
+    if (t < -1.0) t = -1.0;
+    angle = inRadians(asin(t));
+
+}
+
+
+/*
+ * Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet
+ * if we are away from the center of the sphere.
+ */
+double NodeTrackerSpaceMouse::tb_project_to_sphere(double  r, double  x, double  y)
+{
+    float d, t, z;
+
+    d = sqrt(x*x + y*y);
+                                 /* Inside sphere */
+    if (d < r * 0.70710678118654752440)
+    {
+        z = sqrt(r*r - d*d);
+    }                            /* On hyperbola */
+    else
+    {
+        t = r / 1.41421356237309504880;
+        z = t*t / d;
+    }
+    return z;
+}
Index: /osgVisual/trunk/src/manip_Spacemouse/manip_spaceMouse.cpp
===================================================================
--- /osgVisual/trunk/src/manip_Spacemouse/manip_spaceMouse.cpp	(revision 176)
+++ /osgVisual/trunk/src/manip_Spacemouse/manip_spaceMouse.cpp	(revision 176)
@@ -0,0 +1,201 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <manip_spaceMouse.h>
+
+#define _ATL_APARTMENT_THREADED
+#define _ATL_NO_AUTOMATIC_NAMESPACE
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS	// some CString constructors will be explicit
+
+#define _WIN32_DCOM
+
+#include <objbase.h>
+#include <atlbase.h>
+#include <atlcom.h>
+#include <atlwin.h>
+#include <atltypes.h>
+#include <atlctl.h>
+#include <atlhost.h>
+
+
+
+using namespace ATL;
+using namespace osgVisual;
+
+#import "progid:TDxInput.Device" no_namespace
+
+class SpaceMouse::SpaceMouseImpl
+{
+public:
+    enum SupportedStatus
+    {
+        DETECTION_PENDING,
+        SUPPORTED,
+        NOT_SUPPORTED
+    };
+
+    SpaceMouseImpl() : _supported(DETECTION_PENDING)
+    {
+    }
+
+    SupportedStatus isSupported() const
+    {
+        return(_supported);
+    }
+
+    int initialize()
+    {
+        HRESULT hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
+
+        // Create the device object
+        hr = _3DxDevice.CoCreateInstance(__uuidof(Device));
+        if (SUCCEEDED(hr))
+        {
+            CComPtr<ISimpleDevice> _3DxSimpleDevice;
+
+            hr = _3DxDevice.QueryInterface(&_3DxSimpleDevice);
+            if (SUCCEEDED(hr))
+            {
+                // Get the interfaces to the sensor and the keyboard;
+                _3DSensor   = _3DxSimpleDevice->Sensor;
+                _3DKeyboard = _3DxSimpleDevice->Keyboard;
+
+                // Associate a configuration with this device
+                hr = _3DxSimpleDevice->LoadPreferences(_T("Animation"));
+                // Connect to the driver
+                hr = _3DxSimpleDevice->Connect();
+
+                _supported = SUPPORTED;
+
+                return(1); //Base::SUCCESS
+            }
+        }
+
+        _supported = NOT_SUPPORTED;
+
+        return(0);	//Base::FAILURE
+    }
+
+    void shutdown()
+    {
+        if (_3DSensor)
+            _3DSensor.Release();
+
+        if (_3DKeyboard)
+            _3DKeyboard.Release();
+
+        if (_3DxDevice)
+        {
+            _3DxDevice->Disconnect();
+            _3DxDevice.Release();
+        }
+    }
+
+
+    int getTranslations(double& dTX, double& dTY, double& dTZ)
+    {
+        try {
+            CComPtr<IVector3D> pTranslation = _3DSensor->Translation;
+
+            double dTransFactor = pTranslation->Length;
+            dTransFactor /= 5.0;
+
+            dTX = pTranslation->X * dTransFactor;
+            dTY = pTranslation->Y * dTransFactor;
+            dTZ = pTranslation->Z * dTransFactor;
+
+            pTranslation.Release();
+        }
+        catch (...)
+        {
+            return 0;	//Base::FAILURE
+        }
+
+        return 1;	//Base::SUCCESS
+    }
+
+    int getRotations(double& dRX, double& dRY, double& dRZ)
+    {
+        try {
+            CComPtr<IAngleAxis> pRotation = _3DSensor->Rotation;
+
+            double dRotAngle = pRotation->Angle;
+            dRotAngle /= 4000.0;
+
+            dRX = pRotation->X * dRotAngle;
+            dRY = pRotation->Y * dRotAngle;
+            dRZ = pRotation->Z * dRotAngle;
+
+            pRotation.Release();
+        }
+        catch (...)
+        {
+            return 0;	//Base::FAILURE
+        }
+
+        return 1;	//Base::SUCCESS
+    }
+
+private:
+    SupportedStatus _supported;
+
+    CComPtr<ISimpleDevice> _3DxDevice;
+    CComPtr<ISensor>       _3DSensor;
+    CComPtr<IKeyboard>     _3DKeyboard;
+};
+
+
+
+
+
+
+
+
+SpaceMouse::SpaceMouse() : _spaceMouseImpl(new SpaceMouseImpl)
+{
+}
+
+SpaceMouse::~SpaceMouse()
+{
+    delete _spaceMouseImpl;
+}
+
+int SpaceMouse::initialize()
+{
+    return(_spaceMouseImpl->initialize());
+}
+
+void SpaceMouse::shutdown()
+{
+    _spaceMouseImpl->shutdown();
+}
+
+int SpaceMouse::getTranslations(double& dX, double& dY, double& dZ)
+{
+    dX = 0;
+    dY = 0;
+    dZ = 0;
+    return(_spaceMouseImpl->getTranslations(dX, dY, dZ));
+}
+
+int SpaceMouse::getRotations(double& dX, double& dY, double& dZ)
+{
+    dX = 0;
+    dY = 0;
+    dZ = 0;
+    return(_spaceMouseImpl->getRotations(dX, dY, dZ));
+}
Index: /osgVisual/trunk/src/object/object_updater.cpp
===================================================================
--- /osgVisual/trunk/src/object/object_updater.cpp	(revision 176)
+++ /osgVisual/trunk/src/object/object_updater.cpp	(revision 176)
@@ -0,0 +1,70 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <object_updater.h>
+
+using namespace osgVisual;
+
+object_updater::object_updater(osgVisual::visual_object* object_ )
+{
+}
+
+object_updater::~object_updater(void)
+{
+}
+
+void object_updater::preUpdate(osgVisual::visual_object* object_ )
+{
+	OSG_NOTIFY( osg::INFO ) << "preUpdate visual Object " << object_->getName() << std::endl;
+	// perform this preUpdater...
+	//For each visual_object.member,
+	//	try to search according variable in dataIO with direction TO_OBJ and copy value to visual_object.
+
+	
+	object_->lat = osg::DegreesToRadians(osgVisual::visual_dataIO::getInstance()->getSlotDataAsDouble(object_->getName()+"_POS_LAT", osgVisual::dataIO_slot::TO_OBJ ));
+	object_->lon = osg::DegreesToRadians(osgVisual::visual_dataIO::getInstance()->getSlotDataAsDouble(object_->getName()+"_POS_LON", osgVisual::dataIO_slot::TO_OBJ ));
+	object_->alt = osgVisual::visual_dataIO::getInstance()->getSlotDataAsDouble(object_->getName()+"_POS_ALT", osgVisual::dataIO_slot::TO_OBJ );
+	object_->azimuthAngle_psi = osg::DegreesToRadians(osgVisual::visual_dataIO::getInstance()->getSlotDataAsDouble(object_->getName()+"_ROT_Z", osgVisual::dataIO_slot::TO_OBJ ));
+	object_->pitchAngle_theta = osg::DegreesToRadians(osgVisual::visual_dataIO::getInstance()->getSlotDataAsDouble(object_->getName()+"_ROT_Y", osgVisual::dataIO_slot::TO_OBJ ));
+	object_->bankAngle_phi = osg::DegreesToRadians(osgVisual::visual_dataIO::getInstance()->getSlotDataAsDouble(object_->getName()+"_ROT_X", osgVisual::dataIO_slot::TO_OBJ ));
+
+	//object_->setCameraOffsetTranslation(0.0, -150.0, 50.0);	// Trans: (rechts davon, longitudinal, vertikal)
+	object_->setCameraOffsetTranslation( 150.0, 0.0, 30.0);
+	object_->setCameraOffsetRotation( osg::DegreesToRadians(0.0), osg::DegreesToRadians(-15.0), osg::DegreesToRadians(-90.0) );
+	
+
+
+	// Finally execute nested PreUpdater
+	if ( updater.valid() )
+		updater->preUpdate(object_);
+}
+
+void object_updater::postUpdate(osgVisual::visual_object* object_ )
+{
+	OSG_NOTIFY( osg::INFO ) << "postUpdate visual Object " << object_->getName() << std::endl;
+
+	// Finally execute nested PostUpdater
+	if ( updater.valid() )
+		updater->postUpdate(object_);
+}
+
+void object_updater::addUpdater( object_updater* updater_ )
+{
+	if (updater.valid())
+		updater->addUpdater( updater_ );
+	else
+		updater = updater_;
+}
Index: /osgVisual/trunk/src/object/visual_object.cpp
===================================================================
--- /osgVisual/trunk/src/object/visual_object.cpp	(revision 176)
+++ /osgVisual/trunk/src/object/visual_object.cpp	(revision 176)
@@ -0,0 +1,409 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <visual_object.h>
+
+using namespace osgVisual;
+
+visual_object::visual_object( osg::CoordinateSystemNode* sceneRoot_, std::string nodeName_)
+{
+	// Add this node to Scenegraph
+	sceneRoot_->addChild( this );
+
+	// Set Nodename for further identification
+	this->setName( nodeName_ );
+
+	// Set callback.
+	/** \todo: welcher update ist der richtige? voraussichtlich event.) */
+	//this->setUpdateCallback( new visual_objectPositionCallback() );
+	this->setEventCallback( new visual_objectPositionCallback() );
+
+	// Init Position and Attitude
+	lat = 0;
+	lon = 0;
+	alt = 0;
+
+	azimuthAngle_psi = 0;
+	pitchAngle_theta = 0;
+	bankAngle_phi = 0;
+
+	geometry_offset_rotation.makeRotate( 0.0, 1.0, 1.0, 1.0 );
+
+	// Init Scale
+	scaleX = 1.0;
+	scaleY = 1.0;
+	scaleZ = 1.0;
+
+	// Init cameraOffset 
+	cameraTranslationOffset.makeTranslate( osg::Vec3d(0.0, 0.0, 0.0) );	// Trans: (y, x, -z_down)
+	cameraRotationOffset.makeRotate( osg::DegreesToRadians( 90.0 ), osg::Vec3(1, 0, 0) );	// Rot: (-y, +x , -z)
+
+	// Geometrynode hinzufügen
+	geometry = new osg::Group();
+	this->addChild( geometry );
+
+	// Labelnode hinzufügen
+	labels = new osg::Geode();
+	this->addChild( labels ); 
+}
+
+visual_object::~visual_object()
+{
+
+}
+
+void visual_object::setNewPositionAttitude( double lat_, double lon_, double alt_, double azimuthAngle_psi_, double pitchAngle_theta_, double bankAngle_phi_ )
+{
+	lat = lat_;
+	lon = lon_;
+	alt = alt_;
+
+	azimuthAngle_psi = azimuthAngle_psi_;
+	pitchAngle_theta = pitchAngle_theta_;
+	bankAngle_phi = bankAngle_phi_;
+}
+
+void visual_object::setNewPosition( double lat_, double lon_, double alt_ )
+{
+	lat = lat_;
+	lon = lon_;
+	alt = alt_;
+}
+
+void visual_object::setNewAttitude( double azimuthAngle_psi_, double pitchAngle_theta_, double bankAngle_phi_ )
+{
+	azimuthAngle_psi = azimuthAngle_psi_;
+	pitchAngle_theta = pitchAngle_theta_;
+	bankAngle_phi = bankAngle_phi_;
+}
+
+void visual_object::setGeometryOffset( double rotX_, double rotY_, double rotZ_ )
+{
+	geometry_offset_rotation.makeRotate( rotX_, osg::Vec3f(1.0, 0.0, 0.0), 
+						rotY_, osg::Vec3f(0.0, 1.0, 0.0),
+						rotZ_, osg::Vec3f(0.0, 0.0, 1.0) );
+}
+
+void visual_object::setScale( double scale_ )
+{
+	scaleX = scale_;
+	scaleY = scale_;
+	scaleZ = scale_;
+}
+
+void visual_object::setScale( double scaleX_, double scaleY_, double scaleZ_ )
+{
+	scaleX = scaleX_;
+	scaleY = scaleY_;
+	scaleZ = scaleZ_;
+}
+
+bool visual_object::loadGeometry(std::string filename_)
+{
+	// Check if file exists
+	if( !osgDB::fileExists(filename_) )
+	{
+		OSG_NOTIFY(osg::FATAL) << "Error: Model not loaded. File '" << filename_ << "' does not exist." << std::endl;
+	}
+
+	osg::ref_ptr<osg::Node> tmpModel = osgDB::readNodeFile( filename_ );
+	
+	if( tmpModel.valid() )
+	{
+		// remove old geometry
+		geometry->removeChildren(0, geometry->getNumChildren());
+
+		// add new geometry
+		geometry->addChild( tmpModel.get() );
+		return true;
+	}
+	else
+	{
+		std::cout <<": No model loaded: " << filename_ << std::endl;
+        return false;
+    }
+}
+
+bool visual_object::setGeometry(osg::Node* geometry_)
+{
+	// remove old geometry
+	geometry->removeChildren(0, geometry->getNumChildren());
+
+	// add new geometry
+	geometry->addChild( geometry_ );
+
+	return true;
+}
+
+void visual_object::unsetGeometry()
+{
+	// remove old geometry
+	geometry->removeChildren(0, geometry->getNumChildren());
+}
+
+void visual_object::addUpdater( object_updater* updater_ )
+{
+	if ( updater.valid() )
+		updater->addUpdater( updater_ );
+	else
+		updater = updater_;
+}
+
+void visual_object::clearAllUpdater()
+{
+	// release only first updater. Because smartpointer: Will be deleted if not referenced.
+	if ( updater.valid() )
+		updater = NULL;
+}
+
+std::vector<object_updater*> visual_object::getUpdaterList()
+{
+	// iterate through updater and add all pointer.
+	std::vector<object_updater*> updaterList;
+	osg::ref_ptr<object_updater> tmpUpdater = updater;
+
+	while (tmpUpdater.valid())
+	{
+		updaterList.push_back( tmpUpdater );
+		tmpUpdater = tmpUpdater->getPointer();
+	}
+
+	// return list
+	return updaterList;
+}
+
+void visual_object::visual_objectPositionCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
+{
+	visual_object* object = dynamic_cast<visual_object*>(node);
+	if ( !object )
+	{
+		OSG_NOTIFY(osg::FATAL) << "ERROR : No object found. Unable to apply this callback!" << std::endl;
+		return;
+	}
+
+	// execute preUpdater to get new data of this object.
+	if ( object->updater.valid() )
+		object->updater->preUpdate(object);
+    
+	// Nodepath from this node to absolute parent (if no endnode specified)
+	osg::NodePath nodePath = nv->getNodePath();
+
+	// If Nodepath != empty, then mt = last element of node path
+	osg::MatrixTransform* mt = nodePath.empty() ? 0 : dynamic_cast<osg::MatrixTransform*>(nodePath.back());
+	if (mt)
+	{
+		osg::CoordinateSystemNode* csn = 0;
+
+		// find coordinate system node from our parental chain: traverse chain and try to convert every node to a csn.
+		unsigned int i;
+		for(i=0; i<nodePath.size() && csn==0; ++i)	// "&& csn" means: exit loop if csn found
+		{
+			csn = dynamic_cast<osg::CoordinateSystemNode*>(nodePath[i]);	// dynamic_cast returns 0 if dynamic_cast fails.
+		}
+        
+		// Wenn csn gefunden:
+		if (csn)
+		{
+			// Ellipsoidmodel erfragen
+			osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
+			if (ellipsoid)
+			{
+				osg::Matrix inheritedMatrix;
+
+				// durch den _restlichen_ Nodepath durchgehen und alle anfallenden Transformationen durchführen.
+				for(i+=1; i<nodePath.size()-1; ++i)
+				{
+					osg::Transform* transform = nodePath[i]->asTransform();	// Versuchen, den Node zu einer Transformation zu konvertieren
+                    
+					// wenn Node wirklich Trafo, dann die Tranformationsmatrix von Nodekoordinaten nach Global auf inheritedMatrix draufschlagen.
+					if (transform) transform->computeLocalToWorldMatrix(inheritedMatrix, nv);
+				}
+                
+				osg::Matrixd matrix(inheritedMatrix);
+
+				// Set position
+				ellipsoid->computeLocalToWorldTransformFromLatLongHeight(object->lat, object->lon, object->alt, matrix);
+
+				// Set Upvector for position
+				double X,Y,Z;
+				util::calculateXYZAtWGS84Coordinate(object->lat, object->lon, object->alt, csn, X, Y, Z );
+				object->upVector = ellipsoid->computeLocalUpVector(X,Y,Z);
+
+				// Set scale
+				osg::Matrixd scaleMatrix;
+				scaleMatrix.makeScale( object->scaleX, object->scaleY, object->scaleZ );
+				matrix.preMult( scaleMatrix );
+
+				// Set rotation
+				// rotation von links ranmultiplizieren, entspricht: matrix = rotation * matrix. Da rotation ein Quat ist, wäre die direkte Multiplikation nur über Umwege machbar.
+				// Rotate Object to Attitude.
+				osg::Matrixd rotationMatrix;
+				// Move Model by Azimuth
+				rotationMatrix.makeRotate( -object->azimuthAngle_psi, osg::Vec3d(0.0, 0.0, 1.0) );
+				matrix.preMult(rotationMatrix);	
+				// Move Model by Pitch
+				rotationMatrix.makeRotate( object->pitchAngle_theta, osg::Vec3d(1.0, 0.0, 0.0) );
+				matrix.preMult(rotationMatrix);
+				// Move Model by Bank
+				rotationMatrix.makeRotate( object->bankAngle_phi, osg::Vec3d(0.0, 1.0, 0.0) );
+				matrix.preMult(rotationMatrix);
+
+				// Also update camera matrix (without geometry offset, because camera is interested in the objects matrix, not in the model's matrix.)
+				object->cameraMatrix = matrix;
+				/** \todo : Clean up camera matrix management: try to solve it with a single matrix. (each frame two matrix mults less) */
+				// dont know, why this rotation is necessary - maybe manipulator and node MatrixTransform interpret a matrix in different way?
+				object->cameraMatrix.preMult( object->cameraTranslationOffset );
+				object->cameraMatrix.preMult( object->cameraRotationOffset );
+							
+
+				// Set geometry correction
+				matrix.preMultRotate( object->geometry_offset_rotation );
+
+				// Set cumulated object matrix as the matrix of this matrix transform
+				mt->setMatrix(matrix);
+			}
+		}        
+	}
+      
+	// Call any nested callbacks.
+	traverse(node,nv);
+
+	// If SLAVE: execute postUpdater to pass new data of this object to dataIO.
+	if( visual_dataIO::getInstance()->isSlave() )
+	{
+		if ( object->updater.valid() )
+			object->updater->postUpdate(object);
+	}
+
+}   // Callbackfunction [ Operater() ] END
+
+void visual_object::setCameraOffsetTranslation( double x_, double y_, double z_)
+{
+	cameraTranslationOffset.makeTranslate( osg::Vec3d(x_, y_, z_) );	// Trans: (rechts davon, longitudinal, vertikal)
+}
+
+void visual_object::setCameraOffset(double x_, double y_, double z_, double rotX_, double rotY_, double rotZ_)
+{
+	setCameraOffsetTranslation( x_, y_, z_);
+	setCameraOffsetRotation( rotX_, rotY_, rotZ_);
+}
+
+void visual_object::setCameraOffsetRotation(double rotX_, double rotY_, double rotZ_)
+{
+	osg::Matrix tmp;
+	cameraRotationOffset.makeRotate( osg::DegreesToRadians( 90.0 ), osg::Vec3(1, 0, 0) );
+	tmp.makeRotate( -rotZ_, osg::Vec3d(0.0, 1.0, 0.0) );
+	cameraRotationOffset.preMult(tmp);
+	tmp.makeRotate( rotY_, osg::Vec3d(1.0, 0.0, 0.0) );	
+	cameraRotationOffset.preMult(tmp);
+	tmp.makeRotate( -rotX_, osg::Vec3d(0.0, 0.0, 1.0) );	
+	cameraRotationOffset.preMult(tmp);
+}
+
+void visual_object::clearLabels()
+{
+	labels->removeDrawables(0, labels->getNumDrawables());
+}
+
+void visual_object::addLabel(std::string idString_, std::string label_, osg::Vec4 color_, osg::Vec3 offset_)
+{
+	osg::ref_ptr<osgText::Text> text = new osgText::Text();
+
+	text->setName(idString_);
+	text->setText(label_);
+	text->setColor(color_);
+	text->setFont("fonts/arial.ttf");
+	text->setCharacterSizeMode(osgText::Text::OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT);
+	text->setAutoRotateToScreen(true);
+	text->setPosition(offset_);
+
+	text->getOrCreateStateSet()->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
+	labels->addDrawable( text );
+}
+
+bool visual_object::removeLabel(std::string idString_)
+{
+	osg::Node* labelToRemove = util::findNamedNode(idString_, this);
+
+	if(labelToRemove)
+	{
+		removeChild( labelToRemove );
+		return true;
+	}
+	else
+		return false;
+}
+
+bool visual_object::updateLabelText(std::string idString_, std::string label_)
+{
+	osg::Node* labelToUpdate = util::findNamedNode(idString_, this);
+
+	if(labelToUpdate)
+	{
+		osgText::Text* text = dynamic_cast<osgText::Text*>(labelToUpdate);
+		if(text)
+		{
+			text->setText(label_);
+			return true;
+		}
+		return false;
+	}
+	return false;
+}
+
+osgText::Text* visual_object::getLabel(std::string idString_)
+{
+	osg::Node* labelToFind = util::findNamedNode(idString_, this);
+
+	if(labelToFind)
+	{
+		osgText::Text* text = dynamic_cast<osgText::Text*>(labelToFind);
+		if(text)
+			return text;
+	}
+	return NULL;
+
+}
+
+bool visual_object::setDrawLabelAsOverlay(std::string idString_, bool drawAsOverlay)
+{
+	osg::Node* labelToFind = util::findNamedNode(idString_, this);
+
+	if(labelToFind)
+	{
+		if (drawAsOverlay)
+			labelToFind->getOrCreateStateSet()->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF);
+		else
+			labelToFind->getOrCreateStateSet()->setMode(GL_DEPTH_TEST,osg::StateAttribute::ON);
+		return true;
+	}
+	else 
+		return false;
+}
+
+bool visual_object::getDrawLabelAsOverlay(std::string idString_)
+{
+	osg::Node* labelToFind = util::findNamedNode(idString_, this);
+
+	if(labelToFind)
+	{
+		if(labelToFind->getOrCreateStateSet()->getMode(GL_DEPTH_TEST) == osg::StateAttribute::OFF)
+			return false;
+		else 
+			return true;
+	}
+	return false;
+}
Index: /osgVisual/trunk/src/sky_Silverlining/skySilverLining_cloudsDrawable.cpp
===================================================================
--- /osgVisual/trunk/src/sky_Silverlining/skySilverLining_cloudsDrawable.cpp	(revision 176)
+++ /osgVisual/trunk/src/sky_Silverlining/skySilverLining_cloudsDrawable.cpp	(revision 176)
@@ -0,0 +1,63 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+ * 
+ * This file is based on the OSG example of the Silverlining SDK:
+ * Copyright (c) 2008 Sundog Software, LLC. All rights reserved worldwide.
+*/
+
+#include <skySilverLining_cloudsDrawable.h>
+#include <SilverLining.h>
+#include <skySilverLining_AtmosphereReference.h>
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <assert.h>
+
+
+using namespace osgVisual;
+using namespace SilverLining;
+
+skySilverLining_cloudsDrawable::skySilverLining_cloudsDrawable()
+        : osg::Drawable()
+{
+    setDataVariance(osg::Object::DYNAMIC);
+    setUseVertexBufferObjects(false);
+    setUseDisplayList(false);
+}
+
+skySilverLining_cloudsDrawable::skySilverLining_cloudsDrawable(osgViewer::Viewer* view)
+        : osg::Drawable()
+        , _view(view)
+{
+    setDataVariance(osg::Object::DYNAMIC);
+    setUseVertexBufferObjects(false);
+    setUseDisplayList(false);
+}
+
+void skySilverLining_cloudsDrawable::drawImplementation(osg::RenderInfo& renderInfo) const
+{
+	osgVisual::skySilverLining_atmosphereReference *ar = dynamic_cast<osgVisual::skySilverLining_atmosphereReference *>(renderInfo.getCurrentCamera()->getUserData());
+	SilverLining::Atmosphere *atmosphere = 0;
+	if (ar) atmosphere = ar->atmosphere;
+
+	renderInfo.getState()->disableAllVertexArrays();
+
+    if (atmosphere)
+    {
+        atmosphere->EndFrame(true);
+    }
+
+	renderInfo.getState()->dirtyAllVertexArrays();
+}
Index: /osgVisual/trunk/src/sky_Silverlining/skySilverLining_skyDrawable.cpp
===================================================================
--- /osgVisual/trunk/src/sky_Silverlining/skySilverLining_skyDrawable.cpp	(revision 176)
+++ /osgVisual/trunk/src/sky_Silverlining/skySilverLining_skyDrawable.cpp	(revision 176)
@@ -0,0 +1,296 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+ * 
+ * This file is based on the OSG example of the Silverlining SDK:
+ * Copyright (c) 2008 Sundog Software, LLC. All rights reserved worldwide.
+*/
+
+#include <skySilverLining_skyDrawable.h>
+#include <SilverLining.h>
+#include <skySilverLining_AtmosphereReference.h>
+
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <assert.h>
+
+
+
+using namespace SilverLining;
+using namespace osgVisual;
+
+skySilverLining_skyDrawable::skySilverLining_skyDrawable()
+        : osg::Drawable()
+		, _view(0)
+		, _skyboxSize(0)
+{
+    setDataVariance(osg::Object::DYNAMIC);
+    setUseVertexBufferObjects(false);
+    setUseDisplayList(false);
+	pendingNewCloudLayers.clear();
+	newCloudLayersToAdd = false;
+}
+
+skySilverLining_skyDrawable::skySilverLining_skyDrawable(osgViewer::Viewer* view,  osg::CoordinateSystemNode* csn_)
+        : osg::Drawable()
+        , _view(view)
+		, _skyboxSize(0)
+{
+    setDataVariance(osg::Object::DYNAMIC);
+    setUseVertexBufferObjects(false);
+    setUseDisplayList(false);
+	pendingNewCloudLayers.clear();
+	newCloudLayersToAdd = false;
+	sceneRoot = csn_;
+}
+
+void skySilverLining_skyDrawable::setLighting(SilverLining::Atmosphere *atmosphere) const
+{
+    osg::Light *light = _view->getLight();
+    osg::Vec4 ambient, diffuse;
+    osg::Vec3 direction;
+
+    if (atmosphere && light)
+    {
+        float ra, ga, ba, rd, gd, bd, x, y, z;
+        atmosphere->GetAmbientColor(&ra, &ga, &ba);
+        atmosphere->GetSunOrMoonColor(&rd, &gd, &bd);
+        atmosphere->GetSunOrMoonPosition(&x, &y, &z);
+
+        direction = osg::Vec3(x, y, z);
+        ambient = osg::Vec4(ra, ga, ba, 1.0);
+        diffuse = osg::Vec4(rd, gd, bd, 1.0);
+
+        // xform the light direction into camera coordinates
+        osg::Quat view = _view->getCamera()->getViewMatrix().getRotate();
+        //direction = view * direction;
+        direction.normalize();
+
+        light->setAmbient(ambient);
+        light->setDiffuse(diffuse);
+        light->setSpecular(osg::Vec4(0,0,0,1));
+        light->setPosition(osg::Vec4(direction.x(), direction.y(), direction.z(), 0));
+    }
+}
+
+void skySilverLining_skyDrawable::setSceneFog(SilverLining::Atmosphere *atmosphere) const
+{    
+	osg::ref_ptr<osg::Fog> fog = new osg::Fog;
+    fog->setMode(osg::Fog::EXP);
+	//fog->setUseRadialFog( true );
+
+	//_objectsNode  = erde oder object, das mit nebel bedacht werden soll	
+	sceneRoot->getOrCreateStateSet()->setAttributeAndModes(fog.get());
+
+	//float hazeR, hazeG, hazeB;
+	//double hazeDepth, hazeDensity;
+	//atmosphere->GetHaze(hazeR, hazeG, hazeB, hazeDepth, hazeDensity);
+
+    //hazeDensity = 1.0 / 40000;
+	//hazeDensity = 0;
+	float hazeDensity = 1.0 / atmosphere->GetConditions()->GetVisibility();
+
+    // Decrease fog density with altitude, to avoid fog effects through the vacuum of space.
+    static const double H = 8435.0; // Pressure scale height of Earth's atmosphere
+    double isothermalEffect = exp(-(atmosphere->GetConditions()->GetLocation().GetAltitude() / H));     
+    if (isothermalEffect <= 0) isothermalEffect = 1E-9;
+    if (isothermalEffect > 1.0) isothermalEffect = 1.0;
+    hazeDensity *= isothermalEffect;
+
+    bool silverLiningHandledTheFog = false;
+
+    if (atmosphere->GetFogEnabled())
+    {
+            float density, r, g, b;
+            // Note, the fog color returned is already lit
+            atmosphere->GetFogSettings(&density, &r, &g, &b);
+
+            if (density > hazeDensity)
+            {
+				fog->setDensity(density);
+				fog->setColor(osg::Vec4(r, g, b, 1.0));
+
+				silverLiningHandledTheFog = true;
+            }
+    }
+    
+    if (!silverLiningHandledTheFog)
+    {
+		float r, g, b;
+		atmosphere->GetHorizonColor(0, &r, &g, &b);// New version of this call: since SL_1.94 /** \todo transmit the yaw value of the center channel to all slaves for consistent fog color. */
+
+		fog->setDensity(hazeDensity);
+		fog->setColor(osg::Vec4(r, g, b, 1.0));
+    }
+
+}
+
+void skySilverLining_skyDrawable::initializeSilverLining(skySilverLining_atmosphereReference *ar)
+{
+    if (ar && !ar->atmosphereInitialized)
+    {
+        ar->atmosphereInitialized = true; // only try once.
+		SilverLining::Atmosphere *atmosphere = ar->atmosphere;
+
+		if (atmosphere)
+        {
+
+			srand(1234); // constant random seed to ensure consistent clouds across windows
+
+            // Update the path below to where you installed SilverLining's resources folder.
+            //int ret = atmosphere->Initialize(SilverLining::Atmosphere::OPENGL, "C:\\Program Files\\SilverLining SDK\\resources\\", true, 0);
+			int ret = atmosphere->Initialize(SilverLining::Atmosphere::OPENGL, "../resources/sky_silverlining/", true, 0);
+            if (ret != SilverLining::Atmosphere::E_NOERROR)
+            {
+                printf("SilverLining failed to initialize; error code %d.\n", ret);
+                printf("Check that the path to the SilverLining installation directory is set properly ");
+                printf("in skySilverLining_skyDrawable.cpp (in SkyDrawable::initializeSilverLining)\n");
+                exit(0);
+            }
+
+            // Let SilverLining know which way is up. OSG usually has Z going up.
+			atmosphere->SetUpVector(0.662994, 0.136169, 0.736136);
+			atmosphere->SetRightVector(-0.201185, 0.979553, 0.0);
+
+            // Set our location (change this to your own latitude and longitude)
+            SilverLining::Location loc;
+            loc.SetAltitude(0);
+            loc.SetLatitude(47);
+            loc.SetLongitude(11);
+            atmosphere->GetConditions()->SetLocation(loc);
+
+            // Set the system time in PST
+            SilverLining::LocalTime t;
+            t.SetFromSystemTime();
+			t.SetTimeZone(CET);
+            atmosphere->GetConditions()->SetTime(t);
+
+			// Setting Up Visibility
+			atmosphere->GetConditions()->SetVisibility(40000);
+
+			// Setting Up Haze
+			atmosphere->GetConditions()->SetTurbidity(2.2);
+
+			// Setting up time passage
+			atmosphere->GetConditions()->EnableTimePassage( true, 5000 );
+			
+		}	// if atmosphere ENDE
+
+    }	// If atmosphere not initialized ENDE
+}
+
+void skySilverLining_skyDrawable::drawImplementation(osg::RenderInfo& renderInfo) const
+{
+	skySilverLining_atmosphereReference *ar = dynamic_cast<skySilverLining_atmosphereReference *>(renderInfo.getCurrentCamera()->getUserData());
+	SilverLining::Atmosphere *atmosphere = 0;
+
+	if (ar) atmosphere = ar->atmosphere;
+
+	renderInfo.getState()->disableAllVertexArrays();
+
+    if (atmosphere)
+    {
+        initializeSilverLining(ar);
+		const_cast<skySilverLining_skyDrawable*>(this)->seedAndAddCloudLayers(atmosphere);
+
+
+        atmosphere->BeginFrame(true, true, _skyboxSize);
+        setLighting(atmosphere);
+		setSceneFog(atmosphere);
+    }
+
+	renderInfo.getState()->dirtyAllVertexArrays();
+}
+
+void skySilverLining_skyDrawable::addCloudLayerOrder(cloudlayerOrder newCL)
+{
+	OpenThreads::ScopedLock<OpenThreads::Mutex> sLock(cloudLayersToAddMutex); 
+	pendingNewCloudLayers.push_back( newCL );
+	newCloudLayersToAdd = true;
+}
+
+void skySilverLining_skyDrawable::seedAndAddCloudLayers(SilverLining::Atmosphere *atmosphere)
+{
+	// Only try to add if anything to do..
+	if ( newCloudLayersToAdd )
+	{
+		OpenThreads::ScopedLock<OpenThreads::Mutex> sLock(cloudLayersToAddMutex); 
+
+		for ( unsigned int i=0; i<pendingNewCloudLayers.size(); i++)	// Configure & Seed cloudLayer
+		{
+			// Calculation earth radius on specified lat lon position
+			double radius;
+			cloudlayerOrder newCL = pendingNewCloudLayers[i];
+			if ( !util::calculateEarthRadiusAtWGS84Coordinate(newCL.lat, newCL.lon, sceneRoot, radius) )
+			{
+				OSG_ALWAYS << "ERROR: skySilverLining_skyDrawable::seedAndAddCloudLayers() - Unable to deterine earth radius for lat=" <<newCL.lat<< " lon="<<newCL.lat<<std::endl;
+				return;
+			}
+
+			// generate Cloud Layer
+			SilverLining::CloudLayer *cloudLayer_;
+			cloudLayer_ = SilverLining::CloudLayerFactory::Create(newCL.cloudtype);
+			cloudLayer_->SetBaseAltitude( newCL.baseHeight + radius);
+			cloudLayer_->SetThickness(newCL.thickness);
+			cloudLayer_->SetBaseLength(newCL.baseLength);
+			cloudLayer_->SetBaseWidth(newCL.baseWidth);
+			cloudLayer_->SetDensity(newCL.density);
+			cloudLayer_->SetLayerPosition( 0.0, 0.0 );
+			cloudLayer_->GenerateShadowMaps(false);
+			//cloudLayer_->SetIsInfinite( true );
+
+
+			//Save cloudlayer information into SLOT
+			newCL.assocCloudLayerSlot->used = true;
+			newCL.assocCloudLayerSlot->enabled = true;
+			newCL.assocCloudLayerSlot->cloudLayerPointer = cloudLayer_;
+			switch(newCL.cloudtype)
+			{
+			case 0: newCL.assocCloudLayerSlot->typeName = "CIRROCUMULUS";				// High planar cloud puffs		
+				break;
+			case 1: newCL.assocCloudLayerSlot->typeName = "CIRRUS_FIBRATUS";			// High, thicker and fibrous clouds that signal changing weather
+				break;
+			case 2: newCL.assocCloudLayerSlot->typeName = "STRATUS";					// Low clouds represented as a slab
+				break;
+			case 3: newCL.assocCloudLayerSlot->typeName = "CUMULUS_MEDIOCRIS";          // Low, puffy clouds on fair days
+				break;
+			case 4: newCL.assocCloudLayerSlot->typeName = "CUMULUS_CONGESTUS";          // Large cumulus clouds that could turn into a thunderhead
+				break;
+			case 5: newCL.assocCloudLayerSlot->typeName = "CUMULONIMBUS_CAPPILATUS";    // Big storm clouds.
+				break;
+			case 6: newCL.assocCloudLayerSlot->typeName = "STRATOCUMULUS";				// Low, dense, puffy clouds with some sun breaks between them.
+				break;
+			default: OSG_NOTIFY( osg::FATAL ) << "skySilverLining_skyDrawable::seedAndAddCloudLayers() - Invalid cloud type." << std::cout;
+				 break;
+			};
+
+			// Seed Cloudlayer
+			cloudLayer_->SeedClouds(*atmosphere);
+	
+			// Add cloudLayer to atmosphere
+			newCL.assocCloudLayerSlot->cloudLayerHandle = atmosphere->GetConditions()->AddCloudLayer( cloudLayer_ );
+		}
+
+		//Clear the ToDo List
+		pendingNewCloudLayers.clear();
+
+		// Note nothing to do.
+		newCloudLayersToAdd = false;
+	}
+}
+
+void skySilverLining_skyDrawable::shutdown()
+{
+	sceneRoot = NULL;
+}
Index: /osgVisual/trunk/src/sky_Silverlining/visual_skySilverLining.cpp
===================================================================
--- /osgVisual/trunk/src/sky_Silverlining/visual_skySilverLining.cpp	(revision 176)
+++ /osgVisual/trunk/src/sky_Silverlining/visual_skySilverLining.cpp	(revision 176)
@@ -0,0 +1,733 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <visual_skySilverLining.h>
+
+using namespace osgVisual;
+
+visual_skySilverLining::visual_skySilverLining(osgViewer::Viewer* viewer_, std::string configFileName)
+{
+	OSG_NOTIFY( osg::ALWAYS ) << "Initialize visual_skySilverlining..." << std::endl;
+
+	atmosphereInitialized = false;
+	postInitialized = false;
+	atmosphere = NULL;
+	viewer = viewer_;
+	lat = 0;
+	lon = 0;
+
+	for( int i=0; i<MAX_CLOUDLAYER_SLOTS; i++ )
+	{
+		cloudLayerSlots.push_back( cloudLayerSlot() );
+		cloudLayerSlots.back().slot_id = i;
+	}
+}
+
+visual_skySilverLining::~visual_skySilverLining(void)
+{
+	this->removeUpdateCallback( updateCallback );
+	if ( atmosphere != NULL )
+		delete atmosphere;
+}
+
+void visual_skySilverLining::skyUpdateCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
+{
+	//std::cout << "Sky silverlining update callback" << std::endl;
+	// Check if atmosphere is initialized.
+	if (!sky->isInitialized())
+		return;
+
+	// on first time: perform Post-Init.
+	sky->postInit();
+
+	// Update sky
+	double lat, lon, height;
+	util::getWGS84ofCamera( sceneCamera, csn, lat, lon, height );
+	//std::cout << "lat: " << osg::RadiansToDegrees(lat) << ", lon: " << osg::RadiansToDegrees(lon) << ", height: " << height << std::endl;
+	sky->setLocation( lat, lon, height );
+}
+
+void visual_skySilverLining::setDateTime( int year_, int month_, int day_, int hour_, int minute_, int second_, bool daylightSaving_, double timezoneOffset_ )
+{
+	// Check if atmosphere is initialized.
+	if (!isInitialized())
+		return;
+
+	SilverLining::LocalTime t = atmosphere->GetConditions()->GetTime();
+	t.SetYear( year_ );
+	t.SetMonth( month_ );
+	t.SetDay( day_ );
+	t.SetHour( hour_ );
+	t.SetMinutes( minute_ );
+	t.SetSeconds( second_ );
+	t.SetObservingDaylightSavingsTime( daylightSaving_ );
+	t.SetTimeZone( timezoneOffset_ );
+}
+
+void visual_skySilverLining::setTime( int hour_, int minute_, int second_ )
+{
+	// Check if atmosphere is initialized.
+	if (!isInitialized())
+		return;
+	
+	SilverLining::LocalTime t = atmosphere->GetConditions()->GetTime();
+	t.SetHour( hour_ );
+	t.SetMinutes( minute_ );
+	t.SetSeconds( second_ );
+	atmosphere->GetConditions()->SetTime( t );
+}
+
+void visual_skySilverLining::setDate( int year_, int month_, int day_ )
+{
+	// Check if atmosphere is initialized.
+	if (!isInitialized())
+		return;
+
+	SilverLining::LocalTime t = atmosphere->GetConditions()->GetTime();
+	t.SetYear( year_ );
+	t.SetMonth( month_ );
+	t.SetDay( day_ );
+}
+
+void visual_skySilverLining::setDateByEpoch( int secondsSince1970_ )
+{
+	// Check if atmosphere is initialized.
+	if (!isInitialized())
+		return;
+	
+	SilverLining::LocalTime t = atmosphere->GetConditions()->GetTime();
+	t.SetFromEpochSeconds( secondsSince1970_ );
+}
+
+void visual_skySilverLining::setLocation(double lat_, double lon_, double alt_)
+{
+	// Check if atmosphere is initialized.
+	if (!isInitialized())
+		return;
+
+	lat = lat_;
+	lon = lon_;
+	height = alt_;
+	
+	SilverLining::Location loc = atmosphere->GetConditions()->GetLocation();
+	loc.SetAltitude(alt_);
+	loc.SetLatitude(lat_);
+	loc.SetLongitude(lon_);		
+	atmosphere->GetConditions()->SetLocation( loc );
+
+	updateUpVector();
+}
+
+
+bool visual_skySilverLining::isInitialized()
+{
+	// Check if atmosphere is initialized. If not: make a deep lookup. If initialized, perform. Otherwise return
+	if (!atmosphereInitialized)
+	{
+		skySilverLining_atmosphereReference *ar = dynamic_cast<skySilverLining_atmosphereReference *>(viewer->getCamera()->getUserData());
+		if (ar != NULL )
+		{
+			if (ar->atmosphereInitialized)
+				atmosphereInitialized = true;
+		}
+	}
+	return(atmosphereInitialized);
+}
+
+void visual_skySilverLining::init(osg::Group *distortedRoot, osg::CoordinateSystemNode *sceneGraphRoot)
+{
+	sceneRoot = sceneGraphRoot;
+
+	// Use projection matrix callback oder fixed Cullsettings?
+	bool useProjMatrixCallback = true;
+
+	// add Sky to SceneGraphRoot
+	sceneGraphRoot->addChild( this );
+
+	// Deactivate culling for the sky node (required by the silverlining sky framework)
+	this->setCullingActive(false);
+
+	// Instantiate an Atmosphere and associate it with this camera. If you have multiple cameras
+	// in multiple contexts, be sure to instantiate seperate Atmosphere objects for each.
+    // ***IMPORTANT!**** Check that the path to the resources folder for SilverLining in SkyDrawable.cpp
+    // SkyDrawable::initializeSilverLining matches with where you installed SilverLining.
+	atmosphere = new SilverLining::Atmosphere(SILVERLINING_LICENSEE, SILVERLINING_LICENSE);
+
+    // Add the sky (calls Atmosphere::BeginFrame and handles initialization once you're in
+    // the rendering thread)
+	skyDrawable = new skySilverLining_skyDrawable(viewer, sceneRoot);
+
+	if(distortedRoot)	// if distortion used:
+	{
+		int rootKids = distortedRoot->getNumChildren();
+		for (int i = 0; i < rootKids; i++)
+		{
+			osg::Node *n = distortedRoot->getChild(i);
+			osg::Camera *cam = dynamic_cast<osg::Camera*>(n);
+			if (cam && cam->getRenderOrder() == osg::Camera::PRE_RENDER)
+				sceneCamera = cam;
+		}
+	}
+	else	// if no distortion used:
+		sceneCamera = viewer->getCamera();
+
+	osg::Camera *mainCamera = viewer->getCamera();
+	if (!useProjMatrixCallback)
+	{
+		mainCamera->setClearMask(0);
+		mainCamera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
+		double fovy, aspect, zNear, zFar;
+		mainCamera->getProjectionMatrixAsPerspective(fovy, aspect, zNear, zFar);
+		mainCamera->setProjectionMatrixAsPerspective(fovy, aspect, 2, 125000);
+	}
+	else
+	{
+		cb = new skySilverLining_projectionMatrixCallback( atmosphere, viewer->getCamera(), sceneRoot);
+		sceneCamera->setClampProjectionMatrixCallback(cb);
+		cb->setSkyDrawable(skyDrawable);
+	}
+
+	// append atmosphere pointer to the cameras.
+	sceneCamera->setClearMask(0);
+	osg::ref_ptr<skySilverLining_atmosphereReference> ar = new skySilverLining_atmosphereReference;
+	ar->atmosphere = atmosphere;
+	sceneCamera->setUserData(ar);
+	mainCamera->setUserData(ar);
+
+	// Create and install updateCallback (for position etc.)
+	updateCallback = new skyUpdateCallback( sceneGraphRoot, sceneCamera, this );
+	this->setUpdateCallback( updateCallback );
+
+    // Use a RenderBin to enforce that the sky gets drawn first, then the scene, then the clouds
+	skyDrawable->getOrCreateStateSet()->setRenderBinDetails(-1, "RenderBin");
+
+    // Add the models
+    sceneGraphRoot->getOrCreateStateSet()->setRenderBinDetails(1, "RenderBin");
+
+    // Add the clouds (note, you need this even if you don't want clouds - it calls
+    // Atmosphere::EndFrame() )
+	cloudsDrawable = new skySilverLining_cloudsDrawable(viewer);
+	cloudsDrawable->getOrCreateStateSet()->setRenderBinDetails(99, "RenderBin");
+
+	// Add drawable to this geode to get rendered
+	this->addDrawable(skyDrawable);
+	this->addDrawable(cloudsDrawable);
+
+	//SilverLining::Atmosphere::EnableHDR( true );
+}
+
+void visual_skySilverLining::postInit()
+{
+	// Only allow one execution
+	//if(postInitialized)
+	//	return;
+	//else postInitialized = true;
+
+	// Execute Updatecallback once before adding Clouds.
+	//updateCallback->operator ()(this, NULL);
+
+	//atmosphere->GetConditions()->SetFog( 0.8, 1, 1, 1);	// use this for simulation real fog.
+
+	//Todo: secure memory-manager of timer*. oder remove paragraph
+	//MyMillisecondTimer *timer = new MyMillisecondTimer();
+ //   atmosphere->GetConditions()->SetMillisecondTimer(timer);
+	//atmosphere->GetConditions()->EnableTimePassage(true, -1);
+}
+
+void visual_skySilverLining::updateUpVector()
+{
+	double x,y,z;
+    util::getXYZofCamera(sceneCamera, x, y, z);
+
+    osg::Vec3d up(x, y, z);
+
+    up.normalize();
+    osg::Vec3d north(0, 0, 1);	// Z is north
+    osg::Vec3d east = north ^ up;	// Cross product
+    east.normalize();
+
+    atmosphere->SetUpVector(up.x(), up.y(), up.z());
+    atmosphere->SetRightVector(east.x(), east.y(), east.z());
+
+    osg::Matrixd proj = sceneCamera->getProjectionMatrix();
+    double dProj[16];
+
+    int i = 0;
+    for (int row = 0; row < 4; row++)
+    {
+        for (int col = 0; col < 4; col++)
+        {
+            dProj[i] = proj(row, col);
+            i++;
+        }
+    }
+    //atmosphere->SetProjectionMatrix(dProj);
+}
+
+void visual_skySilverLining::shutdown()
+{
+	if (isInitialized())
+	{
+		// Remove this Node from scenegraph
+		sceneRoot->removeChild( this );
+		
+		// Remove updatecallback
+		this->removeUpdateCallback( updateCallback );
+		updateCallback = NULL;
+
+		// delete drawables
+		skyDrawable->shutdown();
+		this->removeDrawable(skyDrawable);
+		this->removeDrawable(cloudsDrawable);
+	}
+}
+
+void visual_skySilverLining::setVisibility(double visibility_)
+{
+	if (isInitialized())
+	{
+		atmosphere->GetConditions()->SetVisibility( visibility_ );
+	}
+
+}
+
+double visual_skySilverLining::getVisibility()
+{
+	if (isInitialized())
+	{
+		return atmosphere->GetConditions()->GetVisibility();
+	}
+	else
+		return -1;
+}
+
+void visual_skySilverLining::setTurbidity(double turbidity_)
+{
+	if (isInitialized())
+	{
+		atmosphere->GetConditions()->SetTurbidity( turbidity_ );
+	}
+}
+
+double visual_skySilverLining::getTurbidity()
+{
+	if (isInitialized())
+	{
+		return atmosphere->GetConditions()->GetTurbidity();
+	}
+	else
+		return -1;
+}
+
+void visual_skySilverLining::clearAllWindVolumes()
+{
+	if (isInitialized())
+	{
+		atmosphere->GetConditions()->ClearWindVolumes();
+	}
+}
+
+bool visual_skySilverLining::insideWind(double height_, double& bottom_, double& top_, double& speed_, double& direction_)
+{
+	if (isInitialized())
+	{
+		// Calculation earth radius on the wind positionl approximated through the now used position.
+		double radius;
+		if ( util::calculateEarthRadiusAtWGS84Coordinate(lat, lon, sceneRoot, radius) )
+		{
+			// go through all wind volumes an check them for inside()
+			//std::map<int, SilverLining::WindVolume> windvolumes = atmosphere->GetConditions()->GetWindVolumes();
+			SL_MAP(int, SilverLining::WindVolume) windvolumes = atmosphere->GetConditions()->GetWindVolumes();
+			for(unsigned int i=0; i<windvolumes.size(); i++)
+			{
+				if( windvolumes[i].Inside(radius + height_) )
+				{
+					// save wind data
+					bottom_ = windvolumes[i].GetMinAltitude();
+					top_ = windvolumes[i].GetMaxAltitude() - radius;
+					speed_ = windvolumes[i].GetWindSpeed() - radius;
+					direction_ = windvolumes[i].GetDirection();
+					// return that wind was found
+					return true;
+				}
+			}	// For END
+		}	// If valid radius END
+	}	// If initialized() END
+	bottom_ = -1;
+	top_ = -1;
+	speed_ = -1;
+	direction_ = -1;
+	return false;
+}
+
+void visual_skySilverLining::addWindVolume(double bottom_, double top_, double speed_, int direction_)
+{
+	if (isInitialized())		
+	{
+		// Calculation earth radius on current lat lon position
+		double radius;
+		if ( util::calculateEarthRadiusAtWGS84Coordinate(lat, lon, sceneRoot, radius) )
+		{
+			// correct wind value:
+			if ( direction_ < 180 )
+				direction_ += 180;
+			else direction_ -= 180;
+
+			// Setting up Wind
+			SilverLining::WindVolume wv;
+			wv.SetDirection( direction_ );
+			wv.SetMinAltitude( radius + bottom_ );
+			wv.SetMaxAltitude( radius + top_ );
+			wv.SetWindSpeed( speed_ );
+			atmosphere->GetConditions()->SetWind(wv);
+		}
+	}
+}
+
+void visual_skySilverLining::setLightPollution(double lightPollution_)
+{
+	if (isInitialized())
+	{
+		return atmosphere->GetConditions()->SetLightPollution( lightPollution_ );
+	}
+}
+
+double visual_skySilverLining::getLightPollution()
+{
+	if (isInitialized())
+	{
+		return atmosphere->GetConditions()->GetLightPollution();
+	}
+	else
+		return -1;
+
+}
+
+void visual_skySilverLining::addCloudLayer(int slot_, double baseLength_, double baseWidth_, double thickness_, double baseHeight_, double density_, CloudTypes cloudtype_ )
+{
+	if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
+	{
+		// create cloudlayer order and pass to skyDrawable to instantiate.
+		cloudlayerOrder newCL;
+		newCL.slot = slot_;
+		newCL.lat = lat;
+		newCL.lon = lon;
+		newCL.baseLength = baseLength_;
+		newCL.baseWidth = baseWidth_;
+		newCL.thickness = thickness_;
+		newCL.baseHeight = baseHeight_;
+		newCL.density = density_;
+		newCL.cloudtype = cloudtype_;
+		newCL.assocCloudLayerSlot = &cloudLayerSlots[slot_];
+		
+		skyDrawable->addCloudLayerOrder( newCL );
+
+	}	 // If isInitialized() END
+}
+
+void visual_skySilverLining::removeCloudLayer( int slot_ )
+{
+	if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
+	{
+		atmosphere->GetConditions()->RemoveCloudLayer( cloudLayerSlots[slot_].cloudLayerHandle );
+		cloudLayerSlots[slot_].used = false;
+		cloudLayerSlots[slot_].cloudLayerHandle = -1;
+		cloudLayerSlots[slot_].cloudLayerPointer = NULL;
+		cloudLayerSlots[slot_].enabled = false;
+	}
+}
+
+void visual_skySilverLining::clearAllSlots()
+{
+	if (isInitialized())
+	{
+		atmosphere->GetConditions()->RemoveAllCloudLayers();
+		for( int i=0; i<MAX_CLOUDLAYER_SLOTS; i++ )
+		{
+			cloudLayerSlots[i].used = false;
+			cloudLayerSlots[i].cloudLayerHandle = -1;
+			cloudLayerSlots[i].cloudLayerPointer = NULL;
+			cloudLayerSlots[i].enabled = false;
+		}
+	}
+}
+
+SilverLining::CloudLayer* visual_skySilverLining::getCloudLayer( int slot_ )
+{
+	if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
+	{
+		if ( cloudLayerSlots[slot_].used )
+			return cloudLayerSlots[slot_].cloudLayerPointer; 
+	}
+
+	return NULL;
+}
+
+void visual_skySilverLining::setEnabled(int slot_, bool enabled_ )
+{
+	if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
+	{
+		cloudLayerSlots[slot_].enabled = enabled_;
+	}
+}
+
+bool visual_skySilverLining::isEnabled( int slot_ )
+{
+	if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
+	{
+		return cloudLayerSlots[slot_].enabled;
+	}
+	return false;
+}
+
+void visual_skySilverLining::fadeVisibility( int slot_, int fadetimeMS_ )
+{
+	if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
+	{
+		if (cloudLayerSlots[slot_].enabled)
+		{
+			cloudLayerSlots[slot_].enabled = false;
+			cloudLayerSlots[slot_].cloudLayerPointer->SetEnabled( false, fadetimeMS_ );
+		}
+		else
+		{
+			cloudLayerSlots[slot_].enabled = true;
+			cloudLayerSlots[slot_].cloudLayerPointer->SetEnabled( true, fadetimeMS_ );
+		}
+	}
+}
+
+std::string visual_skySilverLining::getCloudLayerTypeName( int slot_ )
+{
+	if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
+	{
+		return cloudLayerSlots[slot_].typeName;
+	}
+	return "";
+}
+
+void visual_skySilverLining::clearGlobalPrecipitation()
+{
+	if (isInitialized())
+	{
+		atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 );
+	}
+}
+
+void visual_skySilverLining::setGlobalPrecipitation( double rate_mmPerHour_rain_, double rate_mmPerHour_drySnow_, double rate_mmPerHour_wetSnow_, double rate_mmPerHour_sleet_ )
+{
+	if ( isInitialized() )
+	{
+		// Delete old Precipitation
+		atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 );
+		
+		// Set new Precipitation
+		atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::RAIN, rate_mmPerHour_rain_ );
+		atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::WET_SNOW, rate_mmPerHour_drySnow_ );
+		atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::DRY_SNOW, rate_mmPerHour_wetSnow_ );
+		atmosphere->GetConditions()->SetPrecipitation( SilverLining::CloudLayer::SLEET, rate_mmPerHour_sleet_ );
+	}
+}
+	
+bool visual_skySilverLining::getOverallPrecipitationAtLocation( double& rate_mmPerHour_rain, double& rate_mmPerHour_drySnow, double& rate_mmPerHour_wetSnow, double& rate_mmPerHour_sleet, double lat_, double lon_, double height_ )
+{
+	if (isInitialized())
+	{
+		// Init
+		bool hasPrecipitation = false;
+		double x = 0;
+		double y = 0;
+		double z = 0;
+		//// If -1 : Use sky internal values
+		if ( lat_ == -1 )
+			lat_ = lat;
+		if ( lon_ == -1 )
+			lon_ = lon;
+		if ( height_ == -1 )
+			height_ = height;
+
+		// Set precipitation to zero;
+		rate_mmPerHour_rain = 0;
+		rate_mmPerHour_drySnow = 0;
+		rate_mmPerHour_wetSnow = 0;
+		rate_mmPerHour_sleet = 0;
+
+		// Get global position
+		util::calculateXYZAtWGS84Coordinate(lat_, lon_, height_, sceneRoot, x, y, z);
+
+		// Look up every cloud layer for it's precipitation.
+		for( int i=0; i<MAX_CLOUDLAYER_SLOTS; i++ )
+		{
+			if ( cloudLayerSlots[i].used )	// IF used, Pointer should be valid
+			{
+				if( cloudLayerSlots[i].cloudLayerPointer->HasPrecipitationAtPosition(x, y, z) )
+				{
+					hasPrecipitation = true;
+					SL_MAP (int, double) precipitationMap = cloudLayerSlots[i].cloudLayerPointer->GetPrecipitation();
+					for( SL_MAP (int, double)::iterator it = precipitationMap.begin(); it != precipitationMap.end(); it++ )
+					{
+						switch(it->first)
+						{
+							case SilverLining::CloudLayer::RAIN : rate_mmPerHour_rain += it->second;
+								break;
+							case SilverLining::CloudLayer::DRY_SNOW : rate_mmPerHour_drySnow += it->second;
+								break;
+							case SilverLining::CloudLayer::WET_SNOW : rate_mmPerHour_wetSnow += it->second;
+								break;
+							case SilverLining::CloudLayer::SLEET : rate_mmPerHour_sleet += it->second;
+								break;
+							default: OSG_NOTIFY( osg::FATAL ) << "ERROR: visual_skySilverLining::getOverallPrecipitationAtLocation() : Wrong precipitation type in map!" << std::endl;
+								break;
+						};
+					}
+				}	// If slot has Precipitation END
+			}	// If used END
+		}	// For all slots END
+
+		OSG_NOTIFY( osg::ALWAYS ) << "Rain: " << rate_mmPerHour_rain << ", dry snow: " << rate_mmPerHour_drySnow << ", wet snow: " << rate_mmPerHour_wetSnow << ", sleet: " << rate_mmPerHour_sleet << std::endl;
+		return hasPrecipitation;
+
+	}	// If initialized END
+	return false;
+}
+
+
+bool visual_skySilverLining::getSlotPrecipitationAtLocation( int slot_, double& rate_mmPerHour_rain, double& rate_mmPerHour_drySnow, double& rate_mmPerHour_wetSnow, double& rate_mmPerHour_sleet, double lat_, double lon_, double height_ )
+{
+	if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
+	{
+		if( cloudLayerSlots[slot_].used )	// IF used, Pointer should be valid
+		{
+			double x = 0;
+			double y = 0;
+			double z = 0;
+			rate_mmPerHour_rain = 0;
+			rate_mmPerHour_drySnow = 0;
+			rate_mmPerHour_wetSnow = 0;
+			rate_mmPerHour_sleet = 0;
+			//// If -1 : Use sky internal values
+			if ( lat_ == -1 )
+				lat_ = lat;
+			if ( lon_ == -1 )
+				lon_ = lon;
+			if ( height_ == -1 )
+				height_ = height;
+
+			// Get global position
+			util::calculateXYZAtWGS84Coordinate(lat_, lon_, height_, sceneRoot, x, y, z);
+
+			// Check for precipitation
+			if( cloudLayerSlots[slot_].cloudLayerPointer->HasPrecipitationAtPosition(x, y, z) )
+			{
+				SL_MAP (int, double) precipitationMap = cloudLayerSlots[slot_].cloudLayerPointer->GetPrecipitation();
+				for( SL_MAP (int, double)::iterator it = precipitationMap.begin(); it != precipitationMap.end(); it++ )
+				{
+					switch(it->first)
+					{
+						case SilverLining::CloudLayer::RAIN : rate_mmPerHour_rain = it->second;
+							break;
+						case SilverLining::CloudLayer::DRY_SNOW : rate_mmPerHour_drySnow = it->second;
+							break;
+						case SilverLining::CloudLayer::WET_SNOW : rate_mmPerHour_wetSnow = it->second;
+							break;
+						case SilverLining::CloudLayer::SLEET : rate_mmPerHour_sleet = it->second;
+							break;
+						default: OSG_NOTIFY( osg::FATAL ) << "ERROR: visual_skySilverLining::getSlotPrecipitationAtLocation() : Wrong precipitation type in map!" << std::endl;
+							break;
+					};
+				}	// FOR END
+				OSG_NOTIFY( osg::ALWAYS ) << "Rain: " << rate_mmPerHour_rain << ", dry snow: " << rate_mmPerHour_drySnow << ", wet snow: " << rate_mmPerHour_wetSnow << ", sleet: " << rate_mmPerHour_sleet << std::endl;
+				return true;
+			}	// If slot has Precipitation END
+			else 
+				return false;
+		}	// If used END
+		else
+			return false;
+	}	// If initialized END
+	return false;
+}
+
+bool visual_skySilverLining::getSlotPrecipitation( int slot_, double& rate_mmPerHour_rain, double& rate_mmPerHour_drySnow, double& rate_mmPerHour_wetSnow, double& rate_mmPerHour_sleet )
+{
+	if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
+	{
+		if( cloudLayerSlots[slot_].used )	// IF used, Pointer should be valid
+		{
+			rate_mmPerHour_rain = 0;
+			rate_mmPerHour_drySnow = 0;
+			rate_mmPerHour_wetSnow = 0;
+			rate_mmPerHour_sleet = 0;
+
+			// Check for precipitation
+
+				SL_MAP (int, double) precipitationMap = cloudLayerSlots[slot_].cloudLayerPointer->GetPrecipitation();
+				for( SL_MAP (int, double)::iterator it = precipitationMap.begin(); it != precipitationMap.end(); it++ )
+				{
+					switch(it->first)
+					{
+						case SilverLining::CloudLayer::RAIN : rate_mmPerHour_rain = it->second;
+							break;
+						case SilverLining::CloudLayer::DRY_SNOW : rate_mmPerHour_drySnow = it->second;
+							break;
+						case SilverLining::CloudLayer::WET_SNOW : rate_mmPerHour_wetSnow = it->second;
+							break;
+						case SilverLining::CloudLayer::SLEET : rate_mmPerHour_sleet = it->second;
+							break;
+						default: OSG_NOTIFY( osg::FATAL ) << "ERROR: visual_skySilverLining::getSlotPrecipitation() : Wrong precipitation type in map!" << std::endl;
+							break;
+					};
+				}	// FOR END
+				
+				if ( rate_mmPerHour_rain>0 || rate_mmPerHour_drySnow>0 || rate_mmPerHour_wetSnow>0 || rate_mmPerHour_sleet>0)
+				{
+					OSG_NOTIFY( osg::ALWAYS ) << "Rain: " << rate_mmPerHour_rain << ", dry snow: " << rate_mmPerHour_drySnow << ", wet snow: " << rate_mmPerHour_wetSnow << ", sleet: " << rate_mmPerHour_sleet << std::endl;
+					return true;
+				}
+				else
+					return false;
+		}	// If used END
+		else
+			return false;
+	}	// If initialized END
+	return false;
+}
+
+void visual_skySilverLining::clearAllPrecipitation( int slot_ )
+{
+	if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
+	{
+		if( cloudLayerSlots[slot_].used )	// IF used, Pointer should be valid
+		{
+			cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 );
+			cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::NONE, 0.0 ); // Second Call to clear precipitation rate.
+		}
+	}
+}
+
+void visual_skySilverLining::setSlotPrecipitation( int slot_, double rate_mmPerHour_rain_, double rate_mmPerHour_drySnow_, double rate_mmPerHour_wetSnow_, double rate_mmPerHour_sleet_ )
+{
+	if (isInitialized() && slot_ >= 0 && slot_ < MAX_CLOUDLAYER_SLOTS)
+	{
+		if( cloudLayerSlots[slot_].used )	// IF used, Pointer should be valid
+		{
+			cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::RAIN, rate_mmPerHour_rain_ );
+			cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::DRY_SNOW, rate_mmPerHour_drySnow_ );
+			cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::WET_SNOW, rate_mmPerHour_wetSnow_ );
+			cloudLayerSlots[slot_].cloudLayerPointer->SetPrecipitation( SilverLining::CloudLayer::SLEET, rate_mmPerHour_sleet_ );
+		}
+	}
+}
Index: /osgVisual/trunk/src/util/visual_util.cpp
===================================================================
--- /osgVisual/trunk/src/util/visual_util.cpp	(revision 176)
+++ /osgVisual/trunk/src/util/visual_util.cpp	(revision 176)
@@ -0,0 +1,464 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include <visual_util.h>
+
+using namespace osgVisual;
+
+util::util(void)
+{
+}
+
+util::~util(void)
+{
+}
+
+xmlNode* util::getSceneryXMLConfig(std::string configFilename, xmlDoc*& doc)
+{
+	doc = NULL;
+	xmlNode *root_element = NULL;
+
+	// Check for valid parameters
+	if(configFilename == "")
+	{
+		OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : Invalid Configuration Filename!" << std::endl;
+		return NULL;
+	}
+
+	// It is a valid XML document?
+	doc = xmlReadFile(configFilename.c_str(), NULL, 0);	
+	if (doc == NULL)
+	{
+		OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : " << configFilename << " is not a valid XML file!" << std::endl;
+		return NULL;
+	}
+
+	//  Get the root element node
+	root_element = xmlDocGetRootElement(doc);
+
+	// If file is a valid osgVisual config file, check all the root xml node and all of it's children of osgvisualconfiguration for the specified module
+	xmlNode* tmpNode = checkXMLNodeChildrenForScenery(root_element);
+
+	if( !tmpNode ) // if no valid node was found: clena up. Otherwise: the caller has to clean up.
+	{
+		xmlFreeDoc(doc);	// free the document
+		xmlCleanupParser();	// Free the global variables that may have been allocated by the parser.
+		return NULL;
+	}
+	else
+		return tmpNode;
+}
+
+xmlNode* util::checkXMLNodeChildrenForScenery(xmlNode* node)
+{
+	for (xmlNode *cur_node = node; cur_node; cur_node = cur_node->next)	// iterate through all elements 
+	{
+		// Is the node the one we are searching for?
+		if (cur_node->type == XML_ELEMENT_NODE)
+		{
+			std::string node_name=reinterpret_cast<const char*>(cur_node->name);
+			if (node_name == "scenery")
+			{
+				OSG_DEBUG << "XML node scenery found" << std::endl;
+				return cur_node;
+			}
+			else	// Otherwise: check its children..
+			{
+				xmlNode* tmp_XmlNode = checkXMLNodeChildrenForScenery(cur_node->children);
+				if(tmp_XmlNode)
+					return tmp_XmlNode;
+			}
+		}	// IF NODE TYPE = ELEMENT END
+
+		// Proceed with next node in this loop.
+	}
+	return NULL;
+}
+
+xmlNode* util::getModuleXMLConfig(std::string configFilename, std::string moduleName, xmlDoc*& doc, bool& disabled)
+{
+	doc = NULL;
+	disabled = false;
+	xmlNode *root_element = NULL;
+
+	// Check for valid parameters
+	if(configFilename == "")
+	{
+		OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : Invalid Configuration Filename!" << std::endl;
+		return NULL;
+	}
+	if(moduleName == "")
+	{
+		OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : Invalid Module Filename!" << std::endl;
+		return NULL;
+	}
+
+	// It is a valid XML document?
+	doc = xmlReadFile(configFilename.c_str(), NULL, 0);	
+	if (doc == NULL)
+	{
+		OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : " << configFilename << " is not a valid XML file!" << std::endl;
+		return NULL;
+	}
+
+	//  Get the root element node
+	root_element = xmlDocGetRootElement(doc);
+
+	// Check if it is an osgVisual configuration file
+	std::string node_name=reinterpret_cast<const char*>(root_element->name);
+	if(!(root_element->type == XML_ELEMENT_NODE && node_name == "osgvisualconfiguration"))
+	{
+		OSG_ALWAYS << "ERROR - util::getModuleXMLConfig() : " << configFilename << " is not an osgVisual configuration file!" << std::endl;
+		return NULL;
+	}
+
+	// If file is a valid osgVisual config file, check all the root xml node and all of it's children of osgvisualconfiguration for the specified module
+	xmlNode* tmpNode = checkXMLNodeChildrenForModule(root_element, moduleName, disabled);
+
+	if( !tmpNode ) // if no valid node was found or the module is disabled: clean up. Otherwise: the caller has to clean up.
+	{
+		xmlFreeDoc(doc);	// free the document
+		xmlCleanupParser();	// Free the global variables that may have been allocated by the parser.
+		return NULL;
+	}
+	else
+		return tmpNode;
+
+}
+
+xmlNode* util::checkXMLNodeChildrenForModule(xmlNode* node, std::string moduleName, bool& disabled)
+{
+	for (xmlNode *cur_node = node; cur_node; cur_node = cur_node->next)	// iterate through all XML elements 
+	{
+		// Is the node the one we are searching for?
+		if (cur_node->type == XML_ELEMENT_NODE)
+		{
+			// Extract Node Name and the first attribute: "module name"
+			std::string node_name = reinterpret_cast<const char*>(cur_node->name);
+			std::string modName = "";
+			xmlAttr  *attr = cur_node->properties;
+			while ( attr ) 
+			{ 
+				std::string attr_name=reinterpret_cast<const char*>(attr->name);
+				std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
+				if( attr_name == "name" )
+					modName = attr_value;
+				attr = attr->next;
+			}
+			
+			// Check each node for the searched module
+			if (node_name == "module" && modName == moduleName)
+			{
+				// Check if the module is active
+				xmlAttr  *attr = cur_node->properties;
+				while ( attr ) 
+				{ 
+					std::string attr_name=reinterpret_cast<const char*>(attr->name);
+					std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
+					if( attr_name == "enabled" && attr_value == "yes" )
+					{
+						OSG_DEBUG << "Found XML module configuration for " << moduleName << std::endl;
+						return cur_node;
+					}
+					if( attr_name == "enabled" && attr_value == "no" )
+					{
+						disabled = true;
+						OSG_DEBUG << "Found XML module configuration for " << moduleName << ", but it is DISABLED." << std::endl;
+						return NULL;
+					}
+					attr = attr->next;
+				}
+			}
+			else	// Otherwise: check its children..
+			{
+				xmlNode* tmp_XmlNode = checkXMLNodeChildrenForModule(cur_node->children, moduleName, disabled);
+				if(tmp_XmlNode)
+					return tmp_XmlNode;
+			}
+		}	// IF NODE TYPE = ELEMENT END
+
+		// Proceed with next node in this loop.
+	}
+	return NULL;
+}
+
+osg::Node* util::findNamedNode(const std::string& searchName_, osg::Node* currNode_)
+{
+   osg::Group* currGroup;
+   osg::Node* foundNode;
+
+   // check to see if we have a valid (non-NULL) node.
+   // if we do have a null node, return NULL.
+   if ( !currNode_)
+   {
+      return NULL;
+   }
+
+   // We have a valid node, check to see if this is the node we 
+   // are looking for. If so, return the current node.
+   if (currNode_->getName() == searchName_)
+   {
+      return currNode_;
+   }
+
+   // We have a valid node, but not the one we are looking for.
+   // Check to see if it has children (non-leaf node). If the node
+   // has children, check each of the child nodes by recursive call.
+   // If one of the recursive calls returns a non-null value we have
+   // found the correct node, so return this node.
+   // If we check all of the children and have not found the node,
+   // return NULL
+   currGroup = currNode_->asGroup(); // returns NULL if not a group.
+   if ( currGroup ) 
+   {
+      for (unsigned int i = 0 ; i < currGroup->getNumChildren(); i ++)
+      { 
+         foundNode = findNamedNode(searchName_, currGroup->getChild(i));
+         if (foundNode)
+		 {
+			 std::cout << "Node gefunden in Ebene: " << i << std::endl;
+            return foundNode; // found a match!
+		}
+      }
+      return NULL; // We have checked each child node - no match found.
+   }
+   else 
+   {
+      return NULL; // leaf node, no match 
+   }
+}
+
+osg::ref_ptr<osg::Geode> util::getDemoCylinder(double length_, double width_, osg::Vec3 offset_ )
+{
+	osg::ref_ptr<osg::Geode> cyl = new osg::Geode();
+	osg::ref_ptr<osg::ShapeDrawable> shape = new osg::ShapeDrawable(new osg::Cylinder( offset_, width_, length_ ));
+	osg::Vec4 color = osg::Vec4(255.0, 0.0, 0.0, 1.0);
+	shape->setColor( color );
+	cyl->addDrawable( shape );
+
+	return cyl;
+}
+
+osg::ref_ptr<osg::Geode> util::getDemoSphere(double radius_, osg::Vec3 offset_ )
+{
+	osg::ref_ptr<osg::Geode> sphere = new osg::Geode();
+	osg::ref_ptr<osg::ShapeDrawable> shape = new osg::ShapeDrawable(new osg::Sphere( offset_, radius_ ) );
+	osg::Vec4 color = osg::Vec4(255.0, 0.0, 0.0, 1.0);
+	shape->setColor( color );
+	sphere->addDrawable( shape );
+
+	return sphere;
+}
+
+bool util::intersect(const osg::Vec3d& start_, const osg::Vec3d& end_, osg::Vec3d& intersection_, osg::Node* node_, osg::Node::NodeMask intersectTraversalMask_ )
+{
+	osg::ref_ptr<osgUtil::LineSegmentIntersector> lsi = new osgUtil::LineSegmentIntersector(start_,end_);
+
+	osgUtil::IntersectionVisitor iv(lsi.get());
+	iv.setTraversalMask(intersectTraversalMask_);
+    
+	node_->accept(iv);
+    
+	if (lsi->containsIntersections())
+	{
+		intersection_ = lsi->getIntersections().begin()->getWorldIntersectPoint();
+		return true;	// Intersect found
+	}
+	return false;	// No intersect found
+}
+
+bool util::queryHeightOfTerrain(double& hot_, osg::Node* rootNode_, double lat_, double lon_, osg::Node::NodeMask traversalMask_)
+{
+	// Get ellipsoid model
+	osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
+	if ( !csn )
+	{
+		OSG_NOTIFY( osg::FATAL ) << "util::queryHeightOfTerrain() :: Invalid CSN!" << std::endl;
+		return false;
+	}
+	osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
+	if ( !ellipsoid )
+	{
+		OSG_NOTIFY( osg::FATAL ) << "util::queryHeightOfTerrain() :: Invalid ellipsoid!" << std::endl;
+		return false;
+	}
+
+	// Setup both endpoints of intersect line
+	double X,Y,Z;
+	ellipsoid->convertLatLongHeightToXYZ(lat_, lon_, 30000, X, Y, Z);
+	osg::Vec3d s = osg::Vec3d(X, Y, Z);
+	ellipsoid->convertLatLongHeightToXYZ(lat_, lon_, -30000, X, Y, Z);
+	osg::Vec3d e = osg::Vec3d(X, Y, Z);
+
+	// Query intersection point
+	osg::Vec3d ip;
+	if ( util::intersect(s, e, ip, rootNode_, traversalMask_) )
+	{
+		double lat2_, lon2_;
+		ellipsoid->convertXYZToLatLongHeight( ip.x(), ip.y(), ip.z(), lat2_, lon2_, hot_ );	// Convert Intersection Point back to Lat Lon, HOT.
+		//OSG_NOTIFY(osg::ALWAYS) << "lat: "<< osg::RadiansToDegrees(lat2_) <<", Lon: " << osg::RadiansToDegrees(lon2_) << ", Hot: " << hot_ << std::endl;
+		return true;
+	}
+
+	// If no intersection point found: set HOT to zero and return false.
+	hot_ = 0;
+	return false;
+}
+
+bool util::queryHeightAboveTerrainInWGS84(double& hat_, osg::Node* rootNode_, double lat_, double lon_, double height_, osg::Node::NodeMask traversalMask_)
+{
+	// Get HOT by asking util::queryHeightOfTerrain() :)
+	double HOT;
+	if ( !util::queryHeightOfTerrain(HOT, rootNode_, lat_, lon_, traversalMask_) )
+	{
+		OSG_NOTIFY( osg::INFO ) << "util::queryHeightAboveTerrainInWGS84() :: Unable to get HOT, will use 0 for HOT!" << std::endl;
+	}
+
+	// Calculate HAT
+	hat_ = height_ - HOT;
+	return true;
+}
+
+bool util::queryHeightAboveTerrainInWorld(double& hat_, osg::Node* rootNode_, double x_, double y_, double z_, osg::Node::NodeMask traversalMask_)
+{
+	// Get ellipsoid model
+	osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
+	if ( !csn )
+	{
+		OSG_NOTIFY( osg::FATAL ) << "util::queryHeightAboveTerrainInWorld() :: Invalid CSN!" << std::endl;
+		return false;
+	}
+	osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
+	if ( !ellipsoid )
+	{
+		OSG_NOTIFY( osg::FATAL ) << "util::queryHeightAboveTerrainInWorld() :: Invalid ellipsoid!" << std::endl;
+		return false;
+	}
+
+	// Transform XYZ into LatLonHeight
+	double lat_, lon_, height_;
+	ellipsoid->convertXYZToLatLongHeight(x_, y_, z_, lat_, lon_, height_);
+
+	// ask util::queryHeightAboveTerrainInWGS84() to calc HAT :)
+	if( !util::queryHeightAboveTerrainInWGS84(hat_, rootNode_, lat_, lon_, height_, traversalMask_ ) )
+	{
+		OSG_NOTIFY( osg::FATAL ) << "util::queryHeightAboveTerrainInWorld() :: Unable to get HAT!" << std::endl;
+		return false;
+	}
+
+	return true;
+}
+
+bool util::calculateEarthRadiusAtWGS84Coordinate(double lat_, double lon_, osg::Node* rootNode_, double& radius_)
+{
+	// Calculate radius:
+	double x, y, z;
+	
+	if ( util::calculateXYZAtWGS84Coordinate(lat_, lon_, 0.0, rootNode_, x, y, z) )
+	{
+		radius_ = sqrt( pow(x, 2) + pow(y, 2) + pow(z, 2) );
+		return true;
+	}
+	else
+	{
+		OSG_NOTIFY( osg::FATAL ) << "util::calculateEarthRadiusAtWGS84Coordinate() :: Unable to calculate Earth Radius!" << std::endl;
+		return false;
+	}
+}
+
+bool util::calculateXYZAtWGS84Coordinate(double lat_, double lon_, double height_, osg::Node* rootNode_, double& x_, double& y_, double& z_)
+{
+	// Get ellipsoid model
+	osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
+	if ( !csn )
+		return false;
+	osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
+	if ( !ellipsoid )
+		return false;
+
+	// Calculate xyz:
+	ellipsoid->convertLatLongHeightToXYZ( lat_, lon_, height_, x_, y_, z_);
+	return true;
+}
+
+bool util::getWGS84ofCamera( osg::Camera* camera_, osg::Node* rootNode_, double& lat_, double& lon_, double& height_ )
+{
+	// Get ellipsoid model
+	osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(rootNode_);
+	if ( !csn )
+		return false;
+	osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
+	if ( !ellipsoid )
+		return false;
+
+	osg::Vec3d eye, dir, up;
+	camera_->getViewMatrixAsLookAt(eye,dir,up); // Get XYZ from camera
+	ellipsoid->convertXYZToLatLongHeight(eye.x(), eye.y(), eye.z(), lat_, lon_, height_);
+	return true;
+}
+
+void util::getXYZofCamera( osg::Camera* camera_, double& x_, double& y_, double& z_ )
+{
+	osg::Vec3d eye, dir, up;
+	camera_->getViewMatrixAsLookAt(eye,dir,up); // Get XYZ from camera
+	x_ = eye.x();
+	y_ = eye.y();
+	z_ = eye.z();
+}
+
+bool util::removeClosebuttonOnGLWindow(osgViewer::Viewer* viewer_)
+{
+#ifdef FUNFUNCTIONS_ENABLED
+#ifdef WIN32
+	osgViewer::ViewerBase::Windows wins;
+	viewer_->getWindows(wins);
+	osgViewer::GraphicsHandleWin32* hwnd = dynamic_cast<osgViewer::GraphicsHandleWin32*>(wins[0]);
+	
+	HMENU hMenu = GetSystemMenu(hwnd->getHWND(), FALSE);
+	::EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | (MF_DISABLED | MF_GRAYED)); 
+#endif
+#endif
+	return true;
+}
+
+bool util::setTransparentWindowBackground(osgViewer::Viewer* viewer_)
+{
+#ifdef FUNFUNCTIONS_ENABLED
+#ifdef WIN32
+	osgViewer::ViewerBase::Windows wins;
+	viewer_->getWindows(wins);
+	osgViewer::GraphicsHandleWin32* hwnd = dynamic_cast<osgViewer::GraphicsHandleWin32*>(wins[0]);
+	HWND _hwnd = hwnd->getHWND();
+	viewer_->getDisplaySettings()->setMinimumNumAlphaBits(8);
+
+   // Create and populate the Blur Behind structure
+   DWM_BLURBEHIND bb = {0};
+   // Disable Blur Behind and Blur Region;
+   bb.dwFlags = DWM_BB_ENABLE;
+   bb.fEnable = true;
+   bb.hRgnBlur = NULL;
+
+   // Ensable Blur Behind
+   HRESULT hr = DwmEnableBlurBehindWindow(_hwnd, &bb);
+   if (SUCCEEDED(hr))
+      return true;
+   else
+	   return false;
+
+#endif
+#endif
+	return true;
+}
Index: /osgVisual/trunk/src/vista2D/visual_vista2D.cpp
===================================================================
--- /osgVisual/trunk/src/vista2D/visual_vista2D.cpp	(revision 176)
+++ /osgVisual/trunk/src/vista2D/visual_vista2D.cpp	(revision 176)
@@ -0,0 +1,225 @@
+/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
+ *
+ * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under 
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
+ * (at your option) any later version.  The full license is in LICENSE file
+ * included with this distribution, and on the openscenegraph.org website.
+ *
+ * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
+ * You have to aquire licenses for all used proprietary modules.
+ * 
+ * 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
+ * OpenSceneGraph Public License for more details.
+*/
+
+#include "visual_vista2D.h"
+
+
+using namespace osgVisual;
+
+visual_vista2D::visual_vista2D(void)
+{
+	OSG_NOTIFY (osg::ALWAYS ) << "visual_vista2D instantiated." << std::endl;
+
+   // Create a Vista2D View
+   view = new Vista2D::VistaView();
+
+   	vistaProjectfile = "";
+	paintBackground = false;
+	playanimation = false;
+	position_x = 0;
+	position_y = 0;
+	zoom = 1;
+}
+
+visual_vista2D::~visual_vista2D(void)
+{
+	view->stopView();
+}
+
+void visual_vista2D::startVista2D()
+{
+    /***************
+    load view
+    ***************/
+	view->load( vistaProjectfile );
+    view->setBackgroundMode(paintBackground);	// don't paint background
+	view->setPosition( position_x, position_y);
+	view->setZoom( zoom );
+
+    /***************
+    start animation with
+    self running datasource
+    ***************/
+    view->startView (playanimation);
+}
+
+bool visual_vista2D::processXMLConfiguration()
+{
+	// Init XML
+	xmlDoc* tmpDoc;
+	bool disabled;
+	xmlNode* config = util::getModuleXMLConfig( configFileName, "vista2d", tmpDoc, disabled );
+
+	if( disabled)
+	{
+		OSG_NOTIFY( osg::ALWAYS ) << "..disabled by XML configuration file." << std::endl;
+		return false;
+	}
+	
+	// extract configuration values
+	if(config)
+	{
+		xmlNode* a_node = config->children;
+
+		for (xmlNode *cur_node = a_node; cur_node; cur_node = cur_node->next)
+		{
+		std::string node_name=reinterpret_cast<const char*>(cur_node->name);
+			//OSG_ALWAYS << "----visual_vista2D::processXMLConfiguration() - node type="<< cur_node->type <<", name=" << cur_node->name << std::endl;
+
+			// Check for vista2d node
+			if(cur_node->type == XML_ELEMENT_NODE && node_name == "vista2d")
+			{
+				// Check attributes
+				xmlAttr  *attr = cur_node->properties;
+				while ( attr ) 
+				{ 
+					std::string attr_name=reinterpret_cast<const char*>(attr->name);
+					std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
+
+					if( attr_name == "filename" )
+					{
+						vistaProjectfile=attr_value;
+					}
+
+					if( attr_name == "paintBackground" )
+					{
+						paintBackground = (attr_value == "yes") ? true : false;
+					}
+
+					if( attr_name == "position_x" )
+					{
+						std::stringstream sstr(attr_value);
+						sstr >> position_x;
+					}
+
+					if( attr_name == "position_y" )
+					{
+						std::stringstream sstr(attr_value);
+						sstr >> position_y;
+					}
+
+					if( attr_name == "zoom" )
+					{
+						std::stringstream sstr(attr_value);
+						sstr >> zoom;
+					}
+
+					if( attr_name == "playanimation" )
+					{
+						playanimation = (attr_value == "yes") ? true : false;
+					}
+
+					attr = attr->next;
+				}	// WHILE attr END
+			}	// IF node == vista2d END
+		}	// FOR end
+	
+		// clean up
+		xmlFreeDoc(tmpDoc); xmlCleanupParser();
+		return true;
+	}	// IF Config valid END
+	else
+	{
+		OSG_WARN << "ERROR: visual_vista2D::processXMLConfiguration() - Module configuration not found" << std::endl;
+		return false;
+	}
+
+	return true;
+}
+
+bool visual_vista2D::init( osg::CoordinateSystemNode *sceneGraphRoot_, std::string configFileName )
+{
+	OSG_NOTIFY (osg::ALWAYS ) << "visual_vista2D initialize..";  // The sentence is finished by the init result...
+
+	this->configFileName = configFileName;
+
+	// Process XML configuration
+	if(!processXMLConfiguration())
+		return false;	// Abort vista2D initialization.
+
+	// Check if Vista2D project file exists
+	if ( !osgDB::fileExists(vistaProjectfile) )
+	{
+		OSG_ALWAYS << "WARNING: visual_vista2D::init() - Specified vista2D projectfile '"<< vistaProjectfile <<"' does not exist! Skip using Vista2D!" << std::endl;
+		return false;
+	}
+
+   osg::Geode* vista2Dgeode = new osg::Geode();
+   // Projection node for defining view frustrum for the vista2D-SceneOverlay:
+   osg::Projection* vista2DProjectionMatrix = new osg::Projection;
+
+    // Initialize the projection matrix for viewing everything we
+   // will add as descendants of this node. Use screen coordinates
+   // to define the horizontal and vertical extent of the projection
+   // matrix. Positions described under this node will equate to
+   // pixel coordinates.
+   vista2DProjectionMatrix->setMatrix(osg::Matrix::ortho2D(0,1600,0,900)); /** todo: use screen size dynamically. */
+  
+   // For the HUD model view matrix use an identity matrix:
+   osg::MatrixTransform* vista2DModelViewMatrix = new osg::MatrixTransform;
+   vista2DModelViewMatrix->setMatrix(osg::Matrix::identity());
+
+   // Make sure the model view matrix is not affected by any transforms
+   // above it in the scene graph:
+   vista2DModelViewMatrix->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
+
+   // Set Stateset of vista2DGeode Renderbin to render quite late..
+	osg::StateSet* vista2DoverlayStateSet = vista2Dgeode->getOrCreateStateSet();
+	vista2DoverlayStateSet->setRenderBinDetails( 99, "RenderBin");
+
+   // Add the HUD projection matrix as a child of the root node
+   // and the HUD model view matrix as a child of the projection matrix
+   // Anything under this node will be viewed using this projection matrix
+   // and positioned with this model view matrix.
+   vista2DProjectionMatrix->addChild(vista2DModelViewMatrix);
+
+   // Add the Geometry node to contain HUD geometry as a child of the
+   // HUD model view matrix.
+   vista2DModelViewMatrix->addChild( vista2Dgeode );
+
+	// Add Payload: Vista2D			
+	startVista2D();
+
+	// Add this class to the scene Graph
+	this->setUseDisplayList( false );
+	vista2Dgeode->addDrawable( this );
+
+	sceneGraphRoot_->addChild( vista2DProjectionMatrix );
+	return true;
+}
+
+void visual_vista2D::drawImplementation(osg::RenderInfo& renderInfo) const
+{
+	// save OSG-State
+	osg::ref_ptr<osg::StateSet> clonedStateSet = reinterpret_cast<osg::StateSet*>( renderInfo.getCurrentCamera()->getOrCreateStateSet()->clone(osg::CopyOp::DEEP_COPY_ALL) );
+
+	// Draw View
+    view->draw();
+
+	// restore OSG-State
+	renderInfo.getCurrentCamera()->setStateSet( clonedStateSet );
+
+}
+
+osg::Object* visual_vista2D::cloneType() const
+{
+	return NULL;
+}
+
+osg::Object* visual_vista2D::clone(const osg::CopyOp& copyop) const
+{ 
+	return NULL;
+}
