public static SceneGraph Deserialize(string XMLString)
        {
            // TODO KAM: Complete the deserialize here (and also in your actions, camera...)
            XElement xe = XElement.Parse(XMLString);

            if (xe.Name != "SceneGraph")
            {
                return(null);
            }
            else
            {
                Vector3     translation = Util.DeserializeVector((xe.Nodes().First((x) => (x as XElement).Name == "Translation") as XElement).FirstNode.ToString());
                Quaternion  rotation    = Util.DeserializeQuaternion((xe.Nodes().First((x) => (x as XElement).Name == "Rotation") as XElement).FirstNode.ToString());
                Vector3     scale       = Util.DeserializeVector((xe.Nodes().First((x) => (x as XElement).Name == "Scaling") as XElement).FirstNode.ToString());
                var         fn          = (xe.Nodes().First((x) => (x as XElement).Name == "Renderable") as XElement).FirstNode;
                IRenderable child       = (fn == null) ? null : RenderableFactory.Deserialize(fn.ToString());

                var tr = new SceneGraph(Matrix.Transformation(Vector3.Zero, Quaternion.Identity, scale, Vector3.Zero, rotation, translation), child);

                // Do all children...
                foreach (var xchild in (xe.Nodes().Where((x) => (x as XElement).Name == "Child")))
                {
                    tr.AttachChild(
                        ((xchild as XElement).Nodes().First((x) => (x as XElement).Name == "Name") as XElement).Value,
                        SceneGraph.Deserialize(((xchild as XElement).Nodes().First((x) => (x as XElement).Name == "SceneGraph") as XElement).ToString())
                        );
                }

                return(tr);
            }
        }
        public void Redo()
        {
            if (_isExecuted)
            {
                throw new InvalidOperationException("Cannot redo an acction that has already been performed!");
            }

            RemovedObject = OutsideSimulatorApp.GetInstance().SceneRootNode.GetDescendant(ObjectName);

            OutsideSimulatorApp.GetInstance().SceneRootNode.RemoveDescendent(ObjectName);

            _isExecuted = true;
        }
        public void Undo()
        {
            if (!_isExecuted)
            {
                throw new InvalidOperationException("Cannot undo an action that has yet to be performed!");
            }

            _isExecuted = false;

            OutsideSimulatorApp.GetInstance().SceneRootNode.AttachChild(ObjectName, RemovedObject);

            RemovedObject = null;
        }
