XNA Game Development Forums
2012/05/21 21:09:29 *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   Home   Help Search Calendar Login Register  
Pages: [1] 2
  Print  
Author Topic: Saving scene  (Read 11618 times)
Hunefalk
Newbie
*
Offline Offline

Posts: 7


View Profile
« on: 2006/07/28 13:43:05 »

Hey,

I'd really like to see some part where the created scene is saved. Also, the option of editing the textures for meshes would be great.

I'll be trying myself, but it would be nice to get a "working sample" tutorial for it as well, to look at if I get stuck somewhere Wink

Thanks for great tutorials by the way  Cheesy

EDIT: Another thing I was thinking of is the possibility to drag models around, similar to the way you see in 3Ds Max, Maya etc, with arrows in the x-, y- and z-directions always visible for the mesh node you're working with.
« Last Edit: 2006/07/31 06:07:33 by Hunefalk » Logged
Chr0n1x
Global Moderator
Sr. Member
*****
Offline Offline

Posts: 307


View Profile WWW
« Reply #1 on: 2006/07/31 22:34:34 »

For saving, it'd be cool if you could setup the scene so you can serialize it to an XML or a Binary file, that'd be great, but toughish.

As for the dragging of models, I agree, doing that would be good, and possibly multiple-select/drag.
Logged

mikeschuld
Administrator
Sr. Member
*****
Offline Offline

Posts: 389


View Profile WWW
« Reply #2 on: 2006/08/01 11:11:01 »

