Browse Source

first commit with everything

Ronen 8 years ago
parent
commit
2ff7a031b8

+ 252 - 0
.gitignore

@@ -0,0 +1,252 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml

+ 22 - 0
MonoGameSceneGraph.sln

@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoGameSceneGraph", "MonoGameSceneGraph\MonoGameSceneGraph.csproj", "{235539D2-2263-48F3-9DE4-70AE5E335E07}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x86 = Debug|x86
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{235539D2-2263-48F3-9DE4-70AE5E335E07}.Debug|x86.ActiveCfg = Debug|x86
+		{235539D2-2263-48F3-9DE4-70AE5E335E07}.Debug|x86.Build.0 = Debug|x86
+		{235539D2-2263-48F3-9DE4-70AE5E335E07}.Release|x86.ActiveCfg = Release|x86
+		{235539D2-2263-48F3-9DE4-70AE5E335E07}.Release|x86.Build.0 = Release|x86
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 21 - 0
MonoGameSceneGraph/Content/Content.mgcb

@@ -0,0 +1,21 @@
+
+#----------------------------- Global Properties ----------------------------#
+
+/outputDir:bin/$(Platform)
+/intermediateDir:obj/$(Platform)
+/platform:DesktopGL
+/config:
+/profile:Reach
+/compress:False
+
+#-------------------------------- References --------------------------------#
+
+
+#---------------------------------- Content ---------------------------------#
+
+#begin robot.xnb
+/copy:robot.xnb
+
+#begin robottexture_0.xnb
+/copy:robottexture_0.xnb
+

BIN
MonoGameSceneGraph/Content/robot.xnb


BIN
MonoGameSceneGraph/Content/robottexture_0.xnb


+ 121 - 0
MonoGameSceneGraph/Game1.cs

@@ -0,0 +1,121 @@
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+
+namespace MonoGameSceneGraph
+{
+    /// <summary>
+    /// This is the main type for your game.
+    /// </summary>
+    public class Game1 : Game
+    {
+        // graphics manager
+        GraphicsDeviceManager graphics;
+
+        // sprite batch (for 2d drawings)
+        SpriteBatch spriteBatch;
+
+        // create test nodes and a model to draw
+        Node root;
+        Node node;
+        Node nodeContainer;
+        Node nodeContainerContainer;
+        ModelEntity entity;
+
+        /// <summary>
+        /// Init game.
+        /// </summary>
+        public Game1()
+        {
+            graphics = new GraphicsDeviceManager(this);
+            Content.RootDirectory = "Content";
+        }
+
+        /// <summary>
+        /// Allows the game to perform any initialization it needs to before starting to run.
+        /// This is where it can query for any required services and load any non-graphic
+        /// related content.  Calling base.Initialize will enumerate through any components
+        /// and initialize them as well.
+        /// </summary>
+        protected override void Initialize()
+        {
+            // TODO: Add your initialization logic here
+
+            base.Initialize();
+        }
+
+        /// <summary>
+        /// LoadContent will be called once per game and is the place to load
+        /// all of your content.
+        /// </summary>
+        protected override void LoadContent()
+        {
+            // Create a new SpriteBatch, which can be used to draw textures.
+            spriteBatch = new SpriteBatch(GraphicsDevice);
+
+            // create nodes
+            root = new Node();
+            nodeContainerContainer = new Node();
+            nodeContainer = new Node();
+            node = new Node();
+
+            // arrange them in hirerchy
+            root.AddChildNode(nodeContainerContainer);
+            nodeContainerContainer.AddChildNode(nodeContainer);
+            nodeContainer.AddChildNode(node);
+
+            // create entity and attach to bottom node
+            entity = new ModelEntity(Content.Load<Model>("robot"));
+            node.AddEntity(entity);
+        }
+
+        /// <summary>
+        /// UnloadContent will be called once per game and is the place to unload
+        /// game-specific content.
+        /// </summary>
+        protected override void UnloadContent()
+        {
+            // TODO: Unload any non ContentManager content here
+        }
+
+        /// <summary>
+        /// Allows the game to run logic such as updating the world,
+        /// checking for collisions, gathering input, and playing audio.
+        /// </summary>
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>
+        protected override void Update(GameTime gameTime)
+        {
+            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
+                Exit();
+
+            // TODO: Add your update logic here
+
+            base.Update(gameTime);
+        }
+
+        /// <summary>
+        /// This is called when the game should draw itself.
+        /// </summary>
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>
+        protected override void Draw(GameTime gameTime)
+        {
+            // clear screen
+            GraphicsDevice.Clear(Color.CornflowerBlue);
+
+            // draw scene
+            root.Draw();
+
+            // rotate inner node on X axis
+            node.RotationZ = node.RotationZ + 0.01f;
+
+            // scale node container
+            nodeContainer.ScaleZ = (1.0f + (float)System.Math.Cos(gameTime.TotalGameTime.TotalSeconds * 2f) / 4f);
+
+            // move top node left and right
+            nodeContainerContainer.PositionX = (float)System.Math.Sin(gameTime.TotalGameTime.TotalSeconds) * 4f;
+
+            // call base draw
+            base.Draw(gameTime);
+        }
+    }
+}

BIN
MonoGameSceneGraph/Help/Documentation.chm


BIN
MonoGameSceneGraph/Icon.ico


+ 87 - 0
MonoGameSceneGraph/MonoGameSceneGraph.csproj