Beispiel #4
0
        public static SceneGraph PickClosestObject(SceneGraph root, Camera Camera, Matrix ProjMatrix, Vector2 ClickPoint, Vector2 ScreenDims)
        {
            // Convert screen pixel to view space
            Vector2 viewSpacePixel = new Vector2((2.0f * ClickPoint.X / ScreenDims.X - 1.0f) / ProjMatrix.M11, (-2.0f * ClickPoint.Y / ScreenDims.Y + 1.0f) / ProjMatrix.M22);
            Ray viewRay = new Ray(new Vector3(), new Vector3(viewSpacePixel.X, viewSpacePixel.Y, 1.0f));

            // View Ray is now the thing we will use...
            Matrix toWorld = Matrix.Invert(Camera.GetViewMatrix());
            viewRay.Direction = Vector3.TransformNormal(viewRay.Direction, toWorld);
            viewRay.Position = Vector3.TransformCoordinate(viewRay.Position, toWorld);

            return pickClosestObject(root, Camera.GetViewMatrix(), viewRay);
        }
 public void RemoveDescendent(SceneGraph ToRemove)
 {
     if (Children.ContainsValue(ToRemove))
     {
         Children.Remove(Children.First((x) => x.Value == ToRemove).Key);
     }
     else
     {
         foreach (var Child in Children)
         {
             Child.Value.RemoveDescendent(ToRemove);
         }
     }
 }
        public static XElement Serialize(SceneGraph SceneGraph)
        {
            var tr = new XElement("SceneGraph",
                                  new XElement("Translation", Util.SerializeVector(SceneGraph.Translation)),
                                  new XElement("Rotation", Util.SerializeQuaternion(SceneGraph.Rotation)),
                                  new XElement("Scaling", Util.SerializeVector(SceneGraph.Scale)),
                                  new XElement("Renderable", RenderableFactory.Serialize(SceneGraph.Renderable))
                                  );

            foreach (var Child in SceneGraph.Children)
            {
                tr.Add(new XElement("Child",
                                    new XElement("Name", Child.Key),
                                    Serialize(Child.Value)
                                    ));
            }

            return(tr);
        }
        public string GetDescendentName(SceneGraph Child)
        {
            if (Children.ContainsValue(Child))
            {
                return(Children.First((x) => x.Value == Child).Key);
            }
            else
            {
                foreach (var Childd in Children)
                {
                    var res = Childd.Value.GetDescendentName(Child);
                    if (res != null)
                    {
                        return(res);
                    }
                }
            }

            return(null);
        }
        /// <summary>
        /// Initialize the scene, that's pretty much it.
        /// </summary>
        public void CreateNewScene(out Camera o_Camera, out SceneGraph o_SceneGraph)
        {
            if (!IsExecuted)
            {
                // Create the scene graph
                SceneGraph = new SceneGraph(SlimDX.Matrix.Identity);
                IsExecuted = true;

                // Attach default terrain
                var TerrainThing = new SceneGraph(
                    SlimDX.Matrix.Transformation(SlimDX.Vector3.Zero, SlimDX.Quaternion.Identity, new SlimDX.Vector3(1.0f, 1.0f, 1.0f), SlimDX.Vector3.Zero, SlimDX.Quaternion.Identity, new SlimDX.Vector3(0.0f, 0.0f, 1.0f))
                );
                TerrainThing.Renderable = new TerrainRenderable(100.0f, 100.0f, 5, 5);

                SceneGraph.AttachChild("TerrainThing", TerrainThing);

                // Attach test object
                var CubeThing = new SceneGraph(
                    SlimDX.Matrix.Transformation(SlimDX.Vector3.Zero, SlimDX.Quaternion.Identity, new SlimDX.Vector3(1.0f, 1.0f, 1.0f), SlimDX.Vector3.Zero, SlimDX.Quaternion.Identity, new SlimDX.Vector3(38.0f, 1.0f, 1.0f))
                );
                CubeThing.Renderable = new TestRenderable();

                SceneGraph.AttachChild("CubeThing", CubeThing);

                // Create default camera
                var testCamera = new FlightCamera(new SlimDX.Vector3(10.0f, 8.0f, 0.0f));
                Camera = testCamera;
            }
            else
            {
                Debug.WriteLine("Already performed action CreateNewScene");
            }

            o_Camera = Camera;
            o_SceneGraph = SceneGraph;
        }
        private TestEffectVertex[] GetAllVertices(SceneGraph Node)
        {
            IEnumerable<TestEffectVertex> returnSet = (Node.Renderable == null) ? new TestEffectVertex[] { } : Node.Renderable.GetVertexList(EffectName()).Cast<TestEffectVertex>();

            foreach (var Child in Node.Children)
            {
                returnSet = returnSet.Concat(GetAllVertices(Child.Value));
            }

            return returnSet.ToArray();
        }
        private uint[] GetAllIndices(SceneGraph Node)
        {
            IEnumerable<uint> returnSet = (Node.Renderable == null) ? new uint[] { } : Node.Renderable.GetIndexList(EffectName()).Cast<uint>();

            foreach (var Child in Node.Children)
            {
                returnSet = returnSet.Concat(GetAllIndices(Child.Value));
            }

            return returnSet.ToArray();
        }
        public void OnMouseDown(MouseEventArgs e)
        {
            if (OutsideSimulatorApp.GetInstance().MainMenu != null &&
                OutsideSimulatorApp.GetInstance().MainMenu.ActiveMenu != null) return;

            if (e.Button == MouseButtons.Left)
                ClickedNode = Picker.PickClosestObject(OutsideSimulatorApp.GetInstance().SceneRootNode, OutsideSimulatorApp.GetInstance().SceneCamera,
                    OutsideSimulatorApp.GetInstance().ProjectionMatrix, new SlimDX.Vector2(e.X, e.Y), new SlimDX.Vector2(
                        OutsideSimulatorApp.GetInstance().Width, OutsideSimulatorApp.GetInstance().Height));
        }
 public void RemoveDescendent(SceneGraph ToRemove)
 {
     if (Children.ContainsValue(ToRemove))
     {
         Children.Remove(Children.First((x) => x.Value == ToRemove).Key);
     }
     else
     {
         foreach (var Child in Children)
         {
             Child.Value.RemoveDescendent(ToRemove);
         }
     }
 }
        public string GetDescendentName(SceneGraph Child)
        {
            if (Children.ContainsValue(Child))
            {
                return Children.First((x) => x.Value == Child).Key;
            }
            else
            {
                foreach (var Childd in Children)
                {
                    var res = Childd.Value.GetDescendentName(Child);
                    if (res != null)
                    {
                        return res;
                    }
                }
            }

            return null;
        }
 public void AttachChild(string Name, SceneGraph Child)
 {
     Children.Add(Name, Child);
     Child.Parent = this;
 }
        public static XElement Serialize(SceneGraph SceneGraph)
        {
            var tr = new XElement("SceneGraph",
                new XElement("Translation", Util.SerializeVector(SceneGraph.Translation)),
                new XElement("Rotation", Util.SerializeQuaternion(SceneGraph.Rotation)),
                new XElement("Scaling", Util.SerializeVector(SceneGraph.Scale)),
                new XElement("Renderable", RenderableFactory.Serialize(SceneGraph.Renderable))
            );

            foreach (var Child in SceneGraph.Children)
            {
                tr.Add(new XElement("Child",
                    new XElement("Name", Child.Key),
                    Serialize(Child.Value)
                ));
            }

            return tr;
        }
        public void Render(SceneGraph SceneGraph, Camera Camera, Matrix ProjMatrix)
        {
            // Set input assembler information...
            ImmediateContext.InputAssembler.InputLayout = InputLayout;
            ImmediateContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

            // Since a menu node is a root node (according to the scene graph),
            //  just draw it without traversing or recursing or any of that mess.
            var vertsList = new List<object>();
            var indicesList = new List<uint>();
            var sets = new List<Tuple<int, int>>();
            vertsList.AddRange(SceneGraph.Renderable.GetVertexList(EffectName()));
            indicesList.AddRange(SceneGraph.Renderable.GetIndexList(EffectName()));
            sets.Add(new Tuple<int, int>(vertsList.Count, indicesList.Count));

            // TODO KAM: Remove this hack.
            if (vertsList.Count == 0)
            {
                return;
            }

            // Render buttons individually, both action and submenu buttons
            var menuButtons = (SceneGraph.Renderable as Menu).MenuButtons;
            for (var i = 0; i < menuButtons.Length; i++)
            {
                vertsList.AddRange(menuButtons[i].GetVertexList(EffectName()));
                indicesList.AddRange(menuButtons[i].GetIndexList(EffectName()));
                sets.Add(new Tuple<int, int>(vertsList.Count, indicesList.Count));
            }

            var vertexBufferDesc = new BufferDescription(MenuEffectVertex.Stride * vertsList.Count,
                ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
            Util.ReleaseCom(ref VertexBuffer); // TODO KAM: Make this dirtyable instead
            VertexBuffer = new SlimDX.Direct3D11.Buffer(Device, new SlimDX.DataStream(vertsList.Cast<MenuEffectVertex>().ToArray(), false, false), vertexBufferDesc);

            var indexBufferDesc = new BufferDescription(
                sizeof(uint) * indicesList.Count,
                ResourceUsage.Default,
                BindFlags.IndexBuffer,
                CpuAccessFlags.None,
                ResourceOptionFlags.None,
                0);
            Util.ReleaseCom(ref IndexBuffer);
            IndexBuffer = new SlimDX.Direct3D11.Buffer(Device, new SlimDX.DataStream(indicesList.ToArray(), false, false), indexBufferDesc);

            // Set buffers
            ImmediateContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(VertexBuffer, MenuEffectVertex.Stride, 0));
            ImmediateContext.InputAssembler.SetIndexBuffer(IndexBuffer, SlimDX.DXGI.Format.R32_UInt, 0);

            Pass = Technique.GetPassByIndex(0);
            CPO_BlendColor.Set(new Vector4(1.0f, 1.0f, 1.0f, 0.8f)); // 80% opacity

            //
            // Set depth stencil state
            //
            var existingState = ImmediateContext.OutputMerger.DepthStencilState;
            ImmediateContext.OutputMerger.DepthStencilState = DepthDisabledState;

            //
            // Render background...
            //
            SRV_DiffuseMap.SetResource(TextureManager.GetInstance().GetResource(Device, SceneGraph.Renderable.GetTexturePath()));
            Pass.Apply(ImmediateContext);
            ImmediateContext.DrawIndexed(sets[0].Item2, 0, 0);

            //
            // Render each button...
            //
            for (var i = 0; i < menuButtons.Length; i++)
            {
                CPO_BlendColor.Set(menuButtons[i].GetBlendColor());
                SRV_DiffuseMap.SetResource(TextureManager.GetInstance().GetResource(Device, menuButtons[i].GetTexturePath()));
                Pass.Apply(ImmediateContext);
                ImmediateContext.DrawIndexed(6, sets[i].Item2, sets[i].Item1);
            }

            //
            // Restore depth stencil state
            //
            ImmediateContext.OutputMerger.DepthStencilState = existingState;
        }
        private void RenderNode(SceneGraph Node, Camera Camera, SlimDX.Matrix ProjMatrix, int indexOffset, int vertexOffset, out int indicesConsumed, out int verticesConsumed)
        {
            var ic = indexOffset;
            var vc = vertexOffset;

            if (Node.Renderable != null)
            {
                WorldViewProj = Node.WorldTransform * Camera.GetViewMatrix() * ProjMatrix;
                CPO_WorldViewProj.SetMatrix(WorldViewProj);

                int nIndices = Node.Renderable.GetIndexList(EffectName()).Length;
                int nVerts = Node.Renderable.GetVertexList(EffectName()).Length;

                // TODO KAM: This is horribly inefficient, change this!
                ImmediateContext.DrawIndexed(nIndices, indexOffset, vertexOffset);

                ic += nIndices;
                vc += nVerts;
            }

            foreach (var Child in Node.Children)
            {
                int cic, cvc;
                RenderNode(Child.Value, Camera, ProjMatrix, indexOffset + ic, vertexOffset + vc, out cic, out cvc);
                ic += cic;
                vc += cvc;
            }

            indicesConsumed = ic;
            verticesConsumed = vc;
        }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="objectName">The name of the node to be deleted, as attached to the master parent node</param>
 public DeleteObject(string objectName, SceneGraph removedObject = null)
 {
     ObjectName = objectName;
     RemovedObject = removedObject;
     _isExecuted = false;
 }
 public void AttachChild(string Name, SceneGraph Child)
 {
     Children.Add(Name, Child);
     Child.Parent = this;
 }
        public void Render(SceneGraph SceneGraph, Camera Camera, SlimDX.Matrix ProjMatrix)
        {
            // Set input assembler information...
            ImmediateContext.InputAssembler.InputLayout = InputLayout;

            // TODO KAM: Shouldn't the primitive topology be set by the objects being rendered themselves?
            ImmediateContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

            // Build our vertex and index buffer...
            var verts = GetAllVertices(SceneGraph);
            var indices = GetAllIndices(SceneGraph);

            var vertBufferDesc = new BufferDescription(TestEffectVertex.Stride * verts.Length,
                ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
            Util.ReleaseCom(ref VertexBuffer); // TODO KAM: Make this dirtyable instead
            VertexBuffer = new SlimDX.Direct3D11.Buffer(Device, new SlimDX.DataStream(verts, true, false), vertBufferDesc);

            var indexBuferDesc = new BufferDescription(
                sizeof(uint) * indices.Length,
                ResourceUsage.Default,
                BindFlags.IndexBuffer,
                CpuAccessFlags.None,
                ResourceOptionFlags.None,
                0
            );
            Util.ReleaseCom(ref IndexBuffer);
            IndexBuffer = new SlimDX.Direct3D11.Buffer(Device, new SlimDX.DataStream(indices, false, false), indexBuferDesc);

            // Set our vertex and index buffers
            ImmediateContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(VertexBuffer, TestEffectVertex.Stride, 0));
            ImmediateContext.InputAssembler.SetIndexBuffer(IndexBuffer, SlimDX.DXGI.Format.R32_UInt, 0);

            // Go through, render all nodes
            var renderPass = EffectTechnique.GetPassByIndex(0);
            renderPass.Apply(ImmediateContext);
            int a, b;
            RenderNode(SceneGraph, Camera, ProjMatrix, 0, 0, out a, out b);
        }
        public static SceneGraph Deserialize(string XMLString)
        {
            // TODO KAM: Complete the deserialize here (and also in your actions, camera...)
            XElement xe = XElement.Parse(XMLString);

            if (xe.Name != "SceneGraph")
            {
                return null;
            }
            else
            {
                Vector3 translation = Util.DeserializeVector((xe.Nodes().First((x) => (x as XElement).Name == "Translation") as XElement).FirstNode.ToString());
                Quaternion rotation = Util.DeserializeQuaternion((xe.Nodes().First((x) => (x as XElement).Name == "Rotation") as XElement).FirstNode.ToString());
                Vector3 scale = Util.DeserializeVector((xe.Nodes().First((x) => (x as XElement).Name == "Scaling") as XElement).FirstNode.ToString());
                var fn = (xe.Nodes().First((x) => (x as XElement).Name == "Renderable") as XElement).FirstNode;
                IRenderable child = (fn == null) ? null : RenderableFactory.Deserialize(fn.ToString());

                var tr = new SceneGraph(Matrix.Transformation(Vector3.Zero, Quaternion.Identity, scale, Vector3.Zero, rotation, translation), child);

                // Do all children...
                foreach (var xchild in (xe.Nodes().Where((x) => (x as XElement).Name == "Child")))
                {
                    tr.AttachChild(
                        ((xchild as XElement).Nodes().First((x) => (x as XElement).Name == "Name") as XElement).Value,
                        SceneGraph.Deserialize(((xchild as XElement).Nodes().First((x) => (x as XElement).Name == "SceneGraph") as XElement).ToString())
                    );
                }

                return tr;
            }
        }
