XNA Game Development Forums
2012/05/18 07:08:21 *
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: XNA Scene Editor  (Read 11529 times)
Iterion
Newbie
*
Offline Offline

Posts: 3


View Profile
« on: 2007/03/26 21:27:58 »

I was trying to figure out the best way to implement the engine code written with the XNA framework into a scene editor.  Is it even possible?  Would it be better to just start from scratch with a less powerful engine using MDX?

What do you think?

EDIT:  I have since found an article,  It's german but is easily translated by google.  Anyway it can be found here: http://translate.google.com/translate?u=http%3A%2F%2Fblogs.msdn.com%2Frogerboesch%2Farchive%2F2007%2F01%2F20%2Ftipp-xna-in-eigene-applikationen-einbinden-winforms.aspx&langpair=de%7Cen&hl=en&ie=UTF-8&oe=UTF-8&prev=%2Flanguage_tools
« Last Edit: 2007/03/28 11:31:57 by Iterion » Logged
h4rdc0m
Jr. Member
**
Offline Offline

Posts: 63


View Profile WWW
« Reply #1 on: 2007/04/06 03:39:01 »

I know tha both Nemo and I have a simple form of scene editor, by coupling a separate winform to the demo project. However I haven't made the editor so it can save scenes yet.

However it should be quite trivial to add save funtionality, write the scenegraph off in an XML file.
 
Logged
Nemo Krad
Global Moderator
Hero Member
*****
Offline Offline

Posts: 512


I have seen the fnords


View Profile WWW
« Reply #2 on: 2007/04/06 04:54:59 »

This has been discussed before I think. I wrote a SceneLoader that could load and unload the scene object to and from an XML file. Anther suggestion, and one that would require less coding would be to have the objects serializable and dump them to XML that way.
Logged
alexmbra
Newbie
*
Offline Offline

Posts: 2


View Profile
« Reply #3 on: 2007/04/23 19:58:29 »

I would like to see a tutorial about this also. Not everyone are capable of doing those thing alone, at least yet. There are lots of people here learning.
Logged
XNASorcerer
Newbie
*
Offline Offline

Posts: 25



View Profile
« Reply #4 on: 2007/04/24 18:35:01 »

I second that.
Logged
Nemo Krad
Global Moderator
Hero Member
*****
Offline Offline

Posts: 512


I have seen the fnords


View Profile WWW
« Reply #5 on: 2007/04/25 03:10:59 »

Here is a good start: http://www.ziggyware.com/readarticle.php?article_id=85
Logged
XNASorcerer
Newbie
*
Offline Offline

Posts: 25



View Profile
« Reply #6 on: 2007/04/25 11:12:19 »


Thanks, but some of us really need a tutorial with example of a simple scene editor able to load( pressing a button or using drag and drop) and save positions of models, working with XNA. For example, I just start to use C# recently and without the help with you guys, I won't be able to do anything like this. And probably, there are lots of people like me.
Logged
precious roy
Newbie
*
Offline Offline

Posts: 36


View Profile
« Reply #7 on: 2007/04/25 12:44:36 »

isent xna for xbox360 Huh?
Logged
XNASorcerer
Newbie
*
Offline Offline

Posts: 25



View Profile
« Reply #8 on: 2007/04/25 12:46:39 »

isent xna for xbox360 Huh?

Huh ?
Logged
precious roy
Newbie
*
Offline Offline

Posts: 36


View Profile
« Reply #9 on: 2007/04/25 12:50:15 »

i thot that xna only on the xbox 360 worked  but a quik wiki seach proovd me wrong   

i was going to say (if your game is only going to work on xbox why would you make an Scene Editor )

but never mind
« Last Edit: 2007/04/25 12:52:41 by precious roy » Logged
Nemo Krad
Global Moderator
Hero Member
*****
Offline Offline

Posts: 512


I have seen the fnords


View Profile WWW
« Reply #10 on: 2007/04/26 05:47:07 »

I think this would be a big tut and probably best reserved for Mike to do, unless there is another willing tut writer out there. I would make a start on it but time it tight at the moment sorry.

What you could do is look at the ray picking code and the XML serialization above and come up with your own stuff.
Logged
XNASorcerer
Newbie
*
Offline Offline

Posts: 25



View Profile
« Reply #11 on: 2007/04/26 10:12:13 »

I think this would be a big tut and probably best reserved for Mike to do, unless there is another willing tut writer out there. I would make a start on it but time it tight at the moment sorry.

What you could do is look at the ray picking code and the XML serialization above and come up with your own stuff.

