cloudmap/
lib.rs

1pub use crate::cpu_shader::cm::cm3;
2pub use crate::cpu_shader::cm::cm3_arrow;
3pub use crate::cpu_shader::cm::cm3_blue;
4pub use crate::cpu_shader::cm::cm3_mud;
5mod cpu_shader {
6    pub mod cm {
7        extern crate nalgebra as na;
8        extern crate nalgebra_glm as glm;
9        use na::{Point3, Vector1, Vector3};
10
11        pub fn cm3(u: f64, v: f64, ca: f64, cb: f64, cc: f64, cut: f64, n: i32) -> [u32; 4] {
12            // let n = 12;
13
14            let w1 = 1.0 - u;
15            let w2 = u - v;
16            let w3 = v;
17
18            let mut vv = w1 * ca + w2 * cb + w3 * cc;
19
20            let stair = 0.25;
21            let per_step = n / 4;
22            let mut i = 0;
23            let j = per_step as u32;
24            let mut perPC: [u32; 4] = [0, 0, 0, 0];
25            if  vv<0. {
26                vv=0.;
27            }
28            if vv < cut {
29                // perPC = [255, 255, 255, 255];
30                // let a = 1;
31            } else {
32                if vv <= 0.25 && vv >= 0.0 {
33                    i = 0;
34                    while i < j {
35                        if vv >= i as f64 * stair / per_step as f64
36                            && vv <= ((i as f64) + 1.0) * stair / per_step as f64
37                        {
38                            perPC = [0, (i as f64 / per_step as f64 * 255.0) as u32, 255, 255];
39                            break;
40                        }
41                        i += 1;
42                    }
43                } else if vv > 0.25 && vv <= 0.5 {
44                    i = 0;
45                    while i < j {
46                        if vv >= 0.25 + i as f64 * stair / per_step as f64
47                            && vv <= 0.25 + ((i as f64) + 1.0) * stair / per_step as f64
48                        {
49                            perPC = [
50                                0,
51                                255,
52                                (1.0 - (i + 1) as f64 / per_step as f64 * 255.0) as u32,
53                                255,
54                            ];
55                            break;
56                        }
57                        i += 1;
58                    }
59                } else if vv > 0.5 && vv <= 0.75 {
60                    i = 0;
61                    while i < j {
62                        if vv >= 0.5 + i as f64 * stair / per_step as f64
63                            && vv <= 0.5 + ((i as f64) + 1.0) * stair / per_step as f64
64                        {
65                            perPC = [
66                                ((i + 1) as f64 / per_step as f64 * 255.0) as u32,
67                                255,
68                                0,
69                                255,
70                            ];
71                            break;
72                        }
73                        i += 1;
74                    }
75                } else if vv > 0.75 && vv <= 1.0 {
76                    i = 0;
77                    while i < j {
78                        if vv >= 0.75 + i as f64 * stair / per_step as f64
79                            && vv <= 0.75 + ((i as f64) + 1.0) * stair / per_step as f64
80                        {
81                            perPC = [
82                                255,
83                                ((1.0 - ((i + 1) as f64) / per_step as f64) * 255.0) as u32,
84                                0,
85                                255,
86                            ];
87                            break;
88                        }
89                        i += 1;
90                    }
91                } else {
92                    perPC = [255, 0, 0, 255];
93                }
94            }
95            return perPC;
96        }
97        pub fn cm3_blue(u: f64, v: f64, ca: f64, cb: f64, cc: f64, cut: f64, n: i32) -> [u32; 4] {
98            // let n = 12;
99
100            let w1 = 1.0 - u;
101            let w2 = u - v;
102            let w3 = v;
103
104            let mut vv = w1 * ca + w2 * cb + w3 * cc;
105
106            let stair = 0.25;
107            let per_step = n / 4;
108            let mut i = 0;
109            let j = per_step as u32;
110            let mut perPC: [u32; 4] = [0, 0, 0, 0];
111            // if  vv<0. {
112            //     vv=0.;
113            // }
114            if vv < cut {
115                // perPC = [255, 255, 255, 255];
116            } else {
117                if vv <= 0.25 && vv >= 0.0 {
118                    i = 0;
119                    while i < j {
120                        if vv >= i as f64 * stair / per_step as f64
121                            && vv <= ((i as f64) + 1.0) * stair / per_step as f64
122                        {
123                            perPC = [
124                                0,
125                                ((1.0 - i as f64 / per_step as f64 * stair as f64) * 255.0) as u32,
126                                255,
127                                255,
128                            ];
129                            break;
130                        }
131                        i += 1;
132                    }
133                } else if vv > 0.25 && vv <= 0.5 {
134                    i = 0;
135                    while i < j {
136                        if vv >= 0.25 + i as f64 * stair / per_step as f64
137                            && vv <= 0.25 + ((i as f64) + 1.0) * stair / per_step as f64
138                        {
139                            perPC = [
140                                0,
141                                ((0.75 - i as f64 / per_step as f64 * stair as f64) * 255.0) as u32,
142                                255,
143                                255,
144                            ];
145                            break;
146                        }
147                        i += 1;
148                    }
149                } else if vv > 0.5 && vv <= 0.75 {
150                    i = 0;
151                    while i < j {
152                        if vv >= 0.5 + i as f64 * stair / per_step as f64
153                            && vv <= 0.5 + ((i as f64) + 1.0) * stair / per_step as f64
154                        {
155                            perPC = [
156                                0,
157                                ((0.5 - i as f64 / per_step as f64 * stair as f64) * 255.0) as u32,
158                                255,
159                                255,
160                            ];
161                            break;
162                        }
163                        i += 1;
164                    }
165                } else if vv > 0.75 && vv <= 1.0 {
166                    i = 0;
167                    while i < j {
168                        if vv >= 0.75 + i as f64 * stair / per_step as f64
169                            && vv <= 0.75 + ((i as f64) + 1.0) * stair / per_step as f64
170                        {
171                            perPC = [
172                                0,
173                                ((0.25 - i as f64 / per_step as f64 * stair as f64) * 255.0) as u32,
174                                255,
175                                255,
176                            ];
177                            break;
178                        }
179                        i += 1;
180                    }
181                } else {
182                    perPC = [0, 0, 255, 255];
183                }
184            }
185            return perPC;
186        }
187        pub fn cm3_mud(u: f64, v: f64, ca: f64, cb: f64, cc: f64, cut: f64, n: i32) -> [u32; 4] {
188            // let n = 12;
189
190            let w1 = 1.0 - u;
191            let w2 = u - v;
192            let w3 = v;
193
194            let mut vv = w1 * ca + w2 * cb + w3 * cc;
195
196            let stair = 0.25;
197            let per_step = n / 4;
198            let mut i = 0;
199            let j = per_step as u32;
200            let mut perPC: [u32; 4] = [0, 0, 0, 0];
201            // if  vv<0. {
202            //     vv=0.;
203            // }
204            if vv < cut {
205                // perPC = [255, 255, 255, 255];
206            } else {
207                if vv <= 0.25 && vv >= 0.0 {
208                    i = 0;
209                    let r = 241.0 / 255.0; //0.945098;
210                    let rplus = (241.0 - 191.0) / 255.0; //0.196078;
211                    let g = 226.0 / 255.0; //0.886275;
212                    let gplus = (226.0 - 171.0) / 255.0; //0.215686;
213                    let b = 187.0 / 255.0; //0.7333333333;
214                    let bplus = (187.0 - 103.0) / 255.0; //0.329412;
215                    while i < j {
216                        if vv >= i as f64 * stair / per_step as f64
217                            && vv <= ((i as f64) + 1.0) * stair / per_step as f64
218                        {
219                            perPC = [
220                                ((r - rplus / (per_step as f64) * (i as f64)) * 255.0) as u32,
221                                ((g - gplus / (per_step as f64) * (i as f64)) * 255.0) as u32,
222                                ((b - bplus / (per_step as f64) * (i as f64)) * 255.0) as u32,
223                                255,
224                            ];
225                            let a = 1;
226                            break;
227                        }
228                        i += 1;
229                    }
230                } else if vv > 0.25 && vv <= 0.5 {
231                    i = 0;
232                    let r = 191.0 / 255.0; //0.749019;
233                    let rplus = (191.0 - 155.0) / 255.0; //0.141176;
234                    let g = 171.0 / 255.0; //0.670588;
235                    let gplus = (171.0 - 135.0) / 255.0; //0.141176;
236                    let b = 103.0 / 255.0; //0.403922;
237                    let bplus = (103.0 - 82.0) / 255.0; //0.082353;
238                    while i < j {
239                        if vv >= 0.25 + i as f64 * stair / per_step as f64
240                            && vv <= 0.25 + ((i as f64) + 1.0) * stair / per_step as f64
241                        {
242                            perPC = [
243                                ((r - rplus / (per_step as f64) * (i as f64)) * 255.0) as u32,
244                                ((g - gplus / (per_step as f64) * (i as f64)) * 255.0) as u32,
245                                ((b - bplus / (per_step as f64) * (i as f64)) * 255.0) as u32,
246                                255,
247                            ];
248                            break;
249                        }
250                        i += 1;
251                    }
252                } else if vv > 0.5 && vv <= 0.75 {
253                    i = 0;
254                    let r = 155.0 / 255.0; //0.607843;
255                    let rplus = (155.0 - 133.0) / 255.0; //0.086275;
256                    let g = 135.0 / 255.0; //0.529412;
257                    let gplus = (135.0 - 116.0) / 255.0; //0.0745098;
258                    let b = 82.0 / 255.0; //0.321569;
259                    let bplus = (82.0 - 79.0) / 255.0; //0.0117647;
260                    while i < j {
261                        if vv >= 0.5 + i as f64 * stair / per_step as f64
262                            && vv <= 0.5 + ((i as f64) + 1.0) * stair / per_step as f64
263                        {
264                            perPC = [
265                                ((r - rplus / (per_step as f64) * (i as f64)) * 255.0) as u32,
266                                ((g - gplus / (per_step as f64) * (i as f64)) * 255.0) as u32,
267                                ((b - bplus / (per_step as f64) * (i as f64)) * 255.0) as u32,
268                                255,
269                            ];
270                            break;
271                        }
272                        i += 1;
273                    }
274                } else if vv > 0.75 && vv <= 1.0 {
275                    i = 0;
276                    let r = 133.0 / 255.0; //0.250980;
277                    let rplus = (133.0 - 64.0) / 255.0; //0.270588;
278                    let g = 116.0 / 255.0; //0.2196078;
279                    let gplus = (116.0 - 56.0) / 255.0; //0.235294;
280                    let b = 79.0 / 255.0; //0.137255;
281                    let bplus = (79.0 - 35.0) / 255.0; //0.172549;
282                    while i < j {
283                        if vv >= 0.75 + i as f64 * stair / per_step as f64
284                            && vv <= 0.75 + ((i as f64) + 1.0) * stair / per_step as f64
285                        {
286                            perPC = [
287                                ((r - rplus / (per_step as f64) * (i as f64)) * 255.0) as u32,
288                                ((g - gplus / (per_step as f64) * (i as f64)) * 255.0) as u32,
289                                ((b - bplus / (per_step as f64) * (i as f64)) * 255.0) as u32,
290                                255,
291                            ];
292                            // print!("{:?}\n", perPC);
293                            break;
294                        }
295                        i += 1;
296                    }
297                } else {
298                    perPC = [64, 56, 35, 255];
299                }
300            }
301
302            return perPC;
303        }
304
305        pub fn cm3_f64(u: f64, v: f64, ca: f64, cb: f64, cc: f64, cut: f64, n: i32) -> [f64; 3] {
306            // let n = 12;
307
308            let w1 = 1.0 - u;
309            let w2 = u - v;
310            let w3 = v;
311
312            let mut vv = w1 * ca + w2 * cb + w3 * cc;
313
314            let stair = 0.25;
315            let per_step = n / 4;
316            let mut i = 0;
317            let j = n as u32;
318            let mut perPC: [f64; 3] = [0.0, 0.0, 0.0];
319            // if  vv<0. {
320            //     vv=0.;
321            // }
322            if vv < cut {
323                // perPC = [255, 255, 255, 255];
324            } else {
325                if vv <= 0.25 && vv >= 0.0 {
326                    i = 0;
327                    while i < j {
328                        if vv >= i as f64 * stair / per_step as f64
329                            && vv <= ((i as f64) + 1.0) * stair / per_step as f64
330                        {
331                            perPC = [0.0, (i as f64 / per_step as f64 * 1.0) as f64, 1.0];
332                            break;
333                        }
334                        i += 1;
335                    }
336                } else if vv > 0.25 && vv <= 0.5 {
337                    i = 0;
338                    while i < j {
339                        if vv >= 0.25 + i as f64 * stair / per_step as f64
340                            && vv <= 0.25 + ((i as f64) + 1.0) * stair / per_step as f64
341                        {
342                            perPC = [
343                                0.0,
344                                1.,
345                                (1.0 - (i + 1) as f64 / per_step as f64 * 1.0) as f64,
346                            ];
347                            break;
348                        }
349                        i += 1;
350                    }
351                } else if vv > 0.5 && vv <= 0.75 {
352                    i = 0;
353                    while i < j {
354                        if vv >= 0.5 + i as f64 * stair / per_step as f64
355                            && vv <= 0.5 + ((i as f64) + 1.0) * stair / per_step as f64
356                        {
357                            perPC = [((i + 1) as f64 / per_step as f64 * 1.0) as f64, 1.0, 0.0];
358                            break;
359                        }
360                        i += 1;
361                    }
362                } else if vv > 0.75 && vv <= 1.0 {
363                    i = 0;
364                    while i < j {
365                        if vv >= 0.75 + i as f64 * stair / per_step as f64
366                            && vv <= 0.75 + ((i as f64) + 1.0) * stair / per_step as f64
367                        {
368                            perPC = [1.0, ((1.0 - ((i + 1) as f64) / per_step as f64) * 1.0), 0.0];
369                            break;
370                        }
371                        i += 1;
372                    }
373                } else {
374                    perPC = [1.0, 1.0, 1.0];
375                }
376            }
377            return perPC;
378        }
379        pub fn cm3_f64_mm(vv: f64, cut: f64, n: i32) -> [f64; 3] {
380            let stair = 0.25;
381            let per_step = (n / 4) as f64;
382            let mut i = 0;
383            let j = n as u32;
384            let mut perPC: [f64; 3] = [0.0, 0.0, 0.0];
385            // if  vv<0. {
386            //     vv=0.;
387            // }
388            if vv < cut {
389                // perPC = [255, 255, 255, 255];
390            } else {
391                if vv <= 0.25 && vv >= 0.0 {
392                    i = 0;
393                    while i < j {
394                        if vv >= i as f64 * stair / per_step
395                            && vv <= ((i as f64) + 1.0) * stair / per_step
396                        {
397                            perPC = [0.0, (i as f64 / per_step * 1.0) as f64, 1.0];
398                            break;
399                        }
400                        i += 1;
401                    }
402                } else if vv > 0.25 && vv <= 0.5 {
403                    i = 0;
404                    while i < j {
405                        if vv >= 0.25 + i as f64 * stair / per_step
406                            && vv <= 0.25 + ((i as f64) + 1.0) * stair / per_step
407                        {
408                            perPC = [0.0, 1., (1.0 - (i + 1) as f64 / per_step * 1.0) as f64];
409                            break;
410                        }
411                        i += 1;
412                    }
413                } else if vv > 0.5 && vv <= 0.75 {
414                    i = 0;
415                    while i < j {
416                        if vv >= 0.5 + i as f64 * stair / per_step
417                            && vv <= 0.5 + ((i as f64) + 1.0) * stair / per_step
418                        {
419                            perPC = [((i + 1) as f64 / per_step * 1.0) as f64, 1.0, 0.0];
420                            break;
421                        }
422                        i += 1;
423                    }
424                } else if vv > 0.75 && vv <= 1.0 {
425                    i = 0;
426                    while i < j {
427                        if vv >= 0.75 + i as f64 * stair / per_step
428                            && vv <= 0.75 + ((i as f64) + 1.0) * stair / per_step
429                        {
430                            perPC = [1.0, ((1.0 - ((i + 1) as f64) / per_step) * 1.0), 0.0];
431                            break;
432                        }
433                        i += 1;
434                    }
435                } else {
436                    perPC = [1.0, 1.0, 1.0];
437                }
438            }
439            return perPC;
440        }
441
442        //glsl to cpu math has some problem ,手工适配,调整参数,无道理
443        pub fn cm3_arrow(ux: f64, vy: f64, u: f64, v: f64, vv: f64, cut: f64, n: i32) -> [u32; 4] {
444            let vector1: f64 = sdVectorArrow([u, v], [ux, vy]);
445            // let vector1: f64 = arrow([u, v], [ux, vy]);
446
447            let mut mixcolor = [0., 0., 0.];
448            let x = glm::vec3(0.0, 0.0, 0.0);
449            let pre_y = cm3_f64_mm(vv, cut, n);
450            let y = glm::vec3(pre_y[0], pre_y[1], pre_y[2]);
451            let a = glm::vec1(vector1);
452            let mix_color = glm::mix(&x, &y, vector1);
453
454            let r = *mix_color.get(0).unwrap();
455            let g = *mix_color.get(1).unwrap();
456            let b = *mix_color.get(2).unwrap();
457            if r == 0.0 && g == 0.0 && b == 0.0 {
458                [0, 0, 0, 0]
459            } else {
460                [
461                    (r * 255.0) as u32,
462                    (g * 255.0) as u32,
463                    (b * 255.0) as u32,
464                    255,
465                ]
466            }
467
468            // let d = sdEquilateralTriangle([u, v], 0.1);
469
470            // if d > 0.0 {
471            //     [0, 0, 0, 0]
472            // } else {
473            //     [255, 0, 0, 255]
474            // }
475        }
476
477        fn thc(a: f64, b: f64) -> f64 {
478            return (a * b.cos()).tanh() / a.tanh();
479        }
480
481        fn sdEquilateralTriangle(p: [f64; 2], distance: f64, size: f64) -> f64 {
482            //size 0.6--0.2 比较适合,大小
483            // distance ,控制位移,1:中心附近,0:前移
484            let k = 3.0_f64.sqrt();
485            let p_x = p[0].abs() - size;
486            let p_y = p[1] + distance / k;
487
488            let mut p1: [f64; 2] = [p_x, p_y];
489            if (p_x + k * p_y > 0.0) {
490                p1 = [(p_x - k * p_y) / 2.0, (-k * p_x - p_y) / 2.0];
491            }
492
493            p1[0] = p1[0].clamp(-2.0 * distance, 0.0);
494
495            let len_p1 = glm::length(&glm::vec2(p1[0], p1[1]));
496            let sign_py: f64 = if p1[1] > 0.0 {
497                1.0
498            } else {
499                if p1[1] < 0.0 {
500                    -1.0
501                } else {
502                    0.0
503                }
504            };
505            return -len_p1 * sign_py;
506        }
507
508        fn sdBox(p: [f64; 2], b: [f64; 2]) -> f64 {
509            let g_p = glm::vec2(p[0], p[1]);
510            let g_b = glm::vec2(b[0], b[1]);
511            let d = glm::abs(&g_p) - g_b;
512            let one = glm::length(&glm::max(&d, 0.));
513            return one + (d.x.max(d.y)).min(0.0);
514        }
515
516        fn arrow(uv: [f64; 2], v: [f64; 2], v_old: [f64; 2]) -> f64 {
517            let mut max_u = v_old[0].clone();
518            let mut max_v = v_old[0].clone();
519            max_u = max_u.abs();
520            max_v = max_v.abs();
521
522            let mut max_of_box = max_u.max(max_v);
523            max_of_box *= 0.6;
524            let h = 0.3 + 0.4 * thc(4., 2.);
525            let d1 = sdEquilateralTriangle(
526                [uv[0] - 0., uv[1] - (0.5)],
527                1.0 - max_of_box,
528                max_of_box.clone() * 0.68,
529            ); // 第二个参数 常量0.65 位移
530            let d1_x = glm::length(&glm::vec2(v[0], v[1]));
531            let d1_x_len = -0.1 + 0.1 * d1_x; //-0.1 ,后端位移,带调试,出现弧度?
532
533            let s1: f64 = if d1_x_len < d1 { 0.0 } else { 1.0 }; // glm::step(d1, tt1); //箭头大小
534
535            let t1_for_d2 = [uv[0] - 0.0, uv[1] - h * 0.163];
536            let t2_for_d2 = glm::length(&glm::vec2(v[0], v[1]));
537
538            let d2 = sdBox(
539                t1_for_d2,
540                [
541                    0.085 * t2_for_d2 * max_of_box + 0.085 * t2_for_d2 * max_of_box,
542                    0.52 * max_of_box + 0.52 * t2_for_d2 * max_of_box, //0.42,0.2双值控制远端位移
543                ],
544            );
545            // let s2 = step(d2, 0.);
546            let s2 = if d2 > 0.0 { 0.0 } else { 1.0 };
547
548            return s1.max(s2);
549            // return s1;
550        }
551
552        fn sdVectorArrow(p: [f64; 2], v: [f64; 2]) -> f64 {
553            // return arrow(p, v); //shape
554            let g_p = glm::vec2(p[0], p[1]);
555            let m = glm::length(&glm::vec2(v[0], v[1])); //长度
556            let n = glm::vec2(v[0] / m, v[1] / m); //sdf
557            let dot_for_pp = glm::vec2(n.y * 1.0, n.x * -1.0);
558            let pp = [
559                glm::dot(&g_p, &dot_for_pp),
560                // glm::dot(&g_p, &n),
561                glm::dot(&g_p, &n),
562            ]; //方向判断,n控制长度
563            return arrow(pp, [v[0] / m, v[1] / m], v); //shape
564        }
565    }
566}