OFUSION -> osmloader

cdkeito

27-01-2007 11:22:05

Hi guys,

probably my ofusion is damaged, the class in wiki don't work.
I've rewrote some lines (it work fine), are they correct or baka me?

using System;
using System.Collections;
using System.Drawing;
using System.IO;
using System.Xml;
using System.Globalization;
using Mogre;

namespace Mogre.NNN
{
public class OSMLoader
{
private XmlDocument xd;
private SceneManager mSceneMgr;
private RenderWindow mWindow;
private NumberFormatInfo numberFormat = new NumberFormatInfo();

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)
{
numberFormat.CurrencyDecimalSeparator = ".";
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);
//}
setSceneProperties(xd);
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;
}

private ColourValue parseColor(string r, string g, string b)
{
ColourValue clr = new ColourValue();
clr.r = float.Parse(r, numberFormat);
clr.g = float.Parse(g, numberFormat);
clr.b = float.Parse(b, numberFormat);

return clr;
}

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 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("/oe_scene/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("/oe_scene/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("/oe_scene/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("/oe_scene/skyTechnique");
if (skyElem != null)
{
type = int.Parse(skyElem.GetAttribute("type"));
String materialName = skyElem.GetAttribute("material");

if (materialName != " ")
{
bool drawFirst;
string strdrawFirst = skyElem.GetAttribute("drawFirst");
if (strdrawFirst == "yes")
drawFirst = true;
else
drawFirst = false;
float tiling = float.Parse(skyElem.GetAttribute("tiling"), numberFormat);
float scale = float.Parse(skyElem.GetAttribute("scale"), numberFormat);
float dist = float.Parse(skyElem.GetAttribute("dist"), numberFormat);
float bow = float.Parse(skyElem.GetAttribute("bow"), numberFormat);
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.SetSkyDome(true, materialName, 5, 8);
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"), numberFormat);
pos.y = float.Parse(posElem.GetAttribute("y"), numberFormat);
pos.z = float.Parse(posElem.GetAttribute("z"), numberFormat);
pNode.Position = pos;
}

// Rotation
XmlElement rotElem = (XmlElement)elet.SelectSingleNode("rotation");
if (rotElem != null)
{
pNode.SetOrientation(
float.Parse(rotElem.GetAttribute("w"), numberFormat),
float.Parse(rotElem.GetAttribute("x"), numberFormat),
float.Parse(rotElem.GetAttribute("y"), numberFormat),
float.Parse(rotElem.GetAttribute("z"), numberFormat));

}

// Scale
XmlElement scaleElem = (XmlElement)elet.SelectSingleNode("scale");
if (scaleElem != null)
{
Vector3 scale;
scale.x = float.Parse(scaleElem.GetAttribute("x"), numberFormat);
scale.y = float.Parse(scaleElem.GetAttribute("y"), numberFormat);
scale.z = float.Parse(scaleElem.GetAttribute("z"), numberFormat);
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"), numberFormat);
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"), numberFormat);
TransformKeyFrame pKeyFrame = pTrack.CreateNodeKeyFrame(fTime);

// Position
posElem = (XmlElement)pKeyframeElem.SelectSingleNode("position");
if (posElem != null)
{
Vector3 trans;
trans.x = float.Parse(posElem.GetAttribute("x"), numberFormat);
trans.y = float.Parse(posElem.GetAttribute("y"), numberFormat);
trans.z = float.Parse(posElem.GetAttribute("z"), numberFormat);
pKeyFrame.Translate = trans;
}

// Rotation
rotElem = (XmlElement)pKeyframeElem.SelectSingleNode("rotation");
if (rotElem != null)
{
Quaternion qRot;
qRot.x = float.Parse(rotElem.GetAttribute("x"), numberFormat);
qRot.y = float.Parse(rotElem.GetAttribute("y"), numberFormat);
qRot.z = float.Parse(rotElem.GetAttribute("z"), numberFormat);
qRot.w = float.Parse(rotElem.GetAttribute("w"), numberFormat);
pKeyFrame.Rotation = qRot;
}

// Scale
scaleElem = (XmlElement)pKeyframeElem.SelectSingleNode("scale");
if (scaleElem != null)
{
Vector3 scale;
scale.x = float.Parse(scaleElem.GetAttribute("x"), numberFormat);
scale.y = float.Parse(scaleElem.GetAttribute("y"), numberFormat);
scale.z = float.Parse(scaleElem.GetAttribute("z"), numberFormat);
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"), numberFormat));
pCamera.NearClipDistance = 0.1f;

// 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"), numberFormat))),
new Radian(new Degree(float.Parse(pLightElem.GetAttribute("falloff"), numberFormat))));
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"), numberFormat),
float.Parse(colorElem.GetAttribute("g"), numberFormat),
float.Parse(colorElem.GetAttribute("b"), numberFormat));
}

// Specular Color
XmlElement specularElem = (XmlElement)pLightElem.SelectSingleNode("specular");
if (specularElem != null)
{
pLight.SetSpecularColour(
float.Parse(specularElem.GetAttribute("r"), numberFormat),
float.Parse(specularElem.GetAttribute("g"), numberFormat),
float.Parse(specularElem.GetAttribute("b"), numberFormat));
}

// Attenuation
XmlElement attenElem = (XmlElement)pLightElem.SelectSingleNode("attenuation");
if (attenElem != null)
{
pLight.SetAttenuation(
float.Parse(attenElem.GetAttribute("range"), numberFormat),
float.Parse(attenElem.GetAttribute("constant"), numberFormat),
float.Parse(attenElem.GetAttribute("linear"), numberFormat),
float.Parse(attenElem.GetAttribute("quadratic"), numberFormat));
}

// 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);

}

and for running it:
loader = new OSMLoader(sceneMgr, window);
loader.Initialize("File.osm");
loader.CreateScene(sceneMgr.RootSceneNode);
viewport.Camera = (Camera)loader.Cameras["CameraName"];


Thank you and sorry for my horrible engl! :oops:

smernesto

27-01-2007 18:03:22

Hi.

I found some bugs in the OSM loader in the Wiki, it works and loads scenes but some features donĀ“t work well.

I port again the last version of OFusion loader (July version) line by line.

I will post the loader ehmm I will clean it a little.

cdkeito

27-01-2007 19:31:54

true,

must of my rewriting is for the sky/shadow/... (changed the path)

and the scene manager that always exit so it doesn't initialize the scene (I've ignored the SM e initialized the scene anyways)

I'll wait for yours. For now this works like a charm.

PS (They say there's a new release behind the corner)