# HG changeset patch # User Emmanuel Gil Peyrot # Date 1567958945 -7200 # Node ID 377c241be5597cd4d6b9f619243207e5a54d0bc5 # Parent 6d4802abe1346c69a0e8e7556007f4b1aacba6a9 std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2. diff --git a/src/th06/std.rs b/src/th06/std.rs --- a/src/th06/std.rs +++ b/src/th06/std.rs @@ -155,8 +155,8 @@ declare_stage_instructions!{ 0 => fn SetViewpos(x: f32, y: f32, z: f32), 1 => fn SetFog(r: u8, g: u8, b: u8, a: u8, near: f32, far: f32), 2 => fn SetViewpos2(x: f32, y: f32, z: f32), - 3 => fn StartInterpolatingViewpos2(frame: i32, _unused: i32, _unused: i32), - 4 => fn StartInterpolatingFog(frame: i32, _unused: i32, _unused: i32), + 3 => fn StartInterpolatingViewpos2(frame: u32, _unused: i32, _unused: i32), + 4 => fn StartInterpolatingFog(frame: u32, _unused: i32, _unused: i32), 5 => fn Unknown(_unused: i32, _unused: i32, _unused: i32), } diff --git a/src/th06/std_vm.rs b/src/th06/std_vm.rs --- a/src/th06/std_vm.rs +++ b/src/th06/std_vm.rs @@ -1,7 +1,7 @@ //! Interpreter of STD files. use crate::th06::std::{Stage, Position, Call, Instruction}; -use crate::th06::interpolator::{Interpolator1, Interpolator4}; +use crate::th06::interpolator::{Interpolator1, Interpolator3, Interpolator4, Formula}; use crate::util::math::{Mat4, perspective, setup_camera}; use std::cell::RefCell; use std::rc::Rc; @@ -12,9 +12,8 @@ pub struct StageRunner { pub stage: Rc>, frame: u32, - // TODO: use interpolators. - position: [f32; 3], - direction: [f32; 3], + position: Interpolator3, + direction: Interpolator3, /// XXX: no pub. pub fog_color: [f32; 4], @@ -30,8 +29,8 @@ impl StageRunner { StageRunner { stage, frame: 0, - position: [0.; 3], - direction: [0.; 3], + position: Interpolator3::new([0., 0., 0.], 0, [0., 0., 0.], 0, Formula::Linear), + direction: Interpolator3::new([0., 0., 0.], 0, [0., 0., 0.], 0, Formula::Linear), fog_color: [1.; 4], fog_near: 0., fog_far: 1000., @@ -43,7 +42,8 @@ impl StageRunner { let stage = self.stage.borrow(); for Call { time, instr } in stage.script.iter() { - if *time != self.frame { + let time = *time; + if time != self.frame { continue; } @@ -51,9 +51,16 @@ impl StageRunner { match *instr { Instruction::SetViewpos(x, y, z) => { - self.position[0] = x; - self.position[1] = y; - self.position[2] = z; + self.position.set_start(time, [x, y, z]); + for Call { time, instr } in stage.script.iter().cloned() { + if time <= self.frame { + continue; + } + if let Instruction::SetViewpos(x, y, z) = instr { + self.position.set_end(time, [x, y, z]); + break; + } + } } Instruction::SetFog(b, g, r, a, near, far) => { self.fog_color = [r as f32 / 255., g as f32 / 255., b as f32 / 255., a as f32 / 255.]; @@ -61,11 +68,12 @@ impl StageRunner { self.fog_far = far; } Instruction::SetViewpos2(dx, dy, dz) => { - self.direction[0] = dx; - self.direction[1] = dy; - self.direction[2] = dz; + let direction = [dx, dy, dz]; + self.direction.set_start(time, if time == 0 { direction } else { self.direction.values(time) }); + self.direction.set_end_values(direction); } Instruction::StartInterpolatingViewpos2(frame, _, _) => { + self.direction.set_end_frame(time + frame); } Instruction::StartInterpolatingFog(frame, _, _) => { } @@ -79,9 +87,9 @@ impl StageRunner { /// Generate the model-view matrix for the current frame. pub fn get_model_view(&self) -> Mat4 { - let [x, y, z] = self.position; + let [x, y, z] = self.position.values(self.frame); - let [dx, dy, dz] = self.direction; + let [dx, dy, dz] = self.direction.values(self.frame); let view = setup_camera(dx, dy, dz);