I convert OSM Scene Loader (change syntax) from ODN (here in forum)
that was also converted from original c++ code.
May be this will be useful for someone..
Alternatively here is an other port of the OSM Scene Loader:
MOGRE OSMSceneLoader 2
Code:
Copy to clipboard
//Update: 02/Feb/2007 //Fixed a problem with the code to parse float numbers, //the code was dependent of the culture and the decimal separator. using System; using System.Collections; using System.Drawing; using System.IO; using System.Xml; using System.Globalization; using Mogre; namespace MyApp { 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); } 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, 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.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"), 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.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 = 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"), 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); }
Example of usage
Copy to clipboard
OSMLoader loader = new OSMLoader(sceneMgr, window); loader.Initialize("test.osm"); loader.CreateScene(sceneMgr.RootSceneNode);