changeset 710:377c241be559

std_vm: Implement SetViewpos, SetViewpos2 and StartInterpolatinvViewpos2.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Sun, 08 Sep 2019 18:09:05 +0200
parents 6d4802abe134
children 464c1b02a996
files src/th06/std.rs src/th06/std_vm.rs
diffstat 2 files changed, 25 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- 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),
 }
 
--- 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<RefCell<Stage>>,
     frame: u32,
 
-    // TODO: use interpolators.
-    position: [f32; 3],
-    direction: [f32; 3],
+    position: Interpolator3<f32>,
+    direction: Interpolator3<f32>,
 
     /// 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);