@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\MonoGame\v3.0\MonoGame.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\MonoGame\v3.0\MonoGame.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{235539D2-2263-48F3-9DE4-70AE5E335E07}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>MonoGameSceneGraph</RootNamespace>
+    <AssemblyName>MonoGameSceneGraph</AssemblyName>
+    <FileAlignment>512</FileAlignment>
+    <MonoGamePlatform>DesktopGL</MonoGamePlatform>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\$(MonoGamePlatform)\$(Platform)\$(Configuration)\</OutputPath>
+    <DefineConstants>DEBUG;TRACE;LINUX</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\DesktopGL\x86\Debug\MonoGameSceneGraph.XML</DocumentationFile>
+    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\$(MonoGamePlatform)\$(Platform)\$(Configuration)\</OutputPath>
+    <DefineConstants>TRACE;LINUX</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\DesktopGL\x86\Release\MonoGameSceneGraph.XML</DocumentationFile>
+    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+  </PropertyGroup>
+  <PropertyGroup>
+    <ApplicationIcon>Icon.ico</ApplicationIcon>
+  </PropertyGroup>
+  <PropertyGroup>
+    <StartupObject />
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="Game1.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Source\Entities\ModelEntity.cs" />
+    <Compile Include="Source\Entities\IEntity.cs" />
+    <Compile Include="Source\Node.cs" />
+    <Compile Include="Source\Transformations.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="OpenTK">
+      <HintPath>$(MonoGameInstallDirectory)\MonoGame\v3.0\Assemblies\DesktopGL\OpenTK.dll</HintPath>
+    </Reference>
+    <Reference Include="NVorbis">
+      <HintPath>$(MonoGameInstallDirectory)\MonoGame\v3.0\Assemblies\DesktopGL\NVorbis.dll</HintPath>
+    </Reference>
+    <Reference Include="MonoGame.Framework">
+      <HintPath>$(MonoGameInstallDirectory)\MonoGame\v3.0\Assemblies\DesktopGL\MonoGame.Framework.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Icon.ico" />
+    <Content Include="OpenTK.dll.config">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+  <ItemGroup>
+    <MonoGameContentReference Include="Content\Content.mgcb" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(MSBuildExtensionsPath)\MonoGame\v3.0\MonoGame.Content.Builder.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>

+ 25 - 0
MonoGameSceneGraph/OpenTK.dll.config

@@ -0,0 +1,25 @@
+<configuration>
+  <dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/>
+  <dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/>
+  <dllmap os="linux" dll="openal32.dll" target="libopenal.so.1"/>
+  <dllmap os="linux" dll="alut.dll" target="libalut.so.0"/>
+  <dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/>
+  <dllmap os="linux" dll="libX11" target="libX11.so.6"/>
+  <dllmap os="linux" dll="libXi" target="libXi.so.6"/>
+  <dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0.disabled"/>
+  <dllmap os="osx" dll="opengl32.dll" target="/System/Library/Frameworks/OpenGL.framework/OpenGL"/>
+  <dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
+  <dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
+  <dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
+  <dllmap os="osx" dll="libGLESv1_CM.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
+  <dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
+  <dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/>
+  <dllmap os="osx" dll="SDL2.dll" target="libSDL2.dylib"/>
+  <!-- XQuartz compatibility (X11 on Mac) -->
+  <dllmap os="osx" dll="libGL.so.1" target="/usr/X11/lib/libGL.dylib"/>
+  <dllmap os="osx" dll="libX11" target="/usr/X11/lib/libX11.dylib"/>
+  <dllmap os="osx" dll="libXcursor.so.1" target="/usr/X11/lib/libXcursor.dylib"/>
+  <dllmap os="osx" dll="libXi" target="/usr/X11/lib/libXi.dylib"/>
+  <dllmap os="osx" dll="libXinerama" target="/usr/X11/lib/libXinerama.dylib"/>
+  <dllmap os="osx" dll="libXrandr.so.2" target="/usr/X11/lib/libXrandr.dylib"/>
+</configuration>

+ 20 - 0
MonoGameSceneGraph/Program.cs

@@ -0,0 +1,20 @@
+using System;
+
+namespace MonoGameSceneGraph
+{
+    /// <summary>
+    /// The main class.
+    /// </summary>
+    public static class Program
+    {
+        /// <summary>
+        /// The main entry point for the application.
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            using (var game = new Game1())
+                game.Run();
+        }
+    }
+}

