e2rcore/implement/file/
md5comp.rs1extern crate mazth;
2
3use std::str;
4use std::f32;
5
6use self::mazth::{ mat::Mat3x1, quat::Quat };
7
8use interface::i_md5::compute::*;
9use interface::i_md5::rig::{ PoseCollection, PoseJoints };
10use interface::i_md5::mesh::Md5MeshRoot;
11
12pub fn process( pc: & PoseCollection, m: & Md5MeshRoot, pose_index_start: u64, pose_index_end: u64, interp: f32 ) -> Result< ComputeCollection, & 'static str > {
13 if pose_index_start >= pc._frames.len() as u64 {
14 return Err( "pose_index_start out of bounds." )
15 }
16 if pose_index_end >= pc._frames.len() as u64 {
17 return Err( "pose_index_start out of bounds." )
18 }
19 let interp_clamped = if 0f32 > interp {
20 0f32
21 } else { if 1f32 < interp {
22 1f32
23 }else{
24 interp
25 } };
26 let start = &pc._frames[ pose_index_start as usize ];
27 let end = &pc._frames[ pose_index_end as usize ];
28 interpolate( m, start, end, interp_clamped )
29}
30
31pub fn interpolate( m: & Md5MeshRoot, pose_start: & PoseJoints, pose_end: & PoseJoints, interp: f32 ) -> Result< ComputeCollection, & 'static str > {
32 let mut cc = ComputeCollection {
33 _bbox_lower: [0f32;3],
35 _bbox_upper: [0f32;3],
36 _batch_vert: vec![],
37 _batch_normal: vec![],
38 _batch_tc: vec![],
39 };
40
41 let mut max_pos = [0., 0., 0.];
42 let mut min_pos = [0., 0., 0.];
43
44 for i in &m._meshes {
45 let mut mc = MeshCompute {
46 _verts: vec![],
47 };
49 mc._verts.reserve_exact( i._verts.len() );
50
51 for j in &i._verts {
52 let mut vc = VertCompute {
53 _pos: [0f32;3],
54 _normal: [0f32;3],
55 _tc: j._tex_coords,
56 };
57 for k in 0..j._weight_count {
58 let weight_index = j._weight_start + k;
59
60 let w = &i._weights[ weight_index as usize ];
61 let joint_index = w._joint_index;
62 if joint_index >= pose_start._joints.len() as u64 {
63 return Err( "joint index out of bounds in pose_start." )
64 }
65 if joint_index >= pose_end._joints.len() as u64 {
66 return Err( "joint index out of bounds in pose_start." )
67 }
68 let pose_start_rigjoint = & pose_start._joints[ joint_index as usize ];
69 let pose_end_rigjoint = & pose_end._joints[ joint_index as usize ];
70 let pos_quat = Quat::<f32>::init_from_vals_raw( w._pos[0], w._pos[1], w._pos[2], 0f32 );
72 let orient_interp = Quat::<f32>::interpolate_slerp( pose_start_rigjoint._orient, pose_end_rigjoint._orient, interp );
73 let orient_inv = orient_interp.inverse().normalize();
74 let pos_transform = pose_start_rigjoint._orient.mul( pos_quat ).mul( orient_inv );
75 vc._pos[0] += ( pose_start_rigjoint._pos[0] + pos_transform._x ) * w._weight_bias;
77 vc._pos[1] += ( pose_start_rigjoint._pos[1] + pos_transform._y ) * w._weight_bias;
78 vc._pos[2] += ( pose_start_rigjoint._pos[2] + pos_transform._z ) * w._weight_bias;
79 }
80
81 for h in 0..3 {
82 if vc._pos[h] > max_pos[h] {
83 max_pos[h] = vc._pos[h];
84 } else if vc._pos[h] < min_pos[h] {
85 min_pos[h] = vc._pos[h];
86 }
87 }
88
89 mc._verts.push( vc );
90 }
91 for j in &i._tris {
93 let v0_index = j._vert_indices[ 0 ];
94 let v1_index = j._vert_indices[ 1 ];
95 let v2_index = j._vert_indices[ 2 ];
96 if v0_index >= mc._verts.len() as u64 {
97 return Err( "vert0 index out of bounds" )
98 }
99 if v1_index >= mc._verts.len() as u64 {
100 return Err( "vert1 index out of bounds" )
101 }
102 if v2_index >= mc._verts.len() as u64 {
103 return Err( "vert2 index out of bounds" )
104 }
105 let v0 = Mat3x1 {
106 _val: mc._verts[ v0_index as usize ]._pos,
107 };
108 let v1 = Mat3x1 {
109 _val: mc._verts[ v1_index as usize ]._pos,
110 };
111 let v2 = Mat3x1 {
112 _val: mc._verts[ v2_index as usize ]._pos,
113 };
114
115 let tc0 = mc._verts[ v2_index as usize ]._tc;
116 let tc1 = mc._verts[ v2_index as usize ]._tc;
117 let tc2 = mc._verts[ v2_index as usize ]._tc;
118
119 let v01 = v1.minus( &v0 ).unwrap();
120 let v02 = v2.minus( &v0 ).unwrap();
121 let n = v02.cross( &v01 ).expect("cross product for vertex normal invalid")
122 .normalize().expect("normalize for vertex normal invalid");
123
124 cc._batch_vert.extend_from_slice( &v0._val[..] );
132 cc._batch_vert.extend_from_slice( &v1._val[..] );
133 cc._batch_vert.extend_from_slice( &v2._val[..] );
134 let ns = n._val.into_iter().cycle().cloned().take(9).collect::<Vec<f32>>();
135 cc._batch_normal.extend_from_slice( &ns[..] );
136 cc._batch_tc.extend_from_slice( &[ tc0[0], tc0[1],
138 tc1[0], tc1[1],
139 tc2[0], tc2[1] ] );
140 }
141 }
145
146 cc._bbox_lower = min_pos;
147 cc._bbox_upper = max_pos;
148 Ok( cc )
149}