comparison src/th06/std_vm.rs @ 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 6020e33d4fc4
children 5016c09e5d7c
comparison
equal deleted inserted replaced
709:6d4802abe134 710:377c241be559
1 //! Interpreter of STD files. 1 //! Interpreter of STD files.
2 2
3 use crate::th06::std::{Stage, Position, Call, Instruction}; 3 use crate::th06::std::{Stage, Position, Call, Instruction};
4 use crate::th06::interpolator::{Interpolator1, Interpolator4}; 4 use crate::th06::interpolator::{Interpolator1, Interpolator3, Interpolator4, Formula};
5 use crate::util::math::{Mat4, perspective, setup_camera}; 5 use crate::util::math::{Mat4, perspective, setup_camera};
6 use std::cell::RefCell; 6 use std::cell::RefCell;
7 use std::rc::Rc; 7 use std::rc::Rc;
8 8
9 /// Interpreter for Stage. 9 /// Interpreter for Stage.
10 pub struct StageRunner { 10 pub struct StageRunner {
11 /// XXX: no pub. 11 /// XXX: no pub.
12 pub stage: Rc<RefCell<Stage>>, 12 pub stage: Rc<RefCell<Stage>>,
13 frame: u32, 13 frame: u32,
14 14
15 // TODO: use interpolators. 15 position: Interpolator3<f32>,
16 position: [f32; 3], 16 direction: Interpolator3<f32>,
17 direction: [f32; 3],
18 17
19 /// XXX: no pub. 18 /// XXX: no pub.
20 pub fog_color: [f32; 4], 19 pub fog_color: [f32; 4],
21 /// XXX: no pub. 20 /// XXX: no pub.
22 pub fog_near: f32, 21 pub fog_near: f32,
28 /// Create a new StageRunner attached to a Stage. 27 /// Create a new StageRunner attached to a Stage.
29 pub fn new(stage: Rc<RefCell<Stage>>) -> StageRunner { 28 pub fn new(stage: Rc<RefCell<Stage>>) -> StageRunner {
30 StageRunner { 29 StageRunner {
31 stage, 30 stage,
32 frame: 0, 31 frame: 0,
33 position: [0.; 3], 32 position: Interpolator3::new([0., 0., 0.], 0, [0., 0., 0.], 0, Formula::Linear),
34 direction: [0.; 3], 33 direction: Interpolator3::new([0., 0., 0.], 0, [0., 0., 0.], 0, Formula::Linear),
35 fog_color: [1.; 4], 34 fog_color: [1.; 4],
36 fog_near: 0., 35 fog_near: 0.,
37 fog_far: 1000., 36 fog_far: 1000.,
38 } 37 }
39 } 38 }
41 /// Advance the simulation one frame. 40 /// Advance the simulation one frame.
42 pub fn run_frame(&mut self) { 41 pub fn run_frame(&mut self) {
43 let stage = self.stage.borrow(); 42 let stage = self.stage.borrow();
44 43
45 for Call { time, instr } in stage.script.iter() { 44 for Call { time, instr } in stage.script.iter() {
46 if *time != self.frame { 45 let time = *time;
46 if time != self.frame {
47 continue; 47 continue;
48 } 48 }
49 49
50 println!("{} {:?}", time, instr); 50 println!("{} {:?}", time, instr);
51 51
52 match *instr { 52 match *instr {
53 Instruction::SetViewpos(x, y, z) => { 53 Instruction::SetViewpos(x, y, z) => {
54 self.position[0] = x; 54 self.position.set_start(time, [x, y, z]);
55 self.position[1] = y; 55 for Call { time, instr } in stage.script.iter().cloned() {
56 self.position[2] = z; 56 if time <= self.frame {
57 continue;
58 }
59 if let Instruction::SetViewpos(x, y, z) = instr {
60 self.position.set_end(time, [x, y, z]);
61 break;
62 }
63 }
57 } 64 }
58 Instruction::SetFog(b, g, r, a, near, far) => { 65 Instruction::SetFog(b, g, r, a, near, far) => {
59 self.fog_color = [r as f32 / 255., g as f32 / 255., b as f32 / 255., a as f32 / 255.]; 66 self.fog_color = [r as f32 / 255., g as f32 / 255., b as f32 / 255., a as f32 / 255.];
60 self.fog_near = near; 67 self.fog_near = near;
61 self.fog_far = far; 68 self.fog_far = far;
62 } 69 }
63 Instruction::SetViewpos2(dx, dy, dz) => { 70 Instruction::SetViewpos2(dx, dy, dz) => {
64 self.direction[0] = dx; 71 let direction = [dx, dy, dz];
65 self.direction[1] = dy; 72 self.direction.set_start(time, if time == 0 { direction } else { self.direction.values(time) });
66 self.direction[2] = dz; 73 self.direction.set_end_values(direction);
67 } 74 }
68 Instruction::StartInterpolatingViewpos2(frame, _, _) => { 75 Instruction::StartInterpolatingViewpos2(frame, _, _) => {
76 self.direction.set_end_frame(time + frame);
69 } 77 }
70 Instruction::StartInterpolatingFog(frame, _, _) => { 78 Instruction::StartInterpolatingFog(frame, _, _) => {
71 } 79 }
72 Instruction::Unknown(_, _, _) => { 80 Instruction::Unknown(_, _, _) => {
73 } 81 }
77 self.frame += 1; 85 self.frame += 1;
78 } 86 }
79 87
80 /// Generate the model-view matrix for the current frame. 88 /// Generate the model-view matrix for the current frame.
81 pub fn get_model_view(&self) -> Mat4 { 89 pub fn get_model_view(&self) -> Mat4 {
82 let [x, y, z] = self.position; 90 let [x, y, z] = self.position.values(self.frame);
83 91
84 let [dx, dy, dz] = self.direction; 92 let [dx, dy, dz] = self.direction.values(self.frame);
85 93
86 let view = setup_camera(dx, dy, dz); 94 let view = setup_camera(dx, dy, dz);
87 95
88 let model = Mat4::new([[1., 0., 0., 0.], 96 let model = Mat4::new([[1., 0., 0., 0.],
89 [0., 1., 0., 0.], 97 [0., 1., 0., 0.],