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?
and for running it:
Thank you and sorry for my horrible engl!
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!