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


		#include "scene3d/scene.h"
		#include "scene3d/mobject.h"
		#include "scene3d/instance.h"
		#include "scene3d/mconstraint.h"
		#include "core/resource_factories.h"
		#include "script/scripted_object.h"

		using namespace GS;
		using namespace GS::S3D;


//------------------------------------------------------------------------------
void				Scene::RenderSetup(Core::ResourceFactories *f, bool setup_items)
{
	__LOG__ << "Scene '" << name << "' render setup...\n";

	if	((render_data = new RenderData) != NULL)
	{
		render_data->skybox_shader = f->render->LoadShader(skybox_shader);
		for	(uint n = 0; n < 2; ++n)
			render_data->skybox_layer[n] = f->render->LoadTexture(skybox_layer[n]);

		render_data->radiance_probe = f->render->LoadTexture(radiance_probe);
		render_data->irradiance_probe = f->render->LoadTexture(irradiance_probe);
	}

	if	(setup_items)
		ListForeachPtr(MItem *, i, item_list)
			if	(Core::Item *b = i->GetBaseItem())
				b->RenderSetup(f);
}
void				Scene::InstanceSetup()
{
	ListForeachPtr(MItem *, i, item_list)
		if	(i->GetItemType() == Type_Instance)
			((Instance *)i)->Instantiate(this);
}
void				Scene::Setup(ToolMode tool_mode)
{
	__LOG_H__ << "Setup scene '" << name << "'.\n";

	scene_event->OnSetup(this);

	// Setup items.
	ListForeachPtr(MItem *, i, item_list)
		i->Setup(tool_mode == ToolEdit ? NULL : physic_world.c_ptr());

	scene_event->OnSetupDone(this);
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
void				Scene::TestOptimizeGeometry(Render::Geometry *geo, uint octree_node_size)
{
	if	(!geo)
		return;

	// Avoid infinite recursion.
	if	(geo->shadow_proxy == geo)
		geo->shadow_proxy = NULL;
	if	(geo->lod_proxy == geo)
		geo->lod_proxy = NULL;

	TestOptimizeGeometry(geo->shadow_proxy, octree_node_size);
	TestOptimizeGeometry(geo->lod_proxy, octree_node_size);
}
void				Scene::OptimizeForRealtime(uint octree_node_size)
{
	List <Render::sGeometry> list;
	ListForeachPtr(MItem *, i, item_list)
		if	(i->GetItemType() == Type_Object)
			if	(MObject *o = (MObject *)i)
				if	(o->render_data.IsValid() && o->render_data->geometry.IsValid())
					list.Add(o->render_data->geometry, true, false);

	for (uint n = 0; n < list.GetCount(); ++n)
		TestOptimizeGeometry(list[n], octree_node_size);
}
//------------------------------------------------------------------------------
