I recently decided to do some work on Ogre again. Here are some recent encounters...and work around that could help for starting. Some resource information on specific google searches provide work around advice. At least in terms of getting up and running some practical stuff that may save some headaches here. Much of this being aimed for the linux user in mind. My present work currently makes use of any number of tutorial and open source adaptations that I've found, alongside added work of my own in terms of compiling and working through any added lesser known information. My project link by the way (for linux) is found at https://github.com/christophermoverton/ogre3d-terraineditor . You might find some information here as well as supplements for, for instance, the intermediate tutorials if you are using something like cmake and need relevant cmake files in your local ogre directory to find the necessary cegui headers and the like.
Also while automake tools were covered for dependencies, if you want to use cmake. Then you may need to install this if you already haven't installed the cmake package. You can do so easily at terminal:
sudo apt-get install cmake
or through your software center.
If you want to follow along with build guides for Ogre then you'll need mercurial. For this at terminal you can install mercurial simply by typing:
sudo apt-get install mercurial
To compile ogre from source. You'd go to the source directory where you cloned Ogre.
I cloned from mercurial using Ogre version 1-9 so my clone looks at terminal like:
cd ogre
you verify the 1-9 version branch by typing:
hg branch
you can always pull any change sets to ogre by terminal in the ogre source directory with:
hg pull
hg update
switching to the 1-9 from any branch is done by typing:
hg update v1-9
At terminal in the ogre source directory you can begin the ogre from source build process by:
mkdir build
cd build
cmake ..
(if all is well)
make
sudo make install
(this is basically building the equivalent of the windows .exe file and running the .exe file for a program installation on your system with the added caveat that this program is tailored according to your machine specifications and optional package installs that ogre would utilize.
I'd mention this note because cmake instructions indicate this with a thorough reading but could be easier to pass over if you are attempting a more quick scan of the tutorial.
One last thing, you can find the specular and normal map texture data for splatmaps (for the 3rd basic tutorial) oddly enough in the ogre (your ogre build source directory)/Samples/Media/materials/textures/nvidia directory. You'd need to again transfer these to your project textures local directory, or alternately make sure library references are set up as necessary in script somewhere.
Mostly I've tried to journal my experiences as related to gaps provisioned by some of the tutorials as of yet.
Likely, as with any Ogre build dependencies that you'd have installed I recommend the following below additionally for cmake generation.
while boost will show with the standard libboost package (used for ogre installation) cmake compilation will yield boost showing but not showing on some other things. The libboost-all-dev package will include compilation of python bindings (which could technically be optional) but I believe owing to previous compilation build and installation issues some added packages to get cegui properly configured may be missing otherwise with the libboost as opposed to the libboost-all-dev package.
Otherwise build should be fine.
#include... CEGUI/RendererModules/Ogre/Renderer.h...
You will also want to include, if you want to render your viewport texture in a cegui window
#include ...CEGUI/RendererModules/Ogre/Texture.h...
This is important actually for any render to texturing in CEGUI window I've found in Ogre using Cegui under linux. I spent the better part of a day searching google to no avail on why in the absence of this include I was getting a static_cast issue on Cegui::OgreTexture either a forward or incomplete type issue which amounted to the compiler sort of having class declaration information but sort of not (apparently some declaration circularity issue...).
The source code while providing a number of fixes for cegui version .8x generally works.
Another thing that I've found, not sure if this is exactly right, but when working with updates to source code repositories, it may be wise to set up and alternate build directory of your choosing in the given source directory path (e.g. of ogre, or cegui) and running the cmake and make commands as usual for compilation and builds of updates. I've found that when adding new packages for cmake compilation while cmake provides includes, it appears that compilation and builds may still have exclusions or something on this.
Intermediate Tutorial 2
Since correct source is not compiled either from basic tutorial 3 and 7 which would aid in compilation this has been a bit slower than expected. I'd highly recommend adapting especially from basic tutorial 3 and 7 especially appending as necessary from above for the cmakelist.txt file. Header and .cpp include header files listed in this tutorial are different (and won't work) for ogre 1.9, cegui .8x build, basically you'd use the same header include paths as found in basic tutorial 7 and basic tutorial 3 for present terrain management system (basically a couple of terrain header file includes). I may post a link to source code header and cpp files. Generally everything working up to raytrace camera terrain heightmap collision checking. Here it appears something is fouled up, and I'd like to have cegui rendering something of a debug output, so I am presently studying getting some layouts enabled that would include for console print type output while the application is running, so I can see how the terrain camera to terrain position height checking stl container is reading all this (whether it has, for instance, any value or exactly what value is given here)... Installed also ceed which is basically a visual gui layout editor for cegui.
Further scope of the problem and why the tutorial may be considered generally incompatible I am guessing...
The problem comes with these lines in the collision detection routine.
if (itr != result.end() && itr->worldFragment)
{
Ogre::Real terrainHeight = itr->worldFragment->singleIntersection.y;
if ((terrainHeight + 10.0f) < camPos.y)
mCamera->setPosition( camPos.x, terrainHeight + 10.0f, camPos.z );
}
itr -> worldFragment always returns a False boolean type because with the Octree scene management system by default as of Ogre version 1.8 the old terrain management system has been changed, and World fragment type on the ray scene query by default is set to
Ogre::SceneQuery::WFT_NONE
The problem however in setting this to
Ogre::SceneQuery::WFT_SINGLE_INTERSECTION
for instance on the line
mRaySceneQuery ->setWorldFragmentType(Ogre::SceneQuery::WFT_SINGLE_INTERSECTION );
however is that this automatically yields an error on program execution as
20:07:01: OGRE EXCEPTION(2:InvalidParametersException): This world fragment type is not supported. in SceneQuery::setWorldFragmentType
meaning the scene manager is not supporting this...I haven't found a solution for implementing this as of yet, although it seems that a work around is going to a movable type collision method and forgoing worldFragment collision methods here.
Here is a very crude print log method that I've found using the following layout using cegui by the way. Although you'd need to figure out out how to do input output type conversions on any object that you wanted to print out for the given application running output console.
So here is the Taharez layout file. So that my resources.config file can read this additionally (without having to append this layout in the default resources directory outside my project)...
Resources config file looks like:
# Resources required by the sample browser and most samples.
[Essential]
Zip=../media/packs/SdkTrays.zip
Zip=../media/packs/cubemapsJS.zip
# Resource locations to be added to the default path
[General]
FileSystem=../media
FileSystem=../media/materials/scripts
FileSystem=../media/materials/textures
FileSystem=../media/models
FileSystem=../media/Fonts/Script
[CEGUI]
FileSystem=/usr/local/share/cegui-0/schemes
FileSystem=/usr/local/share/cegui-0/fonts
FileSystem=/usr/local/share/cegui-0/imagesets
FileSystem=/usr/local/share/cegui-0/layouts
FileSystem=/usr/local/share/cegui-0/looknfeel
FileSystem=/usr/local/share/cegui-0/lua_scripts
FileSystem=/usr/local/share/cegui-0/schemes
FileSystem=/usr/local/share/cegui-0/xml_schemas
FileSystem=../media/layouts
For instance while in my main ogre application scene function constructor I've used the following lines:
CEGUI::SchemeManager::getSingleton().createFromFile("TaharezLook.scheme");
CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor().setDefaultImage("TaharezLook/MouseArrow");
CEGUI::Window* myRoot = CEGUI::WindowManager::getSingleton().createWindow( "DefaultWindow", "_MasterRoot" );
CEGUI::System::getSingleton().getDefaultGUIContext().setRootWindow( myRoot );
CEGUI::Window *newWindow = CEGUI::WindowManager::getSingleton().loadLayoutFromFile("TreeDemoTaharez2.layout");
CEGUI::System::getSingleton().getDefaultGUIContext().getRootWindow()->addChild(newWindow);
newWindow ->setAlpha(.5);
CEGUI::Window *MultiLineEditbox = newWindow ->getChild("MultiLineEditbox");
MultiLineEditbox ->setText("Hello World!");
CEGUI::Window *editbox = newWindow ->getChild("Editbox");
editbox ->setText("Hello World!");
Above code also demonstrates accessing, for instance, individual widget "windows" inside the child windows, and setting individual properties. I used Cegui Docs .8 as a reference for function/method calls, or alternate I imagine if using a gui editor you can alternately use a set properties type function likewise.
Heres an example type conversion boolean to string conversion call in c++ that I found...most definitely a bit more code work here relative to other languages...the includes provisioned at the main ogre program outset, for instance,
#include ...iostream...
#include ...string...
#include ...sstream...
...
...
...
std::ostringstream ss, ss2;
bool val;
bool val2;
val = (itr == result.end());
ss << std::boolalpha << val ;
val2 = (itr -> worldFragment);
ss2 << std::boolalpha << val2 ;
then
ss.str() or ss2.str() calls returns a string array object which can then be input into the application console
since I hadn't made more global the scope of the widget which could be of use, alternately inside the particular function that implemented the ray scene query I used (namely, frameRenderingQueued):
CEGUI::Window *newWindow = CEGUI::System::getSingleton().getDefaultGUIContext().getRootWindow()->getChild("DemoWindow");
CEGUI::Window *MultiLineEditbox = newWindow ->getChild("MultiLineEditbox");
where "DemoWindow" is the name of the child window inside the main application window, and "MultiLineEditbox" is inside "DemoWindow". These references are also indicated in the layout file link mentioned above.
Once have a reference to "MultiLineEditbox" child widget window we can set or append text, for instance as follows:
MultiLineEditbox ->setText(ss.str());
MultiLineEditbox ->appendText("\n");
MultiLineEditbox ->appendText(ss2.str());
In this case revealing, the results of ray scene query boolean conditionals given by the tutorial necessary for ray trace camera to terrain collision. The itr is non empty but obviously if you didn't know that itr's worldFragment type mattered, you'd find that the second boolean evaluation would be coming up False or empty all the time... hence leading to the problem likely revolving around the tutorial's incompatibility with present Ogre versions.
Also while automake tools were covered for dependencies, if you want to use cmake. Then you may need to install this if you already haven't installed the cmake package. You can do so easily at terminal:
sudo apt-get install cmake
or through your software center.
If you want to follow along with build guides for Ogre then you'll need mercurial. For this at terminal you can install mercurial simply by typing:
sudo apt-get install mercurial
I’ve had issues running ogre from sdk installation. Not sure about any other’s experience on this matter.
Instead I’ve found compiling Ogre source code from say mercurial works for me following the build guide.
To compile ogre from source. You'd go to the source directory where you cloned Ogre.
I cloned from mercurial using Ogre version 1-9 so my clone looks at terminal like:
hg clone https://bitbucket.org/sinbad/ogre/ -u v1-9Then go to that directory from terminal:
cd ogre
you verify the 1-9 version branch by typing:
hg branch
you can always pull any change sets to ogre by terminal in the ogre source directory with:
hg pull
hg update
switching to the 1-9 from any branch is done by typing:
hg update v1-9
At terminal in the ogre source directory you can begin the ogre from source build process by:
mkdir build
cd build
cmake ..
(if all is well)
make
sudo make install
(this is basically building the equivalent of the windows .exe file and running the .exe file for a program installation on your system with the added caveat that this program is tailored according to your machine specifications and optional package installs that ogre would utilize.
To compile using Tutorial framework with Dist files (all-in-one),
you can use at command line (using for instance Terminal) in the given project/tutorial folder cmake directory:
cmake .
This will automatically compile and install in the dist/bin folder the ogre binary for such project.
Then run at command prompt in the same directory run:
make
Successful compilation and build will place a program binary executable in the dist/bin folder
Up to now it appears there are issues with basic tutorial 3 in so far as compilation including undefined references errors as related to the Terrain and TerrainGroup headers (problems with Singleton references mostly) using the tutorials existing source code. I am not sure if this relates to the ogre installation.
Update to this:
This needs to be added CMakeLists.txt file in the project after “find_package(OGRE REQUIRED)”
# Add OgreTerrain.{so,dll,etc.} to our linked libraries
# These variables are defined in FindOGRE.cmake, mine is
# found at /usr/local/lib/OGRE/cmake/
if (OGRE_Terrain_FOUND)
# pretty sure the following include is unneeded
# include_directories(${OGRE_Terrain_INCLUDE_DIRS})
# append OgreTerrain to the end of the OGRE_LIBRARIES variable
set(OGRE_LIBRARIES ${OGRE_LIBRARIES} ${OGRE_Terrain_LIBRARIES})
message(STATUS "Found OGRE_Terrain: ${OGRE_Terrain_LIBRARIES}")
else (OGRE_Terrain_FOUND)
message(SEND_ERROR "OgreTerrain Library not found.")
endif(OGRE_Terrain_FOUND)
# These variables are defined in FindOGRE.cmake, mine is
# found at /usr/local/lib/OGRE/cmake/
if (OGRE_Terrain_FOUND)
# pretty sure the following include is unneeded
# include_directories(${OGRE_Terrain_INCLUDE_DIRS})
# append OgreTerrain to the end of the OGRE_LIBRARIES variable
set(OGRE_LIBRARIES ${OGRE_LIBRARIES} ${OGRE_Terrain_LIBRARIES})
message(STATUS "Found OGRE_Terrain: ${OGRE_Terrain_LIBRARIES}")
else (OGRE_Terrain_FOUND)
message(SEND_ERROR "OgreTerrain Library not found.")
endif(OGRE_Terrain_FOUND)
I'd mention this note because cmake instructions indicate this with a thorough reading but could be easier to pass over if you are attempting a more quick scan of the tutorial.
If you are still having difficulties you may need to make sure the terrains resource directory with terrain.png (heightmap) being found either appending this resource directory to the CMakeLists.txt file or by adding a resource manager reference...this provides an example of loading a resource manager directory for textures in the tutorials .cpp file given below, provides yet another way of loading resources from script:
Ogre::String lNameOfResourceGroup = "Mission 1 : Deliver Tom";
Ogre::ResourceGroupManager& lRgMgr = Ogre::ResourceGroupManager::getSingleton();
lRgMgr.createResourceGroup(lNameOfResourceGroup);
Ogre::String lDirectoryToLoadTextures = "/usr/local/share/OGRE/Media/materials/textures";
bool lIsRecursive = false;
lRgMgr.addResourceLocation(lDirectoryToLoadTextures, "FileSystem", lNameOfResourceGroup, lIsRecursive);
// The function 'initialiseResourceGroup' parses scripts if any in the locations.
lRgMgr.initialiseResourceGroup(lNameOfResourceGroup);
// Files that can be loaded are loaded.
lRgMgr.loadResourceGroup(lNameOfResourceGroup);
Additional commonplaces to store textures for resource loading.
This often may be placed in the dist/media/materials/textures for instance under a given project file where textures are placed in this local resource location.
Error checking.
A good place to check for errors is in your local ogre project bin directory is found in the (Ogre local project root)/dist/bin/ folder which is the .log file. This will, for instance, indicate when and possibly where errors are occurring in so far as resource loading.
Skybox implementation
Is a several step process actually I’ve found relative to the tutorial setup which makes it seem a bit easier...which might have been the case under previous SDK s, or depending on installation process, for instance, whether windows makes this process much easier in terms of use from the start versus Linux.
So the process generally goes as follows.
You can set resources as stated to the correct directories in script if they aren’t already setup, or alternately you can also modify the configuration file found in the executable /bin directory of your project (once the program is compiled I believe).
So for example for me I found this from my projects source root directory at /dist/bin/resources.cfg
Skyboxes are often found in a .zip package so the configuration file will need to see the .zip file. Here is a sample:
# Resources required by the sample browser and most samples.
[Essential]
Zip=../media/packs/SdkTrays.zip
Zip=../media/packs/cubemapsJS.zip
Zip=../media/SkyBox/skybox.zip
# Resource locations to be added to the default path
[General]
FileSystem=../media
FileSystem=../media/materials/scripts
FileSystem=../media/materials/textures
FileSystem=../media/models
Here, the map actually referenced in my scene rendering file (the .cpp file that makes a call actually to the material file) is cubemapJS.zip
the actual call in the .cpp scene rendering scene call, for example, in the tutorial may be:
mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox", 10000, false);
where “Examples/CloudyNoonSkyBox” is actually a call to the material in the materials script.
I generally loaded both the material file and the cubemapJS.zip file in the necessary directories as given by the zip path found above in the resource.cfg file and also put the material file in the ../media/materials/scripts files. Whenever you want to alternately (outside of a scripted call in your scene manger .cpp file) to load a material in the resources manager, you can do so by placing the material file in the ../media/materials/script directory. Thus in this case we are actually wanting to grab Examples.material file. I actually found this, in my case, in my given Ogre source directory, or you can I imagine alternately access this data from the Ogre/Sdk directory. Specifically in the Ogre source directory this may be found at (Ogre source home)/Samples/Media/materials/scripts
now if you open the file Examples.material, you’ll find at line 163 the materials definition for “Examples/CloudyNoonSkyBox” which basically tells it to use specific texture files for this material.
Thus,
cubic_texture cloudy_noon.jpg separateUV
in this materials definition actually automatically gives instruction to pull the appropriate file references from a cloudy_noon.jpg series to be unpacked and placed appropriately as textures for the given sky box. You hadn’t need worry about referencing each of the six files for the cubic_texture in order or anything like this since
separateUV
actually does this for you in cubic_texture call…
So in short to load a skybox you may need to do the following:
- Grab you skybox .zip archive file and set this up in your project local directory. Generally while some have setup skybox directories. I’ve just placed this alternately in my project local ../media/packs/cubemapsJS.zip directory as indicated in the resources.configuration file above.
- Make sure this zip file is referenced in your configuration.file (that is found in your local project dist/bin file after program compilation and build).
- Get either from the OgreSDK directory (if you installed Ogre using the SDK), or from the source directory of your ogre build, or if you built ogre on your own machine (as opposed to using pre compiled binaries), from (Ogre source home)/Samples/Media/materials/scripts the Examples.material file and put this in ../media/materials/scripts (under you local ogre project file).
- Then set in your scene method/function build use the appropriate call to reference the sky box. For example, mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox", 10000, false);
does this, or in another words, everything in the third basic tutorial should work.
That should technically do it for the third tutorial. If you can’t really see the skybox so well, really gray or something, I’d recommend either adjusting fog settings, or disabling fog. I’ve had some issues with the sky dome loading the textures weirdly.
One last thing, you can find the specular and normal map texture data for splatmaps (for the 3rd basic tutorial) oddly enough in the ogre (your ogre build source directory)/Samples/Media/materials/textures/nvidia directory. You'd need to again transfer these to your project textures local directory, or alternately make sure library references are set up as necessary in script somewhere.
The more common problems that I’ve seen where Ogre subsequently closes right away, are that materials are not properly defined or referenced.
Keep in mind that if a texture is not found even if a material makes a call to a not found texture, Ogre will still run instead rendering something of ‘default’ grey texture (or something which allows the rendering pipeline to work), but if a material can not be found, likely this will cause Ogre to crash before it starts. Thus it is important to have material loaded properly at least, likely this should also show in the .log file (found in the /dist/bin directory of your local project). Generally in linux (not sure what user experience is like on various distros), I've also found installing textures in local project /dist/media/materials/texture folder is a good place.
Odds and End:
Implementing MyGui
Also for MyGui I recommend using
using git for retrieving mygui source and then following similarly compilation of mygui for use as with ogre source compilation.
Older subversion link found through Ogre wiki appears to be an outdated link relative to the present most recent versions of Ogre found
through http://www.ogre3d.org/tikiwiki/MyGUI+Compiling at least as of date, my compilation and build of MyGui through subversion faulted before completion (not sure if deprecation in source code were exactly an issue here).Mostly I've tried to journal my experiences as related to gaps provisioned by some of the tutorials as of yet.
Cegui installation if using most recent mercurial clone,
When you use the mercurial clone call and build the source code libraries. I also found that going to a newer fork of cegui library works (version .8x) will present source library faulted on installation.
Thus for installation I used:
hg clone https://bitbucket.org/cegui/cegui
from terminal go to cegui library source root directory, then use the following command to update your source to the following version fork:
hg pull && hg update v0-8
Installation goes as follows:
Prerequisites:Likely, as with any Ogre build dependencies that you'd have installed I recommend the following below additionally for cmake generation.
You may find an error on a typical cmake build with glew and glm libraries, just go to your distros app center and install the development glew and glm libraries, if these packages show missing. Especially check for these libraries. Also I installed
libboost-all-dev package as well or at terminal
sudo apt-get install libboost-all-dev
Thus installation as per cegui guide is typical or at terminal:
from terminal change directory to cegui source directory,
then
mkdir build
cd build
cmake ..
If everything looks good type in the same directory from terminal:
make
sudo make install
Otherwise build should be fine.
Compiling Ogre Basic Tutorial 7 project with Cmake.
Unfortunately there’s a bit of an absence on direct information on how to implement the CMakeList.txt cegui and ogre_cegui libraries...actually found from http://www.axelschumacher.fr/218/link-ogre-with-cegui-ogre-basic-tutorial-7-using-cmake/
a solution on this.
I did find a potential compilation error with make with adding include libraries in script above and slightly modified a couple of lines which appears to have fixed pathing errors.
Find the bold existing code in your CMakeList.txt and apply those changes:
set(OGRE_LIBRARIES ${OGRE_LIBRARIES} ${Boost_LIBRARIES}
endif()
find_package(CEGUI REQUIRED)
if(NOT CEGUI_FOUND)
message(SEND_ERROR "Failed to find CEGUI.")
endif()
find_package(CEGUIOGRE REQUIRED)
if(NOT CEGUIOGRE_FOUND)
message(SEND_ERROR "Failed to find CEGUIOGRE.")
endif()
set(HDRS
./BaseApplication.h
////////////////////////////////////////////////////
include_directories( ${OIS_INCLUDE_DIRS}
${OGRE_INCLUDE_DIRS}
${OGRE_SAMPLES_INCLUDEPATH}
${CEGUI_INCLUDE_DIR}
${CEGUIOGRE_INCLUDE_DIR}
)
endif()
find_package(CEGUI REQUIRED)
if(NOT CEGUI_FOUND)
message(SEND_ERROR "Failed to find CEGUI.")
endif()
find_package(CEGUIOGRE REQUIRED)
if(NOT CEGUIOGRE_FOUND)
message(SEND_ERROR "Failed to find CEGUIOGRE.")
endif()
set(HDRS
./BaseApplication.h
////////////////////////////////////////////////////
include_directories( ${OIS_INCLUDE_DIRS}
${OGRE_INCLUDE_DIRS}
${OGRE_SAMPLES_INCLUDEPATH}
${CEGUI_INCLUDE_DIR}
${CEGUIOGRE_INCLUDE_DIR}
)
And replace
target_link_libraries(OgreApp ${OGRE_LIBRARIES} ${OIS_LIBRARIES})
by
target_link_libraries(OgreApp ${OGRE_LIBRARIES} ${OIS_LIBRARIES} ${CEGUI_LIBRARY} ${CEGUIOGRE_LIBRARY_OPTIMIZED})
Once you are done with that, you will have to actually own the invoked scripts (find CEGUI and CEGUIOGRE).
You can find them here, and copy them where you installed Ogre (usually in /usr/local/lib/OGRE/cmake/), so that cmake-gui will find them quite easily.
If you don’t want them all, only CompareVersionStrings.cmake, HandleLibraryTypes.cmake, DetermineVersion.cmake, FindCEGUIOGRE.cmake, FindCEGUI.cmake and FindPackageHandleAdvancedArgs.cmake are necessary for our current concern.
The Basictutorial7.h header file should be modified at line
#include ..CEGUI/RendererModules/Ogre/CEGUIOgreRenderer.h..
to
#include... CEGUI/RendererModules/Ogre/Renderer.h...
You will also want to include, if you want to render your viewport texture in a cegui window
#include ...CEGUI/RendererModules/Ogre/Texture.h...
This is important actually for any render to texturing in CEGUI window I've found in Ogre using Cegui under linux. I spent the better part of a day searching google to no avail on why in the absence of this include I was getting a static_cast issue on Cegui::OgreTexture either a forward or incomplete type issue which amounted to the compiler sort of having class declaration information but sort of not (apparently some declaration circularity issue...).
The source code while providing a number of fixes for cegui version .8x generally works.
Another thing that I've found, not sure if this is exactly right, but when working with updates to source code repositories, it may be wise to set up and alternate build directory of your choosing in the given source directory path (e.g. of ogre, or cegui) and running the cmake and make commands as usual for compilation and builds of updates. I've found that when adding new packages for cmake compilation while cmake provides includes, it appears that compilation and builds may still have exclusions or something on this.
Intermediate Tutorial 2
Since correct source is not compiled either from basic tutorial 3 and 7 which would aid in compilation this has been a bit slower than expected. I'd highly recommend adapting especially from basic tutorial 3 and 7 especially appending as necessary from above for the cmakelist.txt file. Header and .cpp include header files listed in this tutorial are different (and won't work) for ogre 1.9, cegui .8x build, basically you'd use the same header include paths as found in basic tutorial 7 and basic tutorial 3 for present terrain management system (basically a couple of terrain header file includes). I may post a link to source code header and cpp files. Generally everything working up to raytrace camera terrain heightmap collision checking. Here it appears something is fouled up, and I'd like to have cegui rendering something of a debug output, so I am presently studying getting some layouts enabled that would include for console print type output while the application is running, so I can see how the terrain camera to terrain position height checking stl container is reading all this (whether it has, for instance, any value or exactly what value is given here)... Installed also ceed which is basically a visual gui layout editor for cegui.
Further scope of the problem and why the tutorial may be considered generally incompatible I am guessing...
The problem comes with these lines in the collision detection routine.
if (itr != result.end() && itr->worldFragment)
{
Ogre::Real terrainHeight = itr->worldFragment->singleIntersection.y;
if ((terrainHeight + 10.0f) < camPos.y)
mCamera->setPosition( camPos.x, terrainHeight + 10.0f, camPos.z );
}
itr -> worldFragment always returns a False boolean type because with the Octree scene management system by default as of Ogre version 1.8 the old terrain management system has been changed, and World fragment type on the ray scene query by default is set to
Ogre::SceneQuery::WFT_NONE
The problem however in setting this to
Ogre::SceneQuery::WFT_SINGLE_INTERSECTION
for instance on the line
mRaySceneQuery ->setWorldFragmentType(Ogre::SceneQuery::WFT_SINGLE_INTERSECTION );
however is that this automatically yields an error on program execution as
20:07:01: OGRE EXCEPTION(2:InvalidParametersException): This world fragment type is not supported. in SceneQuery::setWorldFragmentType
meaning the scene manager is not supporting this...I haven't found a solution for implementing this as of yet, although it seems that a work around is going to a movable type collision method and forgoing worldFragment collision methods here.
Here is a very crude print log method that I've found using the following layout using cegui by the way. Although you'd need to figure out out how to do input output type conversions on any object that you wanted to print out for the given application running output console.
So here is the Taharez layout file. So that my resources.config file can read this additionally (without having to append this layout in the default resources directory outside my project)...
Resources config file looks like:
# Resources required by the sample browser and most samples.
[Essential]
Zip=../media/packs/SdkTrays.zip
Zip=../media/packs/cubemapsJS.zip
# Resource locations to be added to the default path
[General]
FileSystem=../media
FileSystem=../media/materials/scripts
FileSystem=../media/materials/textures
FileSystem=../media/models
FileSystem=../media/Fonts/Script
[CEGUI]
FileSystem=/usr/local/share/cegui-0/schemes
FileSystem=/usr/local/share/cegui-0/fonts
FileSystem=/usr/local/share/cegui-0/imagesets
FileSystem=/usr/local/share/cegui-0/layouts
FileSystem=/usr/local/share/cegui-0/looknfeel
FileSystem=/usr/local/share/cegui-0/lua_scripts
FileSystem=/usr/local/share/cegui-0/schemes
FileSystem=/usr/local/share/cegui-0/xml_schemas
FileSystem=../media/layouts
For instance while in my main ogre application scene function constructor I've used the following lines:
CEGUI::SchemeManager::getSingleton().createFromFile("TaharezLook.scheme");
CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor().setDefaultImage("TaharezLook/MouseArrow");
CEGUI::Window* myRoot = CEGUI::WindowManager::getSingleton().createWindow( "DefaultWindow", "_MasterRoot" );
CEGUI::System::getSingleton().getDefaultGUIContext().setRootWindow( myRoot );
CEGUI::Window *newWindow = CEGUI::WindowManager::getSingleton().loadLayoutFromFile("TreeDemoTaharez2.layout");
CEGUI::System::getSingleton().getDefaultGUIContext().getRootWindow()->addChild(newWindow);
newWindow ->setAlpha(.5);
CEGUI::Window *MultiLineEditbox = newWindow ->getChild("MultiLineEditbox");
MultiLineEditbox ->setText("Hello World!");
CEGUI::Window *editbox = newWindow ->getChild("Editbox");
editbox ->setText("Hello World!");
Above code also demonstrates accessing, for instance, individual widget "windows" inside the child windows, and setting individual properties. I used Cegui Docs .8 as a reference for function/method calls, or alternate I imagine if using a gui editor you can alternately use a set properties type function likewise.
Heres an example type conversion boolean to string conversion call in c++ that I found...most definitely a bit more code work here relative to other languages...the includes provisioned at the main ogre program outset, for instance,
#include ...iostream...
#include ...string...
#include ...sstream...
...
...
...
std::ostringstream ss, ss2;
bool val;
bool val2;
val = (itr == result.end());
ss << std::boolalpha << val ;
val2 = (itr -> worldFragment);
ss2 << std::boolalpha << val2 ;
then
ss.str() or ss2.str() calls returns a string array object which can then be input into the application console
since I hadn't made more global the scope of the widget which could be of use, alternately inside the particular function that implemented the ray scene query I used (namely, frameRenderingQueued):
CEGUI::Window *newWindow = CEGUI::System::getSingleton().getDefaultGUIContext().getRootWindow()->getChild("DemoWindow");
CEGUI::Window *MultiLineEditbox = newWindow ->getChild("MultiLineEditbox");
where "DemoWindow" is the name of the child window inside the main application window, and "MultiLineEditbox" is inside "DemoWindow". These references are also indicated in the layout file link mentioned above.
Once have a reference to "MultiLineEditbox" child widget window we can set or append text, for instance as follows:
MultiLineEditbox ->setText(ss.str());
MultiLineEditbox ->appendText("\n");
MultiLineEditbox ->appendText(ss2.str());
In this case revealing, the results of ray scene query boolean conditionals given by the tutorial necessary for ray trace camera to terrain collision. The itr is non empty but obviously if you didn't know that itr's worldFragment type mattered, you'd find that the second boolean evaluation would be coming up False or empty all the time... hence leading to the problem likely revolving around the tutorial's incompatibility with present Ogre versions.
So as mentioned the ray tracing approach doesn't exactly appear to work, and a test of movable objects on the iterator class appears to be provisioning a rough approximate bounding box around the terrain but hardly useful for camera clamping to terrain below a certain height threshold. Another solution does this:
Ogre::Vector3 camPos = mCamera->getPosition();
....remove everything on collision solution given on the tutorial below the line above.... and substitute this below...
float theight = mTerrainGroup->getHeightAtWorldPosition (camPos);
if (camPos.y < theight + 10.0f)
{
mCamera->setPosition( camPos.x, theight+10.0f, camPos.z );
}
Basically data return on this is exact, and hopefully should work.
Some helpful tidbits. I used the Ogre docs and then from there on the left hand side chose...
Ogre>Modules>Components>Terrain
At this point, examining your tutorial header you can see the terrain object type here which is
TerrainGroup
So selecting the drop down on TerrainGroup yields all sorts of class methods for this particular object, and hence where I found getHeightAtWorldPosition()
Terrain Selection modification for Intermediate Tutorial 2 with Ogre 1.9, Cegui .8.4
Again because raytracing with worldFragment is down because of changes in Terrain managers, in this case although this hadn't allowed us to select clearly from a given terrain a position on the terrain this provides us with a working routine for placing objects (this would always be at the camera's position as given by the code below). This method below does not place an object at the mouse selected region but instead sets up ray, and chooses the camera's position for the source of placing the object. Technically if you wanted terrain selection, you'd need to do some added work, or find a work around to the inherent problems with ray tracing as related to the worldFragment issue in Ogre 1.9
CEGUI::Vector2
Ogre::Ray mouseRay = mCamera->getCameraToViewportRay(mousePos.d_x/float(arg.state.width), mousePos.d_y/float(arg.state.height));
//mRaySceneQuery->setRay(mouseRay);
Ogre::Vector3 ovec = mouseRay.getOrigin();
//I believe this next function always clamps to a position on the terrain even if the viewport
//mouse ray origin has no clear corresponding points bounded over the terrain.
float theight = mTerrainGroup->getHeightAtWorldPosition (ovec);
char name[16];
sprintf( name, "Robot%d", mCount++ );
Ogre::Entity *ent = mSceneMgr->createEntity(name, "robot.mesh");
mCurrentObject = mSceneMgr->getRootSceneNode()->createChildSceneNode(std::string(name) + "Node", Ogre::Vector3(ovec.x,theight,ovec.z));
mCurrentObject->attachObject(ent);
On the other hand we have a Ray defined, and we could attempt some means for collision detection one should imagine, whether we defined our method here...if you were ever interested in exploring possibility outside of predesign in ray tracing, one method could use something as simple as a comparison result before and after. For instance, where we test the ray for one length and a longer length, and then if either show a hit boundary between this we scoot the ray forward by an increment of one half from its previous position to the end point test position or lessen its length by one half for a given travel distance, and then repeat this test procedure until finding the area (within tolerance where the ray intercepts the terrain mesh). Obviously the method utilizes a heightmap point test position where clearly the ray is above and below the heightmap at all times from origin to end, while the method for ray tracing refines the ray travel distance (from a point origin to end test point) in finding the collision object. Obviously as the distance from ray test origin to test end point, decreases in time (rapidly we should hope), a collision is given. Some problems though that can be added to this, the direction of the ray is such that we could have potentially more than one ray intersection for a ray crossing. Obviously we'd need to refind potentially search methods so as to ensure that we, for instance, are choosing the first point of intersection and not a third, or forth down the line.
Okay so here's a really simple collision checking method. It may not be the most efficient but generally does the job rapidly enough
for (int i = 0; i < 4000 ; i ++){
Ogre::Vector3 ovec1 = mouseRay.getPoint(i);
float theight1 = mTerrainGroup->getHeightAtWorldPosition (ovec1);
if (theight1 > ovec1.y){
ovec = ovec1;
theight = theight1;
break;
}
}
This added below the script above yields a simple mouse terrain selection method (with ray tracing).
Or here's the script for mouse pressed method in main application
if (id == OIS::MB_Left)
{
// Setup the ray scene query, use CEGUI's mouse position
CEGUI::Vector2
Ogre::Ray mouseRay = mCamera->getCameraToViewportRay(mousePos.d_x/float(arg.state.width), mousePos.d_y/float(arg.state.height));
//mRaySceneQuery->setRay(mouseRay);
Ogre::Vector3 ovec = mouseRay.getOrigin();
//I believe this next function always clamps to a position on the terrain even if the viewport
//mouse ray origin has no clear corresponding points bounded over the terrain.
float theight = mTerrainGroup->getHeightAtWorldPosition (ovec);
for (int i = 0; i < 4000 ; i ++){
Ogre::Vector3 ovec1 = mouseRay.getPoint(i);
float theight1 = mTerrainGroup->getHeightAtWorldPosition (ovec1);
if (theight1 > ovec1.y){
ovec = ovec1;
theight = theight1;
break;
}
}
char name[16];
sprintf( name, "Robot%d", mCount++ );
Ogre::Entity *ent = mSceneMgr->createEntity(name, "robot.mesh");
mCurrentObject = mSceneMgr->getRootSceneNode()->createChildSceneNode(std::string(name) + "Node", Ogre::Vector3(ovec.x,theight,ovec.z));
mCurrentObject->attachObject(ent);
//mCurrentObject->setScale(0.1f, 0.1f, 0.1f);
mLMouseDown = true;
} // if
You can similarly modify the object dragging script as given in the tutorial with changes listed above, to implement object dragging. It would be noted that when you miss the terrain, the ray tracing method automatically, set's the object's position to the camera's position until a point on the terrain is selected again with the left mouse button held down.
Here is my all-in-one archived linux file/directory set for Intermediate Tutorial 2
Intermediate Tutorial 3
Everything from the previous tutorial should work fine. I slightly modified the tutorial, however, incorporating a 'c' key operation which provides for selection versus object 'robot' or 'ninja' adding, and then I modified selection parameters so that mouse dragging would also allow for ray trace selecting an object. Pretty easy a modification to selection ray tracing check on the ray trace query is given as follows:
for(itr = result.begin(); itr != result.end(); itr++){
if (itr->movable && itr->movable->getName() != "")
{
mCurrentObject = itr->movable->getParentSceneNode();
break;
} // if
}
where itr is starts at the beginning of the ray trace query container as an iterator. Mostly since the world terrain as according to instancing methods given by Basic Tutorial 3, is not given a name, we wouldn't worry about terrain collision, secondly terrain collision isn't exactly working, so we wouldn't need worry about a collision with this as a named movable type. Thus we are looking for a collision basically with any thing named for selection parameters here.
I added this both to mousepressed and mousemoved (for mouse dragging selecting objects with left mouse button held down while dragging the mouse cursor).
Everything beyond this point in the tutorial works find including selection mask queries and so forth. Selection mask enums can be added inside the class at the header outset.
Here is my all-in-source for Ogre Intermediate Tutorial 3
As to the selection versus object adding controls, this can be done inside the mouse pressed and mouse moved event method calls. Generally using another class global boolean parameter (defined in header) that determines whether or not to use object tool selection versus object add methods.
Thus
if (selectMode){
for(itr = result.begin(); itr != result.end(); itr++){
if (itr->movable && itr->movable->getName() != "")
{
mCurrentObject = itr->movable->getParentSceneNode();
break;
} // if
}
}
where selectMode is the boolean parameter that is toggled using the keyboard 'c' key input determines whether selection mode is set versus object add.
beyond this
else{
....
}
does the object add stuff as given in the previous tutorial and including newer stuff in this tutorial.
Intermediate Tutorial 4
C++ or gcc compilation noobness on my part. Making sure to include link info important here...
when including header file, unless you specifically indicate compilation links to .cpp files, I've found you'd likely want to link these as well...
for instance,
not only is
#include "SelectionBox.h"
used in the IntermediateTutorial4.h header but also linking the SelectionBox.cpp is important or at least for my basic configuration important since header links to .cpp evidently not a given so
#include "SelectionBox.cpp"
apparently resolves in the main application.
I used the same cmakelist.txt files for cmake compilation modifying for this tutorial slightly at header references.
Then as usual changes in CEGUI invocations, for instance,
for loading 'scheme' and mouse cursor
CEGUI::SchemeManager::getSingleton().createFromFile("TaharezLook.scheme");
CEGUI::System::getSingleton().getDefaultGUIContext().getMouseCursor().setDefaultImage("TaharezLook/MouseArrow");
The selection box CEGUI calls can be alternately written for obtaining and storing mouse cursor data as:
CEGUI::Vector2
mStart.x = mousePos.d_x / (float)arg.state.width;
mStart.y = mousePos.d_y/ (float)arg.state.height;
Similarly for mStop just substituting this as needed in the appropriate function/method call.
Make sure either to link in cmake your materials and models libraries as usual or import them as necessary, otherwise you'll crash right away. Mostly you just need to have the 'robot.mesh' and skeleton I believe loaded here...although it'd likely be good to grab the materials scripts, and texture libraries.
Otherwise, everything looks pretty good.
No comments:
Post a Comment