I don't understand why did you make your scene graph complicated and so long, here's mine solution and it works ok:
#region NSceneNode class
/// <summary>
/// It's a simple node
/// </summary>
public class NSceneNode
{
#region Variables
#region Object
private NObject theObject;
public NObject Object { get { return theObject; } }
#endregion
#endregion
#region Constructor( objectToAdd )
/// <summary>
/// Constructor
/// </summary>
/// <param name="objectToAdd">The object to add</param>
public NSceneNode(NObject objectToAdd)
{
theObject = objectToAdd;
}
#endregion
}
#endregion
#region NScene class
/// <summary>
/// The scene that contains all the nodes
/// </summary>
public class NScene
{
#region Collection of nodes
private Collection<NSceneNode> sceneNodeCollection = new Collection<NSceneNode>();
#endregion
#region Render( device )
/// <summary>
/// Renders all the objects
/// </summary>
/// <param name="device">The device</param>
public void Render(GraphicsDevice device)
{
//Go through each object in the scene
foreach (NSceneNode obj in sceneNodeCollection)
{
if (obj.Object is NIRenderable) //If it's a renderable object, render it
{
((NIRenderable)obj.Object).Render(device);
}
if (obj.Object is NIModel)
{
((NIModel)obj.Object).RenderModel(device);
}
}
}
#endregion
#region AddObject( objectToAdd )
/// <summary>
/// Adds a object to the scene
/// </summary>
/// <param name="objectToAdd">The object to add</param>
public void AddObject(NObject objectToAdd)
{
NSceneNode newNode = new NSceneNode(objectToAdd);
sceneNodeCollection.Add(newNode);
}
#endregion
#region ClearScene()
public void ClearScene()
{
sceneNodeCollection.Clear();
}
#endregion
#region LoadGraphicContent( device, loader )
/// <summary>
/// Loads all the content
/// </summary>
/// <param name="device">The device</param>
/// <param name="loader">The content loader</param>
public void LoadGraphicContent(GraphicsDevice device, NContentManager loader)
{
//Go through each object in the scene
foreach (NSceneNode node in sceneNodeCollection)
{
if (node.Object is NILoadable) //If it's a renderable object, render it
{
((NILoadable)node.Object).LoadGraphicContent(device, loader);
}
}
}
#endregion
}
#endregion
Also, I think you should use regions often in your code to make it easier to read. And about the Octree, I really think you should remove it and find a better way for culling... What if a object moves its position and goes into another node?? Really complicated...