How to load OSM files in OgreDotNet?

Al Capique

26-04-2006 19:18:49

Is there any way to load complete scenes (.OSM format) with OgreDotNet?

vguruv

08-05-2006 00:39:45

I am trying to accomplish the same thing: load complete scenes.

The oFusion loader addon is probably the way to do this, but I have not been able to find how to use oFusion or other scene loader with ODN.

Any input is greatly appreciated.

vguruv

08-05-2006 03:01:46

http://www.ogre3d.org/phpBB2addons/view ... ight=scene

rastaman

08-05-2006 22:23:01

What is (.OSM format)?
The only advise i can give is to find the c++ version of the loading code and convert it to c#. If there are specific things in ogre that are needed and not wrapped yet, you will have to identify the interfaces and post here so we can work on getting them wrapped.

Vectrex

07-06-2006 02:38:15

http://ofusion.inocentric.com/oFusion.html

It's really quite cool. Osm is their dotsceneish xml format, which is virtually the same as dotscene. But it handles alot of other stuff such as keyframed animation.
The wrapping to dotnet would actually be simple I think as the main bits are just 4 callbacks and a couple of method calls. The loader lib has a simple example which loads and plays animations from a .osm level.

Vectrex

07-06-2006 02:58:16

btw I've never wrapped c++ into c# before so if you can make a small tutorial or point to a good website it'd be great. It'd be a good wiki thing for ODN, actually... *checks wiki ;)

LuRenJia

18-06-2006 18:40:18

hi all!

I had converted oSceneLoader from c++ to c#, but not test yet. Any one would like to test it?

The code posted below:

/* ******************************************************
* Name: OSMLoader
* Desc: The OSMLoader class load a scene from a xml document
* which contains scene data that oFusion exported from
* 3DSMax. It was converted from c++ source file: oSceneLoader.
* Code: ChengYangSheng (程阳生)
* Date: 2006/6/18
* ******************************************************/
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 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);

}