Mercurial > touhou
diff src/th06/anm0_vm.rs @ 643:01849ffd0180
Add an anmrenderer binary.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 02 Aug 2019 20:24:45 +0200 |
parents | 9e40bd5cc26d |
children | 7bde50132735 |
line wrap: on
line diff
--- a/src/th06/anm0_vm.rs +++ b/src/th06/anm0_vm.rs @@ -7,9 +7,22 @@ use crate::th06::anm0::{ Instruction, }; use crate::th06::interpolator::{Interpolator1, Interpolator2, Interpolator3, Formula}; +use crate::util::math::Mat4; use std::cell::RefCell; use std::rc::Rc; +/// TODO +#[repr(C)] +#[derive(Debug)] +pub struct Vertex { + /// XXX + pub pos: [i16; 3], + /// XXX + pub uv: [f32; 2], + /// XXX + pub color: [u8; 4], +} + /// Base visual element. #[derive(Debug, Clone, Default)] pub struct Sprite { @@ -61,9 +74,88 @@ impl Sprite { } } + /// TODO + pub fn fill_vertices(&self, vertices: &mut [Vertex; 4]) { + let mut mat = Mat4::new([[-0.5, 0.5, 0.5, -0.5], + [-0.5, -0.5, 0.5, 0.5], + [0., 0., 0., 0.], + [1., 1., 1., 1.]]); + + let [tx, ty, tw, th] = self.texcoords; + let [sx, sy] = self.rescale; + let width = if self.width_override > 0. { self.width_override } else { tw * sx }; + let height = if self.height_override > 0. { self.height_override } else { th * sy }; + + mat.scale2d(width, height); + if self.mirrored { + mat.flip(); + } + + let [rx, ry, mut rz] = self.rotations_3d; + if self.automatic_orientation { + rz += std::f32::consts::PI / 2. - self.angle; + } else if self.force_rotation { + rz += self.angle; + } + + if rx != 0. { + mat.rotate_x(-rx); + } + if ry != 0. { + mat.rotate_y(ry); + } + if rz != 0. { + mat.rotate_z(-rz); + } + + if self.allow_dest_offset { + mat.translate(self.dest_offset); + } + if self.corner_relative_placement { + mat.translate_2d(width / 2., height / 2.); + } + + let mat = mat.borrow_inner(); + vertices[0].pos[0] = mat[0][0] as i16; + vertices[0].pos[1] = mat[1][0] as i16; + vertices[0].pos[2] = mat[2][0] as i16; + vertices[1].pos[0] = mat[0][1] as i16; + vertices[1].pos[1] = mat[1][1] as i16; + vertices[1].pos[2] = mat[2][1] as i16; + vertices[2].pos[0] = mat[0][2] as i16; + vertices[2].pos[1] = mat[1][2] as i16; + vertices[2].pos[2] = mat[2][2] as i16; + vertices[3].pos[0] = mat[0][3] as i16; + vertices[3].pos[1] = mat[1][3] as i16; + vertices[3].pos[2] = mat[2][3] as i16; + + // XXX: don’t clone here. + let (x_1, y_1) = self.anm.clone().unwrap().inv_size(); + let [tox, toy] = self.texoffsets; + let left = tx * x_1 + tox; + let right = (tx + tw) * x_1 + tox; + let bottom = ty * y_1 + toy; + let top = (ty + th) * y_1 + toy; + + vertices[0].uv[0] = left; + vertices[0].uv[1] = bottom; + vertices[1].uv[0] = right; + vertices[1].uv[1] = bottom; + vertices[2].uv[0] = right; + vertices[2].uv[1] = top; + vertices[3].uv[0] = left; + vertices[3].uv[1] = top; + + vertices[0].color = self.color; + vertices[1].color = self.color; + vertices[2].color = self.color; + vertices[3].color = self.color; + } + /// Update sprite values from the interpolators. pub fn update(&mut self) { self.frame += 1; + self.corner_relative_placement = true; let [sax, say, saz] = self.rotations_speed_3d; if sax != 0. || say != 0. || saz != 0. {