More advanced interface controls will be added once the DirectInput support has been put into the engine (which you can read about in the requests section. I am considering very carefully the file format that scenes would be saved out as. My biggest hangup is trying to get all of the textures, models, and shaders that are loaded into the app to save out into a folder that is associated only with the current scene (or group of scenes if we end up with a project based setup) so that the scene folder itself can simply be dragged somewhere all at once and run from within the engine by calling only the XML file (or whatever other method we use.) Thoughts on this technique or other methods of solving this problem are welcome.
Logged
Nelson
Newbie
*
Offline Offline

Posts: 21


View Profile
« Reply #3 on: 2006/08/01 15:09:10 »

You can always implement a method of compression into the Engine (zlib) and group all the resources files together in this manner. For the scene saving, XML would probably be best or some binary format of your own invention.

Logged
Chr0n1x
Global Moderator
Sr. Member
*****
Offline Offline

Posts: 307


View Profile WWW
« Reply #4 on: 2006/08/01 23:18:48 »

A compression library would be good, I could go for that. If you wanna keep it to just folders, say for pre-release, I remember a topic in my oversized C# book about a bit of .NET2 that did that quite easily, um think its called ActiveDirectory, I will take a look into that and can provide some info if you need.

I think a dir structure like:
Code:
<Game Dir>\Data\<levelname>
\Models
\Shaders
etc

and then in the engine have it automatically during loading of those resources just tack that bit on, then the filename. I did this with a recent version of my engine and it worked quite nicely. Having the level name as a string var and then using that in those positions when loading makes it nice and easy, and the xml file can have a structure like:
Code:
<Models>
? ? <Model src="tiger" />
</Models>
etc.
The above code assumes you are using .x and the engine plugs that on.
Logged

Nelson
Newbie
*
Offline Offline

Posts: 21


View Profile
« Reply #5 on: 2006/08/03 12:35:54 »

That's a simple solution as well, if anything both can be implemented if you just abstract the methods.
Logged
Jonotron
Newbie
*
Offline Offline

Posts: 27


View Profile
« Reply #6 on: 2006/08/09 12:32:36 »

Hey,

I'd really like to see some part where the created scene is saved. Also, the option of editing the textures for meshes would be great.

I'll be trying myself, but it would be nice to get a "working sample" tutorial for it as well, to look at if I get stuck somewhere Wink

Thanks for great tutorials by the way  Cheesy

EDIT: Another thing I was thinking of is the possibility to drag models around, similar to the way you see in 3Ds Max, Maya etc, with arrows in the x-, y- and z-directions always visible for the mesh node you're working with.

I've added a simple part to the mousemove procedure.  If you hold shift and drag the mouse, it'll modify the meshes position (only x and z axis though  Sad).  Here is what I used:
Code:
            //if shift is pressed, move object
            if ((Control.ModifierKeys & Keys.Shift) != 0)
            {
                if (mouseClick.Button == MouseButtons.Left)
                {
                    Point delta = new Point(lastMouseLoc.X - e.X, lastMouseLoc.Y - e.Y);
                    lastMouseLoc = e.Location;
                    if (activeObject != null)
                    {
                        activeObject.SetPosition(activeObject.Position - new Vector3((float)delta.X * .015f, -(float)delta.Y * .015f, 0));
                        UpdateProperties(null, null);
                    }
                    else
                    {
                        mySystem.Camera.Rotate((float)delta.X * .01f, -(float)delta.Y * .01f);
                    }
                }
            }
Logged
Nemo Krad
Global Moderator
Hero Member
*****
Offline Offline

Posts: 512


I have seen the fnords


View Profile WWW
« Reply #7 on: 2006/12/21 08:07:40 »

I am probably wrong but, XAML would be good to use, I got an example off Microsoft giving a room with objects as an example. I understand that the current XNA stuff is for framework 2 but I am sure we could come up with a pseudo XAML object to mange this.


« Last Edit: 2006/12/21 08:52:27 by Nemo Krad » Logged
Nemo Krad
Global Moderator
Hero Member
*****
Offline Offline

Posts: 512


I have seen the fnords


View Profile WWW
« Reply #8 on: 2006/12/21 08:51:34 »

Just had a quick thought about this and I think something like this would do:

Code:
<?xml version="1.0" encoding="utf-8" ?>
<scene id=""  name="" maxX="" minX="" maxY="" minY="" maxZ="" minZ="">
<skybox scalingX="" scalingY="" scalingZ="" offsetXYZ="">
<front></front>
<back></back>
<left></left>
<right></right>
<top></top>
<bottom></bottom>
</skybox>
<shaders>
<shader id="" name=""></shader>
</shaders>
<models>
<model id="" name="" positionX="" positionY="" positionZ="" rotationX="" rotationY="" rotationZ="" scalingX="" scalingY="" scalingZ="">
<asset></asset>
<ambientLight>
<color></color>
<vector>
<x></x>
<y></y>
<z></z>
</vector>
<alpha></alpha>
</ambientLight>
<diffuseColor>
<color></color>
<vector>
<x></x>
<y></y>
<z></z>
</vector>
<alpha></alpha>
</diffuseColor>
<specularPower></specularPower>
</model>
</models>
</scene>

I just have to write the object to load and save it now and push the data to the relevant HM objects.

Please add or remove as you see fit. I hope to have something before Xmas, work and family permitting.
Logged
mikeschuld
Administrator
Sr. Member
*****
Offline Offline

Posts: 389


View Profile WWW
« Reply #9 on: 2006/12/21 11:15:06 »

All of the XNA stuff on here isn't for beta 2 its fully release capable Wink
Logged
Chr0n1x
Global Moderator
Sr. Member
*****
Offline Offline

Posts: 307


View Profile WWW
« Reply #10 on: 2006/12/21 16:45:19 »

In the end thats just XML, so thats what you would be doing, serialising a scene to XML. There is a bit of XML support in the CompactFramework on the 360 which would allow this to be done.
Logged

Nemo Krad
Global Moderator
Hero Member
*****
Offline Offline

Posts: 512


I have seen the fnords


View Profile WWW
« Reply #11 on: 2006/12/22 01:11:44 »

Mike,

Sorry for the confusion, but I was referring to XAML being on .NET Framework 3  and that the XNA stuff is for .NET Framework 2, not the beta versions of XNA or do I still have the wrong end of the stick??

Chr0n1x,

So the 360 supports System.XML and System.XML.XPath?
If it does would it be worth my time writing an XML object to manage the import,export, edit and update of my scenes?

I ask this because I love games that allow you to alter the environment of the world they are set in. I think it gives the game an extra element if you can create your own levels/environments etc...
Logged
Chr0n1x
Global Moderator
Sr. Member
*****
Offline Offline

Posts: 307


View Profile WWW
« Reply #12 on: 2006/12/22 15:40:11 »

The first clue you notice that the 360 has XML support is that the Content Processor has got an XML capability. I know it(XNA) has got the ability to do XML, but I do not know in what method, but I know it has XML support.
If you want to write up an XML object to manage that stuff and then share it with us, maybe in tutorial form, it would be great!
Logged

Nelson
Newbie
*
Offline Offline

Posts: 21


View Profile
« Reply #13 on: 2006/12/23 16:54:32 »

What I do for my world format is save it in XML form then deserialize the XML into a class. Really easy to work with.
Logged
Nemo Krad
Global Moderator
Hero Member
*****
Offline Offline

Posts: 512


I have seen the fnords


View Profile WWW
« Reply #14 on: 2006/12/24 04:20:36 »

OK,

This is what I have so far. At the moment all the object does is load a scene or number of scenes. This is not a Tutorial but I am just showing you what I have done so I know if I should continue with it or not.

This is the xml file that stored my scenes. I place it in the Content/Scene folder off the Demo assembly and named it TestScene.xml.
Code:
<?xml version="1.0" encoding="utf-8" ?>
<sceneManager name="TestScene" sceneCount="1">
    <shaders>
        <shader id="0" name="BasicShader" asset="Content/Shaders/BasicShader"/>
        <shader id="1" name="TrandformTexture" asset="Content/Shaders/TransformTexture"/>
    </shaders>
    <skyboxs skyboxCount="1">
        <skybox id="0" name="MountainLake"
            front="Content/Textures/Skybox/MountainLake/front"
            back="Content/Textures/Skybox/MountainLake/back"
            left="Content/Textures/Skybox/MountainLake/left"
            right="Content/Textures/Skybox/MountainLake/right"
            top="Content/Textures/Skybox/MountainLake/top"
            bottom="Content/Textures/Skybox/MountainLake/bottom"/>
    </skyboxs>
    <models modelCount="2">
        <model id="0" name="skull" asset="Content/Models/skullocc" specularPower="16">
            <ambientLight red="1" green="1" blue="0" alpha="1"/>
            <diffuseColor red="1" green="0.8431373" blue="0" alpha="1"/>
        </model>
        <model id="1" name="tiger" asset="Content/Models/tiger" specularPower="16">
            <ambientLight red="1" green="0" blue="0" alpha="1"/>
            <diffuseColor red="0" green="0" blue="1" alpha="1"/>
        </model>
    </models>
    <scene id="0"  name="Scene1" maxX="1000" minX="-1000" maxY="1000" minY="-1000" maxZ="1000" minZ="-1000">
        <skybox id="0" name="MountainLake" scalingX="9999" scalingY="9999" scalingZ="9999" offsetXYZ="0.5" shader="TrandformTexture"/>
        <models>
            <model id="0" name="skull" positionX="0.5" positionY="0" positionZ="0" rotationX="0" rotationY="0" rotationZ="1" scalingX="0.5" scalingY="0.5" scalingZ="0.5" shader="BasicShader"/>
            <model id="1" name="skull2" positionX="5" positionY="0" positionZ="0" rotationX="0" rotationY="0" rotationZ="1" scalingX="2" scalingY="2" scalingZ="2" shader="TrandformTexture"/>
        </models>
    </scene>
</sceneManager>

I have put name and id attributes on most elements so later I can access them in there respective object arrays buy either method. They are not fully implemented yet though.

The top level element (root) is the sceneManager element, this has a name to identify it as you never know you may have multiple SceneManager objects in the future. It also has a scene count as we are storing the scenes in a simple array at the moment and not in something like an array list so this tells my SceneLoader how many scenes to load.

Then we have four areas of interest, the <shaders/>, <skyboxes/>, <models/> and <scene/>  objects . <shaders/> holds ALL the shaders to be used in ALL the scenes loaded into this SceneManager, the same goes for <skyboxes/> and <models/>. <scene/> holds all the objects and a skybox to be used in a given scene and the skybox and models are references to the instances in the previous elements (<skyboxes/>, <models/> etc...)

Here is the SceneLoader class (replace my RC objects with your notation, in the case of the tutorial here replace with HM)
[EDIT]
Forgot to add that you need the  following in your Scene source file:
Code:
using System.Xml;
using System.Xml.XPath;
[/EDIT]
Code:
    public class RCSceneLoader
    {
        private string myXMLAsset;
        public RCSkyBox[] mySkyBoxs;       
        public RCModel[] myModels;
        public RCSceneGraph[] myScenes;
        private string myName;
       
        public string Name
        {
            get { return myName; }
        }
        public int SceneCount
        {
            get { return myScenes.Length; }
        }

        public RCSceneLoader(string newXMLAsset)
        {
            XmlTextReader xtr = new XmlTextReader(newXMLAsset);
            myXMLAsset = newXMLAsset;
            XmlDocument doc = new XmlDocument();
            doc.Load(xtr);
            xtr.Close();

            XmlNode node = doc.FirstChild.NextSibling;
            myName = node.Attributes["name"].Value;           
            myScenes = new RCSceneGraph[Convert.ToInt32(node.Attributes["sceneCount"].Value)];
            // Load shaders.
            node = doc.SelectSingleNode("sceneManager/shaders");
            node = node.FirstChild;
            do
            {
                RCShader shader = new RCShader(node.Attributes["asset"].Value);
                RCShaderManager.AddShader(shader, node.Attributes["name"].Value);
            } while ((node = node.NextSibling) != null);
            // Load Skyboxs.
            node = doc.SelectSingleNode("sceneManager/skyboxs");
            mySkyBoxs = new RCSkyBox[Convert.ToInt32(node.Attributes["skyboxCount"].Value)];
            node = node.FirstChild;
            for(int box=0;box<mySkyBoxs.Length;box++)
            {
                string skyboxName = node.Attributes["name"].Value;              
                mySkyBoxs[box] = new RCSkyBox(new string[] { node.Attributes["top"].Value, node.Attributes["bottom"].Value,
                                            node.Attributes["left"].Value, node.Attributes["right"].Value,
                                            node.Attributes["front"].Value, node.Attributes["back"].Value });
               
            }
            // Load Objects/Models.
            node = doc.SelectSingleNode("sceneManager/models");
            myModels = new RCModel[Convert.ToInt32(node.Attributes["modelCount"].Value)];
            node = node.FirstChild;
            for(int mod=0;mod<myModels.Length;mod++)
            {  
                myModels[mod] = new RCModel(node.Attributes["asset"].Value);
                myModels[mod].SpecularPower = (float)Convert.ToDouble(node.Attributes["specularPower"].Value);

                XmlNode modNode = node.SelectSingleNode("ambientLight");
                myModels[mod].AmbientLightColor = new Vector4((float)Convert.ToDouble(modNode.Attributes["red"].Value),
                                                               (float)Convert.ToDouble(modNode.Attributes["green"].Value),
                                                               (float)Convert.ToDouble(modNode.Attributes["blue"].Value),
                                                                (float)Convert.ToDouble(modNode.Attributes["alpha"].Value));
                modNode = node.SelectSingleNode("diffuseColor");
                myModels[mod].DiffuseColor = new Vector4((float)Convert.ToDouble(modNode.Attributes["red"].Value),
                                                               (float)Convert.ToDouble(modNode.Attributes["green"].Value),
                                                               (float)Convert.ToDouble(modNode.Attributes["blue"].Value),
                                                                (float)Convert.ToDouble(modNode.Attributes["alpha"].Value));
                node = node.NextSibling;
            }
            // Load Scenes
            node = doc.FirstChild.NextSibling.SelectSingleNode("scene");
            for (int scn = 0; scn < myScenes.Length; scn++)
            {
                myScenes[scn] = new RCSceneGraph();
                XmlNode skyboxNode = node.SelectSingleNode("skybox");
                XmlNode modelsNode = node.SelectSingleNode("models");

                // Add skybox
                mySkyBoxs[Convert.ToInt32(skyboxNode.Attributes["id"].Value)].SetShader(skyboxNode.Attributes["shader"].Value);
                mySkyBoxs[Convert.ToInt32(skyboxNode.Attributes["id"].Value)].Scaling = new Vector3((float)Convert.ToDecimal(skyboxNode.Attributes["scalingX"].Value),
                                                                                                    (float)Convert.ToDecimal(skyboxNode.Attributes["scalingY"].Value),
                                                                                                    (float)Convert.ToDecimal(skyboxNode.Attributes["scalingZ"].Value));
                myScenes[scn].AddObject(mySkyBoxs[Convert.ToInt32(skyboxNode.Attributes["id"].Value)]);

                modelsNode = modelsNode.FirstChild;
                int mod = 0;
                do
                {
                    myModels[Convert.ToInt32(modelsNode.Attributes["id"].Value)].SetShader(modelsNode.Attributes["shader"].Value);
                    myModels[Convert.ToInt32(modelsNode.Attributes["id"].Value)].Position = new Vector3((float)Convert.ToDecimal(modelsNode.Attributes["positionX"].Value),
                                                                                                        (float)Convert.ToDecimal(modelsNode.Attributes["positionY"].Value),
                                                                                                        (float)Convert.ToDecimal(modelsNode.Attributes["positionZ"].Value));
                    myModels[Convert.ToInt32(modelsNode.Attributes["id"].Value)].Scaling = new Vector3((float)Convert.ToDecimal(modelsNode.Attributes["scalingX"].Value),
                                                                                                        (float)Convert.ToDecimal(modelsNode.Attributes["scalingY"].Value),
                                                                                                        (float)Convert.ToDecimal(modelsNode.Attributes["scalingZ"].Value));
                    myScenes[scn].AddObject(myModels[Convert.ToInt32(modelsNode.Attributes["id"].Value)]);
                    mod++;
                } while ((modelsNode = modelsNode.NextSibling) != null);               
            }
            node = node.NextSibling;
        }
    }

Add an instance of the new object to RCGame (HMGame)
Code:
private RCSceneLoader myLoadedScenes;

And a new function to load the xml file
Code:
        public void LoadScenesFomXML(string XmlFile)
        {
            myLoadedScenes = new RCSceneLoader(XmlFile);
            myScene = myLoadedScenes.myScenes[SelectedScene];
        }

So all I have to do is call the following code from the SetupScene in the EngineDemo
Code:
    game.LoadScenesFomXML("Content/Scenes/TestScene.xml");

I have a few things I will probably change and that is move the lighting for models into the <scene><models><model/> element so you can then have different lighting effects for the same model.
I also have to write the save method to put any changes back to the xml or to just build one from scratch.
I will put some resilience in there to, nothing like users to miss values out or put characters where numbers are expected Smiley
Also you wll notice that some elements are not yet used in my loader, the Scene min/max XYZ and a models rotation, I will probably get on to those things after the new year, come on guys it's Christmas, I need a break too!

Nelson,
What you are doing is probably best but I think that can make the xml hard to edit for a player that just wants to create there own scene or add there own model, I think this way is easier for players to edit and understand.

All,
Please add any ideas you have or if you think I am doing something glaringly stupid, let me know and I will put it right, we are all here to learn from each other after all.
« Last Edit: 2006/12/24 05:17:29 by Nemo Krad » Logged
Pages: [1] 2
  Print  
 
Jump to:  

Related Topics
Subject Started by Replies Views Last post
Hazy Mind Scene Editor Hazy Mind Scene Editor mikeschuld 5 4608 Last post 2006/11/10 23:34:51
by AndroiD
Tutorial 2 :: Scene Graph and Object Framework Tutorial Discussion « 1 2 » mikeschuld 18 10053 Last post 2008/07/31 22:50:22
by mikeschuld
Scene graph Hazy Mind XNA Engine EclipsE 3 1812 Last post 2007/03/13 18:24:26
by mikeschuld
Powered by MySQL Powered by PHP Powered by SMF 1.1.12 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Page created in 0.317 seconds with 19 queries.