abrasion/engine/src/render/renderable.rs

153 lines
3.8 KiB
Rust

// Copyright 2020 Sergiusz 'q3k' Bazanski <q3k@q3k.org>
//
// This file is part of Abrasion.
//
// Abrasion is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, version 3.
//
// Abrasion is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// Abrasion. If not, see <https://www.gnu.org/licenses/>.
use std::collections::HashMap;
use std::hash;
use cgmath as cgm;
use crate::render::light::Omni;
use crate::render::material::Material;
use crate::render::mesh::Mesh;
pub struct ResourceManager {
meshes: HashMap<u64, Mesh>,
materials: HashMap<u64, Material>,
lights: HashMap<u64, Omni>,
}
#[derive(Copy, Clone)]
pub enum ResourceID {
Material(u64),
Mesh(u64),
Light(u64),
}
impl ResourceID {
pub fn id(&self) -> u64 {
match self {
ResourceID::Material(i) => *i,
ResourceID::Mesh(i) => *i,
ResourceID::Light(i) => *i,
}
}
}
impl hash::Hash for ResourceID {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
match self {
ResourceID::Material(i) => i.hash(state),
ResourceID::Mesh(i) => i.hash(state),
ResourceID::Light(i) => i.hash(state),
}
}
}
impl PartialEq for ResourceID {
fn eq(&self, other: &Self) -> bool {
self.id() == other.id()
}
}
impl Eq for ResourceID {}
impl<'a> ResourceManager {
pub fn new() -> Self {
Self {
meshes: HashMap::new(),
materials: HashMap::new(),
lights: HashMap::new(),
}
}
pub fn add_material(&mut self, t: Material) -> ResourceID {
let id = t.id;
self.materials.insert(id, t);
ResourceID::Material(id)
}
pub fn add_mesh(&mut self, t: Mesh) -> ResourceID {
let id = t.id;
self.meshes.insert(id, t);
ResourceID::Mesh(id)
}
pub fn add_light(&mut self, t: Omni) -> ResourceID {
let id = t.id;
self.lights.insert(id, t);
ResourceID::Light(id)
}
pub fn material(&'a self, id: &ResourceID) -> Option<&'a Material> {
if let ResourceID::Material(i) = id {
return Some(self.materials.get(&i).unwrap());
}
return None
}
pub fn mesh(&'a self, id: &ResourceID) -> Option<&'a Mesh> {
if let ResourceID::Mesh(i) = id {
return Some(self.meshes.get(&i).unwrap());
}
return None
}
pub fn light(&'a self, id: &ResourceID) -> Option<&'a Omni> {
if let ResourceID::Light(i) = id {
return Some(self.lights.get(&i).unwrap());
}
return None
}
pub fn light_mut(&'a mut self, id: &ResourceID) -> Option<&'a mut Omni> {
if let ResourceID::Light(i) = id {
return Some(self.lights.get_mut(&i).unwrap());
}
return None
}
}
pub trait Renderable {
fn render_data(&self) -> Option<(ResourceID, ResourceID, &cgm::Matrix4<f32>)> {
None
}
fn light_data(&self) -> Option<ResourceID> {
None
}
}
pub struct Object {
pub mesh: ResourceID,
pub material: ResourceID,
pub transform: cgm::Matrix4<f32>,
}
impl Renderable for Object {
fn render_data(&self) -> Option<(ResourceID, ResourceID, &cgm::Matrix4<f32>)> {
Some((self.mesh, self.material, &self.transform))
}
}
pub struct Light {
pub light: ResourceID,
}
impl Renderable for Light {
fn light_data(&self) -> Option<ResourceID> {
Some(self.light)
}
}