use na::{one, Pnt3, UnitQuat, Vec3, Vec4, Mat4, Mat3, Vec2, FastMul, Unit};
use rin::events::{Stream, IterAsync, StreamT};
use rin::math::{Rect, Deg};
use std::ops::{Deref, DerefMut};
use rin::{
graphics::{self, CameraExt, NodeMut},
};
use rinecs::{Entities, Resources, System};
use rin::math::Rad;
pub use self::trafo_update::*;
use serde::Serialize;
mod trafo_update;
#[derive(Clone, Component, Debug, Serialize, Deserialize)]
pub struct PreviousTransformation(pub graphics::Node);
impl Default for PreviousTransformation{
fn default() -> PreviousTransformation{
PreviousTransformation(one())
}
}
impl PreviousTransformation{
pub fn new(pos: Pnt3, rot: UnitQuat, scale: Vec3) -> PreviousTransformation{
PreviousTransformation(graphics::Node::new(pos, rot, scale))
}
pub fn from_position(pos: Pnt3) -> PreviousTransformation{
PreviousTransformation(graphics::Node::new(pos, one(), vec3!(1.)))
}
}
#[cfg(feature="blender")]
impl<'a> From<&'a rinblender::Transformations> for PreviousTransformation {
fn from(trafo: &'a rinblender::Transformations) -> PreviousTransformation {
if let Some(parent_inv) = trafo.parent_inv {
PreviousTransformation( graphics::Node::with_preparent(parent_inv,
trafo.position, trafo.into_quat(), trafo.scale))
}else{
PreviousTransformation::new(trafo.position, trafo.into_quat(), trafo.scale)
}
}
}
#[derive(Component, Debug, Serialize, Deserialize)]
pub struct DynamicTransformation;
#[derive(Clone,Debug,Copy,PartialEq,Eq, Serialize, Deserialize)]
#[allow(dead_code)]
#[repr(i16)]
pub enum RotMode {
Quat = 0,
EulerXYZ = 1,
EulerXZY = 2,
EulerYXZ = 3,
EulerYZX = 4,
EulerZXY = 5,
EulerZYX = 6,
AxisAngle = -1,
}
#[derive(HierarchicalComponent, Debug, Serialize, Deserialize)]
#[debug_custom]
pub struct Bone{
pub original: graphics::Node,
pub animated: graphics::Node,
pub rot_mode: RotMode,
pub rest_mat: Mat4,
pub inv_rest_mat: Mat4,
pub inv_rest_mat3: Mat3,
pub animated_id: usize,
pub head: Pnt3,
pub tail: Pnt3,
pub head_radius: f32,
pub tail_radius: f32,
pub name: String,
pub has_changed: bool,
pub flags: graphics::node::Flags,
pub used: bool,
}
impl Bone{
#[inline]
pub fn pose_mat(&self) -> Mat4{
self.animated.global_transformation()
}
#[inline]
pub fn local_mat(&self) -> Mat4{
self.pose_mat().fast_mul(&self.inv_rest_mat)
}
#[inline]
pub fn normal_mat(&self) -> Mat3{
let p = Mat3::from_iterator(self.pose_mat().columns(0,3).rows(0,3).iter().map(|v| *v));
p.fast_mul(&self.inv_rest_mat3)
}
#[inline]
pub fn global_head(&self) -> Pnt3{
(self.animated.global_transformation() * pnt4!(self.head, 1.0)).xyz()
}
#[inline]
pub fn global_tail(&self) -> Pnt3{
(self.animated.global_transformation() * pnt4!(self.tail, 1.0)).xyz()
}
pub fn update_with_parent_flags(&mut self, parent: Option<&graphics::Node>, flags: graphics::node::Flags) -> bool{
self.original.update_with_parent(parent) |
self.animated.update_with_parent_flags(Some(&self.original), flags)
}
}
impl rinecs::DebugParameter for Bone{
fn debug<S: serde::Serializer>(&self, serializer: S) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>{
#[derive(Serialize)]
struct Position{
x: f32,
y: f32,
z: f32,
}
#[derive(Serialize)]
struct Orientation{
x: f32,
y: f32,
z: f32,
w: f32,
}
#[derive(Serialize)]
struct Scale{
x: f32,
y: f32,
z: f32,
}
#[derive(Serialize)]
struct Node{
position: Position,
orientation: Orientation,
scale: Scale,
global_position: Position,
global_orientation: Orientation,
global_scale: Scale,
}
#[derive(Serialize)]
struct Bone<'a>{
original: Node,
animated: Node,
rot_mode: RotMode,
rest_mat: &'a Mat4,
inv_rest_mat: &'a Mat4,
inv_rest_mat3: &'a Mat3,
animated_id: usize,
head: &'a Pnt3,
tail: &'a Pnt3,
head_radius: f32,
tail_radius: f32,
name: &'a str,
has_changed: bool,
flags: graphics::node::Flags,
}
let p = self.original.position();
let q = self.original.orientation();
let s = self.original.scale();
let gp = self.original.global_position();
let gq = self.original.global_orientation();
let gs = self.original.global_scale();
let original = Node{
position: Position{
x: p[0], y: p[1], z: p[2]
},
orientation: Orientation{
x: q[0], y: q[1], z: q[2], w: q[3]
},
scale: Scale{
x: s.x, y: s.y, z: s.z
},
global_position: Position{
x: gp[0], y: gp[1], z: gp[2]
},
global_orientation: Orientation{
x: gq[0], y: gq[1], z: gq[2], w: gq[3]
},
global_scale: Scale{
x: gs.x, y: gs.y, z: gs.z
},
};
let p = self.animated.position();
let q = self.animated.orientation();
let s = self.animated.scale();
let gp = self.animated.global_position();
let gq = self.animated.global_orientation();
let gs = self.animated.global_scale();
let animated = Node{
position: Position{
x: p[0], y: p[1], z: p[2]
},
orientation: Orientation{
x: q[0], y: q[1], z: q[2], w: q[3]
},
scale: Scale{
x: s.x, y: s.y, z: s.z
},
global_position: Position{
x: gp[0], y: gp[1], z: gp[2]
},
global_orientation: Orientation{
x: gq[0], y: gq[1], z: gq[2], w: gq[3]
},
global_scale: Scale{
x: gs.x, y: gs.y, z: gs.z
},
};
Bone{
original,
animated,
rot_mode: self.rot_mode,
rest_mat: &self.rest_mat,
inv_rest_mat: &self.inv_rest_mat,
inv_rest_mat3: &self.inv_rest_mat3,
animated_id: self.animated_id,
head: &self.head,
tail: &self.tail,
head_radius: self.head_radius,
tail_radius: self.tail_radius,
name: &self.name,
has_changed: self.has_changed,
flags: self.flags,
}.serialize(serializer)
}
}
#[derive(OneToNComponent, Debug, Serialize, Deserialize)]
pub struct RenderPlane {
camera_matrices: graphics::mvp::CameraMatrices,
clip_plane: Option<Vec4>,
bias: f32,
has_changed: bool,
}
impl RenderPlane {
pub fn new<C: CameraExt>(camera: &C, viewport: Rect<i32>, clip_plane: Option<Vec4>, bias: f32) -> RenderPlane{
let camera_matrices = if let Some(clip) = clip_plane{
let clip_plane = vec4!(clip.xyz(), clip.w + bias);
graphics::mvp::CameraMatrices::with_camera_viewport_clip_plane(camera, viewport, clip_plane)
}else{
graphics::mvp::CameraMatrices::with_camera_viewport(camera, viewport)
};
RenderPlane{
camera_matrices,
clip_plane,
bias,
has_changed: false,
}
}
pub fn biased_clip_plane(&self) -> Option<Vec4>{
self.clip_plane.map(|clip| vec4!(clip.xyz(), clip.w + self.bias))
}
pub fn camera_matrices(&self) -> &graphics::mvp::CameraMatrices{
&self.camera_matrices
}
pub fn update_camera_viewport<C: CameraExt>(&mut self, camera: &C, viewport: Rect<i32>){
self.has_changed = true;
let camera_matrices = if let Some(clip) = self.biased_clip_plane(){
graphics::mvp::CameraMatrices::with_camera_viewport_clip_plane(camera, viewport, clip)
}else{
graphics::mvp::CameraMatrices::with_camera_viewport(camera, viewport)
};
self.camera_matrices = camera_matrices;
}
pub fn update_camera_viewport_bias<C: CameraExt>(&mut self, camera: &C, viewport: Rect<i32>, bias: f32){
self.has_changed = true;
self.bias = bias;
let camera_matrices = if let Some(clip) = self.biased_clip_plane(){
graphics::mvp::CameraMatrices::with_camera_viewport_clip_plane(camera, viewport, clip)
}else{
graphics::mvp::CameraMatrices::with_camera_viewport(camera, viewport)
};
self.camera_matrices = camera_matrices;
}
pub fn set_clip_plane(&mut self, clip_plane: Vec4){
self.has_changed = true;
self.clip_plane = Some(clip_plane);
self.camera_matrices.set_clip_plane(self.biased_clip_plane().unwrap());
}
pub fn clip_plane(&self) -> Option<Vec4>{
self.clip_plane
}
pub fn bias(&self) -> f32{
self.bias
}
pub fn has_changed(&self) -> bool{
self.has_changed
}
pub fn reset_has_changed(&mut self){
self.has_changed = false;
}
}
pub struct Viewport{
viewport: Rect<i32>,
changed: bool,
}
impl Viewport{
pub fn new(viewport: Rect<i32>) -> Viewport{
Viewport{
viewport,
changed: false,
}
}
pub fn has_changed(&self) -> bool{
self.changed
}
}
impl Deref for Viewport {
type Target = Rect<i32>;
fn deref(&self) -> &Rect<i32>{
&self.viewport
}
}
impl DerefMut for Viewport {
fn deref_mut(&mut self) -> &mut Rect<i32>{
&mut self.viewport
}
}
pub struct Camera{
camera: Box<CameraExt + Send>,
changed: bool,
}
impl Camera{
pub fn new<C: CameraExt + Send + 'static>(camera: C) -> Camera{
Camera{
camera: Box::new(camera),
changed: false,
}
}
pub fn update(&mut self) -> bool{
self.changed = self.camera.update();
self.changed
}
pub fn has_changed(&self) -> bool{
self.changed
}
}
impl Deref for Camera {
type Target = dyn CameraExt;
fn deref(&self) -> &(dyn CameraExt + 'static){
&*self.camera
}
}
impl DerefMut for Camera {
fn deref_mut(&mut self) -> &mut (dyn CameraExt + 'static){
&mut *self.camera
}
}
impl graphics::NodeRef for Camera{
fn node(&self) -> &graphics::Node{
self.camera.node()
}
}
impl CameraExt for Camera{
fn projection(&self) -> Mat4{
self.camera.projection()
}
fn view(&self) -> Mat4{
self.camera.view()
}
fn projection_view(&self) -> Mat4{
self.camera.projection_view()
}
fn fov(&self) -> Option<Deg<f32>>{
self.camera.fov()
}
fn width(&self) -> Option<f32>{
self.camera.width()
}
fn near_far_clip(&self) -> (f32,f32){
self.camera.near_far_clip()
}
fn near_clip(&self) -> f32{
self.camera.near_clip()
}
fn far_clip(&self) -> f32{
self.camera.far_clip()
}
fn set_near(&mut self, near: f32){
self.camera.set_near(near);
}
fn set_far(&mut self, far: f32){
self.camera.set_far(far);
}
fn set_near_far(&mut self, near: f32, far: f32){
self.camera.set_near_far(near,far);
}
fn set_aspect_ratio(&mut self, aspect: f32){
self.camera.set_aspect_ratio(aspect);
}
fn aspect_ratio(&self) -> f32{
self.camera.aspect_ratio()
}
fn target(&self) -> &Pnt3{
self.camera.target()
}
fn set_target(&mut self, target: Pnt3){
self.camera.set_target(target)
}
fn up(&self) -> &Unit<Vec3>{
self.camera.up()
}
fn update(&mut self) -> bool{
self.changed |= self.camera.update();
self.changed
}
}
impl NodeMut for Camera{
fn node_mut(&mut self) -> &mut graphics::Node{
self.camera.node_mut()
}
fn update_with_parent_flags(&mut self, parent: Option<&graphics::Node>, flags: graphics::node::Flags) -> bool{
self.camera.update_with_parent_flags(parent, flags)
}
fn update_with_parent(&mut self, parent: Option<&graphics::Node>) -> bool{
self.update_with_parent_flags(parent, graphics::node::Flags::empty())
}
fn look_at(&mut self, at: &Pnt3, up: &Vec3){
self.camera.look_at(at, up)
}
fn rotate(&mut self, angle: Rad<f32>, axis: &Unit<Vec3>){
self.camera.rotate(angle, axis)
}
fn append_orientation(&mut self, orientation: &UnitQuat){
self.camera.append_orientation(orientation)
}
fn tilt(&mut self, angle: Rad<f32>){
self.camera.tilt(angle)
}
fn pan(&mut self, angle: Rad<f32>){
self.camera.pan(angle)
}
fn roll(&mut self, angle: Rad<f32>){
self.camera.roll(angle)
}
fn set_scale(&mut self, _: Vec3){
}
fn translate(&mut self, t: &Vec3){
self.camera.translate(t)
}
fn set_position(&mut self, pos: Pnt3){
self.camera.set_position(pos)
}
fn set_angle_axis(&mut self, angle: Rad<f32>, axis: &Unit<Vec3>){
self.camera.set_angle_axis(angle, axis)
}
fn set_orientation(&mut self, orientation: UnitQuat){
self.camera.set_orientation(orientation)
}
}
pub struct CameraUpdater{
size_changed: IterAsync<'static, Vec2<i32>>,
}
impl CameraUpdater{
pub fn new(size_changed: Stream<'static, Vec2<i32>>) -> CameraUpdater{
CameraUpdater{
size_changed: size_changed.iter_async()
}
}
}
impl<'a> System<'a> for CameraUpdater{
fn run(&mut self, _e: Entities, resources: Resources){
let mut camera = resources.get_mut::<Camera>().unwrap();
let mut viewport = resources.get_mut::<Viewport>().unwrap();
if let Some(new_size) = self.size_changed.by_ref().last() {
viewport.width = new_size.x;
viewport.height = new_size.y;
viewport.changed = true;
camera.set_aspect_ratio(viewport.width as f32 / viewport.height as f32);
}else{
viewport.changed = false;
}
camera.update();
}
}