+
+ShadowMap *ShadowMap::Template::create(const map<string, Renderable *> &renderables) const
+{
+ Renderable *content = get_item(renderables, content_name);
+ if(!content || !lighting)
+ throw invalid_operation("ShadowMap::Template::create");
+
+ RefPtr<ShadowMap> shadow_map = new ShadowMap(width, height, *content, *lighting);
+ shadow_map->set_target(target, radius);
+ shadow_map->set_depth_bias(depth_bias);
+ shadow_map->set_darkness(darkness);
+
+ for(const ShadowedLight &l: lights)
+ {
+ Renderable *shadow_caster = get_item(renderables, l.shadow_caster_name);
+ if(!l.light || !shadow_caster)
+ throw invalid_operation("ShadowMap::Template::create");
+ if(const DirectionalLight *dir_light = dynamic_cast<const DirectionalLight *>(l.light))
+ shadow_map->add_light(*dir_light, l.size, *shadow_caster);
+ else if(const PointLight *point_light = dynamic_cast<const PointLight *>(l.light))
+ shadow_map->add_light(*point_light, l.size, *shadow_caster);
+ else
+ throw invalid_operation("ShadowMap::Template::create");
+ }
+
+ return shadow_map.release();
+}
+
+
+DataFile::Loader::ActionMap ShadowMap::Template::Loader::shared_actions;
+
+ShadowMap::Template::Loader::Loader(Template &t, Collection &c):
+ DerivedObjectLoader<Template, Effect::Template::Loader>(t, c)
+{
+ set_actions(shared_actions);
+}
+
+void ShadowMap::Template::Loader::init_actions()
+{
+ Effect::Template::Loader::init_actions();
+ add("darkness", &Template::darkness);
+ add("depth_bias", &Template::depth_bias);
+ add("light", &Loader::light);
+ add("lighting", &Template::lighting);
+ add("radius", &Template::radius);
+ add("size", &Loader::size_square);
+ add("size", &Template::width, &Template::height);
+ add("target", &Loader::target);
+}
+
+void ShadowMap::Template::Loader::light(const string &name)
+{
+ ShadowedLight light;
+ light.light = &get_collection().get<Light>(name);
+ load_sub(light);
+ obj.lights.push_back(light);
+}
+
+void ShadowMap::Template::Loader::size_square(unsigned s)
+{
+ obj.width = s;
+ obj.height = s;
+}
+
+void ShadowMap::Template::Loader::target(float x, float y, float z)
+{
+ obj.target = Vector3(x, y, z);
+}
+
+
+DataFile::Loader::ActionMap ShadowMap::Template::ShadowedLight::Loader::shared_actions;
+
+ShadowMap::Template::ShadowedLight::Loader::Loader(ShadowedLight &l):
+ ObjectLoader<ShadowedLight>(l)
+{
+ set_actions(shared_actions);
+}
+
+void ShadowMap::Template::ShadowedLight::Loader::init_actions()
+{
+ add("size", &ShadowedLight::size);
+ add("shadow_caster", &ShadowedLight::shadow_caster_name);
+}
+