+ 36 - 0
MonoGameSceneGraph/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("MonoGameNodes")]
+[assembly: AssemblyProduct("MonoGameNodes")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyCopyright("Copyright ©  2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("0db17934-d933-4db3-ac0b-af3e6298e5d9")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 31 - 0
MonoGameSceneGraph/Source/Entities/IEntity.cs

@@ -0,0 +1,31 @@
+#region File Description
+//-----------------------------------------------------------------------------
+// An entity is the basic renderable entity, eg something you can draw.
+// Entities don't have transformations of their own; instead, you put them inside
+// nodes which handle matrices and transformations for them.
+//
+// Author: Ronen Ness.
+// Since: 2017.
+//-----------------------------------------------------------------------------
+#endregion
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using System.Collections.Generic;
+
+
+namespace MonoGameSceneGraph
+{
+    /// <summary>
+    /// A basic renderable entity.
+    /// </summary>
+    public interface IEntity
+    {
+        /// <summary>
+        /// Draw this entity.
+        /// </summary>
+        /// <param name="parent">Parent node that's currently drawing this entity.</param>
+        /// <param name="localTransformations">Local transformations from the direct parent node.</param>
+        /// <param name="worldTransformations">World transformations to apply on this entity (this is what you should use to draw this entity).</param>
+        void Draw(Node parent, Matrix localTransformations, Matrix worldTransformations);
+    }
+}

+ 114 - 0
MonoGameSceneGraph/Source/Entities/ModelEntity.cs

@@ -0,0 +1,114 @@
+#region File Description
+//-----------------------------------------------------------------------------
+// A basic renderable model.
+//
+// Author: Ronen Ness.
+// Since: 2017.
+//-----------------------------------------------------------------------------
+#endregion
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using System.Collections.Generic;
+
+
+namespace MonoGameSceneGraph
+{
+    /// <summary>
+    /// A basic renderable model.
+    /// Note: this object is more of an example of how to create a renderable entity, you will probably
+    /// need to implement something more sophisticated on your own.
+    /// </summary>
+    public class ModelEntity : IEntity
+    {
+        /// <summary>
+        /// The model to render.
+        /// </summary>
+        public Model Model;
+
+        /// <summary>
+        /// Projection matrix to use with model.
+        /// </summary>
+        public Matrix Projection;
+
+        /// <summary>
+        /// View matrix to use with model.
+        /// </summary>
+        public Matrix View;
+
+        /// <summary>
+        /// Enable / disable default lighting on model.
+        /// </summary>
+        public bool EnableLighting = true;
+
+        /// <summary>
+        /// Create the model entity.
+        /// </summary>
+        /// <param name="model">Model to draw.</param>
+        public ModelEntity(Model model)
+        {
+            // store model
+            Model = model;
+
+            // Create default Projection matrix (viewport)
+            float aspectRatio = 1f;
+            float fieldOfView = Microsoft.Xna.Framework.MathHelper.PiOver4;
+            float nearClipPlane = 1;
+            float farClipPlane = 200;
+            Projection = Matrix.CreatePerspectiveFieldOfView(
+                    fieldOfView, aspectRatio, nearClipPlane, farClipPlane);
+
+            // Create default View matrix (camera)
+            var cameraPosition = new Vector3(0, 20, 0);
+            var cameraLookAtVector = Vector3.Zero;
+            var cameraUpVector = Vector3.UnitZ;
+            View = Matrix.CreateLookAt(cameraPosition, cameraLookAtVector, cameraUpVector);
+        }
+
+        /// <summary>
+        /// Draw this model.
+        /// </summary>
+        /// <param name="parent">Parent node that's currently drawing this entity.</param>
+        /// <param name="localTransformations">Local transformations from the direct parent node.</param>
+        /// <param name="worldTransformations">World transformations to apply on this entity (this is what you should use to draw this entity).</param>
+        public void Draw(Node parent, Matrix localTransformations, Matrix worldTransformations)
+        {
+            // A model is composed of "Meshes" which are
+            // parts of the model which can be positioned
+            // independently, which can use different textures,
+            // and which can have different rendering states
+            // such as lighting applied.
+            foreach (var mesh in Model.Meshes)
+            {
+                // "Effect" refers to a shader. Each mesh may
+                // have multiple shaders applied to it for more
+                // advanced visuals. 
+                foreach (BasicEffect effect in mesh.Effects)
+                {
+                    // enable lights
+                    if (EnableLighting)
+                    {
+                        // set default lightings
+                        effect.EnableDefaultLighting();
+
+                        // This makes lighting look more realistic on
+                        // round surfaces, but at a slight performance cost:
+                        effect.PreferPerPixelLighting = true;
+                    }
+
+                    // set world matrix
+                    effect.World = worldTransformations;
+
+                    // set view matrix
+                    effect.View = View;
+
+                    // set projection matrix
+                    effect.Projection = Projection;
+                }
+
+                // Now that we've assigned our properties on the effects we can
+                // draw the entire mesh
+                mesh.Draw();
+            }
+        }
+    }
+}

+ 413 - 0
MonoGameSceneGraph/Source/Node.cs

@@ -0,0 +1,413 @@
+#region File Description
+//-----------------------------------------------------------------------------
+// A node is the basic container in the scene graph. Its basically a point in
+// transformations that can contain child nodes (and inherit transformations), 
+// and contain renderable entities to draw inside.
+//
+// Author: Ronen Ness.
+// Since: 2017.
+//-----------------------------------------------------------------------------
+#endregion
+using Microsoft.Xna.Framework;
+using System.Collections.Generic;
+
+namespace MonoGameSceneGraph
+{
+    /// <summary>
+    /// MonoGameSceneGraph is the main namespace that contains all the MonoGame-SceneGraph entities.
+    /// </summary>
+    [System.Runtime.CompilerServices.CompilerGenerated]
+    class NamespaceDoc
+    {
+    }
+
+    /// <summary>
+    /// A node with transformations, you can attach renderable entities to it, or append
+    /// child nodes to inherit transformations.
+    /// </summary>
+    public class Node
+    {
+        /// <summary>
+        /// Parent node.
+        /// </summary>
+        protected Node _parent = null;
+
+        /// <summary>
+        /// Node's transformations.
+        /// </summary>
+        protected Transformations _transformations = new Transformations();
+
+        /// <summary>
+        /// Is this node currently visible?
+        /// </summary>
+        public bool IsVisible = true;
+
+        /// <summary>
+        /// Optional identifier we can give to nodes.
+        /// </summary>
+        public string Identifier;
+
+        /// <summary>
+        /// Optional user data we can attach to nodes.
+        /// </summary>
+        public object UserData;
+
+        /// <summary>
+        /// The order in which we apply transformations when building the matrix for this node.
+        /// </summary>
+        protected TransformOrder _transformationsOrder = TransformOrder.ScaleRotationPosition;
+
+        /// <summary>
+        /// The order in which we apply rotation when building the matrix for this node.
+        /// </summary>
+        protected RotationOrder _rotationOrder = RotationOrder.RotateYXZ;
+
+        /// <summary>
+        /// Local transformations matrix, eg the result of the current local transformations.
+        /// </summary>
+        protected Matrix _localTransform = Matrix.Identity;
+
+        /// <summary>
+        /// World transformations matrix, eg the result of the local transformations multiplied with parent transformations.
+        /// </summary>
+        protected Matrix _worldTransform = Matrix.Identity;
+
+        /// <summary>
+        /// Child nodes under this node.
+        /// </summary>
+        protected List<Node> _childNodes = new List<Node>();
+
+        /// <summary>
+        /// Child entities under this node.
+        /// </summary>
+        protected List<IEntity> _childEntities = new List<IEntity>();
+
+        /// <summary>
+        /// Turns true when the transformations of this node changes.
+        /// </summary>
+        protected bool _isDirty = true;
+
+        /// <summary>
+        /// This number increment every time we update transformations.
+        /// We use it to check if our parent's transformations had been changed since last
+        /// time this node was rendered, and if so, we re-apply parent updated transformations.
+        /// </summary>
+        protected uint _transformVersion = 0;
+
+        /// <summary>
+        /// The last transformations version we got from our parent.
+        /// </summary>
+        protected uint _parentLastTransformVersion = 0;
+
+        /// <summary>
+        /// Get parent node.
+        /// </summary>
+        public Node Parent { get { return _parent; } }
+
+        /// <summary>
+        /// Draw the node and its children.
+        /// </summary>
+        public virtual void Draw()
+        {
+            // not visible? skip
+            if (!IsVisible)
+            {
+                return;
+            }
+
+            // update transformations (only if needed, testing logic is inside)
+            UpdateTransformations();
+
+            // draw all child nodes
+            foreach (Node node in _childNodes)
+            {
+                node.Draw();
+            }
+
+            // draw all child entities
+            foreach (IEntity entity in _childEntities)
+            {
+                entity.Draw(this, _localTransform, _worldTransform);
+            }
+        }
+
+        /// <summary>
+        /// Add an entity to this node.
+        /// </summary>
+        /// <param name="entity">Entity to add.</param>
+        public void AddEntity(IEntity entity)
+        {
+            _childEntities.Add(entity);
+        }
+
+        /// <summary>
+        /// Remove an entity from this node.
+        /// </summary>
+        /// <param name="entity">Entity to add.</param>
+        public void RemoveEntity(IEntity entity)
+        {
+            _childEntities.Remove(entity);
+        }
+
+        /// <summary>
+        /// Add a child node to this node.
+        /// </summary>
+        /// <param name="node">Node to add.</param>
+        public void AddChildNode(Node node)
+        {
+            // node already got a parent?
+            if (node._parent != null)
+            {
+                throw new System.Exception("Can't add a node that already have a parent.");
+            }
+
+            // add node to children list
+            _childNodes.Add(node);
+
+            // set self as node's parent, and make sure it will update world transformations next draw call
+            node._parent = this;
+            node._parentLastTransformVersion = _transformVersion - 1;
+        }
+
+        /// <summary>
+        /// Remove a child node from this node.
+        /// </summary>
+        /// <param name="node">Node to add.</param>
+        public void RemoveChildNode(Node node)
+        {
+            // make sure the node is a child of this node
+            if (node._parent != this)
+            {
+                throw new System.Exception("Can't remove a node that don't belong to this parent.");
+            }
+
+            // remove node from children list
+            _childNodes.Remove(node);
+
+            // clear node parent pointer and set parent transformations to 1, to make sure it will recalc world transform next draw
+            node._parent = null;
+            node._parentLastTransformVersion = 1;
+        }
+
+        /// <summary>
+        /// Remove this node from its parent.
+        /// </summary>
+        public void RemoveFromParent()
+        {
+            // don't have a parent?
+            if (_parent == null)
+            {
+                throw new System.Exception("Can't remove an orphan node from parent.");
+            }
+
+            // remove from parent
+            _parent.RemoveChildNode(this);
+        }
+
+        /// <summary>
+        /// Set this node as "dirty", eg that we need to update local transformations.
+        /// </summary>
+        protected void OnWorldMatrixChange()
+        {
+            _isDirty = true;
+        }
+
+        /// <summary>
+        /// Calc final transformations for current frame.
+        /// This uses an indicator to know if an update is needed, so no harm is done if you call it multiple times.
+        /// </summary>
+        protected void UpdateTransformations()
+        {
+            // if local transformations are dirty, we need to update them
+            if (_isDirty)
+            {
+                _localTransform = _transformations.BuildMatrix(_transformationsOrder, _rotationOrder);
+                _transformVersion++;
+            }
+            
+            // if local transformations are dirty, or parent transformations are out-of-date, update global transformations
+            if (_isDirty || 
+                (_parent != null && _parentLastTransformVersion != _parent._transformVersion) |
+                (_parent == null && _parentLastTransformVersion != 0))
+            {
+                // if we got parent, apply its transformations
+                if (_parent != null)
+                {
+                    _worldTransform = _localTransform * _parent._worldTransform;
+                    _parentLastTransformVersion = _parent._transformVersion;
+                }
+                // if not, world transformations are the same as local, and reset parent last transformations version
+                else
+                {
+                    _worldTransform = _localTransform;
+                    _parentLastTransformVersion = 0;
+                }
+            }
+
+            // no longer dirty
+            _isDirty = false;
+        }
+
+        /// <summary>
+        /// Return local transformations matrix (note: will recalculate if needed).
+        /// </summary>
+        public Matrix LocalTransformations
+        {
+            get { UpdateTransformations(); return _localTransform; }
+        }
+
+        /// <summary>
+        /// Return world transformations matrix (note: will recalculate if needed).
+        /// </summary>
+        public Matrix WorldTransformations
+        {
+            get { UpdateTransformations(); return _worldTransform; }
+        }
+
+        /// <summary>
+        /// Reset all local transformations.
+        /// </summary>
+        public void ResetTransformations()
+        {
+            _transformations = new Transformations();
+            OnWorldMatrixChange();
+        }
+
+        /// <summary>
+        /// Get / Set the order in which we apply local transformations in this node.
+        /// </summary>
+        public TransformOrder TransformationsOrder
+        {
+            get { return _transformationsOrder; }
+            set { _transformationsOrder = value;  OnWorldMatrixChange(); }
+        }
+
+        /// <summary>
+        /// Get / Set the order in which we apply local rotation in this node.
+        /// </summary>
+        public RotationOrder RotationOrder
+        {
+            get { return _rotationOrder; }
+            set { _rotationOrder = value; OnWorldMatrixChange(); }
+        }
+
+        /// <summary>
+        /// Get / Set node local position.
+        /// </summary>
+        public Vector3 Position
+        {
+            get { return _transformations.Position; }
+            set { _transformations.Position = value; OnWorldMatrixChange(); }
+        }
+
+        /// <summary>
+        /// Get / Set node local scale.
+        /// </summary>
+        public Vector3 Scale
+        {
+            get { return _transformations.Scale; }
+            set { _transformations.Scale = value; OnWorldMatrixChange(); }
+        }
+
+        /// <summary>
+        /// Get / Set node local rotation.
+        /// </summary>
+        public Vector3 Rotation
+        {
+            get { return _transformations.Rotation; }
+            set { _transformations.Rotation = value; OnWorldMatrixChange(); }
+        }
+
+        /// <summary>
+        /// Alias to access rotation X directly.
+        /// </summary>
+        public float RotationX
+        {
+            get { return _transformations.Rotation.X; }
+            set { _transformations.Rotation.X = value; OnWorldMatrixChange(); }
+        }
+
+        /// <summary>
+        /// Alias to access rotation Y directly.
+        /// </summary>
+        public float RotationY
+        {
+            get { return _transformations.Rotation.Y; }
+            set { _transformations.Rotation.Y = value; OnWorldMatrixChange(); }
+        }
+
+        /// <summary>
+        /// Alias to access rotation Z directly.
+        /// </summary>
+        public float RotationZ
+        {
+            get { return _transformations.Rotation.Z; }
+            set { _transformations.Rotation.Z = value; OnWorldMatrixChange(); }
+        }
+
+        /// <summary>
+        /// Alias to access scale X directly.
+        /// </summary>
+        public float ScaleX
+        {
+            get { return _transformations.Scale.X; }
+            set { _transformations.Scale.X = value; OnWorldMatrixChange(); }
+        }
+
+        /// <summary>
+        /// Alias to access scale Y directly.
+        /// </summary>
+        public float ScaleY
+        {
+            get { return _transformations.Scale.Y; }
+            set { _transformations.Scale.Y = value; OnWorldMatrixChange(); }
+        }
+
+        /// <summary>
+        /// Alias to access scale Z directly.
+        /// </summary>
+        public float ScaleZ
+        {
+            get { return _transformations.Scale.Z; }
+            set { _transformations.Scale.Z = value; OnWorldMatrixChange(); }
+        }
+
+
+        /// <summary>
+        /// Alias to access position X directly.
+        /// </summary>
+        public float PositionX
+        {
+            get { return _transformations.Position.X; }
+            set { _transformations.Position.X = value; OnWorldMatrixChange(); }
+        }
+
+        /// <summary>
+        /// Alias to access position Y directly.
+        /// </summary>
+        public float PositionY
+        {
+            get { return _transformations.Position.Y; }
+            set { _transformations.Position.Y = value; OnWorldMatrixChange(); }
+        }
+
+        /// <summary>
+        /// Alias to access position Z directly.
+        /// </summary>
+        public float PositionZ
+        {
+            get { return _transformations.Position.Z; }
+            set { _transformations.Position.Z = value; OnWorldMatrixChange(); }
+        }
+
+        /// <summary>
+        /// Move position by vector.
+        /// </summary>
+        /// <param name="moveBy">Vector to translate by.</param>
+        public void Translate(Vector3 moveBy)
+        {
+            _transformations.Position += moveBy;
+            OnWorldMatrixChange();
+        }
+    }
+}

+ 200 - 0
MonoGameSceneGraph/Source/Transformations.cs

@@ -0,0 +1,200 @@
+#region File Description
+//-----------------------------------------------------------------------------
+// A class containing all the basic transformations a renderable object can have.
+// This include: Translation, Rotation, and Scale.
+//
+// Author: Ronen Ness.
+// Since: 2017.
+//-----------------------------------------------------------------------------
+#endregion
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace MonoGameSceneGraph
+{
+    /// <summary>
+    /// Different way to build matrix from transformations.
+    /// </summary>
+    public enum TransformOrder
+    {
+        /// <summary>
+        /// Apply position, then rotation, then scale.
+        /// </summary>
+        PositionRotationScale,
+
+        /// <summary>
+        /// Apply position, then scale, then rotation.
+        /// </summary>
+        PositionScaleRotation,
+
+        /// <summary>
+        /// Apply scale, then position, then rotation.
+        /// </summary>
+        ScalePositionRotation,
+
+        /// <summary>
+        /// Apply scale, then rotation, then position.
+        /// </summary>
+        ScaleRotationPosition,
+
+        /// <summary>
+        /// Apply rotation, then scale, then position.
+        /// </summary>
+        RotationScalePosition,
+
+        /// <summary>
+        /// Apply rotation, then position, then scale.
+        /// </summary>
+        RotationPositionScale,
+    }
+
+    /// <summary>
+    /// Different ways to apply rotation (order in which we rotate the different axis).
+    /// </summary>
+    public enum RotationOrder
+    {
+        /// <summary>
+        /// Rotate by axis order X, Y, Z.
+        /// </summary>
+        RotateXYZ,
+
+        /// <summary>
+        /// Rotate by axis order X, Z, Y.
+        /// </summary>
+        RotateXZY,
+
+        /// <summary>
+        /// Rotate by axis order Y, X, Z.
+        /// </summary>
+        RotateYXZ,
+
+        /// <summary>
+        /// Rotate by axis order Y, Z, X.
+        /// </summary>
+        RotateYZX,
+
+        /// <summary>
+        /// Rotate by axis order Z, X, Y.
+        /// </summary>
+        RotateZXY,
+
+        /// <summary>
+        /// Rotate by axis order Z, Y, X.
+        /// </summary>
+        RotateZYX,
+    }
+
+    /// <summary>
+    /// Contain all the possible node transformations.
+    /// </summary>
+    public class Transformations
+    {
+
+        /// <summary>
+        /// Node position / translation.
+        /// </summary>
+        public Vector3 Position;
+
+        /// <summary>
+        /// Node rotation.
+        /// </summary>
+        public Vector3 Rotation;
+
+        /// <summary>
+        /// Node scale.
+        /// </summary>
+        public Vector3 Scale;
+
+        /// <summary>
+        /// Create new default transformations.
+        /// </summary>
+        public Transformations()
+        {
+            Position = Vector3.Zero;
+            Rotation = Vector3.Zero;
+            Scale = Vector3.One;
+        }
+
+        /// <summary>
+        /// Clone transformations.
+        /// </summary>
+        public Transformations(Transformations other)
+        {
+            Position = other.Position;
+            Rotation = other.Rotation;
+            Scale = other.Scale;
+        }
+
+        /// <summary>
+        /// Build and return just the rotation matrix for this treansformations.
+        /// </summary>
+        /// <param name="rotationOrder">In which order to apply rotation (axis order) when applying rotation.</param>
+        /// <returns></returns>
+        public Matrix BuildRotationMatrix(RotationOrder rotationOrder = RotationOrder.RotateYXZ)
+        {
+            switch (rotationOrder)
+            {
+                case RotationOrder.RotateXYZ:
+                    return Matrix.CreateRotationX(Rotation.X) * Matrix.CreateRotationY(Rotation.Y) * Matrix.CreateRotationZ(Rotation.Z);
+
+                case RotationOrder.RotateXZY:
+                    return Matrix.CreateRotationX(Rotation.X) * Matrix.CreateRotationZ(Rotation.Z) * Matrix.CreateRotationY(Rotation.Y);
+
+                case RotationOrder.RotateYXZ:
+                    return Matrix.CreateFromYawPitchRoll(Rotation.Y, Rotation.X, Rotation.Z);
+
+                case RotationOrder.RotateYZX:
+                    return Matrix.CreateRotationY(Rotation.Y) * Matrix.CreateRotationZ(Rotation.Z) * Matrix.CreateRotationX(Rotation.X);
+
+                case RotationOrder.RotateZXY:
+                    return Matrix.CreateRotationZ(Rotation.Z) * Matrix.CreateRotationX(Rotation.X) * Matrix.CreateRotationY(Rotation.Y);
+
+                case RotationOrder.RotateZYX:
+                    return Matrix.CreateRotationZ(Rotation.Z) * Matrix.CreateRotationY(Rotation.Y) * Matrix.CreateRotationX(Rotation.X);
+
+                default:
+                    throw new System.Exception("Unknown rotation order!");
+            }
+        }
+
+        /// <summary>
+        /// Build and return a matrix from current transformations.
+        /// </summary>
+        /// <param name="transformOrder">In which order to apply transformations to produce final matrix.</param>
+        /// <param name="rotationOrder">In which order to apply rotation (axis order) when applying rotation.</param>
+        /// <returns>Matrix with all transformations applied.</returns>
+        public Matrix BuildMatrix(TransformOrder transformOrder = TransformOrder.ScaleRotationPosition, 
+            RotationOrder rotationOrder = RotationOrder.RotateYXZ)
+        {
+            // create the matrix parts
+            Matrix pos = Matrix.CreateTranslation(Position);
+            Matrix rot = BuildRotationMatrix(rotationOrder);
+            Matrix scale = Matrix.CreateScale(Scale);
+
+            // build and return matrix based on order
+            switch (transformOrder)
+            {
+                case TransformOrder.PositionRotationScale:
+                    return pos * rot * scale;
+
+                case TransformOrder.PositionScaleRotation:
+                    return pos * scale * rot;
+
+                case TransformOrder.ScalePositionRotation:
+                    return scale * pos * rot;
+
+                case TransformOrder.ScaleRotationPosition:
+                    return scale * rot * pos;
+
+                case TransformOrder.RotationScalePosition:
+                    return rot * scale * pos;
+
+                case TransformOrder.RotationPositionScale:
+                    return rot * pos * scale;
+
+                default:
+                    throw new System.Exception("Unknown build matrix order!");
+            }
+        }
+    }
+}

+ 60 - 0
MonoGameSceneGraph/docs-generator.shfbproj

@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <!-- The configuration and platform will be used to determine which assemblies to include from solution and
+				 project documentation sources -->
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{d3a470e0-aa21-4f38-a8c0-194f4adddfc2}</ProjectGuid>
+    <SHFBSchemaVersion>2015.6.5.0</SHFBSchemaVersion>
+    <!-- AssemblyName, Name, and RootNamespace are not used by SHFB but Visual Studio adds them anyway -->
+    <AssemblyName>Documentation</AssemblyName>
+    <RootNamespace>Documentation</RootNamespace>
+    <Name>Documentation</Name>
+    <!-- SHFB properties -->
+    <FrameworkVersion>.NET Framework 4.5</FrameworkVersion>
+    <OutputPath>.\Help\</OutputPath>
+    <HtmlHelpName>Documentation</HtmlHelpName>
+    <Language>en-US</Language>
+    <DocumentationSources>
+      <DocumentationSource sourceFile="bin\DesktopGL\x86\Debug\MonoGameSceneGraph.XML" />
+<DocumentationSource sourceFile="bin\DesktopGL\x86\Debug\MonoGameSceneGraph.dll" /></DocumentationSources>
+    <ApiFilter>
+      <Filter entryType="Namespace" fullName="MonoGameSceneGraph" isExposed="True" xmlns="">
+  <Filter entryType="Class" fullName="MonoGameSceneGraph.Game1" filterName="Game1" isExposed="False" />
+  <Filter entryType="Class" fullName="MonoGameSceneGraph.Program" filterName="Program" isExposed="False" />
+</Filter>
+    </ApiFilter>
+    <VisibleItems>InheritedMembers, InheritedFrameworkMembers, Protected, ProtectedInternalAsProtected</VisibleItems>
+  </PropertyGroup>
+  <!-- There are no properties for these groups.  AnyCPU needs to appear in order for Visual Studio to perform
+			 the build.  The others are optional common platform types that may appear. -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Win32' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Win32' ">
+  </PropertyGroup>
+  <!-- Import the SHFB build targets -->
+  <Import Project="$(SHFBROOT)\SandcastleHelpFileBuilder.targets" />
+  <!-- The pre-build and post-build event properties must appear *after* the targets file import in order to be
+			 evaluated correctly. -->
+  <PropertyGroup>
+    <PreBuildEvent>
+    </PreBuildEvent>
+    <PostBuildEvent>
+    </PostBuildEvent>
+    <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+  </PropertyGroup>
+</Project>

+ 22 - 0
MonoSprites.nuspec

@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
+  <metadata>
+	<id>MonoGame.SceneGraph</id>
+	<version>1.0.0.0</version>
+	<authors>Ronen Ness</authors>
+	<owners>RonenNess</owners>
+	<licenseUrl>https://en.wikipedia.org/wiki/MIT_License</licenseUrl>
+	<projectUrl>https://github.com/RonenNess/MonoGame-SceneGraph</projectUrl>
+	<iconUrl>https://raw.githubusercontent.com/RonenNess/MonoGame-SceneGraph/master/icon.png</iconUrl>
+	<requireLicenseAcceptance>false</requireLicenseAcceptance>
+	<releaseNotes>Stable version with nodes, transformations, and basic model entity.</releaseNotes>
+	<description>Basic scene graph (node-based transformations) for 3D MonoGame projects.</description>
+	<tags>monogame scene graph gamedev nodes 3d animations</tags>
+	<dependencies>
+	</dependencies>
+  </metadata>
+  <files>
+	<file src="readme.txt" target="" />
+	<file src="MonoGameSceneGraph\bin\DesktopGL\x86\Release\MonoGameSceneGraph.dll" target="lib\ronenness\MonoGameSceneGraph.dll"/>
+  </files>
+</package>

+ 174 - 0
README.md

@@ -0,0 +1,174 @@
+# MonoGame-SceneGraph
+Simple Nodes &amp; Entities for scene graphs in MonoGame.
+
+## What is it
+This mini-lib implements basic node and transformations to allow easy implementation of scene graphs.
+
+### But what's a scene graph?
+
+From [Wikipedia](https://en.wikipedia.org/wiki/Scene_graph):
+
+A scene graph is a collection of nodes in a graph or tree structure. A tree node (in the overall tree structure of the scene graph) may have many children but often only a single parent, with the effect of a parent applied to all its child nodes; an operation performed on a group automatically propagates its effect to all of its members. In many programs, associating a geometrical transformation matrix (see also transformation and matrix) at each group level and concatenating such matrices together is an efficient and natural way to process such operations. A common feature, for instance, is the ability to group related shapes/objects into a compound object that can then be moved, transformed, selected, etc. as easily as a single object.
+
+Scene graphs are useful for modern games using 3D graphics and increasingly large worlds or levels. In such applications, nodes in a scene graph (generally) represent entities or objects in the scene.
+For instance, a game might define a logical relationship between a knight and a horse so that the knight is considered an extension to the horse. The scene graph would have a 'horse' node with a 'knight' node attached to it.
+As well as describing the logical relationship, the scene graph may also describe the spatial relationship of the various entities: the knight moves through 3D space as the horse moves.
+
+## Live example
+To see a live example, open and execute the solution in this repo (make sure to build as ```Application``` and not ```Class Library```).
+
+## Using MonoGame-SceneGraph
+
+### Install
+
+To install the lib you can use NuGet:
+
+```
+Install-Package MonoGame.SceneGraph
+```
+
+Or instead you can manually copy the source files from ```MonoGameSceneGraph/Source/``` into your project.
+
+### Main objects
+This lib contains 4 main classes you should know:
+
+#### Node
+A basic scene node with transformation. To build your scene create nodes and child-nodes and set their transformations.
+
+Note: a Node does not have a graphic representation, eg it does not render anything. A node only handles the hierarchy and transformation and hold entities that render stuff.
+
+#### Entity
+An entity is a renderable object you attach to nodes. For example, the most basic Entity is a ModelEntity, which renders a 3D model loaded by the content manager.
+
+Remember: Entities handle rendering, Nodes handle transformations.
+
+#### ModelEntity
+A basic Entity that renders a 3D model. 
+
+Note: This entity uses the default MG effect, so you'll most likely want to impelement your own Model Entity to draw models with your own custom effects and camera. This class is just an example / reference.
+
+#### Transformations
+A set of transformations that a Node can have + helper functions to build a matrix.
+Normally you don't need to use this class, it is used internally by the Nodes.
+
+### How to use
+
+As mentioned before, the most basic component of the scene graph is the Node.
+To create a new node:
+
+```cs
+MonoGameSceneGraph.Node node = new MonoGameSceneGraph.Node();
+```
+
+Now that we have a node we can apply different transformations on it. For example:
+
+```cs
+// set node position
+node.Position = new Vector3(10, 0, 0);
+
+// rotate node on X axis
+node.RotationX = 0.2f;
+
+// scale node
+node.Scale = Vector3.One * 2f;
+
+// etc etc. see Node api for more options..
+```
+
+Or, we can start adding child nodes to it in order to build our scene:
+
+```cs
+MonoGameSceneGraph.Node childNode = new MonoGameSceneGraph.Node();
+node.AddChildNode(childNode);
+```
+
+Now the transformations of the parent node will also apply the child node. But on top of that, the child node can have its own local transformations:
+
+```cs
+// set local position to (0, 10, 0).
+// note: since our parent position is (10, 0, 0), our final position would be (10, 10, 0).
+childNode.Position = new Vector3(0, 10, 0);
+```
+
+But what about actual rendering? As mentioned before nodes don't really handle rendering, they only handle transformations. To start drawing stuff we need to add entities to them, like the built-in ModelEntity:
+
+```cs
+// create a basic ModelEntity with a 'robot' model, and add to our child node from before.
+MonoGameSceneGraph.entity = new MonoGameSceneGraph.ModelEntity(Content.Load<Model>("robot"));
+childNode.AddEntity(entity);
+```
+
+And now that we have a scene with an entity, we can draw our scene:
+
+```cs
+// this should go inside the game Draw() function, after clearing the device buffers.
+node.Draw();
+```
+
+If you used to code above properly (and have a robot model) you should now be able to see it on the screen.
+If it doesn't work check out the sample code in ```Game1.cs```.
+
+#### Creating Your Entities
+
+The built-in ```ModelEntity``` is designed to be a reference and not really used in projects. It only renders static models with built-in lighting and constant camera. Clearly you need more than that.
+
+In order to make your own renderable entities, inherit from the ```IEntity``` interface, and implement its ```Draw()``` function:
+
+```cs
+/// <summary>
+/// Custom entity class for your game.
+/// </summary>
+public class MyEntityType : IEntity
+{
+	/// <summary>
+	/// Draw this model.
+	/// </summary>
+	/// <param name="parent">Parent node that's currently drawing this entity.</param>
+	/// <param name="localTransformations">Local transformations from the direct parent node.</param>
+	/// <param name="worldTransformations">World transformations to apply on this entity (this is what you should use to draw this entity).</param>
+	public void Draw(Node parent, Matrix localTransformations, Matrix worldTransformations)
+	{
+		// your drawing comes here..
+	}
+}
+```
+
+As you can see from the code above, when an entity is drawn you get 3 paramets: the parent node that's currently drawing it (an entity can be attached to multiple nodes), parent node's local transformations, and node's final world transformations, as calculated by the graph.
+
+Using these params you should be able to draw everything you need. The rendering logic and type of entities is up to you.
+
+#### Caching
+
+Calculating transformations every frame can be heavy on CPU.
+
+Because of that, MonoGame-SceneGraph Nodes only recalculate transformations when something changes (or when their parent node was changed).
+This means that when using Nodes you should avoid changing stuff for the same value. For example, consider the following code:
+
+```cs
+// 'player' is a Node holding the player's graphics. 
+// 'currSpeed' is a vector that's either 0 when standing still, or contain the value of the current player movement direction.
+// `Translate()` is just a sugarcoat for `node.Position = node.Position + vector`.
+player.Translate(currSpeed)
+```
+
+As you can see above, currSpeed can either be zero, or a movement vector when player is moving. However, because we set ```player.Position``` every frame, regardless of the value of ```currSpeed```, this means the ```player``` node will recalculate its matrix every single frame.
+
+To avoid this unnecessary overhead, the code can be simply modified into this:
+
+```cs
+// 'player' is a Node holding the player's graphics. 
+// 'currSpeed' is a vector that's either 0 when standing still, or contain the value of the current player movement direction.
+if (currSpeed.Length() > 0)
+{
+	player.Translate(currSpeed)
+}
+```
+
+And now the ```player``` node will only calculate its matrix when really needed.
+
+#### Further Reading
+
+In this doc we didn't cover much of the API, only the very basics needed to get you going. To learn more, please see the doc file in ```Help/Documentation.chm```, or check out the code documentation (mostly ```Node.cs```).
+
+## Lisence
+MonoGame-SceneGraph is distributed with the permissive MIT License. For more info, check out the ```LICENSE``` file in this repo.

BIN
icon.png


+ 4 - 0
readme.txt

@@ -0,0 +1,4 @@
+Thank you for using MonoGame.SceneGraph!
+To see a quick usage guide check out the repo readme:
+
+https://github.com/RonenNess/MonoGame-SceneGraph/blob/master/README.md