Revision: 1524
          http://rigsofrods.svn.sourceforge.net/rigsofrods/?rev=1524&view=rev
Author:   rorthomas
Date:     2010-08-21 12:29:48 +0000 (Sat, 21 Aug 2010)

Log Message:
-----------
added RoR viewer application that is in the making since some time. Not totally 
ready yet, still needs a toolbar and improved mouse handling

Modified Paths:
--------------
    trunk/CMakeDependenciesConfig.txt
    trunk/source/CMakeLists.txt

Added Paths:
-----------
    trunk/source/viewer/
    trunk/source/viewer/CMakeLists.txt
    trunk/source/viewer/RoRViewer.cpp
    trunk/source/viewer/RoRViewer.h
    trunk/source/viewer/RoRViewer.ico
    trunk/source/viewer/icon.rc
    trunk/source/viewer/main.cpp
    trunk/source/viewer/main.h
    trunk/source/viewer/panel_meshprop.h
    trunk/source/viewer/panel_meshtree.h
    trunk/source/viewer/wxutils.cpp
    trunk/source/viewer/wxutils.h

Modified: trunk/CMakeDependenciesConfig.txt
===================================================================
--- trunk/CMakeDependenciesConfig.txt   2010-08-21 09:11:32 UTC (rev 1523)
+++ trunk/CMakeDependenciesConfig.txt   2010-08-21 12:29:48 UTC (rev 1524)
@@ -1,4 +1,5 @@
 # components
+set(ROR_BUILD_VIEWER "TRUE" CACHE BOOL "build the RoR Viewer Application")
 set(ROR_USE_MYGUI   "FALSE" CACHE BOOL "use MyGUI")
 set(ROR_USE_OPENAL  "FALSE" CACHE BOOL "use OPENAL")
 set(ROR_USE_LUA     "FALSE" CACHE BOOL "use LUA")

Modified: trunk/source/CMakeLists.txt
===================================================================
--- trunk/source/CMakeLists.txt 2010-08-21 09:11:32 UTC (rev 1523)
+++ trunk/source/CMakeLists.txt 2010-08-21 12:29:48 UTC (rev 1524)
@@ -17,4 +17,6 @@
 #  add_subdirectory(editor)
 #ENDIF(ROR_BUILD_EDITOR)
 
-#add_subdirectory(serializer)
+IF(ROR_BUILD_VIEWER)
+  add_subdirectory(viewer)
+ENDIF(ROR_BUILD_VIEWER)