Whenever you have time, would be good.  :Smiley  Wink

thanks
Logged
digicate
Newbie
*
Offline Offline

Posts: 1


View Profile
« Reply #12 on: 2007/06/21 02:53:48 »

Hi,

Using the code from this site http://blogs.msdn.com/rogerboesch/archive/2007/01/20/tipp-xna-in-eigene-applikationen-einbinden-winforms.aspx Thanks to Roger Boesch! I have been able to create a sample application that can be a starting point for an XNA Scene Editor. I read the tutorials for the Hazy Mind Scene Editor and realised that they were tied to the Hazy Mind 3D Engine, which is written in Managed DirectX. I really wanted to stick with XNA, so I hacked together the following code. In the spirit of this community, I offer my work in the hope somebody else will find it helpful.

The following may go without saying on this site, but just in case... DISCLAIMER: As the code is mostly the work of Roger Boesch and Michael Schuld, full credit should go to them. In regard to any editing that I have done to bring the code together, I disclaim any responsibility for any damage or loss that you suffer from the use of this code. USE AT YOUR OWN RISK.

Code:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using System.Windows.Forms;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using HMEngine.HMOctrees;
using HMEngine.HMShaders;
using HMEngine.HMCameras;
using HMEngine.HMScene;

namespace HMEngine
{
    // This class mostly copied from http://blogs.msdn.com/rogerboesch/archive/2007/01/20/tipp-xna-in-eigene-applikationen-einbinden-winforms.aspx
    // Partially refactored in line with the naming convention of the HMEngine http://www.thehazymind.com/
    class HMGraphicsDeviceService : IGraphicsDeviceService, IGraphicsDeviceManager
    {
        private GraphicsDevice m_graphicsDevice;
        private Control m_renderControl;

        public HMGraphicsDeviceService(Control control)
        {
            this.m_renderControl = control;
        }

        #region IGraphicsDeviceService Members

        public event EventHandler DeviceCreated;
        public event EventHandler DeviceDisposing;
        public event EventHandler DeviceReset;
        public event EventHandler DeviceResetting;

        public GraphicsDevice GraphicsDevice
        {
            get { return this.m_graphicsDevice; }
        }

        #endregion

        #region IGraphicsDeviceManager Members

        public bool BeginDraw()
        {
            return false;
        }

        public void CreateDevice()
        {
            PresentationParameters pp = new PresentationParameters();
            pp.IsFullScreen = false;
            pp.BackBufferCount = 1;
            pp.BackBufferHeight = this.m_renderControl.Height;
            pp.BackBufferWidth = this.m_renderControl.Width;

            this.m_graphicsDevice = new GraphicsDevice(GraphicsAdapter.Adapters[0], DeviceType.Hardware,
                                                       this.m_renderControl.Handle, CreateOptions.SoftwareVertexProcessing, pp);
        }

        public void EndDraw()
        {
        }
        #endregion
    }


    public class HMGameView : HMPanel, IServiceProvider
    {
        private HMGraphicsDeviceService m_graphicsDeviceService;
        // Roger Boesch omitted this line from his sample code
        private ContentManager m_contentManager;
        // Reference to our scene graph for setting up our scene
        private HMSceneGraph myScene;
        public HMSceneGraph Scene { get { return myScene; } }

        public void InitializeGraphics()
        {
            // Credit to Roger Boesch
            this.m_graphicsDeviceService = new HMGraphicsDeviceService(this);
            this.m_graphicsDeviceService.CreateDevice();
            this.m_contentManager = new ContentManager(this);

            // Credit to Michael Schuld
            // Load Shader Graphics
            HMShaderManager.LoadGraphicsContent(m_graphicsDeviceService.GraphicsDevice, m_contentManager);
            // Load Scene Graphics (models)
            myScene.SceneRoot.LoadGraphicsContent(m_graphicsDeviceService.GraphicsDevice, m_contentManager);
            // Load octree graphics
            HMOctreeManager.LoadGraphicsContent(m_graphicsDeviceService.GraphicsDevice);
            // Create the default camera
            HMCamera defaultCamera = new HMCamera(m_graphicsDeviceService.GraphicsDevice.Viewport);
            HMCameraManager.AddCamera(defaultCamera, "default");
            HMCameraManager.SetActiveCamera("default");
            // Credit to Roger Boesch
            // Initialise the timer
            Timer timer = new Timer();
            timer.Tick += new EventHandler(TimerHandler);
            timer.Interval = 100;
            timer.Start();
        }

