shape.rs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2024 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use crate::{
  19. error::{Error, Result},
  20. expr::{Op, SExprCode, SExprMachine, SExprVal},
  21. gfx::{GfxBufferId, GfxDrawCall, GfxDrawInstruction, GfxDrawMesh, Rectangle, Vertex},
  22. mesh::Color,
  23. prop::{PropertyPtr, PropertyUint32, Role},
  24. util::enumerate,
  25. ExecutorPtr,
  26. };
  27. #[derive(Debug)]
  28. pub struct ShapeVertex {
  29. x: SExprCode,
  30. y: SExprCode,
  31. color: Color,
  32. }
  33. impl ShapeVertex {
  34. pub fn new(x: SExprCode, y: SExprCode, color: Color) -> Self {
  35. Self { x, y, color }
  36. }
  37. pub fn from_xy(x: f32, y: f32, color: Color) -> Self {
  38. Self { x: vec![Op::ConstFloat32(x)], y: vec![Op::ConstFloat32(y)], color }
  39. }
  40. pub fn scale(mut self, scale: f32) -> Self {
  41. let last_x = self.x.pop().unwrap();
  42. let last_y = self.y.pop().unwrap();
  43. let mut x = self.x;
  44. x.push(Op::Mul((Box::new(Op::ConstFloat32(scale)), Box::new(last_x))));
  45. let mut y = self.y;
  46. y.push(Op::Mul((Box::new(Op::ConstFloat32(scale)), Box::new(last_y))));
  47. Self { x, y, color: self.color }
  48. }
  49. }
  50. #[derive(Debug)]
  51. pub struct VectorShape {
  52. pub verts: Vec<ShapeVertex>,
  53. pub indices: Vec<u16>,
  54. }
  55. impl VectorShape {
  56. pub fn new() -> Self {
  57. Self { verts: vec![], indices: vec![] }
  58. }
  59. pub fn eval(&self, w: f32, h: f32) -> Result<Vec<Vertex>> {
  60. let mut verts = vec![];
  61. for shape_vert in &self.verts {
  62. let mut pos = [0.; 2];
  63. for (i, shape_X) in [(0, &shape_vert.x), (1, &shape_vert.y)] {
  64. let mut machine = SExprMachine {
  65. globals: vec![
  66. ("w".to_string(), SExprVal::Float32(w)),
  67. ("h".to_string(), SExprVal::Float32(h)),
  68. ],
  69. stmts: shape_X,
  70. };
  71. pos[i] = machine.call()?.as_f32()?;
  72. }
  73. let vert = Vertex { pos, color: shape_vert.color.clone(), uv: [0., 0.] };
  74. verts.push(vert);
  75. }
  76. Ok(verts)
  77. }
  78. pub fn add_filled_box(
  79. &mut self,
  80. x1: SExprCode,
  81. y1: SExprCode,
  82. x2: SExprCode,
  83. y2: SExprCode,
  84. color: Color,
  85. ) {
  86. self.add_gradient_box(x1, y1, x2, y2, [color.clone(), color.clone(), color.clone(), color])
  87. }
  88. /// Colors go clockwise from top-left
  89. pub fn add_gradient_box(
  90. &mut self,
  91. x1: SExprCode,
  92. y1: SExprCode,
  93. x2: SExprCode,
  94. y2: SExprCode,
  95. color: [Color; 4],
  96. ) {
  97. let mut verts = vec![
  98. ShapeVertex::new(x1.clone(), y1.clone(), color[0]),
  99. ShapeVertex::new(x2.clone(), y1.clone(), color[1]),
  100. ShapeVertex::new(x1.clone(), y2.clone(), color[3]),
  101. ShapeVertex::new(x2, y2, color[2]),
  102. ];
  103. let i = self.verts.len() as u16;
  104. let mut indices = vec![i + 0, i + 2, i + 1, i + 1, i + 2, i + 3];
  105. self.verts.append(&mut verts);
  106. self.indices.append(&mut indices);
  107. }
  108. // s-expr surgery
  109. fn sexpr_add(mut x: SExprCode, border_px: f32) -> Option<SExprCode> {
  110. let eqn = x.pop()?;
  111. x.push(Op::Add((Box::new(eqn), Box::new(Op::ConstFloat32(border_px)))));
  112. Some(x)
  113. }
  114. pub fn add_outline(
  115. &mut self,
  116. x1: SExprCode,
  117. y1: SExprCode,
  118. x2: SExprCode,
  119. y2: SExprCode,
  120. border_px: f32,
  121. color: Color,
  122. ) {
  123. // LHS
  124. self.add_filled_box(
  125. x1.clone(),
  126. y1.clone(),
  127. Self::sexpr_add(x1.clone(), border_px).unwrap(),
  128. y2.clone(),
  129. color.clone(),
  130. );
  131. // THS
  132. self.add_filled_box(
  133. x1.clone(),
  134. y1.clone(),
  135. x2.clone(),
  136. Self::sexpr_add(y1.clone(), border_px).unwrap(),
  137. color.clone(),
  138. );
  139. // RHS
  140. self.add_filled_box(
  141. Self::sexpr_add(x2.clone(), -border_px).unwrap(),
  142. y1.clone(),
  143. x2.clone(),
  144. y2.clone(),
  145. color.clone(),
  146. );
  147. // BHS
  148. self.add_filled_box(
  149. x1.clone(),
  150. Self::sexpr_add(y2.clone(), -border_px).unwrap(),
  151. x2.clone(),
  152. y2.clone(),
  153. color.clone(),
  154. );
  155. }
  156. pub fn scaled(self, scale: f32) -> Self {
  157. Self {
  158. verts: self.verts.into_iter().map(|v| v.scale(scale)).collect(),
  159. indices: self.indices,
  160. }
  161. }
  162. }