I had converted oFusion SceneLoader from c++ to c#!

LuRenJia

19-06-2006 09:34:15

Hi all!

I had converted oFusion SceneLoader from c++ to c# yesterday, but not test yet, any one would like to test it?

The source code posted below:

using System;
using System.Collections;
using System.Drawing;
using System.IO;
using System.Xml;
using Math3D;
using OgreDotNet;

namespace OgreAddons
{
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.Instance.logMessage(@"
**********************************************
** OSM Scene Loader **
**********************************************
");
LogManager.Instance.logMessage("OSMLoader loading scene form file: " + xmlFile);
if (!File.Exists(xmlFile))
{
LogManager.Instance.logMessage("Not found file: " + xmlFile);
throw new FileNotFoundException("Not found scene file.", xmlFile);
}

xd = new XmlDocument();
try
{
xd.Load(xmlFile);
}
catch (XmlException ex)
{
xd = null;
LogManager.Instance.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.Instance.logMessage("OSMLoader: Creating scene on '" +
(parent == null ? "Root" : parent.Name) + "' node.");

if (mSceneMgr == null)
{
if (xd.SelectSingleNode("/sceneManager") != null)
setSceneProperties(xd);
else
mSceneMgr = Root.GetSingleton().CreateSceneManager((ushort) SceneType.Generic);
}

if (parent == null)
mSceneMgr.RootSceneNode.CreateChildSceneNode();

try
{
CreateCameras(xd.SelectNodes("/cameras/*"), parent);
}
catch
{
}
try
{
CreateLights(xd.SelectNodes("/lights/*"), parent);
}
catch
{
}
try
{
CreateEntities(xd.SelectNodes("/entities/*"), parent);
}
catch
{
}

LogManager.Instance.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 Color parseColor(string r, string g, string b)
{
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.Instance.CreateSceneManager((ushort) 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)
{
Color color = parseColor(
colorElem.GetAttribute("r"),
colorElem.GetAttribute("g"),
colorElem.GetAttribute("b"));

mWindow.GetViewport(0).SetBackgroundColour(color);
}

// Ambient light Color
colorElem = (XmlElement) xd.SelectSingleNode("lightColor");
if (colorElem != null)
{
Color color = parseColor(
colorElem.GetAttribute("r"),
colorElem.GetAttribute("g"),
colorElem.GetAttribute("b"));
mSceneMgr.SetAmbientLight(color);
}


// Scene shadows
XmlElement shadowsElem = (XmlElement) xd.SelectSingleNode("shadowTechnique");
if (shadowsElem != null)
{
type = int.Parse(shadowsElem.GetAttribute("type"));
ShadowTechnique shadowType = (ShadowTechnique) type;

mSceneMgr.SetShadowTechnique(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)
{
Color color = parseColor(
colorElem.GetAttribute("r"),
colorElem.GetAttribute("g"),
colorElem.GetAttribute("b"));

mSceneMgr.SetShadowColour(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 OgreVector3(-Vector3.UnitY);


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 == null) return null;

// Check if this node has a parent
string pszParent = elet.GetAttribute("parent");
if (pszParent == null)
{
// 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.SetPosition(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.Linear);
}

// Create animation track for this node
NodeAnimationTrack pTrack = pAnim.CreateNodeTrack((ushort) (pAnim.GetNumNodeTracks() + 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.SetTranslate(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.SetRotation(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.SetScale(scale);
}
}
}
}

return pNode;
}

private void ENABLE_LOGMANAGER()
{
throw new NotImplementedException();
}

private void DISABLE_LOGMANAGER()
{
throw new NotImplementedException();
}

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.SetFOVy(new Radian(float.Parse(item.GetAttribute("FOV"))));
pCamera.SetNearClipDistance(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.Point;
}
else if (pszType == "spot")
{
pLight.Type = Light.LightTypes.Spot;
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.Directional;
}

// Check if the light should be on
string pszOn = pLightElem.GetAttribute("on");
if (pszOn == "true")
pLight.SetVisible(true);
else
pLight.SetVisible(false);

// Check if the object should cast shadows
string pszCastShadows = pLightElem.GetAttribute("CastShadows");
if (pszCastShadows == "no")
pLight.SetCastShadows(false);
else
pLight.SetCastShadows(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.SetCastShadows(false);
else
pEntity.SetCastShadows(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
{
continue;
}
}
}
}

public delegate void LoadedSceneObjectEventHandler(Object obj, XmlElement xmlSrc);

}

Greenjacket

06-07-2006 17:32:08

Thanks! just when I was about to do the same, I thought I'd check the forum!! :wink:

Have you had any experience with this yet? And how have you got on with oFusion in general?

Reason being, I've just spent the morning going through the oFusion Forum, and it seems that a lot of the problems people have been having with oFusion may be associated with using the current oFusion CE release (of beginning March) with Ogre 1.2, when apparently, the current oFusion CE release is only fully compatible with the previous Ogre release.

Any comments? Most welcome!

cheers
Greenjacket

pjcast

08-07-2006 22:21:15

Thanks, I may implement this code in my Ogre Studio editor for a Ofusion file loader / saver (I already have .Scene) :)

LuRenJia

13-07-2006 05:10:51

The source posted above have some bugs, I had fixed them.

The biggest problem I meet is performance. Check this thread:
http://www.ogre3d.org/phpBB2addons/view ... highlight=

Greenjacket

13-07-2006 10:00:18

LuRenJia,

thanks for letting us know about the bugs - is the posted code fixed? And how did you get round your performance issues?

cheers
Greenjacket

LuRenJia

14-07-2006 15:40:52

update source code, it was tested.:

using System;
using System.Collections;
using System.Drawing;
using System.IO;
using System.Xml;
using Math3D;
using OgreDotNet;

namespace BVR
{
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.Instance.logMessage(@"
**********************************************
** OSM Scene Loader **
**********************************************
");
LogManager.Instance.logMessage("OSMLoader loading scene form file: " + xmlFile);
if (!ResourceGroupManager.Instance.resourceExists(
ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME,
xmlFile))
{
LogManager.Instance.logMessage("Not found file: " + xmlFile);
throw new FileNotFoundException("Not found scene file.", xmlFile);
}

xd = new XmlDocument();
try
{
DataStreamPtr dsp = ResourceGroupManager.Instance.openResource(xmlFile);
xd.LoadXml(dsp.getAsString());
dsp.Dispose();
}
catch (XmlException ex)
{
xd = null;
LogManager.Instance.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.Instance.logMessage("OSMLoader: Creating scene on '" +
(parent == null ? "Root" : parent.Name) + "' node.");

if (mSceneMgr == null)
{
if (xd.SelectSingleNode("/sceneManager") != null)
setSceneProperties(xd);
else
mSceneMgr = Root.GetSingleton().CreateSceneManager((ushort) SceneType.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.Instance.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 Color parseColor(string r, string g, string b)
{
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.Instance.CreateSceneManager((ushort) 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)
{
Color color = parseColor(
colorElem.GetAttribute("r"),
colorElem.GetAttribute("g"),
colorElem.GetAttribute("b"));

mWindow.GetViewport(0).SetBackgroundColour(color);
}

// Ambient light Color
colorElem = (XmlElement) xd.SelectSingleNode("lightColor");
if (colorElem != null)
{
Color color = parseColor(
colorElem.GetAttribute("r"),
colorElem.GetAttribute("g"),
colorElem.GetAttribute("b"));
mSceneMgr.SetAmbientLight(color);
}


// Scene shadows
XmlElement shadowsElem = (XmlElement) xd.SelectSingleNode("shadowTechnique");
if (shadowsElem != null)
{
type = int.Parse(shadowsElem.GetAttribute("type"));
ShadowTechnique shadowType = (ShadowTechnique) type;

mSceneMgr.SetShadowTechnique(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)
{
Color color = parseColor(
colorElem.GetAttribute("r"),
colorElem.GetAttribute("g"),
colorElem.GetAttribute("b"));

mSceneMgr.SetShadowColour(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 OgreVector3(-Vector3.UnitY);


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.SetPosition(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.Linear);
}

// Create animation track for this node
NodeAnimationTrack pTrack = pAnim.CreateNodeTrack((ushort) (pAnim.GetNumNodeTracks() + 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.SetTranslate(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.SetRotation(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.SetScale(scale);
}
}
}
}

return pNode;
}

private void ENABLE_LOGMANAGER()
{
LogManager.Instance.setLogDetail(OgreLoggingLevel.LL_NORMAL);
}

private void DISABLE_LOGMANAGER()
{
LogManager.Instance.setLogDetail(OgreLoggingLevel.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.SetFOVy(new Radian(float.Parse(item.GetAttribute("FOV"))));
pCamera.SetNearClipDistance(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.Point;
}
else if (pszType == "spot")
{
pLight.Type = Light.LightTypes.Spot;
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.Directional;
}

// Check if the light should be on
string pszOn = pLightElem.GetAttribute("on");
if (pszOn == "true")
pLight.SetVisible(true);
else
pLight.SetVisible(false);

// Check if the object should cast shadows
string pszCastShadows = pLightElem.GetAttribute("CastShadows");
if (pszCastShadows == "no")
pLight.SetCastShadows(false);
else
pLight.SetCastShadows(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.SetCastShadows(false);
else
pEntity.SetCastShadows(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
{
continue;
}
}
}
}

public delegate void LoadedSceneObjectEventHandler(Object obj, XmlElement xmlSrc);

}

Greenjacket

14-07-2006 17:52:34

Thanks LuRenJia :D

marc_antoine

29-12-2006 19:26:34

hi..hmm i'm a noob to the OGRE stuff, and i want to load an entire scene composed of many 3d elements i believe that with ofusion exporter i can, i'm working in c# and i found your post, how do i use your code?.. :oops:

here is the code i'm using

RenderWindow rw=null;
OSM.OSMLoader cargaOSM = new
OSM.OSMLoader(mSceneManager,rw);
cargaOSM.Initialize("C:\\OGRE_CSHARP\\OGRE_CSHARP\\bin\\Release\\escenario\\escenario_ayudantes.osm");
cargaOSM.CreateScene(mSceneManager.RootSceneNode);

is that correct? cose i don´t see anything in the window . :( i tried before the code in the tutorial, but it works fine i loaded a robot mesh.

smernesto

05-01-2007 07:58:16

@marc_antoine.

Hi marc_antoine , I think that you speak spanish for some words in your code that is in spanish, I also speak spanish.

I had a problem with the ofusion loader, a person in the Mogre forum converted the OgreDotNet oFusion loader to Mogre. Both has the same error and I wrote a post in the Mogre forum: http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=3008

Is about how to parse the float numbers. float.Parse() is culture dependent, if you have your windows with the decimal separator set to ',' (coma) you will have problems with the oFusion loader, they will interpret 3.4 how 34. I posted a code with the float.parse error fixed in the mogre forum, you can take it how a model to fix the OgreDotNet oFusion loader.

Well hehehe actually, I don´t know if this is your error but maybe.
If you want to debug your application, set a breakpoint in a float.parse in the oFusion loader and see how the sentence parse a decimal number.

Bye

Ernesto Gutierrez

marc_antoine

05-01-2007 18:07:49

hi Ernesto! thanks for the reply..

well i ended using Mogre and converted the code of the post where the c++ code of the OSMloder is ported to c#, i converted it into a dll to use it in my projects and everythings works fine, i even hd porblems relating to the position of the elements in the scene i just x-form the objects, and re-aligned the pivot points so it worked!, but now i want to do some vertex animation but seems it is not supported by the exporter and OGRE, i don't know or if Reactor animtions in 3dsMx can be exported and used in OGRE, hope to find it out soon.. by the way nice tip about the float i didn't knew that it was language dependant.
well so if anyone knows the way to exportvertex animations or someting similar to that into OGRE let me know!!