Added: trunk/source/viewer/CMakeLists.txt
===================================================================
--- trunk/source/viewer/CMakeLists.txt                          (rev 0)
+++ trunk/source/viewer/CMakeLists.txt  2010-08-21 12:29:48 UTC (rev 1524)
@@ -0,0 +1,117 @@
+project(RoR_Viewer)
+
+# find wxWidgets
+include_directories(${WXWIDGETS_SHARED_INCLUDE_DIRS})
+link_directories   (${WXWIDGETS_SHARED_LIBRARY_DIRS})
+
+IF(WIN32)
+ include_directories(${BOOST_INCLUDE_DIRS})
+ link_directories   (${BOOST_LIBRARY_DIRS})
+ include_directories(${PThread_INCLUDE_DIRS})
+ link_directories   (${PThread_LIBRARY_DIRS})
+ include_directories(${PThread_INCLUDE_DIRS})
+ link_directories   (${PThread_LIBRARY_DIRS})
+
+ #set(OS_LIBS "${PThread_LIBRARIES}")
+ set(OS_SOURCE "icon.rc")
+
+ # disable some annoying VS warnings:
+ # warning C4244: 'initializing' : conversion from 'const float' to 'int', 
possible loss of data
+ # warning C4305: 'initializing' : truncation from 'double' to 'const float'
+ add_definitions("/wd4305 /wd4244")
+
+ELSEIF(UNIX)
+ find_package(PkgConfig)
+ PKG_CHECK_MODULES  (GTK gtk+-2.0 REQUIRED)
+ INCLUDE_DIRECTORIES(${GTK_INCLUDE_DIRS})
+
+ PKG_CHECK_MODULES  (Ogre OGRE REQUIRED)
+ PKG_CHECK_MODULES  (Ois OIS REQUIRED)
+
+ set(OS_SOURCE "")
+ENDIF(WIN32)
+
+include_directories(${Ogre_INCLUDE_DIRS})
+link_directories   (${Ogre_LIBRARY_DIRS})
+include_directories(${Ogre_Terrain_INCLUDE_DIRS})
+link_directories   (${Ogre_Terrain_LIBRARY_DIRS})
+include_directories(${Ogre_Paging_INCLUDE_DIRS})
+link_directories   (${Ogre_Paging_LIBRARY_DIRS})
+include_directories(${Ogre_RTShader_INCLUDE_DIRS})
+link_directories   (${Ogre_RTShader_LIBRARY_DIRS})
+include_directories(${Ois_INCLUDE_DIRS})
+link_directories   (${Ois_LIBRARY_DIRS})
+
+add_definitions("-D_UNICODE -DNOLANG")
+include_directories(../main)
+
+if(WIN32)
+  # we have to extend the cflags to add USE_CONSOLE definition for non release 
modes
+  set(CMAKE_CXX_FLAGS_MINSIZEREL     "${CMAKE_CXX_FLAGS_MINSIZEREL}     /D 
USE_CONSOLE")
+  set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /D 
USE_CONSOLE")
+  set(CMAKE_CXX_FLAGS_DEBUG          "${CMAKE_CXX_FLAGS_DEBUG}          /D 
USE_CONSOLE")
+endif(WIN32)
+
+#setup libraries
+macro(setup_lib name)
+   if(ROR_USE_${name})
+      message(STATUS "Enabled:     ${name}")
+      include_directories(${${name}_INCLUDE_DIRS})
+      link_directories   (${${name}_LIBRARY_DIRS})
+      add_definitions("-DUSE_${name}")
+      set(optional_libs ${optional_libs} ${${name}_LIBRARIES})
+      message(STATUS "${name}_INCLUDE_DIRS:     ${${name}_INCLUDE_DIRS}")
+      message(STATUS "${name}_LIBRARY_DIRS:     ${${name}_LIBRARY_DIRS}")
+      message(STATUS "${name}_LIBRARIES:     ${${name}_LIBRARIES}")
+   else()
+      message(STATUS "Not enabled: ${name}")
+   endif(ROR_USE_${name})
+endmacro(setup_lib)
+
+# config below
+IF(WIN32)
+   include_directories(${PThread_INCLUDE_DIRS})
+   link_directories   (${PThread_LIBRARY_DIRS})
+   set(OS_LIBS "${PThread_LIBRARIES} dinput8.lib dxguid.lib")
+
+   # disable some annoying VS warnings:
+   # warning C4244: 'initializing' : conversion from 'const float' to 'int', 
possible loss of data
+   # warning C4305: 'initializing' : truncation from 'double' to 'const float'
+   add_definitions("/wd4305 /wd4244 -DNOMINMAX")
+ELSEIF(UNIX)
+   include_directories(${GTK_INCLUDE_DIRS})
+   set(OS_LIBS "X11")
+ENDIF(WIN32)
+
+# required components
+include_directories(${Ogre_INCLUDE_DIRS})
+link_directories   (${Ogre_LIBRARY_DIRS})
+include_directories(${Ois_INCLUDE_DIRS})
+link_directories   (${Ois_LIBRARY_DIRS})
+link_directories   (${Ois_LIBRARY_DIRS})
+include_directories(${RoR_SOURCE_DIR}/source/protocol)
+
+
+# things to be used but not yet supported:
+#setup_lib(OPENAL)
+#setup_lib(LUA)
+#setup_lib(PAGED)
+#setup_lib(CAELUM)
+#setup_lib(ANGELSCRIPT)
+#setup_lib(HYDRAX)
+#setup_lib(CRASHRPT)
+
+
+
+FILE(GLOB viewer_sources "*.cpp")
+FILE(GLOB viewer_headers "*.h")
+
+include_directories(.)
+include_directories(../main)
+
+add_executable(RoRViewer ${viewer_sources} ${viewer_headers} ${OS_SOURCE} 
${additional_sources} ${HEADER_FILES} ${SOURCE_FILES} ../main/Settings.cpp 
../main/errorutils.cpp)
+windows_hacks(RoRViewer)
+
+TARGET_LINK_LIBRARIES(RoRViewer ${WXWIDGETS_SHARED_LIBRARIES} 
${Ogre_LIBRARIES} ${Ois_LIBRARIES} ${OS_LIBS} ${optional_libs})
+
+

Added: trunk/source/viewer/RoRViewer.cpp
===================================================================
--- trunk/source/viewer/RoRViewer.cpp                           (rev 0)
+++ trunk/source/viewer/RoRViewer.cpp   2010-08-21 12:29:48 UTC (rev 1524)
@@ -0,0 +1,180 @@
+/*
+This source file is part of Rigs of Rods
+Copyright 2005,2006,2007,2008,2009 Pierre-Michel Ricordel
+Copyright 2007,2008,2009 Thomas Fischer
+
+For more information, see http://www.rigsofrods.com/
+
+Rigs of Rods is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3, as
+published by the Free Software Foundation.
+
+Rigs of Rods is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Rigs of Rods.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "RoRViewer.h"
+
+#include "Settings.h"
+#include "errorutils.h"
+
+RoRViewer::RoRViewer(string _meshPath)
+{
+       active_node = NULL;
+       active_mesh.setNull();
+       active_entity = NULL;
+       ogre_root = NULL;
+       scene_mgr = NULL;
+       window = NULL;
+       meshPath = _meshPath;
+}
+
+RoRViewer::~RoRViewer(void)
+{
+}
+
+bool RoRViewer::Initialize(std::string hwndStr)
+{
+       if(!SETTINGS.setupPaths())
+               return false;
+
+       // load RoR.cfg directly after setting up paths
+       SETTINGS.loadSettings(SETTINGS.getSetting("Config Root")+"RoR.cfg");
+
+       String logFilename   = SETTINGS.getSetting("Log Path") + 
Ogre::String("RoRViewer.log");
+       String programPath   = SETTINGS.getSetting("Program Path");
+       String pluginsConfig = ""; // important to be empty 
//SETTINGS.getSetting("plugins.cfg");
+       
+       String ogreConfig    = SETTINGS.getSetting("ogre.cfg");
+       ogre_root = new Ogre::Root(pluginsConfig, ogreConfig, logFilename);
+
+       // load plugins by hand
+#ifdef WIN32
+       ogre_root->loadPlugin(programPath + "RenderSystem_Direct3D9");
+#endif // WIN32
+       ogre_root->loadPlugin(programPath + "RenderSystem_GL");
+       ogre_root->loadPlugin(programPath + "Plugin_ParticleFX");
+       ogre_root->loadPlugin(programPath + "Plugin_OctreeSceneManager");
+       ogre_root->loadPlugin(programPath + "Plugin_CgProgramManager");
+
+       ogre_root->restoreConfig();
+       ogre_root->initialise(false);
+
+
+       Ogre::NameValuePairList param;
+       param["externalWindowHandle"] = hwndStr;
+
+       window    = ogre_root->createRenderWindow("viewer", 320, 240, false, 
&param);
+       scene_mgr = ogre_root->createSceneManager(ST_GENERIC);
+       camera    = scene_mgr->createCamera("ViewerCam");
+       viewport  = window->addViewport(camera);
+
+       camera_node = scene_mgr->createSceneNode();
+       scene_mgr->getRootSceneNode()->addChild(camera_node);
+       camera_node->attachObject(camera);
+       camera_node->setPosition(0, 0.01f, 3.3);
+       camera->setNearClipDistance(0.1);
+       camera->setFarClipDistance(1000);
+       camera->setFOVy(Ogre::Radian(Ogre::Degree(60)));
+       camera->setAutoAspectRatio(true);
+       camera->lookAt(0, 0, 0);
+
+       viewport->setBackgroundColour(ColourValue(0.35, 0.35, 0.35));
+
+       timer = new Ogre::Timer();
+       timer->reset();
+
+
+       light = scene_mgr->createLight("Lamp01");
+       light->setType(Light::LT_DIRECTIONAL);
+       light->setPosition(0, 50, 0);
+       light_node = scene_mgr->createSceneNode("RoRViewerLightNode");
+       light_node->attachObject(light);
+       scene_mgr->getRootSceneNode()->addChild(light_node);
+       light_node->lookAt(Vector3::NEGATIVE_UNIT_Y, Node::TS_WORLD, 
Vector3::UNIT_Z);
+
+       scene_mgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
+
+       // figure out the files path
+       Ogre::String filename, filepath;
+       Ogre::StringUtil::splitFilename(meshPath, filename, filepath);
+
+       // add the file path to the resource lookup path
+       
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(filepath, 
"FileSystem");
+
+       // add default RoR resources, not too bad if this fails
+       try
+       {
+               
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(programPath + 
"resources/OgreCore.zip", "Zip");
+               
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(programPath + 
"resources/materials.zip", "Zip");
+               
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(programPath + 
"resources/textures.zip", "Zip");
+       } catch(...)
+       {
+       }
+       // init all resource locations
+       
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
+
+
+       // load the mesh
+       String group = 
Ogre::ResourceGroupManager::getSingleton().findGroupContainingResource(filename);
+       active_mesh = Ogre::MeshManager::getSingleton().load(filename, group);
+       active_entity = scene_mgr->createEntity(filepath, 
active_mesh->getName());
+
+       active_node = scene_mgr->getRootSceneNode()->createChildSceneNode();
+       active_node->attachObject(active_entity);
+
+       active_node->setPosition(0,0,0);
+
+       // reposition camera
+       float radius = active_mesh->getBoundingSphereRadius();
+       camera_node->setPosition(0, 1.7, 3.3 + radius);
+       camera->lookAt(0, 0, 0);
+
+       return true;
+}
+
+void RoRViewer::Deinitialize(void)
+{
+       if (!initialized) return;
+       ResourceGroupManager* rg_mgr = ResourceGroupManager::getSingletonPtr();
+
+       if(timer) delete timer;
+       window->removeViewport(0);
+       scene_mgr->getRootSceneNode()->removeChild(camera_node);
+       scene_mgr->destroySceneNode(camera_node);
+       scene_mgr->destroyCamera(camera);
+       ogre_root->destroySceneManager(scene_mgr);
+       ogre_root->detachRenderTarget("RoRViewer");
+       ogre_root->shutdown();
+
+       initialized = false;
+}
+
+void RoRViewer::Update()
+{
+       double tm = timer->getMilliseconds();
+       timer->reset();
+       ogre_root->renderOneFrame(tm);
+
+}
+
+void RoRViewer::TurnCamera(Vector3 speed)
+{
+       speed = - speed; // invert
+       active_node->yaw(Radian(Degree(speed.x)), Node::TS_WORLD);
+       active_node->pitch(Radian(Degree(speed.y)), Node::TS_LOCAL);
+
+       if(speed.z != 0)
+       {
+               Vector3 pos = camera_node->getPosition();
+               pos += Vector3(0,0,speed.z);
+               camera_node->setPosition(pos);
+               camera->lookAt(0, 0, 0);
+       }
+
+}
\ No newline at end of file

Added: trunk/source/viewer/RoRViewer.h
===================================================================
--- trunk/source/viewer/RoRViewer.h                             (rev 0)
+++ trunk/source/viewer/RoRViewer.h     2010-08-21 12:29:48 UTC (rev 1524)
@@ -0,0 +1,70 @@
+/*
+This source file is part of Rigs of Rods
+Copyright 2005,2006,2007,2008,2009 Pierre-Michel Ricordel
+Copyright 2007,2008,2009 Thomas Fischer
+
+For more information, see http://www.rigsofrods.com/
+
+Rigs of Rods is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3, as
+published by the Free Software Foundation.
+
+Rigs of Rods is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Rigs of Rods.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef RORVIEWER_H__
+#define RORVIEWER_H__
+#include <string>
+#include <Ogre.h>
+
+using namespace std;
+using namespace Ogre;
+
+class RoRViewer
+{
+public:
+       RoRViewer(string meshPath);
+       ~RoRViewer(void);
+
+       bool Initialize(std::string hwndStr);
+       void Deinitialize(void);
+       void Update(void);
+       
+       RenderWindow* GetOgreWindow(void){return window;}
+       SceneManager* GetSceneManager(void){return scene_mgr;}
+       Viewport* GetViewport(void){return viewport;}
+       Camera* GetCamera(void){return camera;}
+       MeshPtr GetMesh(void){return active_mesh;}
+       Entity* GetEntity(void){return active_entity;}
+       SceneNode* GetSceneNode(void){return active_node;}
+
+       void TurnCamera(Vector3 speed);
+
+private:
+       bool                    initialized;
+       Root*                   ogre_root;
+       SceneManager*   scene_mgr;
+       RenderWindow*   window;
+       Camera*                 camera;
+       SceneNode*              camera_node;
+       Viewport*               viewport;
+
+       MeshPtr                 active_mesh;
+       Entity*                 active_entity;
+       SceneNode*              active_node;
+
+       SceneNode*              light_node;
+       Light*                  light;
+
+       Ogre::Timer*    timer;
+       
+       string          meshPath;
+};
+
+#endif //RORVIEWER_H__
\ No newline at end of file

Added: trunk/source/viewer/RoRViewer.ico
===================================================================
(Binary files differ)


Property changes on: trunk/source/viewer/RoRViewer.ico
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/source/viewer/icon.rc
===================================================================
--- trunk/source/viewer/icon.rc                         (rev 0)
+++ trunk/source/viewer/icon.rc 2010-08-21 12:29:48 UTC (rev 1524)
@@ -0,0 +1,72 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+//#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+//#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+//#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// French (France) resources
+
+//#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA)
+//#ifdef _WIN32
+//LANGUAGE LANG_FRENCH, SUBLANG_FRENCH
+//#pragma code_page(1252)
+//#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1               ICON    DISCARDABLE     "RoRViewer.ico"
+
+//#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+//1 TEXTINCLUDE DISCARDABLE 
+//BEGIN
+//    "resource.h\0"
+//END
+
+//2 TEXTINCLUDE DISCARDABLE 
+//BEGIN
+//    "#include ""afxres.h""\r\n"
+//    "\0"
+//END
+
+//3 TEXTINCLUDE DISCARDABLE 
+//BEGIN
+//    "\r\n"
+//    "\0"
+//END
+
+//#endif    // APSTUDIO_INVOKED
+
+//#endif    // French (France) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+//#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+//#endif    // not APSTUDIO_INVOKED
+

Added: trunk/source/viewer/main.cpp
===================================================================
--- trunk/source/viewer/main.cpp                                (rev 0)
+++ trunk/source/viewer/main.cpp        2010-08-21 12:29:48 UTC (rev 1524)
@@ -0,0 +1,265 @@
+/*
+This source file is part of Rigs of Rods
+Copyright 2005,2006,2007,2008,2009 Pierre-Michel Ricordel
+Copyright 2007,2008,2009 Thomas Fischer
+
+For more information, see http://www.rigsofrods.com/
+
+Rigs of Rods is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3, as
+published by the Free Software Foundation.
+
+Rigs of Rods is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Rigs of Rods.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "main.h"
+
+#include "panel_meshprop.h"
+#include "panel_meshtree.h"
+
+#include "wxutils.h"
+#include "Settings.h"
+
+Window3D::Window3D(wxWindow* parent, wxWindowID id) : wxPanel(parent, id, 
wxDefaultPosition, wxDefaultSize, wxTRANSPARENT_WINDOW | wxBORDER_NONE | 
wxNO_FULL_REPAINT_ON_RESIZE)
+{
+       wnd = NULL;
+       cam = NULL;
+       handler = NULL;
+}
+
+void Window3D::OnSize(wxSizeEvent& e)
+{
+       if (!wnd || !cam) return;
+
+       // Setting new size;
+       int width;
+       int height;
+       GetSize(&width, &height);
+       wnd->resize(width, height);
+
+       // Letting Ogre know the window has been resized;
+       wnd->windowMovedOrResized();
+
+       // Set the aspect ratio for the new size;
+       cam->setAspectRatio(Ogre::Real(width) / Ogre::Real(height));
+}
+
+void Window3D::OnLeftUp(wxMouseEvent& e)
+{
+       if (handler) handler->OnLeftUp(e.m_x, e.m_y);
+}
+
+void Window3D::OnMouseMove(wxMouseEvent& e)
+{
+       if (handler) handler->OnMouseMove(e);
+}
+
+void Window3D::OnKeyDown(wxKeyEvent& e)
+{
+       if (handler) handler->OnKeyDown(e.ControlDown(), e.AltDown(), 
e.ShiftDown(), e.GetKeyCode());
+}
+
+bool RoRViewerApp::OnInit(void)
+{
+       if (!wxApp::OnInit())
+               return false;
+
+       frame = new RoRViewerFrame(L"RoR Viewer");
+       SetTopWindow(frame);
+       frame->Show();
+       
+       frame->InitializeAUI();
+       if (!frame->InitializeRoRViewer(meshPath))
+       {
+               frame->DeinitializeAUI();
+               return false;
+       }
+
+       return true;
+}
+
+void RoRViewerApp::OnInitCmdLine(wxCmdLineParser& parser)
+{
+       parser.AddParam(_T("<file>"), wxCMD_LINE_VAL_STRING, 
wxCMD_LINE_OPTION_MANDATORY);
+}
+
+bool RoRViewerApp::OnCmdLineParsed(wxCmdLineParser& parser)
+{
+       meshPath = parser.GetParam();
+       return !meshPath.empty();
+}
+
+int RoRViewerApp::OnExit(void)
+{
+       return 0;
+}
+
+RoRViewerFrame::RoRViewerFrame(wxString title) : wxFrame(NULL, wxID_ANY, title)
+{
+       msx = 0;
+       msy = 0;
+       msw = 0;
+
+       viewer = NULL;
+
+       SetMinSize(wxSize(640, 480));
+       SetClientSize(640, 480);
+
+       Show();
+}
+
+RoRViewerFrame::~RoRViewerFrame()
+{
+       DenitializeRoRViewer();
+       DeinitializeAUI();
+
+}
+
+void RoRViewerFrame::InitializeAUI(void)
+{
+       aui_mgr = new wxAuiManager(this);
+
+       // main 3D viewport
+       pane_viewport = new wxAuiPaneInfo();
+       pane_viewport->PaneBorder(false);
+       pane_viewport->CaptionVisible(false);
+       pane_viewport->Caption(L"3D Viewport");
+       pane_viewport->FloatingSize(wxSize(200, 300));
+       pane_viewport->MinSize(wxSize(200, 300));
+       pane_viewport->Center();
+       pane_viewport->Dock();
+       panel_viewport = new Window3D(this, ID_VIEWPORT);
+       panel_viewport->SetBackgroundColour(wxColour(L"Gray"));
+       aui_mgr->AddPane(panel_viewport, *pane_viewport);
+       panel_viewport->handler = this;
+
+       // property grid
+       pane_meshprop = new wxAuiPaneInfo();
+       pane_meshprop->CaptionVisible(true);
+       pane_meshprop->Caption(L"Properties");
+       pane_meshprop->FloatingSize(wxSize(200, 150));
+       pane_meshprop->MinSize(wxSize(200, 250));
+       //pane_meshprop->MaxSize(wxSize(200, 150));
+       pane_meshprop->BestSize(wxSize(200, 250));
+       pane_meshprop->Resizable(true);
+       pane_meshprop->TopDockable(false);
+       pane_meshprop->BottomDockable(false);
+       pane_meshprop->Left();
+       pane_meshprop->Position(1);
+       pane_meshprop->Dock();
+       panel_meshprop = new PanelMeshProp(0, this, wxID_ANY);
+       aui_mgr->AddPane(panel_meshprop, *pane_meshprop);
+
+       // tree
+       pane_meshtree = new wxAuiPaneInfo();
+       pane_meshtree->CaptionVisible(true);
+       pane_meshtree->Caption(L"Tree");
+       pane_meshtree->FloatingSize(wxSize(200, 150));
+       pane_meshtree->MinSize(wxSize(200, 250));
+       //pane_meshtree->MaxSize(wxSize(200, 150));
+       pane_meshtree->BestSize(wxSize(200, 250));
+       pane_meshtree->Resizable(true);
+       pane_meshtree->TopDockable(false);
+       pane_meshtree->BottomDockable(false);
+       pane_meshtree->Left();
+       pane_meshtree->Position(0);
+       pane_meshtree->Dock();
+       panel_meshtree = new PanelMeshTree(0, this, wxID_ANY);
+       panel_meshtree->setPropGrid(panel_meshprop);
+       aui_mgr->AddPane(panel_meshtree, *pane_meshtree);
+
+       // done with AUI
+       aui_mgr->Update();
+
+       // try to load the old window layout
+       String perspective_str = SETTINGS.getSetting("ViewerPerspective");
+       if(!perspective_str.empty())
+       {
+               aui_mgr->LoadPerspective(wxString(perspective_str.c_str()));
+       }
+}
+
+void RoRViewerFrame::DeinitializeAUI(void)
+{
+       // save the window layout
+       string perspective_str = 
std::string(aui_mgr->SavePerspective().mb_str());
+       SETTINGS.setSetting("ViewerPerspective",perspective_str);
+       SETTINGS.saveSettings();
+
+       aui_mgr->UnInit();
+}
+
+bool RoRViewerFrame::InitializeRoRViewer(wxString meshPath)
+{
+       string mstr = std::string(meshPath.mb_str());
+       viewer = new RoRViewer(mstr);
+       if (!viewer->Initialize(getWindowHandle(panel_viewport)))
+       {
+               delete viewer;
+               viewer = NULL;
+               return false;
+       }
+       panel_meshprop->setViewer(viewer);
+       panel_meshtree->setViewer(viewer);
+
+       panel_viewport->wnd = viewer->GetOgreWindow();
+       panel_viewport->cam = viewer->GetCamera();
+
+       return true;
+}
+
+void RoRViewerFrame::DenitializeRoRViewer(void)
+{
+       panel_viewport->handler = NULL;
+       panel_viewport->wnd = NULL;
+
+       if (viewer)
+       {
+               viewer->Deinitialize();
+               delete viewer;
+               viewer = NULL;
+       }
+}
+
+void RoRViewerFrame::updatePanelData()
+{
+       panel_meshprop->updateData();
+       panel_meshtree->updateData();
+}
+
+void RoRViewerFrame::OnIdle(wxIdleEvent& e)
+{
+       viewer->Update();
+       updatePanelData();
+
+       e.RequestMore();
+}
+
+void RoRViewerFrame::OnLeftUp(int x, int y)
+{
+}
+
+void RoRViewerFrame::OnMouseMove(wxMouseEvent& e)
+{
+       int xp = msx - e.m_x;
+       int yp = msy - e.m_y;
+       int wp = e.m_wheelRotation;
+       msx = e.m_x;
+       msy = e.m_y;
+
+       /// shit behaves badly, to be fixed!
+       if (e.LeftIsDown() || wp != 0)
+       {
+               viewer->TurnCamera(Vector3(xp*0.2f, yp*0.2f, wp*0.002f));
+       }
+}
+
+void RoRViewerFrame::OnKeyDown(bool ctrl, bool alt, bool shift, int key)
+{
+}

Added: trunk/source/viewer/main.h
===================================================================
--- trunk/source/viewer/main.h                          (rev 0)
+++ trunk/source/viewer/main.h  2010-08-21 12:29:48 UTC (rev 1524)
@@ -0,0 +1,154 @@
+/*
+This source file is part of Rigs of Rods
+Copyright 2005,2006,2007,2008,2009 Pierre-Michel Ricordel
+Copyright 2007,2008,2009 Thomas Fischer
+
+For more information, see http://www.rigsofrods.com/
+
+Rigs of Rods is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3, as
+published by the Free Software Foundation.
+
+Rigs of Rods is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Rigs of Rods.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef MESHVIEWERMAIN_H__
+#define MESHVIEWERMAIN_H__
+
+#include <vector>
+#include <wx/wx.h>
+#include <wx/aui/aui.h>
+#include <wx/artprov.h>
+#include <wx/menu.h>
+#include <wx/toolbar.h>
+#include <wx/statusbr.h>
+#include <wx/colordlg.h>
+#include <wx/wrapsizer.h>
+#include <wx/msgdlg.h>
+#include <wx/event.h>
+#include <wx/gdicmn.h>
+#include <wx/vscroll.h>
+#include <wx/rawbmp.h>
+#include <wx/dir.h>
+#include <wx/spinctrl.h>
+#include <wx/cmdline.h>
+
+#include "RoRViewer.h"
+
+// RoR includes
+#include "Settings.h"
+
+using namespace std;
+
+class PanelMeshProp;
+class PanelMeshTree;
+
+enum
+{
+       ID_VIEWPORT,
+};
+
+class Window3DHandler
+{
+public:
+       virtual void OnLeftUp(int x, int y) = 0;
+       virtual void OnMouseMove(wxMouseEvent& e) = 0;
+       virtual void OnKeyDown(bool ctrl, bool alt, bool shift, int key) = 0;
+};
+
+class Window3D : public wxPanel
+{
+public:
+       Window3D(wxWindow* parent, wxWindowID id);
+
+       void OnSize(wxSizeEvent& e);
+       void OnLeftUp(wxMouseEvent& e);
+       void OnMouseMove(wxMouseEvent& e);
+       void OnKeyDown(wxKeyEvent& event);
+       Window3DHandler* handler;
+       Ogre::RenderWindow* wnd;
+       Ogre::Camera* cam;
+
+private:
+        DECLARE_EVENT_TABLE()
+};
+
+BEGIN_EVENT_TABLE(Window3D, wxPanel)
+       EVT_LEFT_UP(Window3D::OnLeftUp)
+       EVT_KEY_DOWN(Window3D::OnKeyDown)
+       EVT_MOTION(Window3D::OnMouseMove)
+       EVT_MOUSEWHEEL(Window3D::OnMouseMove)
+       EVT_SIZE(Window3D::OnSize)
+       // maybe use EVT_MOUSE_EVENTS for all events
+END_EVENT_TABLE()
+
+class RoRViewerFrame : public wxFrame, Window3DHandler
+{
+public:
+       RoRViewerFrame(wxString title);
+       ~RoRViewerFrame();
+
+       void updatePanelData(void);
+
+       void InitializeAUI(void);
+       void DeinitializeAUI(void);
+
+       bool InitializeRoRViewer(wxString meshPath);
+       void DenitializeRoRViewer(void);
+
+       void OnIdle(wxIdleEvent& event);
+
+       // Window3DHandler
+       void OnLeftUp(int x, int y);
+       void OnMouseMove(wxMouseEvent& e);
+       void OnKeyDown(bool ctrl, bool alt, bool shift, int key);
+private:
+       int msx, msy, msw;
+
+       // AUI elements
+       wxAuiManager* aui_mgr;
+
+       Window3D* panel_viewport;
+       wxAuiPaneInfo* pane_viewport;
+
+       PanelMeshProp* panel_meshprop;
+       wxAuiPaneInfo* pane_meshprop;
+
+       PanelMeshTree* panel_meshtree;
+       wxAuiPaneInfo* pane_meshtree;
+
+       RoRViewer* viewer;
+    DECLARE_EVENT_TABLE()
+};
+
+class RoRViewerApp : public wxApp
+{
+public:
+       bool OnInit(void);
+
+       void OnInitCmdLine(wxCmdLineParser& parser);
+       bool OnCmdLineParsed(wxCmdLineParser& parser);
+       int OnExit(void);
+private:
+       wxString meshPath;
+       RoRViewerFrame* frame;
+};
+
+
+BEGIN_EVENT_TABLE(RoRViewerFrame, wxFrame)
+       EVT_IDLE(RoRViewerFrame::OnIdle)
+END_EVENT_TABLE()
+
+#ifdef USE_CONSOLE
+IMPLEMENT_APP_CONSOLE(RoRViewerApp)
+#else
+IMPLEMENT_APP(RoRViewerApp)
+#endif
+
+#endif //MESHVIEWERMAIN_H__
\ No newline at end of file

Added: trunk/source/viewer/panel_meshprop.h
===================================================================
--- trunk/source/viewer/panel_meshprop.h                                (rev 0)
+++ trunk/source/viewer/panel_meshprop.h        2010-08-21 12:29:48 UTC (rev 
1524)
@@ -0,0 +1,317 @@
+/*
+This source file is part of Rigs of Rods
+Copyright 2005,2006,2007,2008,2009 Pierre-Michel Ricordel
+Copyright 2007,2008,2009 Thomas Fischer
+
+For more information, see http://www.rigsofrods.com/
+
+Rigs of Rods is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3, as
+published by the Free Software Foundation.
+
+Rigs of Rods is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Rigs of Rods.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef PANEL_MESHPROP_H__
+#define PANEL_MESHPROP_H__
+
+#include <wx/wx.h>
+
+// Main propertygrid header.
+#include <wx/propgrid/propgrid.h>
+
+// Extra property classes.
+#include <wx/propgrid/advprops.h>
+
+// This defines wxPropertyGridManager.
+#include <wx/propgrid/manager.h>
+
+#include "RoRViewer.h"
+
+class PanelMeshProp : public wxPanel
+{
+protected:
+       RoRViewer *viewer;
+       Ogre::MeshPtr current_mesh;
+       int current_item;
+       wxPropertyGrid  *pg;
+       wxPropertyGridManager *pgman;
+       enum { 
+               PGID1,
+               PGID2,
+       };
+
+public:
+       void setViewer(RoRViewer *_viewer)
+       {
+               viewer = _viewer;
+       }
+
+    PanelMeshProp(RoRViewer *_viewer, wxWindow *parent,
+            wxWindowID winid = wxID_ANY,
+            const wxPoint& pos = wxDefaultPosition,
+            const wxSize& size = wxDefaultSize,
+            long style = wxTAB_TRAVERSAL | wxNO_BORDER,
+            const wxString& name = wxPanelNameStr) :
+               wxPanel(parent, winid, pos, size, style, name), 
viewer(_viewer), current_mesh(0), current_item(-1)
+    {
+               // create sizer and PG
+               wxBoxSizer *vsizer = new wxBoxSizer ( wxVERTICAL );
+               this->SetSizer(vsizer);
+               vsizer->SetSizeHints(this);
+               
+               // then add the propertygrid
+               int pgstyle = wxPG_BOLD_MODIFIED | wxPG_SPLITTER_AUTO_CENTER | 
wxPG_AUTO_SORT | wxPG_TOOLBAR | wxPG_DESCRIPTION;
+               int extrastyle = wxPG_EX_MODE_BUTTONS;
+               pg = new wxPropertyGrid(this,
+                                                                       PGID1,
+                                                                       
wxDefaultPosition,
+                                                                       
wxDefaultSize,
+                                                                       
pgstyle);
+               pgman = new wxPropertyGridManager(this,
+                                  PGID2,
+                                  wxDefaultPosition,
+                                  wxDefaultSize,
+                                  pgstyle );
+               pgman->SetExtraStyle(extrastyle);
+               vsizer->Add( pgman, 1, wxEXPAND );
+               //pg->Bind(wxEVT_PG_CHANGED, 
&PanelTruckProp::onPropertyGridChange, this, PGID1);
+    }
+       
+       void updateData()
+       {
+               if(!viewer) return;
+               Ogre::MeshPtr mesh = viewer->GetMesh();
+               if(mesh.isNull())
+                       return;
+
+               // only update if mesh changed
+               if(mesh == current_mesh)
+                       return;
+
+               current_mesh = mesh;
+       }
+
+       void OnPropertyChange(wxPropertyGridEvent &ev)
+       {
+               wxPGProperty *p = ev.GetProperty();
+       }
+
+       void updatePG(int item)
+       {
+               wxPGProperty *p=0;
+
+               // check if update is needed
+               if(item == current_item)
+                       return;
+               current_item = item;
+
+               pgman->Clear();
+               if(item == 0)
+               {
+                       // main mesh
+                       wxPropertyGridPage *pgp = pgman->AddPage(wxT("Mesh"));
+
+                       // bounds
+                       pgp->Append(new wxPropertyCategory("Bounds"));
+
+                       AxisAlignedBox bounds = current_mesh->getBounds();
+                       Vector3 bounds_min = bounds.getMinimum();
+                       Vector3 bounds_max = bounds.getMaximum();
+                       wxPGProperty *boundsProp    = pgp->Append(new 
wxStringProperty("Bounds", wxPG_LABEL, "<composed>"));
+                       pgp->SetPropertyReadOnly(boundsProp);
+                       pgp->SetPropertyHelpString(boundsProp, "axis-aligned 
bounding box for this mesh."); 
+                       wxPGProperty *boundsMinProp = pgp->AppendIn(boundsProp, 
new wxStringProperty("Minimum", wxPG_LABEL, "<composed>"));
+                       boundsMinProp->SetExpanded(false);
+                       wxPGProperty *boundsMinX    = 
pgp->AppendIn(boundsMinProp, new wxIntProperty("X", wxPG_LABEL, bounds_min.x));
+                       wxPGProperty *boundsMinY    = 
pgp->AppendIn(boundsMinProp, new wxIntProperty("Y", wxPG_LABEL, bounds_min.y));
+                       wxPGProperty *boundsMinZ    = 
pgp->AppendIn(boundsMinProp, new wxIntProperty("Z", wxPG_LABEL, bounds_min.z));
+                       wxPGProperty *boundsMaxProp = pgp->AppendIn(boundsProp, 
new wxStringProperty("Maximum", wxPG_LABEL, "<composed>"));
+                       
+                       boundsMaxProp->SetExpanded(false);
+                       wxPGProperty *boundsMaxX    = 
pgp->AppendIn(boundsMaxProp, new wxIntProperty("X", wxPG_LABEL, bounds_max.x));
+                       wxPGProperty *boundsMaxY    = 
pgp->AppendIn(boundsMaxProp, new wxIntProperty("Y", wxPG_LABEL, bounds_max.y));
+                       wxPGProperty *boundsMaxZ    = 
pgp->AppendIn(boundsMaxProp, new wxIntProperty("Z", wxPG_LABEL, bounds_max.z));
+
+                       pgp->Append(p = new wxFloatProperty("Bounding Sphere 
Radius", wxPG_LABEL, current_mesh->getBoundingSphereRadius()));
+                       pgp->SetPropertyHelpString(p, "radius of the bounding 
sphere surrounding this mesh"); 
+                       pgp->SetPropertyReadOnly(p);
+
+                       
+                       pgp->Append(new wxPropertyCategory("LODs"));
+                       pgp->Append(p = new wxIntProperty("Number of LOD 
Levels", wxPG_LABEL, current_mesh->getNumLodLevels()));
+                       pgp->SetPropertyHelpString(p, "number of levels of 
detail that this mesh supports");
+                       pgp->SetPropertyReadOnly(p);
+                       
+                       for(int i=0; i<current_mesh->getNumLodLevels(); i++)
+                       {
+                               MeshLodUsage lu = current_mesh->getLodLevel(i);
+                               pgp->Append(p = new wxFloatProperty("value", 
wxPG_LABEL, lu.value));
+                               pgp->SetPropertyHelpString(p, "Value used to 
determine when this lod applies");
+                               pgp->SetPropertyReadOnly(p);
+                               pgp->Append(p = new 
wxFloatProperty("userValue", wxPG_LABEL, lu.userValue));
+                               pgp->SetPropertyHelpString(p, "User-supplied 
values used to determine when th is lod applies");
+                               pgp->SetPropertyReadOnly(p);
+                               pgp->Append(p = new 
wxStringProperty("manualName", wxPG_LABEL, lu.manualName));
+                               pgp->SetPropertyHelpString(p, "name of the 
alternative mesh to use");
+                               pgp->SetPropertyReadOnly(p);
+                               pgp->Append(p = new 
wxStringProperty("manualGroup", wxPG_LABEL, lu.manualGroup));
+                               pgp->SetPropertyHelpString(p, "name of the 
group of the alternative mesh");
+                               pgp->SetPropertyReadOnly(p);
+                               EdgeData *edgeData = lu.edgeData;
+                               if(edgeData)
+                               {
+                                       pgp->Append(p = new 
wxIntProperty("TriangleCount", wxPG_LABEL, edgeData->triangles.size()));
+                                       pgp->SetPropertyReadOnly(p);
+                               }
+                       }
+                       pgp->Append(p = new wxBoolProperty("isLodManual", 
wxPG_LABEL, current_mesh->isLodManual()));
+                       pgp->SetPropertyHelpString(p, "true if this mesh is 
using manual LOD");
+                       pgp->SetPropertyReadOnly(p);
+
+                       
+                       pgp->Append(new wxPropertyCategory("Unsorted"));
+                       pgp->Append(p = new wxIntProperty("Number of 
Submeshes", wxPG_LABEL, current_mesh->getNumSubMeshes()));
+                       pgp->SetPropertyHelpString(p, "number of sub meshes 
which comprise this mesh");
+                       pgp->SetPropertyReadOnly(p);
+
+                       wxArrayString arrBufferUsage;
+                       arrBufferUsage.Add("HBU_STATIC");
+                       arrBufferUsage.Add("HBU_DYNAMIC");
+                       arrBufferUsage.Add("HBU_WRITE_ONLY");
+                       arrBufferUsage.Add("HBU_DISCARDABLE");
+                       arrBufferUsage.Add("HBU_STATIC_WRITE_ONLY");
+                       arrBufferUsage.Add("HBU_DYNAMIC_WRITE_ONLY");
+                       
arrBufferUsage.Add("HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE");
+
+                       pgp->Append(p = new 
wxEnumProperty("getVertexBufferUsage", wxPG_LABEL, arrBufferUsage, 
wxArrayInt(), current_mesh->getVertexBufferUsage()));
+                       pgp->SetPropertyHelpString(p, "usage setting for this 
meshes vertex buffers");
+                       pgp->SetPropertyReadOnly(p);
+                       pgp->Append(p = new 
wxEnumProperty("getIndexBufferUsage",  wxPG_LABEL, arrBufferUsage, 
wxArrayInt(), current_mesh->getIndexBufferUsage()));
+                       pgp->SetPropertyHelpString(p, "usage setting for this 
meshes index buffers");
+                       pgp->SetPropertyReadOnly(p);
+
+                       pgp->Append(p = new 
wxBoolProperty("isVertexBufferShadowed", wxPG_LABEL, 
current_mesh->isVertexBufferShadowed()));
+                       pgp->SetPropertyHelpString(p, "whether or not this 
meshes vertex buffers are shadowed");
+                       pgp->SetPropertyReadOnly(p);
+                       pgp->Append(p = new 
wxBoolProperty("isIndexBufferShadowed", wxPG_LABEL, 
current_mesh->isIndexBufferShadowed()));
+                       pgp->SetPropertyHelpString(p, "whether or not this 
meshes index buffers are shadowed");
+                       pgp->SetPropertyReadOnly(p);
+                        
+                       pgp->Append(new wxPropertyCategory("Animations"));
+                       pgp->Append(p = new wxIntProperty("Animations Count", 
wxPG_LABEL, current_mesh->getNumAnimations()));
+                       pgp->SetPropertyHelpString(p, "number of morph 
animations in this mesh");
+                       pgp->SetPropertyReadOnly(p);
+
+                       pgp->Append(p = new wxIntProperty("Pose Count", 
wxPG_LABEL, current_mesh->getPoseCount()));
+                       pgp->SetPropertyHelpString(p, "number of poses");
+                       pgp->SetPropertyReadOnly(p);
+
+                       pgp->Append(p = new wxBoolProperty("Has Skeleton", 
wxPG_LABEL, current_mesh->hasSkeleton()));
+                       pgp->SetPropertyHelpString(p, "true if this Mesh has a 
linked Skeleton");
+                       pgp->SetPropertyReadOnly(p);
+                       
+                       if(current_mesh->hasSkeleton())
+                       {
+                               pgp->Append(p = new wxStringProperty("Skeleton 
Name", wxPG_LABEL, current_mesh->getSkeletonName()));
+                               pgp->SetPropertyHelpString(p, "name of any 
linked Skeleton");
+                               pgp->SetPropertyReadOnly(p);
+                       }
+                       pgp->Append(p = new wxBoolProperty("Has Vertex 
Animation", wxPG_LABEL, current_mesh->hasVertexAnimation()));
+                       pgp->SetPropertyHelpString(p, "whether or not this mesh 
has some kind of vertex animation");
+                       pgp->SetPropertyReadOnly(p);
+
+                       pgp->Append(new wxPropertyCategory("Parameters"));
+                       ParameterList pl = current_mesh->getParameters();
+                       pgp->Append(p = new wxIntProperty("Parameter Count", 
wxPG_LABEL, pl.size()));
+                       pgp->SetPropertyReadOnly(p);
+                       for(int i=0; i < (int)pl.size(); i++)
+                       {
+                               wxPGProperty *parameterProp = pgp->Append(new 
wxIntProperty("Parameter " + StringConverter::toString(i), wxPG_LABEL, 
pl.size()));
+                               pgp->AppendIn(parameterProp, p = new 
wxStringProperty("name", wxPG_LABEL, pl[i].name));
+                               pgp->SetPropertyReadOnly(p);
+                               pgp->AppendIn(parameterProp, p = new 
wxStringProperty("description", wxPG_LABEL, pl[i].description));
+                               pgp->SetPropertyReadOnly(p);
+                               pgp->AppendIn(parameterProp, p = new 
wxIntProperty("paramType", wxPG_LABEL, pl[i].paramType));
+                               pgp->SetPropertyReadOnly(p);
+                               pgp->AppendIn(parameterProp, p = new 
wxStringProperty("value", wxPG_LABEL, current_mesh->getParameter(pl[i].name)));
+                               pgp->SetPropertyReadOnly(p);
+                       }
+               } else
+               {
+                       // a submesh
+                       // reduce item number by one, so it fits again
+                       item--;
+
+                       wxPropertyGridPage *pgp = 
pgman->AddPage(wxT("SubMesh"));
+                       SubMesh *sm = current_mesh->getSubMesh(item);
+                       if(!sm) return;
+                       pgp->Append(new wxPropertyCategory("General"));
+                       pgp->Append(p = new wxStringProperty("Material Name", 
wxPG_LABEL, sm->getMaterialName()));
+                       pgp->SetPropertyReadOnly(p);
+
+                       pgp->Append(p = new wxBoolProperty("isMatInitialised", 
wxPG_LABEL, sm->isMatInitialised()));
+                       pgp->SetPropertyHelpString(p, "true if a material has 
been assigned to the submesh, otherwise false");
+                       pgp->SetPropertyReadOnly(p);
+
+                       pgp->Append(p = new wxBoolProperty("hasTextureAliases", 
wxPG_LABEL, sm->hasTextureAliases()));
+                       pgp->SetPropertyHelpString(p, "true if the sub mesh has 
texture aliases");
+                       pgp->SetPropertyReadOnly(p);
+                       
+                       if(sm->hasTextureAliases())
+                       {
+                               pgp->Append(p = new 
wxIntProperty("textureAliasCount", wxPG_LABEL, sm->getTextureAliasCount()));
+                               pgp->SetPropertyHelpString(p, "number of 
texture aliases assigned to the sub mesh");
+                               pgp->SetPropertyReadOnly(p);
+                       }
+
+                       wxArrayString arrVertAnimType;
+                       arrVertAnimType.Add("VAT_NONE");
+                       arrVertAnimType.Add("VAT_MORPH");
+                       arrVertAnimType.Add("VAT_POSE");
+
+                       pgp->Append(p = new 
wxEnumProperty("vertexAnimationType", wxPG_LABEL, arrVertAnimType, 
wxArrayInt(), sm->getVertexAnimationType()));
+                       pgp->SetPropertyHelpString(p, "type of any vertex 
animation used by dedicated geometry");
+                       pgp->SetPropertyReadOnly(p);
+                       
+                       pgp->Append(p = new wxBoolProperty("buildEdgesEnabled", 
wxPG_LABEL, sm->isBuildEdgesEnabled()));
+                       pgp->SetPropertyHelpString(p, "true(by default) if the 
submesh should be included in the mesh EdgeList, otherwise returns false");
+                       pgp->SetPropertyReadOnly(p);
+
+                       pgp->Append(p = new wxBoolProperty("useSharedVertices", 
wxPG_LABEL, sm->useSharedVertices));
+                       pgp->SetPropertyHelpString(p, "Indicates if this 
submesh shares vertex data with other meshes or whether it has it's own 
vertices");
+                       pgp->SetPropertyReadOnly(p);
+
+                       if(sm->vertexData)
+                       {
+                               pgp->Append(p = new 
wxIntProperty("vertexCount", wxPG_LABEL, sm->vertexData->vertexCount));
+                               pgp->SetPropertyHelpString(p, "The number of 
vertices used in this operation");
+                               pgp->SetPropertyReadOnly(p);
+                       }
+
+                       if(sm->indexData)
+                       {
+                               pgp->Append(p = new wxIntProperty("indexCount", 
wxPG_LABEL, sm->indexData->indexCount));
+                               pgp->SetPropertyHelpString(p, "The number of 
indexes to use from the buffer");
+                               pgp->SetPropertyReadOnly(p);
+                       }
+
+                       // maybe add sm->extremityPoints ?
+               }
+       }
+
+private:
+    DECLARE_EVENT_TABLE()
+};
+
+BEGIN_EVENT_TABLE(PanelMeshProp, wxPanel)
+    EVT_PG_CHANGED( wxID_ANY, PanelMeshProp::OnPropertyChange )
+END_EVENT_TABLE()
+
+#endif //PANEL_MESHPROP_H__

Added: trunk/source/viewer/panel_meshtree.h
===================================================================
--- trunk/source/viewer/panel_meshtree.h                                (rev 0)
+++ trunk/source/viewer/panel_meshtree.h        2010-08-21 12:29:48 UTC (rev 
1524)
@@ -0,0 +1,166 @@
+/*
+This source file is part of Rigs of Rods
+Copyright 2005,2006,2007,2008,2009 Pierre-Michel Ricordel
+Copyright 2007,2008,2009 Thomas Fischer
+
+For more information, see http://www.rigsofrods.com/
+
+Rigs of Rods is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3, as
+published by the Free Software Foundation.
+
+Rigs of Rods is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Rigs of Rods.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef PANEL_MESHTREE_H__
+#define PANEL_MESHTREE_H__
+
+#include <wx/wx.h>
+
+#include <wx/treectrl.h> // for treectrl
+
+#include "RoRViewer.h"
+
+#include "panel_meshprop.h"
+
+
+class TreeItemData : public wxTreeItemData
+{
+public:
+       TreeItemData(int _value) : value(_value)
+       {
+       }
+
+       ~TreeItemData()
+       {
+       }
+
+       int value;
+};
+
+class PanelMeshTree : public wxPanel
+{
+protected:
+       wxTreeCtrl *tree;
+       RoRViewer *viewer;
+       PanelMeshProp *meshProp;
+       Ogre::MeshPtr current_mesh;
+       enum { 
+               MESHTREE,
+       };
+
+public:
+       void setViewer(RoRViewer *_viewer)
+       {
+               viewer = _viewer;
+       }
+       
+       void setPropGrid(PanelMeshProp *_meshProp)
+       {
+               meshProp = _meshProp;
+       }
+
+    PanelMeshTree(RoRViewer *_viewer, wxWindow *parent,
+            wxWindowID winid = wxID_ANY,
+            const wxPoint& pos = wxDefaultPosition,
+            const wxSize& size = wxDefaultSize,
+            long style = wxTAB_TRAVERSAL | wxNO_BORDER,
+            const wxString& name = wxPanelNameStr) :
+               wxPanel(parent, winid, pos, size, style, name), 
viewer(_viewer), current_mesh(0)
+    {
+               // create sizer and tree
+               wxBoxSizer *vsizer = new wxBoxSizer ( wxVERTICAL );
+               this->SetSizer(vsizer);
+               vsizer->SetSizeHints(this);
+               
+               // add the treeview
+               tree = new wxTreeCtrl(this, MESHTREE);
+               vsizer->Add( tree, 1, wxEXPAND );
+    }
+       
+       void updateData()
+       {
+               if(!viewer) return;
+               Ogre::MeshPtr mesh = viewer->GetMesh();
+               if(mesh.isNull())
+                       return;
+
+               // only update if mesh changed
+               if(mesh == current_mesh)
+                       return;
+
+               current_mesh = mesh;
+
+               // mesh valid, lets do the update work
+               
+               // tree first
+               tree->DeleteAllItems();
+               wxTreeItemId root = tree->AddRoot(mesh->getName(), -1, -1, new 
TreeItemData(0));
+
+               // add submeshes
+               for(int i = 0; i < mesh->getNumSubMeshes(); i++)
+               {
+                       Ogre::SubMesh *sm = mesh->getSubMesh(i);
+                       if(!sm) continue;
+                       tree->AppendItem(root, "SubMesh " + 
StringConverter::toString(i), -1, -1, new TreeItemData(i+1));
+               }
+
+               // select mesh item
+               tree->SelectItem(root);
+
+               tree->ExpandAll();
+
+
+               // update PG
+               if(meshProp)
+                       meshProp->updatePG(0);
+       }
+
+       void OnTreeItemChange(wxTreeEvent &event)
+       {
+               wxTreeItemId id = (wxTreeItemId) event.GetItem();
+               TreeItemData *data = (TreeItemData *)tree->GetItemData(id);
+               if(!data)
+                       return;
+               if(!meshProp)
+                       return;
+               
+               // update 3d viewport :)
+               Ogre::Entity *e = viewer->GetEntity();
+               if(e && data->value == 0)
+               {
+                       // show full mesh
+                       for(int i = 0; i < (int)e->getNumSubEntities(); i++)
+                       {
+                               SubEntity *se = e->getSubEntity(i);
+                               if(se) se->setVisible(true);
+                       }
+               } else if (e && data->value != 0)
+               {
+                       // show only one specific submesh
+                       for(int i = 0; i < (int)e->getNumSubEntities(); i++)
+                       {
+                               SubEntity *se = e->getSubEntity(i);
+                               if(se) se->setVisible( (i == (data->value - 1)) 
);
+                       }
+               }
+               
+               // update PG
+               meshProp->updatePG(data->value);
+       }
+
+private:
+    DECLARE_EVENT_TABLE()
+};
+
+BEGIN_EVENT_TABLE(PanelMeshTree, wxPanel)
+       EVT_TREE_SEL_CHANGED(MESHTREE, PanelMeshTree::OnTreeItemChange)
+END_EVENT_TABLE()
+
+#endif //PANEL_MESHTREE_H__

Added: trunk/source/viewer/wxutils.cpp
===================================================================
--- trunk/source/viewer/wxutils.cpp                             (rev 0)
+++ trunk/source/viewer/wxutils.cpp     2010-08-21 12:29:48 UTC (rev 1524)
@@ -0,0 +1,99 @@
+/*
+This source file is part of Rigs of Rods
+Copyright 2005,2006,2007,2008,2009 Pierre-Michel Ricordel
+Copyright 2007,2008,2009 Thomas Fischer
+
+For more information, see http://www.rigsofrods.com/
+
+Rigs of Rods is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3, as
+published by the Free Software Foundation.
+
+Rigs of Rods is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Rigs of Rods.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "wxutils.h"
+
+#include <iostream>
+#include <sstream>
+
+// this is in a separate file to reduce the clutter in the global namespace 
and their conflicts
+
+#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
+# ifdef __WXGTK__
+#include <gdk/gdk.h>
+#include <gtk/gtk.h> // just this should suffice as it should include gdk.h 
itself
+/* Seems to be needed under Linux */
+//#include <wx/gtk/win_gtk.h>
+#include "wx/gtk/private/win_gtk.h"
+#include <gdk/gdkx.h>
+#include <GL/glx.h>
+
+#if  wxCHECK_VERSION(2, 9, 0)
+#define piz(wxwin) WX_PIZZA((wxwin)->m_wxwindow)
+#define GetXWindow(wxwin) (wxwin)->m_wxwindow ? \
+           GDK_WINDOW_XWINDOW(((GtkWidget*)piz(wxwin))->window) : \
+           GDK_WINDOW_XWINDOW((wxwin)->m_widget->window)
+#else
+#define GetXWindow(wxwin) (wxwin)->m_wxwindow ? \
+           GDK_WINDOW_XWINDOW(GTK_PIZZA((wxwin)->m_wxwindow)->bin_window) : \
+           GDK_WINDOW_XWINDOW((wxwin)->m_widget->window)
+#endif
+
+#ifdef __WXX11__
+#include "wx/x11/privx.h"
+#define GetXWindow(wxwin)   ((Window)(wxwin)->GetHandle())
+#endif
+
+# endif //__WXGTK__
+#endif //OGRE_PLATFORM_LINUX
+
+std::string getWindowHandle(wxWindow *window)
+{
+#if WIN32
+    std::stringstream sstr;
+       size_t hWnd = (size_t)window->GetHandle();
+    sstr << hWnd;
+    std::string result = sstr.str();
+       return result;
+#else
+
+    // TODO: Someone test this. you might to use "parentWindowHandle" if this
+    // does not work.  Ogre 1.2 + Linux + GLX platform wants a string of the
+    // format display:screen:window, which has variable types ulong:uint:ulong.
+    GtkWidget* widget = window->GetHandle();
+    //gtk_widget_set_double_buffered (widget, FALSE);
+    gtk_widget_realize( widget );      // Mandatory. Otherwise, a segfault 
happens.
+    //XSync(GDK_WINDOW_XDISPLAY(widget->window), False);
+    
+    Display* display = GDK_WINDOW_XDISPLAY( widget->window );
+
+    
+    //Window wid = GetXWindow(window);
+    Window wid = GDK_WINDOW_XWINDOW( widget->window );
+
+    std::stringstream sstr;
+    /* Get the right display (DisplayString() returns ":display.screen") */
+    std::string displayStr = DisplayString( display );
+    displayStr = displayStr.substr( 1, ( displayStr.find( ".", 0 ) - 1 ) );
+
+    int screenNum = DefaultScreen( display );
+
+    /* Put all together */
+    printf("using display: %s\n", displayStr.c_str());
+    printf("using screen: %d\n", screenNum);
+    printf("using window: 0x%x\n", wid);
+
+    // old format:
+    sstr << displayStr << ':' << screenNum << ':' << wid;
+    std::string result = sstr.str();
+
+    printf("getWindowHandle() = %s\n", result.c_str());
+    return result;
+#endif
+}

Added: trunk/source/viewer/wxutils.h
===================================================================
--- trunk/source/viewer/wxutils.h                               (rev 0)
+++ trunk/source/viewer/wxutils.h       2010-08-21 12:29:48 UTC (rev 1524)
@@ -0,0 +1,29 @@
+/*
+This source file is part of Rigs of Rods
+Copyright 2005,2006,2007,2008,2009 Pierre-Michel Ricordel
+Copyright 2007,2008,2009 Thomas Fischer
+
+For more information, see http://www.rigsofrods.com/
+
+Rigs of Rods is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3, as
+published by the Free Software Foundation.
+
+Rigs of Rods is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Rigs of Rods.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _WXUTILS_H
+#define        _WXUTILS_H
+
+#include <wx/wx.h>
+#include <string.h>
+
+std::string getWindowHandle(wxWindow *window);
+
+#endif /* _WXUTILS_H */


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
This SF.net email is sponsored by 

Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev 
_______________________________________________
Rigsofrods-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/rigsofrods-devel

Reply via email to