        // Added so that the scene graph could be initialised prior to setting up the models
        public void Initialize()
        {
            // Initialise the scene graph
            myScene = new HMSceneGraph();
            // Initialise Shader - will give us a BasicEffect to use for lines in the Octree
            HMShaderManager.Initialize();
        }

        void TimerHandler(object sender, EventArgs e)
        {
            // Draw all object currently in the screen graph / octree
            // When the same scene is drawn by the runtime engine, there may be other effects applied additionally. e.g. PostProcessing
            m_graphicsDeviceService.GraphicsDevice.Clear(Color.CornflowerBlue);
            HMOctreeManager.OctRoot.Draw(m_graphicsDeviceService.GraphicsDevice);
            // Present() is required because our object is derived from Control (I think)
            // instead of Microsoft.Xna.Framework.Game
            // Comment out the next line and the gameview will be undrawn (contain background garbage)
            m_graphicsDeviceService.GraphicsDevice.Present();
            // Roger Boesch's code simply said RenderLoop();
        }


        #region IServiceProvider Members

        public new object GetService(Type serviceType)
        {
            if (serviceType == typeof(Microsoft.Xna.Framework.Graphics.IGraphicsDeviceService))
            {
                return this.m_graphicsDeviceService;
            }
            else
            {
                return base.GetService(serviceType);
            }
        }

        #endregion

    }

    // Roger Boesch's code omitted this class, fortunately Michael Schuld's code from his Hazy Mind Scene Editor was suitable to use
    public class HMPanel : Panel
    {
        public HMPanel()
        {
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
        }
    }
}

The key here is that you are basically replacing/removing your HMGame class for this application and reusing the other classes that have been developed.

So, HMGame is for game type applications (windowed or fullscreen) and HMGameView is for windows forms applications that also require a 3d rendered surface as part of the user interface, for example, a scene editor.

I had a hard time getting the timing right between the Initialize() call and the InitializeGraphics() call. My runtime was raising a lot NullReferenceExceptions because it was trying to draw an object or use an effect before it had been loaded. I believe I have resolved this in the code I am about to show.

Using HMGameView in an Application

The following notes are basically the steps followed by Michael Schuld in his Hazy Mind Scene Editor. Please read his tutoriall also in case I have glossed over or missed a step.

Add a new Windows Game to your HMEngine solution.

Rename Program.cs to HMSceneEditor.cs and Form1.cs to HMSceneEditorForm.cs. Refactor your project.

Open the visual editor for HMSceneEditorForm and drop an instance of HMGameView onto the surface.

View code on HMSceneEditorForm and add the following code after the call to InitializeComponent();
Code:
           
// After InitializeComponent()
// Initialize the game view
hmGameView1.Initialize();

Open up HMSceneEditor.cs and look for your Main() function.

Make your function something like this:

Code:
        // The Hazy Mind XNA Engine tutorial omit's this attribute but I do not know why
        [STAThread]             
        public static void Main()
        {
            // Create your form
            HMSceneEditorForm editor = new HMSceneEditorForm();
            // Put some objects in the scene
            SetupScene(editor.GameView.Scene);
            // Load the graphics setup in the scene
            editor.GameView.InitializeGraphics();
            // Start the message loop and show the form
            Application.Run(editor);
        }

If you have been following the XNA Engine tutorials on this site, you probably have your own SetupScene function already. Notice that I am passing in my HMSceneManager member from the GameView class. This is different from the code in the HMDemo.cs, I don't think it really matters, whatever suits your application.

My SetupScene loads 100 teapots and randomly distributes them throughout the Octree. This is just for testing at this stage, as the purpose of the scene editor is to actually have some control over object placement. However, in the long run you might want to load some objects in setup scene that are helpful to the user, e.g. a grid showing the axes of the coordinate system.

Once you have setup your scene, you must call InitializeGraphics() from the HMGameView class to actually load the objects into the content pipeline for later rendering by the timer. (The Hazy Mind Scene Editor returns a boolean from the InitializeGraphics call to indicate success prior to drawing the form. I will leave that as an exercise for the reader).

This is my SetupScene that I use for testing:

Code:
        private static void SetupScene(HMSceneGraph scene)
        {
            HMShader shader = new HMShader(@"Content/Shaders/BasicShader");
            HMShaderManager.AddShader(shader, "BS");
            // Enable drawing octrees (demo/debugging use only)
            HMOctreeManager.DrawOctnodes = true;
           
            HMModel[] models = new HMModel[100];

            int i = 0;
            for (i = 0; i < models.Length; i++)
            {
                models[i] = new HMModel(@"Content/Models/teapot");
                models[i].SetShader("BS");
            }
            float offset = 100.0f / 2.0f;
            Random r = new Random();
            float scale = 1.0f;
            for (i = 0; i < models.Length; i++)
            {
                // Move the model to a position within the bounds of the octree
                models[i].Position = new Vector3(r.Next(Convert.ToInt32(-offset), Convert.ToInt32(offset)),
                    r.Next(Convert.ToInt32(-offset), Convert.ToInt32(offset)),
                    r.Next(Convert.ToInt32(-offset), Convert.ToInt32(offset)));
                // Make the object up to 4 times bigger
                scale = r.Next(1, 5);
                models[i].Scaling = new Vector3(scale, scale, scale);
                scene.AddObject(models[i]);
                HMOctreeManager.OctRoot.AddObject(models[i]);
            }             
        }

Note that an object must be added both to HMSceneGraph and to the OctRoot. This code could possibly be restructured, so that calling OctRoot.AddObject automatically added the object to the scene also. I am just learning this engine, so there could be undesired effects of doing that. If you forget to call both, you will get a NullReferenceException when you call HMOctreeManager.OctRoot.Draw(m_graphicsDeviceService.GraphicsDevice);

I think that is about it. Read Michael's tutorials on the Hazy Mind Scene Editor http://www.thehazymind.com/SceneEditor.htm for some instructions on handling user input e.g. mouse movement.

As this is my first post, I must say what a huge help this community has been for me with learning XNA development. There are many websites out there that are cut and paste articles from other sites, generally poor information. Also, many books I read do not reach the quality of information that I have read here. Keep up the good work!
Logged
mikeschuld
Administrator
Sr. Member
*****
Offline Offline

Posts: 389


View Profile WWW
« Reply #13 on: 2007/08/03 12:08:57 »

The XNA version of the Scene Editor will come sooner or later on the website as well. Looks like you've got a pretty good starting point there.

plans  for my version include:
  • built in shader editor
  • GUI designer
  • model loading/unloading/texturing (picking bump/light maps etc.)

and a whole mess of other features I can't remember off the top of my head (and I'm away from my desktop atm)
Logged
Mike2
Newbie
*
Offline Offline

Posts: 16


View Profile
« Reply #14 on: 2007/08/23 13:12:34 »

hey guys,

I was looking for a while for a decent winform implement and this is my little "hack", anyone knows how to hack the GameTime-thingie?  Cool  Cool Cool

Code:
namespace Engine.Device_handeling
{
    public partial class IceGameForm : Form
    {
        private ContentManager content;
        public ContentManager ContentManager { get { return content; } }

        protected GraphicsDevice myGraphicsDevice;

        private Control myRenderControl;
        public Control IceControl { get { return myRenderControl; } set { myRenderControl = value; } }
       
        private IcePostProcessor myPostProcessor;
        public IcePostProcessor PostProcessor { get { return myPostProcessor; } }
                       
        protected GameTime gameTime;
        private DateTime oldTime, currentTime, startTime;
        private TimeSpan delta;
        private bool done = false;

        private const float timeStep = 1000f / 60f; // 60 fps update
        private float nextUpdate = 0;

        private bool isFixedTimeStep = false;


        public IceGameForm()
        {
        }

        protected virtual void Initialize()
        {
            FormClosing += new FormClosingEventHandler(ShutDown);

            startTime = currentTime = DateTime.Now;
            gameTime = new GameTime();

            if (myRenderControl == null)
                throw new Exception("No Control to render to");
           
            CreateDevice();
            content = new ContentManager(new GraphicsDeviceService(myGraphicsDevice));

            myPostProcessor = new IcePostProcessor();
        }

        public void CreateDevice()
        {
            PresentationParameters pp = new PresentationParameters();
            pp.IsFullScreen = false;
            pp.BackBufferCount = 1;
            pp.BackBufferHeight = myRenderControl.Height;
            pp.BackBufferWidth = myRenderControl.Width;

            myGraphicsDevice = new GraphicsDevice(
                GraphicsAdapter.Adapters[0],
                DeviceType.Hardware,
                myRenderControl.Handle,
                CreateOptions.HardwareVertexProcessing,
                pp);
        }

        protected void ShutDown(object sender, FormClosingEventArgs e)
        {
            done = true;
            e.Cancel = true;
        }

        protected virtual void LoadGraphicsContent(bool loadAllContent)
        {
            if (loadAllContent)
            {

            }
            myPostProcessor.LoadGraphicsContent(myGraphicsDevice, content);
            IceShaderManager.LoadGraphicsContent(content);
        }

