_Archic
12-12-2006 12:49:30
Hi!
I convert OSM Scene Loader (change syntax) from ODN (http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=1483&highlight=ofusion)
that was also converted from original c++ code
May be this will be useful for someone..
Example of usage
I convert OSM Scene Loader (change syntax) from ODN (http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=1483&highlight=ofusion)
that was also converted from original c++ code
May be this will be useful for someone..
using System;
using System.Collections;
using System.Drawing;
using System.IO;
using System.Xml;
using Mogre;
namespace MyApp
{
public class OSMLoader
{
private XmlDocument xd;
private SceneManager mSceneMgr;
private RenderWindow mWindow;
private const int SCENE_SKYPLANE = 1;
private const int SCENE_SKYDOME = 2;
private const int SCENE_SKYBOX = 3;
private Hashtable cameras, lights, entities;
public Hashtable Cameras
{
get { return cameras; }
}
public Hashtable Lights
{
get { return lights; }
}
public Hashtable Entities
{
get { return entities; }
}
public SceneManager SceneMgr
{
get { return mSceneMgr; }
}
public event LoadedSceneObjectEventHandler OnCameraCreate;
public event LoadedSceneObjectEventHandler OnNodeCreate;
public event LoadedSceneObjectEventHandler OnLightCreate;
public event LoadedSceneObjectEventHandler OnEntityCreate;
public OSMLoader(SceneManager mgr, RenderWindow wnd)
{
mSceneMgr = mgr;
mWindow = wnd;
cameras = new Hashtable();
entities = new Hashtable();
lights = new Hashtable();
}
public void Initialize(string xmlFile)
{
LogManager.Singleton.LogMessage(@"
**********************************************
** OSM Scene Loader **
**********************************************
");
LogManager.Singleton.LogMessage("OSMLoader loading scene form file: " + xmlFile);
if (!ResourceGroupManager.Singleton.ResourceExists(
ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME,
xmlFile))
{
LogManager.Singleton.LogMessage("Not found file: " + xmlFile);
throw new FileNotFoundException("Not found scene file.", xmlFile);
}
xd = new XmlDocument();
try
{
DataStreamPtr dsp = ResourceGroupManager.Singleton.OpenResource(xmlFile);
xd.LoadXml(dsp.AsString);
dsp.Dispose();
}
catch (XmlException ex)
{
xd = null;
LogManager.Singleton.LogMessage("Can't parse scene data, detail error message:\r\n" + ex.Message);
throw ex;
}
}
public bool CreateScene(SceneNode parent)
{
if (xd == null) return false;
LogManager.Singleton.LogMessage("OSMLoader: Creating scene on '" +
(parent == null ? "Root" : parent.Name) + "' node.");
if (mSceneMgr == null)
{
if (xd.SelectSingleNode("/sceneManager") != null)
setSceneProperties(xd);
else
mSceneMgr = Root.Singleton.CreateSceneManager(SceneType.ST_GENERIC);
}
if (parent == null)
parent = mSceneMgr.RootSceneNode.CreateChildSceneNode();
try
{
CreateEntities(xd.SelectNodes("/oe_scene/entities/entity"), parent);
}
catch
{
}
try
{
CreateLights(xd.SelectNodes("/oe_scene/lights/light"), parent);
}
catch
{
}
try
{
CreateCameras(xd.SelectNodes("/oe_scene/cameras/camera"), parent);
}
catch
{
}
LogManager.Singleton.LogMessage(@"
********************************
** oSceneLoader: Scene loaded **
********************************
");
return true;
}
// no use
/*
private void declareResources()
{
if (xd == null) return;
try
{
XmlElement xe = (XmlElement) xd.SelectSingleNode("/entities");
if (xe != null)
foreach (XmlElement item in xe.ChildNodes)
ResourceGroupManager.Instance.declareResource(item.GetAttribute("filename"), "Mesh");
}
catch
{
} // i don't know why not process exception here in c++ source file.
}
*/
private ColourValue parseColor(string r, string g, string b)
{
ColourValue clr = new ColourValue();
clr.r = float.Parse(r);
clr.g = float.Parse(g);
clr.b = float.Parse(b);
return clr;
/*return Color.FromArgb(
(int)(255 * float.Parse(r)),
(int)(255 * float.Parse(g)),
(int)(255 * float.Parse(b)));*/
}
private void setSceneProperties(XmlDocument xd)
{
// Scene manager
XmlElement sceneMgrElem = (XmlElement)xd.SelectSingleNode("sceneManager");
/*
ST_GENERIC = 1,
ST_EXTERIOR_CLOSE = 2,
ST_EXTERIOR_FAR = 4,
ST_EXTERIOR_REAL_FAR = 8,
ST_INTERIOR = 16
*/
int type = int.Parse(sceneMgrElem.GetAttribute("type"));
SceneType sceneType = (SceneType)type;
mSceneMgr = Root.Singleton.CreateSceneManager(sceneType);
string worldGeometry = sceneMgrElem.GetAttribute("worldGeometry");
if (worldGeometry != null)
mSceneMgr.SetWorldGeometry(worldGeometry);
// Background Color
XmlElement colorElem = (XmlElement)xd.SelectSingleNode("bkgcolor");
if (colorElem != null && mWindow != null)
{
ColourValue color = parseColor(
colorElem.GetAttribute("r"),
colorElem.GetAttribute("g"),
colorElem.GetAttribute("b"));
mWindow.GetViewport(0).BackgroundColour = color;
}
// Ambient light Color
colorElem = (XmlElement)xd.SelectSingleNode("lightColor");
if (colorElem != null)
{
ColourValue color = parseColor(
colorElem.GetAttribute("r"),
colorElem.GetAttribute("g"),
colorElem.GetAttribute("b"));
mSceneMgr.AmbientLight = color;
}
// Scene shadows
XmlElement shadowsElem = (XmlElement)xd.SelectSingleNode("shadowTechnique");
if (shadowsElem != null)
{
type = int.Parse(shadowsElem.GetAttribute("type"));
ShadowTechnique shadowType = (ShadowTechnique)type;
mSceneMgr.ShadowTechnique = shadowType;
int tex_size = int.Parse(shadowsElem.GetAttribute("tex_size"));
int tex_count = int.Parse(shadowsElem.GetAttribute("tex_count"));
mSceneMgr.SetShadowTextureSettings((ushort)tex_size, (ushort)tex_count);
// Shadow Color
colorElem = (XmlElement)shadowsElem.SelectSingleNode("color");
if (colorElem != null)
{
ColourValue color = parseColor(
colorElem.GetAttribute("r"),
colorElem.GetAttribute("g"),
colorElem.GetAttribute("b"));
mSceneMgr.ShadowColour = color;
}
}
// Scene sky
XmlElement skyElem = (XmlElement)xd.SelectSingleNode("skyTechnique");
if (skyElem != null)
{
type = int.Parse(skyElem.GetAttribute("type"));
String materialName = skyElem.GetAttribute("material");
if (materialName != " ")
{
bool drawFirst = bool.Parse(skyElem.GetAttribute("drawFirst"));
float tiling = float.Parse(skyElem.GetAttribute("tiling"));
float scale = float.Parse(skyElem.GetAttribute("scale"));
float dist = float.Parse(skyElem.GetAttribute("dist"));
float bow = float.Parse(skyElem.GetAttribute("bow"));
int xSegments = int.Parse(skyElem.GetAttribute("xSegments"));
int ySegments = int.Parse(skyElem.GetAttribute("ySegments"));
Quaternion quat = Quaternion.IDENTITY;
Plane plane = new Plane();
plane.d = dist;
plane.normal = new Vector3();
plane.normal = -(Vector3.UNIT_Y);
switch (type)
{
case SCENE_SKYPLANE:
mSceneMgr.SetSkyPlane(true, plane, materialName, scale,
tiling, drawFirst, bow, xSegments, ySegments);
mSceneMgr.SetSkyBox(false, "");
mSceneMgr.SetSkyDome(false, "");
break;
case SCENE_SKYBOX:
mSceneMgr.SetSkyBox(true, materialName, dist, drawFirst, quat);
mSceneMgr.SetSkyPlane(false, plane, "");
mSceneMgr.SetSkyDome(false, "");
break;
case SCENE_SKYDOME:
mSceneMgr.SetSkyDome(true, materialName, bow, tiling, dist,
drawFirst, quat, xSegments, ySegments);
mSceneMgr.SetSkyPlane(false, plane, "");
mSceneMgr.SetSkyBox(false, "");
break;
}
}
}
}
private SceneNode CreateNode(XmlElement elet, SceneNode parent)
{
SceneNode pNode = null;
// Try to find the parent node
string pszName = elet.GetAttribute("name");
if (pszName == string.Empty) return null;
// Check if this node has a parent
string pszParent = elet.GetAttribute("parent");
if (pszParent == string.Empty)
{
// Check if the scene node has already been created by a child
DISABLE_LOGMANAGER();
try
{
pNode = mSceneMgr.GetSceneNode(pszName);
}
catch
{
pNode = parent.CreateChildSceneNode(pszName);
}
ENABLE_LOGMANAGER();
}
else
{
SceneNode pParent = null;
DISABLE_LOGMANAGER();
try
{
// Try to find parent scenenode
pParent = mSceneMgr.GetSceneNode(pszParent);
}
catch
{
// We try to create the parent node as child of root node.
// Later when the parent (hopefully) is created, we can adjust it,
// if it is child of another node.
pParent = parent.CreateChildSceneNode(pszParent);
}
try
{
// Check if the scene node has already been created by a child
// In this case we would have to change the parent.
pNode = mSceneMgr.GetSceneNode(pszName);
// Get old parent (probably scene root)
SceneNode pOldParent = pNode.ParentSceneNode;
// Remove this node
pOldParent.RemoveChild(pNode);
// Insert us as child on the "real" parent
pParent.AddChild(pNode);
}
catch
{
pNode = pParent.CreateChildSceneNode(pszName);
}
ENABLE_LOGMANAGER();
}
// Position
XmlElement posElem = (XmlElement)elet.SelectSingleNode("position");
if (posElem != null)
{
Vector3 pos;
pos.x = float.Parse(posElem.GetAttribute("x"));
pos.y = float.Parse(posElem.GetAttribute("y"));
pos.z = float.Parse(posElem.GetAttribute("z"));
pNode.Position = pos;
}
// Rotation
XmlElement rotElem = (XmlElement)elet.SelectSingleNode("rotation");
if (rotElem != null)
{
pNode.SetOrientation(
float.Parse(rotElem.GetAttribute("w")),
float.Parse(rotElem.GetAttribute("x")),
float.Parse(rotElem.GetAttribute("y")),
float.Parse(rotElem.GetAttribute("z")));
}
// Scale
XmlElement scaleElem = (XmlElement)elet.SelectSingleNode("scale");
if (scaleElem != null)
{
Vector3 scale;
scale.x = float.Parse(scaleElem.GetAttribute("x"));
scale.y = float.Parse(scaleElem.GetAttribute("y"));
scale.z = float.Parse(scaleElem.GetAttribute("z"));
pNode.SetScale(scale);
}
// Notify
if (OnNodeCreate != null)
OnNodeCreate(pNode, elet);
// Animation
XmlElement animList = (XmlElement)elet.SelectSingleNode("animations");
if (animList != null)
{
//
foreach (XmlElement animElem in animList.ChildNodes)
{
// Get name of animation
string aniName = animElem.GetAttribute("name");
Animation pAnim = null;
DISABLE_LOGMANAGER();
try
{
pAnim = mSceneMgr.GetAnimation(aniName);
}
catch
{
}
ENABLE_LOGMANAGER();
// If this animation has not been created yet, we create it
if (pAnim == null)
{
float fLength = float.Parse(animElem.GetAttribute("length"));
pAnim = mSceneMgr.CreateAnimation(aniName, fLength);
pAnim.SetInterpolationMode(Animation.InterpolationMode.IM_LINEAR);
}
// Create animation track for this node
NodeAnimationTrack pTrack = pAnim.CreateNodeTrack((ushort)(pAnim.NumNodeTracks + 1), pNode);
// Iterate all keyframes for this node
foreach (XmlElement pKeyframeElem in animElem.ChildNodes)
{
float fTime = float.Parse(pKeyframeElem.GetAttribute("time"));
TransformKeyFrame pKeyFrame = pTrack.CreateNodeKeyFrame(fTime);
// Position
posElem = (XmlElement)pKeyframeElem.SelectSingleNode("position");
if (posElem != null)
{
Vector3 trans;
trans.x = float.Parse(posElem.GetAttribute("x"));
trans.y = float.Parse(posElem.GetAttribute("y"));
trans.z = float.Parse(posElem.GetAttribute("z"));
pKeyFrame.Translate = trans;
}
// Rotation
rotElem = (XmlElement)pKeyframeElem.SelectSingleNode("rotation");
if (rotElem != null)
{
Quaternion qRot;
qRot.x = float.Parse(rotElem.GetAttribute("x"));
qRot.y = float.Parse(rotElem.GetAttribute("y"));
qRot.z = float.Parse(rotElem.GetAttribute("z"));
qRot.w = float.Parse(rotElem.GetAttribute("w"));
pKeyFrame.Rotation= qRot;
}
// Scale
scaleElem = (XmlElement)pKeyframeElem.SelectSingleNode("scale");
if (scaleElem != null)
{
Vector3 scale;
scale.x = float.Parse(scaleElem.GetAttribute("x"));
scale.y = float.Parse(scaleElem.GetAttribute("y"));
scale.z = float.Parse(scaleElem.GetAttribute("z"));
pKeyFrame.Scale = scale;
}
}
}
}
return pNode;
}
private void ENABLE_LOGMANAGER()
{
LogManager.Singleton.SetLogDetail(LoggingLevel.LL_NORMAL);
}
private void DISABLE_LOGMANAGER()
{
LogManager.Singleton.SetLogDetail(LoggingLevel.LL_LOW);
}
private void CreateCameras(XmlNodeList list, SceneNode parent)
{
// Iterate all Cameras, creating them. We do not attach them yet, since
// we need to make sure all potential item entities have been created.
foreach (XmlElement item in list)
{
// Ogre could cast an exception, in which case we just try to
// continue reading the other Cameras
try
{
// Create camera
Camera pCamera = mSceneMgr.CreateCamera(item.GetAttribute("name"));
if (pCamera == null) continue;
// Set Field of View on camera
pCamera.FOVy = new Radian(float.Parse(item.GetAttribute("FOV")));
pCamera.NearClipDistance = 5;
// Create node with full information
SceneNode pCameraNode = CreateNode(item, parent);
// Attach the Camera entity to node
pCameraNode.AttachObject(pCamera);
// Target
XmlElement targetElem = (XmlElement)item.SelectSingleNode("target");
if (targetElem != null)
{
// Create node with full information
SceneNode pTargetNode = CreateNode(targetElem, parent);
pCameraNode.SetAutoTracking(true, pTargetNode);
}
// Notify
if (OnCameraCreate != null)
OnCameraCreate(pCamera, item);
// Add to camera list
cameras.Add(pCamera.Name, pCamera);
}
catch
{
continue;
}
}
}
private void CreateLights(XmlNodeList list, SceneNode parent)
{
// Iterate all Lights, creating them. We do not attach them yet, since
// we need to make sure all potential parent entities have been created.
foreach (XmlElement pLightElem in list)
{
// Ogre could cast an exception, in which case we just try to
// continue reading the other Lights
try
{
string pszName = pLightElem.GetAttribute("name");
Light pLight = mSceneMgr.CreateLight(pszName);
if (pLight == null) continue;
// Figure out which type of light we are using
string pszType = pLightElem.GetAttribute("type");
if (pszType == "omni")
{
pLight.Type = Light.LightTypes.LT_POINT;
}
else if (pszType == "spot")
{
pLight.Type = Light.LightTypes.LT_SPOTLIGHT;
pLight.SetSpotlightRange(
new Radian(new Degree(float.Parse(pLightElem.GetAttribute("hotspot")))),
new Radian(new Degree(float.Parse(pLightElem.GetAttribute("falloff")))));
pLight.SetDirection(0, 0, -1);
}
else if (pszType == "directional")
{
pLight.Type = Light.LightTypes.LT_DIRECTIONAL;
}
// Check if the light should be on
string pszOn = pLightElem.GetAttribute("on");
if (pszOn == "true")
pLight.Visible = true;
else
pLight.Visible = false;
// Check if the object should cast shadows
string pszCastShadows = pLightElem.GetAttribute("CastShadows");
if (pszCastShadows == "no")
pLight.CastShadows = false;
else
pLight.CastShadows = true;
// Diffuse Color
XmlElement colorElem = (XmlElement)pLightElem.SelectSingleNode("color");
if (colorElem != null)
{
pLight.SetDiffuseColour(
float.Parse(colorElem.GetAttribute("r")),
float.Parse(colorElem.GetAttribute("g")),
float.Parse(colorElem.GetAttribute("b")));
}
// Specular Color
XmlElement specularElem = (XmlElement)pLightElem.SelectSingleNode("specular");
if (specularElem != null)
{
pLight.SetSpecularColour(
float.Parse(specularElem.GetAttribute("r")),
float.Parse(specularElem.GetAttribute("g")),
float.Parse(specularElem.GetAttribute("b")));
}
// Attenuation
XmlElement attenElem = (XmlElement)pLightElem.SelectSingleNode("attenuation");
if (attenElem != null)
{
pLight.SetAttenuation(
float.Parse(attenElem.GetAttribute("range")),
float.Parse(attenElem.GetAttribute("constant")),
float.Parse(attenElem.GetAttribute("linear")),
float.Parse(attenElem.GetAttribute("quadratic")));
}
// Create node with full information
SceneNode pLightNode = CreateNode(pLightElem, parent);
// Attach the Light entity to node
pLightNode.AttachObject(pLight);
// Target
XmlElement targetElem = (XmlElement)pLightElem.SelectSingleNode("target");
if (targetElem != null)
{
// Create node with full information
SceneNode pTargetNode = CreateNode(targetElem, parent);
pLightNode.SetAutoTracking(true, pTargetNode);
}
// Notify
if (OnLightCreate != null)
OnLightCreate(pLight, pLightElem);
// Add to light list
lights.Add(pszName, pLight);
}
catch
{
continue;
}
}
}
private void CreateEntities(XmlNodeList list, SceneNode parent)
{
// Iterate all meshes, creating them.
foreach (XmlElement pMeshElem in list)
{
// Ogre could cast an exception, in which case we just try to
// continue reading the other meshes
try
{
string pszName = pMeshElem.GetAttribute("name");
string pszFileName = pMeshElem.GetAttribute("filename");
// try to create the mesh
Entity pEntity = mSceneMgr.CreateEntity(pszName, pszFileName);
if (pEntity == null) continue;
// Check if the object should cast shadows
string pszCastShadows = pMeshElem.GetAttribute("CastShadows");
if (pszCastShadows == "no")
pEntity.CastShadows = false;
else
pEntity.CastShadows = true;
// Create node with full information
SceneNode pObjNode = CreateNode(pMeshElem, parent);
// Attach the mesh entity to node
pObjNode.AttachObject(pEntity);
// Notify
if (OnEntityCreate != null)
OnEntityCreate(pEntity, pMeshElem);
// Add to entity list
entities.Add(pszName, pEntity);
}
catch (Exception ex)
{
continue;
}
}
}
}
public delegate void LoadedSceneObjectEventHandler(Object obj, XmlElement xmlSrc);
}
Example of usage
OSMLoader loader = new OSMLoader(sceneMgr, window);
loader.Initialize("test.osm");
loader.CreateScene(sceneMgr.RootSceneNode);