/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */


#ifndef	__OCTREE_RENDERABLE__
#define	__OCTREE_RENDERABLE__


		#include "core/renderable.h"
		#include "container/narray_list.h"


namespace GS {
	namespace Core {

/*
	@short	Octree for static renderable.
	@author	Emmanuel Julien (ejulien@nworks.fr)
*/
class	OctreeCullingSystem : public Renderable
{
public:

struct	CachedNode
{
		Renderable		*renderable;
		MinMax			minmax;
		CachedNode() : renderable(0) {}
};

struct	Node
{
		Array <CachedNode *> cached_node;
		MinMax			minmax;
		AutoPtr <Node>	child[2];
};

private:

		bool			dirty;

		Array <CachedNode> nodes;
		AutoPtr <Node>	root;

		ArrayList <Renderable *> renderable_list;

		/// Perform list insertion into the octree.
		Node			*InsertList(List <CachedNode *> &list);

		void			GetNodeRenderablePrimitive(Node *, const Camera &view, const Camera &default_view, Stack <Render::Primitive *> &, Context);
		void			CullNodeRenderablePrimitive(Node *, const Camera &view, const Camera &default_view, Stack <Render::Primitive *> &, Context);

public:

		void			AddRenderable(Renderable *);
		void			DeleteRenderable(Renderable *);

		bool			Update();

		/// Compute renderable min-max.
virtual	void			ComputeRenderableMinMax(MinMax &);
		/// Get primitive list.
virtual	uint			GetRenderablePrimitiveList(const Camera &view, const Camera &default_view, Stack <Render::Primitive *> &list, Context context = Context_Default, bool cull = true);

		OctreeCullingSystem() : dirty(true) {}
};

	} // Core
} // GS


#endif	// __OCTREE_RENDERABLE__