        protected virtual void UnLoadGraphicsContent(bool unloadAllContent)
        {
            if (unloadAllContent)
            {
                content.Unload();
            }
        }

        public virtual void Update(GameTime gametime)
        {
        }

        public virtual void Draw(GameTime gametime)
        {
            if (myPostProcessor.Effect != null)
            {
                myPostProcessor.PreRender(myGraphicsDevice);
            }

            //Do your rendering over here...

            if (myPostProcessor.Effect != null)
            {
                myPostProcessor.PostRender(myGraphicsDevice);
            }

            myGraphicsDevice.Present();
        }

        private void ResizeWindow(object sender, EventArgs e)
        {
            if (myRenderControl.Width < 1 || myRenderControl.Height < 1)
                return;

            myGraphicsDevice.PresentationParameters.BackBufferWidth = myRenderControl.Width;
            myGraphicsDevice.PresentationParameters.BackBufferHeight = myRenderControl.Height;

            myGraphicsDevice.Reset();
        }

        private void UpdateGameTime()
        {
        }

        public void Run()
        {
            Initialize();

            LoadGraphicsContent(true);

            while (!done)
            {
                oldTime = currentTime;

                currentTime = DateTime.Now;
                delta = currentTime - oldTime;

                if (isFixedTimeStep)
                {
                    if (gameTime.ElapsedRealTime.TotalMilliseconds > nextUpdate)
                    {
                        Update(gameTime);
                    }

                }
                else
                {
                    Update(gameTime);
                }
                Draw(gameTime);
                Application.DoEvents();
            }
            UnLoadGraphicsContent(true);

            Close();           
        }
    }

    #region GraphicsDeviceService
    public class GraphicsDeviceService : IGraphicsDeviceService, IServiceProvider
    {
        private GraphicsDevice graphicsDevice = null;


        public GraphicsDeviceService(GraphicsDevice GraphicsDevice)
        {
            graphicsDevice = GraphicsDevice;
        }
        public GraphicsDevice GraphicsDevice
        {
            get { return graphicsDevice; }
        }

        public event EventHandler DeviceCreated;
        public event EventHandler DeviceDisposing;
        public event EventHandler DeviceReset;
        public event EventHandler DeviceResetting;
        public event EventHandler<PreparingDeviceSettingsEventArgs> PreparingDeviceSettings;

        public Object GetService(System.Type ServiceType)
        {
            if (ServiceType == typeof(IGraphicsDeviceService))
                return this;
            else
                throw new ArgumentException(); ;
        }
    }
    #endregion
}

and in my editor I do:

Code:
   public partial class Editor : IceGameForm
    {
        public Editor()
        {
            InitializeComponent();
        }

        protected override void Initialize()
        {
            IceControl = this.splitContainer1.Panel1;
            base.Initialize();

            SetupScene();
        }

        public override void Draw(Microsoft.Xna.Framework.GameTime gametime)
        {
            myGraphicsDevice.Clear(Color.CornflowerBlue);
            base.Draw(gametime);
        }

        private void SetupScene()
        {
        }
    }

does anyone see a point to change/runit better... plss don't say delete and start over, did a while to get to this point   Grin

greetz!!!
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 4604 Last post 2006/11/10 23:34:51
by AndroiD
Saving scene Hazy Mind Scene Editor Requests « 1 2 » Hunefalk 27 11610 Last post 2011/04/30 10:06:26
by gunther6616
Tutorial 2 :: Scene Graph and Object Framework Tutorial Discussion « 1 2 » mikeschuld 18 10042 Last post 2008/07/31 22:50:22
by mikeschuld
How can i edit in science editor General Discussion satsatsat 1 1621 Last post 2006/10/15 20:54:37
by mikeschuld
Crytek Engine 2 level editor General Discussion Cdy7e 7 2651 Last post 2007/03/15 18:55:36
by Chr0n1x
Scene graph Hazy Mind XNA Engine EclipsE 3 1812 Last post 2007/03/13 18:24:26
by mikeschuld
XNA Animation Component Library in XNA HMEngine Hazy Mind XNA Engine dotslash 0 2617 Last post 2007/05/31 13:53:12
by dotslash
Physics simulation: BulletX (Bullet for XNA) physics and Hazy Mind Xna Engine Hazy Mind XNA Engine Yubastard 6 5549 Last post 2007/08/12 08:57:21
by Yubastard
XNA Editor Load while already running Hazy Mind Scene Editor Mike2 11 4747 Last post 2007/08/22 16:10:32
by muchrejoicing
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.335 seconds with 19 queries.