Beispiel #22
0
        private static SceneGraph pickClosestObject(SceneGraph Root, Matrix ViewProj, Ray ViewRay2)
        {
            // TODO KAM: This totally isn't working.
            // (1) If the node we're looking at may be picked, select it
            //var toWorld = Matrix.Invert(Camera.GetViewMatrix() * ProjMatrix);

            //viewRay = new Ray(Vector3.TransformCoordinate(viewRay.Position, toWorld), Vector3.TransformNormal(viewRay.Direction, toWorld));
            //viewRay.Direction.Normalize();

            var invWorld = Matrix.Invert(Root.WorldTransform);
            var oVR2 = new Ray(ViewRay2.Position, ViewRay2.Direction);
            oVR2.Direction = Vector3.TransformNormal(oVR2.Direction, invWorld);
            oVR2.Position = Vector3.TransformCoordinate(oVR2.Position, invWorld);
            oVR2.Direction.Normalize();

            var boundingBox = Root.GetBoundingBox();
            float dist;
            if (boundingBox != null) boundingBox = (Ray.Intersects(oVR2, boundingBox.Value, out dist)) ? boundingBox : null;
            var element = (boundingBox == null) ? null : Root;

            // (2) Find all children picked
            foreach (var child in Root.Children)
            {
                BoundingBox? childbox;
                var childret = pickClosestObject(child.Value, ViewProj, ViewRay2);
                if (childret == null)
                {
                    childbox = null;
                }
                else
                {
                    childbox = childret.GetBoundingBox();
                }

                if (boundingBox == null)
                {
                    boundingBox = childbox;
                    element = childret;
                }
                else if (childbox != null)
                {
                    float currDist, otherDist;
                    Ray.Intersects(oVR2, boundingBox.Value, out currDist);

                    var oVR3 = new Ray(ViewRay2.Position, ViewRay2.Direction);
                    var cInvWorld = Matrix.Invert(childret.WorldTransform);
                    oVR3.Direction = Vector3.TransformNormal(oVR3.Direction, cInvWorld);
                    oVR3.Position = Vector3.TransformCoordinate(oVR3.Position, cInvWorld);

                    Ray.Intersects(oVR3, childbox.Value, out otherDist);

                    // (3) Take the smallest of the list and return it
                    if (otherDist < currDist)
                    {
                        boundingBox = childbox;
                        element = child.Value;
                    }
                }
            }

            return element;
        }
        /// <summary>
        /// Creates the default scene
        /// </summary>
        public void CreateNewScene()
        {
            //
            // Create Startup Scene
            //
            SceneGraph = new SceneGraph(SlimDX.Matrix.Identity);
            SceneGraph.AttachChild("Menu", new SceneGraph(SlimDX.Matrix.Identity));
            SceneGraph.Children["Menu"].Renderable = Builders.MenuFactory.BuildMainMenu();

            Unsubscribe(Camera);

            SceneGraph defaultScene;
            NewSceneCreator = new CreateNewDefaultScene();
            NewSceneCreator.CreateNewScene(out Camera, out defaultScene);
            SceneGraph.AttachChild("Scene", defaultScene);
        }