e2rcore/implement/render/
primitive.rs

1extern crate pretty_env_logger;
2extern crate mazth;
3
4use std::collections::HashMap;
5use std::any::Any;
6
7use interface::i_ele;
8use interface::i_renderobj;
9use interface::i_component;
10
11use self::mazth::mat;
12
13/// # 6 sided polyhedral / box
14#[derive(Clone)]
15pub struct Poly6 {
16    /// # _pos := center of the box
17    pub _pos: mat::Mat3x1< f32 >,
18    pub _scale: mat::Mat3x1< f32 >,
19    /// # _radius := approximation of the box size
20    pub _radius: f32,
21}
22
23impl i_ele::IObjImpl for Poly6 {
24    fn as_any( & self ) -> & Any {
25        self
26    }
27    fn update_components( & mut self, components: & mut Vec< Box< i_component::IComponent > > ) -> Result< (), & 'static str > {
28
29        //store vertex data
30        {
31            let x0 = self._pos[0] - self._radius/2.0 * self._scale[0];
32            let x1 = self._pos[0] + self._radius/2.0 * self._scale[0];
33
34            let y0 = self._pos[1] - self._radius/2.0 * self._scale[1];
35            let y1 = self._pos[1] + self._radius/2.0 * self._scale[1];
36
37            let z0 = self._pos[2] - self._radius/2.0 * self._scale[2];
38            let z1 = self._pos[2] + self._radius/2.0 * self._scale[2];
39
40            let mut pos = vec![];
41            let mut normal = vec![];
42            let mut tc = vec![];
43
44            //face 1 (front) trig 1
45            pos.extend_from_slice( &[ x0, y0, z1 ] );
46            normal.extend_from_slice( &[ 0.0, 0.0, 1.0 ] );
47            tc.extend_from_slice( &[ 0.0, 0.0 ] );
48
49            pos.extend_from_slice( &[ x1, y0, z1 ] );
50            normal.extend_from_slice( &[ 0.0, 0.0, 1.0 ] );
51            tc.extend_from_slice( &[ 0.0, 0.0 ] );
52
53            pos.extend_from_slice( &[ x1, y1, z1 ] );
54            normal.extend_from_slice( &[ 0.0, 0.0, 1.0 ] );
55            tc.extend_from_slice( &[ 0.0, 0.0 ] );
56
57            //face 1 (front) trig 2
58            pos.extend_from_slice( &[ x0, y0, z1 ] );
59            normal.extend_from_slice( &[ 0.0, 0.0, 1.0 ] );
60            tc.extend_from_slice( &[ 0.0, 0.0 ] );
61
62            pos.extend_from_slice( &[ x1, y1, z1 ] );
63            normal.extend_from_slice( &[ 0.0, 0.0, 1.0 ] );
64            tc.extend_from_slice( &[ 0.0, 0.0 ] );
65
66            pos.extend_from_slice( &[ x0, y1, z1 ] );
67            normal.extend_from_slice( &[ 0.0, 0.0, 1.0 ] );
68            tc.extend_from_slice( &[ 0.0, 0.0 ] );
69
70            //face 2 (back) trig 1.0
71            pos.extend_from_slice( &[ x0, y0, z0 ] );
72            normal.extend_from_slice( &[ 0.0, 0.0, -1.0 ] );
73            tc.extend_from_slice( &[ 0.0, 0.0 ] );
74
75            pos.extend_from_slice( &[ x0, y1, z0 ] );
76            normal.extend_from_slice( &[ 0.0, 0.0, -1.0 ] );
77            tc.extend_from_slice( &[ 0.0, 0.0 ] );
78
79            pos.extend_from_slice( &[ x1, y0, z0 ] );
80            normal.extend_from_slice( &[ 0.0, 0.0, -1.0 ] );
81            tc.extend_from_slice( &[ 0.0, 0.0 ] );
82
83            //face 2 (back) trig 2
84            pos.extend_from_slice( &[ x1, y0, z0 ] );
85            normal.extend_from_slice( &[ 0.0, 0.0, -1.0 ] );
86            tc.extend_from_slice( &[ 0.0, 0.0 ] );
87
88            pos.extend_from_slice( &[ x0, y1, z0 ] );
89            normal.extend_from_slice( &[ 0.0, 0.0, -1.0 ] );
90            tc.extend_from_slice( &[ 0.0, 0.0 ] );
91
92            pos.extend_from_slice( &[ x1, y1, z0 ] );
93            normal.extend_from_slice( &[ 0.0, 0.0, -1.0 ] );
94            tc.extend_from_slice( &[ 0.0, 0.0 ] );
95
96            //face 3 (left) trig 1.0
97            pos.extend_from_slice( &[ x0, y0, z1 ] );
98            normal.extend_from_slice( &[ -1.0, 0.0, 0.0 ] );
99            tc.extend_from_slice( &[ 0.0, 0.0 ] );
100
101            pos.extend_from_slice( &[ x0, y1, z1 ] );
102            normal.extend_from_slice( &[ -1.0, 0.0, 0.0 ] );
103            tc.extend_from_slice( &[ 0.0, 0.0 ] );
104
105            pos.extend_from_slice( &[ x0, y1, z0 ] );
106            normal.extend_from_slice( &[ -1.0, 0.0, 0.0 ] );
107            tc.extend_from_slice( &[ 0.0, 0.0 ] );
108
109            //face 3 (left) trig 2
110            pos.extend_from_slice( &[ x0, y0, z1 ] );
111            normal.extend_from_slice( &[ -1.0, 0.0, 0.0 ] );
112            tc.extend_from_slice( &[ 0.0, 0.0 ] );
113
114            pos.extend_from_slice( &[ x0, y1, z0 ] );
115            normal.extend_from_slice( &[ -1.0, 0.0, 0.0 ] );
116            tc.extend_from_slice( &[ 0.0, 0.0 ] );
117
118            pos.extend_from_slice( &[ x0, y0, z0 ] );
119            normal.extend_from_slice( &[ -1.0, 0.0, 0.0 ] );
120            tc.extend_from_slice( &[ 0.0, 0.0 ] );
121
122            //face 4 (right) trig 1.0
123            pos.extend_from_slice( &[ x1, y0, z1 ] );
124            normal.extend_from_slice( &[ 1.0, 0.0, 0.0 ] );
125            tc.extend_from_slice( &[ 0.0, 0.0 ] );
126
127            pos.extend_from_slice( &[ x1, y0, z0 ] );
128            normal.extend_from_slice( &[ 1.0, 0.0, 0.0 ] );
129            tc.extend_from_slice( &[ 0.0, 0.0 ] );
130
131            pos.extend_from_slice( &[ x1, y1, z0 ] );
132            normal.extend_from_slice( &[ 1.0, 0.0, 0.0 ] );
133            tc.extend_from_slice( &[ 0.0, 0.0 ] );
134
135            //face 4 (right) trig 2
136            pos.extend_from_slice( &[ x1, y0, z1 ] );
137            normal.extend_from_slice( &[ 1.0, 0.0, 0.0 ] );
138            tc.extend_from_slice( &[ 0.0, 0.0 ] );
139
140            pos.extend_from_slice( &[ x1, y1, z0 ] );
141            normal.extend_from_slice( &[ 1.0, 0.0, 0.0 ] );
142            tc.extend_from_slice( &[ 0.0, 0.0 ] );
143
144            pos.extend_from_slice( &[ x1, y1, z1 ] );
145            normal.extend_from_slice( &[ 1.0, 0.0, 0.0 ] );
146            tc.extend_from_slice( &[ 0.0, 0.0 ] );
147
148            //face 5 (top) trig 1.0
149            pos.extend_from_slice( &[ x0, y1, z1 ] );
150            normal.extend_from_slice( &[ 0.0, 1.0, 0.0 ] );
151            tc.extend_from_slice( &[ 0.0, 0.0 ] );
152
153            pos.extend_from_slice( &[ x1, y1, z1 ] );
154            normal.extend_from_slice( &[ 0.0, 1.0, 0.0 ] );
155            tc.extend_from_slice( &[ 0.0, 0.0 ] );
156
157            pos.extend_from_slice( &[ x1, y1, z0 ] );
158            normal.extend_from_slice( &[ 0.0, 1.0, 0.0 ] );
159            tc.extend_from_slice( &[ 0.0, 0.0 ] );
160
161            //face 5 (top) trig 2
162            pos.extend_from_slice( &[ x0, y1, z1 ] );
163            normal.extend_from_slice( &[ 0.0, 1.0, 0.0 ] );
164            tc.extend_from_slice( &[ 0.0, 0.0 ] );
165
166            pos.extend_from_slice( &[ x1, y1, z0 ] );
167            normal.extend_from_slice( &[ 0.0, 1.0, 0.0 ] );
168            tc.extend_from_slice( &[ 0.0, 0.0 ] );
169
170            pos.extend_from_slice( &[ x0, y1, z0 ] );
171            normal.extend_from_slice( &[ 0.0, 1.0, 0.0 ] );
172            tc.extend_from_slice( &[ 0.0, 0.0 ] );
173
174            //face 6 (bottom) trig 1.0
175            pos.extend_from_slice( &[ x0, y0, z1 ] );
176            normal.extend_from_slice( &[ 0.0, -1.0, 0.0 ] );
177            tc.extend_from_slice( &[ 0.0, 0.0 ] );
178
179            pos.extend_from_slice( &[ x0, y0, z0 ] );
180            normal.extend_from_slice( &[ 0.0, -1.0, 0.0 ] );
181            tc.extend_from_slice( &[ 0.0, 0.0 ] );
182
183            pos.extend_from_slice( &[ x1, y0, z0 ] );
184            normal.extend_from_slice( &[ 0.0, -1.0, 0.0 ] );
185            tc.extend_from_slice( &[ 0.0, 0.0 ] );
186
187            //face 6 (bottom) trig 2
188            pos.extend_from_slice( &[ x0, y0, z1 ] );
189            normal.extend_from_slice( &[ 0.0, -1.0, 0.0 ] );
190            tc.extend_from_slice( &[ 0.0, 0.0 ] );
191
192            pos.extend_from_slice( &[ x1, y0, z0 ] );
193            normal.extend_from_slice( &[ 0.0, -1.0, 0.0 ] );
194            tc.extend_from_slice( &[ 0.0, 0.0 ] );
195
196            pos.extend_from_slice( &[ x1, y0, z1 ] );
197            normal.extend_from_slice( &[ 0.0, -1.0, 0.0 ] );
198            tc.extend_from_slice( &[ 0.0, 0.0 ] );
199
200            let ele_len = pos.len();
201
202            let data_map : HashMap< i_renderobj::BuffDataType, Vec< f32 > > =  [ ( i_renderobj::BuffDataType::POS, pos ),
203                                                                                 ( i_renderobj::BuffDataType::NORMAL, normal ),
204                                                                                 ( i_renderobj::BuffDataType::TC, tc ) ].iter().cloned().collect();
205
206            let c = i_component::ComponentRenderBuffer {
207                _data_dict: data_map,
208            };
209            components.push( Box::new(c) );
210            trace!( "load into ComponentRenderBuffer: Poly6: vertex count:{}", ele_len / 3 );
211        }
212        //store uniform data
213        {
214            
215            
216        }
217        Ok( () )
218    }
219}
220
221#[derive(Clone)]
222pub struct SphereIcosahedron {
223    pub _pos: mat::Mat3x1< f32 >,
224    pub _radius: f32,
225    pub _index: usize,
226    pub _positions: Vec<[f32;3]>,
227}
228
229impl SphereIcosahedron {
230    pub fn init( pos: mat::Mat3x1< f32 >, radius: f32 ) -> SphereIcosahedron {
231        SphereIcosahedron {
232            _pos: pos,
233            _radius: radius,
234            _index: 0,
235            _positions: vec![],
236        }
237    }
238    /// # add vertex to mesh, fix position to be on unit sphere, return index
239    pub fn add_vertex( & mut self, p: &[f32] ) {
240        let length = (p[0] * p[0] + p[1] * p[1] + p[2] * p[2] ).sqrt();
241        self._positions.push( [ p[0]/length, p[1]/length, p[2]/length ] );
242        self._index += 1;
243    }
244    /// # return index of point in the middle of p1 and p2
245    pub fn get_middle_point( & mut self, p1: usize, p2: usize ) -> usize {
246        // first check if we have it already
247        let first_is_smaller : bool = p1 < p2;
248        let smaller_index = if first_is_smaller { p1 } else { p2 };
249        let greater_index = if first_is_smaller { p2 } else { p1 };
250        let _key = (smaller_index << 32) + greater_index;
251        
252        // int ret;
253        // if (this.middlePointIndexCache.TryGetValue(key, out ret))
254        // {
255        //     return ret;
256        // }
257
258        // not in cache, calculate it
259        let point1 = self._positions[p1];
260        let point2 = self._positions[p2];
261        let middle = [ (point1[0] + point2[0]) / 2.0,
262                        (point1[1] + point2[1]) / 2.0,
263                        (point1[2] + point2[2]) / 2.0 ];
264
265        // add vertex makes sure point is on unit sphere
266        let i = self._index;
267        self.add_vertex( &middle );
268
269        // // store it, return index
270        // this.middlePointIndexCache.Add(key, i);
271        i
272    }
273}
274
275impl i_ele::IObjImpl for SphereIcosahedron {
276    fn as_any( & self ) -> & Any {
277        self
278    }
279    fn update_components( & mut self, components: & mut Vec< Box< i_component::IComponent > > ) -> Result< (), & 'static str > {
280
281        //store vertex data
282        {
283            //starting icosahedron
284            let t = ( 1f32 + 5f32.sqrt() ) / 2f32;
285
286            self.add_vertex( &[-1f32,  t,  0f32 ] );
287            self.add_vertex( &[ 1f32,  t,  0f32 ] );
288            self.add_vertex( &[-1f32, -t,  0f32 ] );
289            self.add_vertex( &[ 1f32, -t,  0f32 ] );
290
291            self.add_vertex( &[ 0f32, -1f32,  t ] );
292            self.add_vertex( &[ 0f32,  1f32,  t ] );
293            self.add_vertex( &[ 0f32, -1f32, -t ] );
294            self.add_vertex( &[ 0f32,  1f32, -t ] );
295
296            self.add_vertex( &[ t,  0f32, -1f32 ] );
297            self.add_vertex( &[ t,  0f32,  1f32 ] );
298            self.add_vertex( &[-t,  0f32, -1f32 ] );
299            self.add_vertex( &[-t,  0f32,  1f32 ] );
300            
301            // create 20f32 triangles of the icosahedron
302            let mut faces = vec![];
303
304            // 5 faces around point 0
305            faces.push( [0, 11, 5] );
306            faces.push( [0, 5, 1] );
307            faces.push( [0, 1, 7] );
308            faces.push( [0, 7, 10] );
309            faces.push( [0, 10, 11] );
310
311            // 5 adjacent faces
312            faces.push( [1, 5, 9] );
313            faces.push( [5, 11, 4] );
314            faces.push( [11, 10, 2] );
315            faces.push( [10, 7, 6] );
316            faces.push( [7, 1, 8] );
317
318            // 5 faces around point 3
319            faces.push( [3, 9, 4] );
320            faces.push( [3, 4, 2] );
321            faces.push( [3, 2, 6] );
322            faces.push( [3, 6, 8] );
323            faces.push( [3, 8, 9] );
324
325            // 5 adjacent faces
326            faces.push( [4, 9, 5] );
327            faces.push( [2, 4, 11] );
328            faces.push( [6, 2, 10] );
329            faces.push( [8, 6, 7] );
330            faces.push( [9, 8, 1] );
331
332            let iterations = 2;
333            // refine triangles
334            for _ in 0..iterations {
335                let mut faces2 = vec![];
336                for tri in faces.iter() {
337                    // subdivide triangle into 4
338                    let a = self.get_middle_point( tri[0], tri[1] );
339                    let b = self.get_middle_point( tri[1], tri[2] );
340                    let c = self.get_middle_point( tri[2], tri[0] );
341                    faces2.push( [ tri[0], a, c ] );
342                    faces2.push( [ tri[1], b, a ] );
343                    faces2.push( [ tri[2], c, b ] );
344                    faces2.push( [ a, b, c ] );
345                }
346                faces = faces2;
347            }
348
349            let mut pos = vec![];
350            let mut normal = vec![];
351            let mut tc = vec![];
352            let r = self._radius;
353            let offset = self._pos;
354            for i in faces.iter() {
355                let x = self._positions[ i[0] ].into_iter().enumerate().map(|(k,o)| o*r + offset[k] ).collect::<Vec<f32> >();
356                let y = self._positions[ i[1] ].into_iter().enumerate().map(|(k,o)| o*r + offset[k] ).collect::<Vec<f32> >();
357                let z = self._positions[ i[2] ].into_iter().enumerate().map(|(k,o)| o*r + offset[k] ).collect::<Vec<f32> >();
358
359                let n = mat::Mat3x1 { _val: [ z[0]-y[0], z[1]-y[1], z[2]-y[2] ] }.cross( & mat::Mat3x1 { _val: [ x[0]-y[0], x[1]-y[1], x[2]-y[2] ] } ).unwrap().normalize().unwrap();
360                pos.extend_from_slice( &x[..] );
361                pos.extend_from_slice( &y[..] );
362                pos.extend_from_slice( &z[..] );
363                normal.extend_from_slice( &n._val[..] );
364                normal.extend_from_slice( &n._val[..] );
365                normal.extend_from_slice( &n._val[..] );
366                tc.extend_from_slice( &[ 0f32; 6 ] );            
367            }
368
369            let ele_len = pos.len();
370            
371            let data_map : HashMap< i_renderobj::BuffDataType, Vec< f32 > > =  [ ( i_renderobj::BuffDataType::POS, pos ),
372                                                                                 ( i_renderobj::BuffDataType::NORMAL, normal ),
373                                                                                 ( i_renderobj::BuffDataType::TC, tc ) ].iter().cloned().collect();
374            
375            let c = i_component::ComponentRenderBuffer {
376                _data_dict: data_map,
377            };
378            components.push( Box::new(c) );
379            trace!( "load into ComponentRenderBuffer: SphereIcosahedron: vertex count:{}", ele_len / 3 );
380        }
381        //store uniform data
382        {
383            
384        }
385        Ok( () )
386    }
387}
388
389//todo
390#[derive(Clone)]
391pub struct Point {
392    pub _pos: mat::Mat3x1< f32 >,
393    pub _radius: f32,
394}
395
396impl i_ele::IObjImpl for Point {
397    fn as_any( & self ) -> & Any {
398        self
399    }
400    fn update_components( & mut self, components: & mut Vec< Box< i_component::IComponent > > ) -> Result< (), & 'static str > {
401
402        //store vertex data
403        {
404            let mut pos = vec![];
405            let mut normal = vec![];
406            let mut tc = vec![];
407
408            pos.extend_from_slice( &self._pos._val[..] );
409            //todo: remove dummy noromal and texture coordinate
410            for i in 0..self._pos._val.len() {
411                if i % 3 == 2 {
412                    normal.push( 1f32 );
413                }else{
414                    normal.push( 0f32 );
415                }
416                tc.push( 0f32 );
417            }
418
419            let ele_len = pos.len();
420
421            let data_map : HashMap< i_renderobj::BuffDataType, Vec< f32 > > =  [ ( i_renderobj::BuffDataType::POS, pos ),
422                                                                                 ( i_renderobj::BuffDataType::NORMAL, normal ),
423                                                                                 ( i_renderobj::BuffDataType::TC, tc ) ].iter().cloned().collect();
424
425            let c = i_component::ComponentRenderBuffer {
426                _data_dict: data_map,
427            };
428            components.push( Box::new(c) );
429            trace!( "load into ComponentRenderBuffer: Point: vertex count:{}", ele_len / 3 );
430        }
431        Ok( () )
432    }
433}
434
435//todo
436pub struct Line {
437    pub _pos_start: mat::Mat3x1< f32 >,
438    pub _pos_end: mat::Mat3x1< f32 >,
439}
440