use crate::{
Bundle,
components::{Name, Visible, Ty, SourcePath, reset_visible_changed},
geometry::{
Geometry, GeometryRef, Submesh, VertexGroups,
},
material::{MaterialRef, texture::{TextureRef, SamplerRef, Sampler}},
transformation::{self,
Transformation, Bone, DynamicTransformation,
PreviousTransformation, Camera, RenderPlane,
},
light::{self,
Light,
DirectionalLight,
DirectionalLightBuilder,
DirectionalLightMatrices,
PointLightBuilder,
SpotLight,
SpotLightBuilder,
SpotLightMatrices,
AmbientLight,
PointLight,
shadow},
};
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
use crate::renderer::{
self,
Material, MaterialPool, TexturesPool,
light::{
ImageBasedLightBuilder,
},
};
#[cfg(not(any(feature="gl", feature="gles", feature="webgl")))]
use crate::material::Material;
use rinecs::{
World, Entity, System, SystemThreadLocal, CreationSystem, SystemDebug,
Component, ComponentThreadLocal, ComponentSend,
OneToNComponentSend, OneToNComponentThreadLocal, OneToNStorage,
Entities, EntitiesThreadLocal, WriteAndParent, Not,
};
use rin::{
graphics::{
Node, NodeMut, CameraExt, Mesh
},
};
#[cfg(feature="stats")]
use rin::events::Property;
#[cfg(feature="stats")]
use std::time;
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
use rin::gl;
#[cfg(feature="parking_lot")]
use parking_lot::*;
#[cfg(not(feature="parking_lot"))]
use std::sync::{RwLockReadGuard, RwLockWriteGuard};
use na::one;
use serde::{Serialize, Deserialize};
use crate::EventsDispatcher;
use std::fmt::Debug;
use std::mem;
pub struct Scene{
world: World,
vertex_register: renderer::VertexRegister,
}
impl Scene{
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
pub fn new(mut renderer: renderer::Bundle, events_dispatcher: EventsDispatcher) -> Scene {
let mut world = rinecs::World::new();
world.register::<Name>();
world.register::<Visible>();
world.register::<Ty>();
world.register::<SourcePath>();
world.register::<Transformation>();
world.register::<PreviousTransformation>();
world.register::<DynamicTransformation>();
world.register::<RenderPlane>();
world.register::<Bone>();
world.register::<GeometryRef>();
world.register::<VertexGroups>();
world.register::<Submesh>();
world.register::<Light>();
world.register::<DirectionalLight>();
world.register::<DirectionalLightMatrices>();
world.register::<SpotLight>();
world.register::<SpotLightMatrices>();
world.register::<PointLight>();
world.register::<AmbientLight>();
world.register::<light::Attenuation>();
world.register::<shadow::Map>();
world.register::<shadow::StaticMap>();
world.register::<shadow::Type>();
renderer::Bundle::register_components(&mut world);
world.add_resource(transformation::Viewport::new(renderer.viewport()));
world.add_resource(light::LightInfo::default());
world.add_system_with_name_thread_local(events_dispatcher, "events dispatcher");
world.add_system_with_name(reset_visible_changed, "reset visibles");
let viewport_size = renderer.viewport_size_stream();
world.add_system_with_name(transformation::CameraUpdater::new(viewport_size), "update camera");
world.add_system_with_name(light::check_lights_changed_system, "count lights");
world.add_barrier();
let vertex_register = renderer.vertex_register();
renderer.into_resources(&mut world);
Scene {
world,
vertex_register,
}
}
pub fn register_vertex_type<T>(&mut self)
where T: 'static + glin::VertexFormat + Send + Clone + Copy + Debug +
Serialize + Deserialize<'static>
{
let registered = {
let mut vertex_register = self.world.resource_mut::<renderer::DeferredVertexRegister>()
.unwrap();
vertex_register.deferred_register_vertex_type::<T>()
};
if registered {
self.register_component::<Geometry<T>>();
let world: &mut rinecs::World = unsafe{ mem::transmute(&mut self.world) };
let mut vertex_register = self.world.resource_mut::<renderer::DeferredVertexRegister>()
.unwrap();
vertex_register.update_registers(world, &mut self.vertex_register);
}
}
pub fn register_component<'a, C: Component + Send>(&'a mut self)
where <<C as Component>::Storage as rinecs::Storage<'a, C>>::Get: rinecs::DebugParameter,
{
self.world.register::<C>()
}
pub fn register_component_thread_local<'a, C: Component>(&'a mut self)
where <<C as Component>::Storage as rinecs::Storage<'a, C>>::Get: rinecs::DebugParameter,
{
self.world.register_thread_local::<C>()
}
pub fn register<B: Bundle>(&mut self){
B::register(self)
}
pub fn add<'a, B: Builder<'a, World>>(&'a mut self, settings: <B as Builder<'a, World>>::Settings) -> B{
B::new(&mut self.world, settings)
}
pub fn add_model(&mut self, name: &str) -> ModelBuilder{
ModelBuilder{
builder: self.world.new_entity()
.add(Name(name.to_string()))
.add(Ty::Model),
visible: true,
added_trafo: false,
}
}
pub fn add_empty(&mut self, name: &str) -> EmptyBuilder{
EmptyBuilder{
builder: self.world.new_entity()
.add(Name(name.to_string()))
.add(Ty::Empty),
added_trafo: false,
}
}
pub fn add_mesh<T>(&mut self, geom: Mesh<T>) -> GeometryRef
where T: 'static + glin::VertexFormat + Send + Clone + Copy + Debug +
Serialize + Deserialize<'static>
{
self.register_vertex_type::<T>();
let entity = self.world.new_entity()
.add(Geometry::new(geom))
.add(Ty::Mesh)
.build();
GeometryRef(entity)
}
pub fn add_named_mesh<T>(&mut self, geom: Mesh<T>, name: &str) -> GeometryRef
where T: 'static + glin::VertexFormat + Send + Clone + Copy + Debug +
Serialize + Deserialize<'static>
{
self.register_vertex_type::<T>();
let entity = self.world.new_entity()
.add(Name(name.to_owned()))
.add(Geometry::new(geom))
.add(Ty::Mesh)
.build();
GeometryRef(entity)
}
pub fn add_directional_light<'a>(&'a mut self, name: &'a str) -> DirectionalLightBuilder<'a, World>{
DirectionalLightBuilder::new(&mut self.world, name)
}
pub fn add_spot_light<'a>(&'a mut self, name: &'a str) -> SpotLightBuilder<'a, World>{
SpotLightBuilder::new(&mut self.world, name)
}
pub fn add_point_light<'a>(&'a mut self, name: &'a str) -> PointLightBuilder<'a, World>{
PointLightBuilder::new(&mut self.world, name)
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
pub fn add_image_based_light<'a>(&'a mut self, name: &'a str) -> ImageBasedLightBuilder<'a, World>{
ImageBasedLightBuilder::new(&mut self.world, name)
}
pub fn add_camera<C: CameraExt + Send + 'static>(&mut self, camera: C){
self.world.add_resource(Camera::new(camera));
}
pub fn add_bundle<B: Bundle>(&mut self, bundle: B){
bundle.setup(self)
}
pub fn update_all_transformations(&mut self){
transformation::update_all(self.world.entities(), self.world.resources());
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
pub fn register_material<M: Material + 'static>(&mut self, name: &str, material: M) -> MaterialRef{
self.resource_mut::<MaterialPool>().unwrap()
.register_material(name, material)
}
#[cfg(not(any(feature="gl", feature="gles", feature="webgl")))]
pub fn register_material<M: Material + 'static>(&mut self, name: &str, material: M) -> MaterialRef{
unimplemented!()
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
pub fn find_material(&self, name: &str) -> Option<MaterialRef>{
self.resource_mut::<MaterialPool>().unwrap()
.find_material(name)
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
pub fn register_texture(&mut self, texture: glin::Texture) -> TextureRef{
self.resource_mut::<TexturesPool>().unwrap()
.insert_texture(texture)
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
pub fn register_texture_from_data_format<T: 'static>(&mut self, format: glin::texture::LoadDataFormat, data: &[T]) -> Result<TextureRef, glin::Error>{
let renderer = self.resource::<gl::Renderer<'static>>().unwrap();
self.resource_mut::<TexturesPool>().unwrap()
.insert_texture_from_data_format(format, data, renderer.context())
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
pub fn register_image<I: glin::Image>(&mut self, img: &I) -> Result<TextureRef, glin::Error>{
let renderer = self.resource::<gl::Renderer<'static>>().unwrap();
self.resource_mut::<TexturesPool>().unwrap()
.insert_image(img, renderer.context())
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
pub fn register_named_texture_from_data_format<T: 'static>(&mut self, name: &str, format: glin::texture::LoadDataFormat, data: &[T]) -> Result<TextureRef, glin::Error>{
let renderer = self.resource::<gl::Renderer<'static>>().unwrap();
self.resource_mut::<TexturesPool>().unwrap()
.insert_named_texture_from_data_format(name, format, data, renderer.context())
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
pub fn register_named_image<I: glin::Image>(&mut self, name: &str, img: &I) -> Result<TextureRef, glin::Error>{
let renderer = self.resource::<gl::Renderer<'static>>().unwrap();
self.resource_mut::<TexturesPool>().unwrap()
.insert_named_image(name, img, renderer.context())
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
pub fn register_sampler(&mut self, sampler: Sampler) -> SamplerRef{
let renderer = self.resource::<gl::Renderer<'static>>().unwrap();
self.resource_mut::<TexturesPool>().unwrap()
.insert_sampler(sampler, renderer.context())
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
pub fn register_named_sampler(&mut self, name: &str, sampler: Sampler) -> SamplerRef{
let renderer = self.resource::<gl::Renderer<'static>>().unwrap();
self.resource_mut::<TexturesPool>().unwrap()
.insert_named_sampler(name, sampler, renderer.context())
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
pub fn find_texture(&self, name: &str) -> Option<TextureRef>{
self.resource_mut::<TexturesPool>().unwrap()
.find_named_texture(name)
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
pub fn add_renderer_systems(&mut self){
renderer::Bundle::add_systems(&mut self.world);
}
pub fn run_once(&mut self) {
self.world.run_once()
}
pub fn run_single_threaded(&mut self) {
self.world.run_single_threaded();
let world: &mut rinecs::World = unsafe{ mem::transmute(&mut self.world) };
let mut vertex_register = self.world.resource_mut::<renderer::DeferredVertexRegister>()
.unwrap();
vertex_register.update_registers(world, &mut self.vertex_register);
}
#[cfg(feature="multithreaded")]
pub fn run_multi_threaded(&mut self) {
self.world.run_multi_threaded();
let world: &mut rinecs::World = unsafe{ mem::transmute(&mut self.world) };
let mut vertex_register = self.world.resource_mut::<renderer::DeferredVertexRegister>()
.unwrap();
vertex_register.update_registers(world, &mut self.vertex_register);
}
#[cfg(feature="debug_concurrency")]
pub fn run_debug_concurrency(&mut self) {
self.world.run_debug_concurrency();
let world: &mut rinecs::World = unsafe{ mem::transmute(&mut self.world) };
let mut vertex_register = self.world.resource_mut::<renderer::DeferredVertexRegister>()
.unwrap();
vertex_register.update_registers(world, &mut self.vertex_register);
}
pub fn resources(&self) -> rinecs::Resources{
self.world.resources()
}
pub fn remove_resource<T: 'static>(&mut self) -> Option<T> {
self.world.remove_resource()
}
pub fn add_resource<T: Send + 'static>(&mut self, resource: T){
self.world.add_resource(resource)
}
pub fn add_resource_thread_local<T: 'static>(&mut self, resource: T){
self.world.add_resource_thread_local(resource)
}
pub fn resource<T: 'static>(&self) -> Option<RwLockReadGuard<T>>{
self.world.resource()
}
pub fn resource_mut<T: 'static>(&self) -> Option<RwLockWriteGuard<T>>{
self.world.resource_mut()
}
pub fn resources_thread_local(&self) -> rinecs::ResourcesThreadLocal{
self.world.resources_thread_local()
}
pub fn creation_proxy(&mut self) -> rinecs::CreationProxy{
self.world.creation_proxy()
}
pub fn add_system<S>(&mut self, system: S) -> &mut World
where for<'a> S: System<'a> + 'static
{
self.world.add_system(system)
}
pub fn add_system_thread_local<S>(&mut self, system: S) -> &mut World
where for<'a> S: SystemThreadLocal<'a> + 'static
{
self.world.add_system_thread_local(system)
}
pub fn add_creation_system<S>(&mut self, system: S) -> &mut World
where S: for<'a> CreationSystem<'a> + 'static
{
self.world.add_creation_system(system)
}
pub fn add_debug_system<S>(&mut self, system: S) -> &mut World
where S: for<'a> SystemDebug<'a> + 'static
{
self.world.add_debug_system(system)
}
pub fn add_system_with_name<S>(&mut self, system: S, name: &str) -> &mut World
where for<'a> S: System<'a> + 'static
{
self.world.add_system_with_name(system, name)
}
pub fn add_system_with_name_thread_local<S>(&mut self, system: S, name: &str) -> &mut World
where for<'a> S: SystemThreadLocal<'a> + 'static
{
self.world.add_system_with_name_thread_local(system, name)
}
pub fn add_system_with_name_thread_local_gpu<S>(&mut self, system: S, name: &str) -> &mut World
where for<'a> S: SystemThreadLocal<'a> + 'static
{
self.world.add_system_with_name_thread_local_gpu(system, name)
}
pub fn add_creation_system_with_name<S>(&mut self, system: S, name: &str) -> &mut World
where for<'a> S: CreationSystem<'a> + 'static
{
self.world.add_creation_system_with_name(system, name)
}
pub fn add_debug_system_with_name<S>(&mut self, system: S, name: &str) -> &mut World
where S: for<'a> SystemDebug<'a> + 'static
{
self.world.add_debug_system_with_name(system, name)
}
pub fn add_barrier(&mut self) -> &mut World {
self.world.add_barrier()
}
pub fn add_component_to<C: ComponentSend>(&mut self, entity: &Entity, component: C){
self.world.add_component_to(entity, component)
}
pub fn add_component_to_thread_local<C: ComponentThreadLocal>(&mut self, entity: &Entity, component: C){
self.world.add_component_to_thread_local(entity, component)
}
pub fn add_slice_component_to<C, I>(&mut self, entity: &Entity, component: I)
where C: OneToNComponentSend,
for<'a> <C as Component>::Storage: OneToNStorage<'a, C>,
I: IntoIterator<Item = C>
{
self.world.add_slice_component_to(entity, component)
}
pub fn add_slice_component_to_thread_local<C, I>(&mut self, entity: &Entity, component: I)
where C: OneToNComponentThreadLocal,
for<'a> <C as Component>::Storage: OneToNStorage<'a, C>,
I: IntoIterator<Item = C>
{
self.world.add_slice_component_to_thread_local(entity, component)
}
pub fn remove_component_from<C: Component>(&mut self, entity: &Entity){
self.world.remove_component_from::<C>(entity)
}
pub fn remove_entity(&mut self, entity: &Entity){
self.world.remove_entity(entity)
}
pub fn entities(&self) -> Entities{
self.world.entities()
}
pub fn entities_thread_local(&self) -> EntitiesThreadLocal{
self.world.entities_thread_local()
}
pub fn component_for<C: Component>(&self, entity: &Entity) -> Option<rinecs::Ptr<C>> {
self.world.entities_thread_local().component_for::<C>(entity)
}
pub fn component_for_mut<C: Component>(&self, entity: &Entity) -> Option<rinecs::PtrMut<C>> {
self.world.entities_thread_local().component_for_mut::<C>(entity)
}
#[cfg(feature="stats")]
pub fn stats(&mut self) -> impl Iterator<Item = (&str, Property<'static, time::Duration>)>{
self.world.stats()
}
#[cfg(feature="stats")]
pub fn gpu_stats<'g, C>(&'g mut self, gl: &'g C) -> impl Iterator<Item = (&str, Property<'static, time::Duration>)> + 'g
where C: glin::CreationContext
{
self.world.gpu_stats(gl)
}
#[cfg(feature="stats")]
pub fn enabled_systems(&mut self) -> impl Iterator<Item = (&str, Property<'static, bool>)> {
self.world.enabled_systems()
}
}
pub trait Builder<'a, C: CreationContext = World>{
type Settings;
fn new(world: &'a mut C, settings: Self::Settings) -> Self;
}
pub struct ModelBuilder<'a>{
builder: rinecs::EntityBuilder<'a>,
added_trafo: bool,
visible: bool,
}
impl<'a> ModelBuilder<'a>{
pub fn transformation<M: Into<Node>>(self, model: M) -> ModelBuilder<'a>{
ModelBuilder{
builder: self.builder
.add(Transformation::from_node(model.into())),
visible: self.visible,
added_trafo: true,
}
}
pub fn dynamic_transformation<M: Into<Node>>(self, model: M) -> ModelBuilder<'a>{
ModelBuilder{
builder: self.builder
.add(Transformation::from_node(model.into()))
.add(DynamicTransformation),
visible: self.visible,
added_trafo: true,
}
}
pub fn material(self, material: MaterialRef) -> ModelBuilder<'a>{
ModelBuilder{
builder: self.builder.add(material),
visible: self.visible,
added_trafo: self.added_trafo,
}
}
pub fn geometry(self, geom: GeometryRef) -> ModelBuilder<'a>{
ModelBuilder{
builder: self.builder.add(geom),
visible: self.visible,
added_trafo: self.added_trafo,
}
}
pub fn invisible(self) -> ModelBuilder<'a>{
ModelBuilder{
builder: self.builder,
visible: false,
added_trafo: self.added_trafo,
}
}
pub fn add<C: Component + Send>(self, component: C) -> ModelBuilder<'a>{
ModelBuilder{
builder: self.builder.add(component),
visible: self.visible,
added_trafo: self.added_trafo,
}
}
pub fn add_thread_local<C: Component>(self, component: C) -> ModelBuilder<'a>{
ModelBuilder{
builder: self.builder.add_thread_local(component),
visible: self.visible,
added_trafo: self.added_trafo,
}
}
pub fn build(self) -> Entity {
let builder = self.builder.add(Visible::new(self.visible));
if !self.added_trafo{
builder.add(Transformation::from_node(one())).build()
}else{
builder.build()
}
}
}
pub struct EmptyBuilder<'a>{
builder: rinecs::EntityBuilder<'a>,
added_trafo: bool,
}
impl<'a> EmptyBuilder<'a>{
pub fn transformation<M: Into<Node>>(self, model: M) -> EmptyBuilder<'a>{
EmptyBuilder{
builder: self.builder
.add(Transformation::from_node(model.into())),
added_trafo: true,
}
}
pub fn dynamic_transformation<M: Into<Node>>(self, model: M) -> EmptyBuilder<'a>{
EmptyBuilder{
builder: self.builder
.add(Transformation::from_node(model.into()))
.add(DynamicTransformation),
added_trafo: true,
}
}
pub fn add<C: Component + Send>(self, component: C) -> EmptyBuilder<'a>{
EmptyBuilder{
builder: self.builder.add(component),
added_trafo: self.added_trafo,
}
}
pub fn add_thread_local<C: Component>(self, component: C) -> EmptyBuilder<'a>{
EmptyBuilder{
builder: self.builder.add_thread_local(component),
added_trafo: self.added_trafo,
}
}
pub fn build(self) -> Entity {
if !self.added_trafo{
self.builder.add(Transformation::from_node(one())).build()
}else{
self.builder.build()
}
}
}
pub trait CreationContext: rinecs::CreationContext{
fn add<'a, B: Builder<'a, Self>>(&'a mut self, settings: <B as Builder<'a, Self>>::Settings) -> B where Self: Sized;
fn add_model(&mut self, name: &str) -> ModelBuilder;
fn add_empty(&mut self, name: &str) -> EmptyBuilder;
fn add_mesh<T>(&mut self, geom: Mesh<T>) -> GeometryRef
where T: 'static + glin::VertexFormat + Send + Clone + Copy + Debug +
Serialize + Deserialize<'static>;
fn add_named_mesh<T>(&mut self, geom: Mesh<T>, name: &str) -> GeometryRef
where T: 'static + glin::VertexFormat + Send + Clone + Copy + Debug +
Serialize + Deserialize<'static>;
fn add_directional_light<'a>(&'a mut self, name: &'a str) -> DirectionalLightBuilder<'a, Self> where Self: Sized;
fn add_spot_light<'a>(&'a mut self, name: &'a str) -> SpotLightBuilder<'a, Self> where Self: Sized;
fn add_point_light<'a>(&'a mut self, name: &'a str) -> PointLightBuilder<'a, Self> where Self: Sized;
fn update_all_transformations(&mut self);
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn add_image_based_light<'a>(&'a mut self, name: &'a str) -> ImageBasedLightBuilder<'a, Self> where Self: Sized;
fn register_material<M: Material + 'static>(&mut self, name: &str, material: M) -> MaterialRef;
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn find_material(&self, name: &str) -> Option<MaterialRef>;
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn register_texture(&mut self, texture: glin::Texture) -> TextureRef;
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn register_texture_from_data_format<T: 'static>(&mut self, format: glin::texture::LoadDataFormat, data: &[T]) -> Result<TextureRef, glin::Error>;
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn register_image<I: glin::Image>(&mut self, img: &I) -> Result<TextureRef, glin::Error>;
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
#[cfg(feature="squish")]
fn register_compress_image<I: glin::Image<DataType = u8>>(&mut self, img: &I) -> Result<TextureRef, glin::Error>;
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
#[cfg(feature="squish")]
fn register_compress_named_image<I: glin::Image<DataType = u8>>(&mut self, name: &str, img: &I) -> Result<TextureRef, glin::Error>;
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn register_named_texture_from_data_format<T: 'static>(&mut self, name: &str, format: glin::texture::LoadDataFormat, data: &[T]) -> Result<TextureRef, glin::Error>;
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn register_named_image<I: glin::Image>(&mut self, name: &str, img: &I) -> Result<TextureRef, glin::Error>;
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn register_sampler(&mut self, sampler: Sampler) -> SamplerRef;
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn register_named_sampler(&mut self, name: &str, sampler: Sampler) -> SamplerRef;
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn find_named_texture(&self, name: &str) -> Option<TextureRef>;
}
impl<C: rinecs::CreationContext> CreationContext for C {
fn add<'a, B: Builder<'a, Self>>(&'a mut self, settings: <B as Builder<'a, Self>>::Settings) -> B{
B::new(self, settings)
}
fn add_model(&mut self, name: &str) -> ModelBuilder{
ModelBuilder{
builder: self.new_entity()
.add(Name(name.to_string()))
.add(Ty::Model),
visible: true,
added_trafo: false,
}
}
fn add_empty(&mut self, name: &str) -> EmptyBuilder{
EmptyBuilder{
builder: self.new_entity()
.add(Name(name.to_string()))
.add(Ty::Empty),
added_trafo: false,
}
}
fn add_mesh<T>(&mut self, geom: Mesh<T>) -> GeometryRef
where T: 'static + glin::VertexFormat + Send + Clone + Copy + Debug +
Serialize + Deserialize<'static>
{
let registered = {
let mut vertex_register = self.resource_mut::<renderer::DeferredVertexRegister>()
.unwrap();
vertex_register.deferred_register_vertex_type::<T>()
};
if registered {
self.register::<Geometry<T>>();
}
let entity = self.new_entity()
.add(Geometry::new(geom))
.build();
GeometryRef(entity)
}
fn add_named_mesh<T>(&mut self, geom: Mesh<T>, name: &str) -> GeometryRef
where T: 'static + glin::VertexFormat + Send + Clone + Copy + Debug +
Serialize + Deserialize<'static>
{
let registered = {
let mut vertex_register = self.resource_mut::<renderer::DeferredVertexRegister>()
.unwrap();
vertex_register.deferred_register_vertex_type::<T>()
};
if registered {
self.register::<Geometry<T>>();
}
let entity = self.new_entity()
.add(Name(name.to_owned()))
.add(Geometry::new(geom))
.build();
GeometryRef(entity)
}
fn add_directional_light<'a>(&'a mut self, name: &'a str) -> DirectionalLightBuilder<'a, Self> where Self: Sized{
DirectionalLightBuilder::new(self, name)
}
fn add_spot_light<'a>(&'a mut self, name: &'a str) -> SpotLightBuilder<'a, Self> where Self: Sized{
SpotLightBuilder::new(self, name)
}
fn add_point_light<'a>(&'a mut self, name: &'a str) -> PointLightBuilder<'a, Self> where Self: Sized{
PointLightBuilder::new(self, name)
}
fn update_all_transformations(&mut self){
for ((trafo, parent), _) in self.ordered_iter_for::<(WriteAndParent<Transformation>, Not<Bone>)>(){
trafo.update_with_parent(parent.map(|t| &t.node));
}
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn add_image_based_light<'a>(&'a mut self, name: &'a str) -> ImageBasedLightBuilder<'a, Self> where Self: Sized{
ImageBasedLightBuilder::new(self, name)
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn register_material<M: Material + 'static>(&mut self, name: &str, material: M) -> MaterialRef{
self.resource_mut::<MaterialPool>().unwrap()
.register_material(name, material)
}
#[cfg(not(any(feature="gl", feature="gles", feature="webgl")))]
fn register_material<M: Material + 'static>(&mut self, name: &str, material: M) -> MaterialRef{
unimplemented!()
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn find_material(&self, name: &str) -> Option<MaterialRef>{
self.resource_mut::<MaterialPool>().unwrap()
.find_material(name)
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn register_texture(&mut self, texture: glin::Texture) -> TextureRef{
self.resource_mut::<TexturesPool>().unwrap()
.insert_texture(texture)
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn register_texture_from_data_format<T: 'static>(&mut self, format: glin::texture::LoadDataFormat, data: &[T]) -> Result<TextureRef, glin::Error>{
let renderer = self.resource::<gl::Renderer<'static>>().unwrap();
self.resource_mut::<TexturesPool>().unwrap()
.insert_texture_from_data_format(format, data, renderer.context())
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn register_image<I: glin::Image>(&mut self, img: &I) -> Result<TextureRef, glin::Error>{
let renderer = self.resource::<gl::Renderer<'static>>().unwrap();
self.resource_mut::<TexturesPool>().unwrap()
.insert_image(img, renderer.context())
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
#[cfg(feature="squish")]
fn register_compress_image<I: glin::Image<DataType = u8>>(&mut self, img: &I) -> Result<TextureRef, glin::Error>{
let renderer = self.resource::<gl::Renderer<'static>>().unwrap();
self.resource_mut::<TexturesPool>().unwrap()
.insert_compress_image(img, renderer.context())
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
#[cfg(feature="squish")]
fn register_compress_named_image<I: glin::Image<DataType = u8>>(&mut self, name: &str, img: &I) -> Result<TextureRef, glin::Error>{
let renderer = self.resource::<gl::Renderer<'static>>().unwrap();
self.resource_mut::<TexturesPool>().unwrap()
.insert_compress_named_image(name, img, renderer.context())
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn register_named_texture_from_data_format<T: 'static>(&mut self, name: &str, format: glin::texture::LoadDataFormat, data: &[T]) -> Result<TextureRef, glin::Error>{
let renderer = self.resource::<gl::Renderer<'static>>().unwrap();
self.resource_mut::<TexturesPool>().unwrap()
.insert_named_texture_from_data_format(name, format, data, renderer.context())
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn register_named_image<I: glin::Image>(&mut self, name: &str, img: &I) -> Result<TextureRef, glin::Error>{
let renderer = self.resource::<gl::Renderer<'static>>().unwrap();
self.resource_mut::<TexturesPool>().unwrap()
.insert_named_image(name, img, renderer.context())
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn register_sampler(&mut self, sampler: Sampler) -> SamplerRef{
let renderer = self.resource::<gl::Renderer<'static>>().unwrap();
self.resource_mut::<TexturesPool>().unwrap()
.insert_sampler(sampler, renderer.context())
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn register_named_sampler(&mut self, name: &str, sampler: Sampler) -> SamplerRef{
let renderer = self.resource::<gl::Renderer<'static>>().unwrap();
self.resource_mut::<TexturesPool>().unwrap()
.insert_named_sampler(name, sampler, renderer.context())
}
#[cfg(any(feature="gl", feature="gles", feature="webgl"))]
fn find_named_texture(&self, name: &str) -> Option<TextureRef>{
self.resource_mut::<TexturesPool>().unwrap()
.find_named_texture(name)
}
}
impl rinecs::CreationContext for Scene{
fn iter_for<'e, S: rinecs::UnorderedDataLocal<'e> + 'e>(&'e self) -> <S as rinecs::UnorderedDataLocal<'e>>::Iter{
self.world.iter_for::<S>()
}
fn ordered_iter_for<'e, S: rinecs::OrderedDataLocal<'e> + 'e>(&'e self) -> <S as rinecs::OrderedDataLocal<'e>>::Iter{
self.world.ordered_iter_for::<S>()
}
fn iter_for_entities<'e, S, E>(&'e self, entities: E) -> <S as rinecs::EntitiesDataLocal<'e, E>>::Iter
where S: rinecs::UnorderedDataLocal<'e> + 'e,
E: IntoIterator<Item = Entity>
{
self.world.iter_for_entities::<S,E>(entities)
}
fn entity_components<'e, S>(&'e self, entity: &Entity) -> Option<<S as rinecs::EntitiesComponentsLocal<'e>>::Components>
where S: rinecs::UnorderedDataLocal<'e> + 'e,
{
self.world.entity_components::<S>(entity)
}
fn component_for<C: rinecs::Component>(&self, entity: &Entity) -> Option<rinecs::Ptr<C>> {
self.world.component_for::<C>(entity)
}
fn component_for_mut<C: rinecs::Component>(&self, entity: &Entity) -> Option<rinecs::PtrMut<C>> {
self.world.component_for_mut::<C>(entity)
}
fn tree_node_for<'e, C: rinecs::Component>(&'e self, entity: &Entity) -> Option<rinecs::NodePtr<'e, C>>
where <C as rinecs::Component>::Storage: rinecs::HierarchicalStorage<'e, C>
{
self.world.tree_node_for::<C>(entity)
}
fn tree_node_for_mut<'e, C: rinecs::Component>(&'e self, entity: &Entity) -> Option<rinecs::NodePtrMut<'e, C>>
where <C as rinecs::Component>::Storage: rinecs::HierarchicalStorage<'e, C>
{
self.world.tree_node_for_mut::<C>(entity)
}
fn new_entity(&mut self) -> rinecs::EntityBuilder{
self.world.new_entity()
}
fn add_component_to<C: ComponentSend>(&mut self, entity: &Entity, component: C){
self.world.add_component_to(entity, component)
}
fn add_component_to_thread_local<C: ComponentThreadLocal>(&mut self, entity: &Entity, component: C){
self.world.add_component_to_thread_local(entity, component)
}
fn add_slice_component_to<C, I>(&mut self, entity: &Entity, component: I)
where C: OneToNComponentSend,
for<'b> <C as rinecs::Component>::Storage: rinecs::OneToNStorage<'b, C>,
I: IntoIterator<Item = C>
{
self.world.add_slice_component_to(entity, component)
}
fn add_slice_component_to_thread_local<C, I>(&mut self, entity: &Entity, component: I)
where C: OneToNComponentThreadLocal,
for<'b> <C as rinecs::Component>::Storage: rinecs::OneToNStorage<'b, C>,
I: IntoIterator<Item = C>
{
self.world.add_slice_component_to_thread_local(entity, component)
}
fn remove_component_from<C: rinecs::Component>(&mut self, entity: &rinecs::Entity){
self.world.remove_component_from::<C>(entity)
}
fn remove_entity(&mut self, entity: &rinecs::Entity){
self.world.remove_entity(entity)
}
fn resource<T: 'static>(&self) -> Option<RwLockReadGuard<T>>{
self.world.resource::<T>()
}
fn resource_mut<T: 'static>(&self) -> Option<RwLockWriteGuard<T>>{
self.world.resource_mut::<T>()
}
fn add_resource<T: 'static + Send>(&mut self, resource: T){
self.world.add_resource(resource)
}
fn add_resource_thread_local<T: 'static>(&mut self, resource: T){
self.world.add_resource_thread_local(resource)
}
fn remove_resource<T: 'static>(&mut self) -> Option<T>{
self.world.remove_resource::<T>()
}
fn register<'e, T: ComponentSend>(&'e mut self)
where <<T as Component>::Storage as rinecs::Storage<'e, T>>::Get: rinecs::DebugParameter{
self.world.register::<T>()
}
fn register_thread_local<'e, T: ComponentThreadLocal>(&'e mut self)
where <<T as Component>::Storage as rinecs::Storage<'e, T>>::Get: rinecs::DebugParameter{
self.world.register_thread_local::<T>()
}
}