shape.rs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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(
  45. Op::Mul((
  46. Box::new(Op::ConstFloat32(scale)),
  47. Box::new(last_x)
  48. ))
  49. );
  50. let mut y = self.y;
  51. y.push(
  52. Op::Mul((
  53. Box::new(Op::ConstFloat32(scale)),
  54. Box::new(last_y)
  55. ))
  56. );
  57. Self {
  58. x, y,
  59. color: self.color
  60. }
  61. }
  62. }
  63. #[derive(Debug)]
  64. pub struct VectorShape {
  65. pub verts: Vec<ShapeVertex>,
  66. pub indices: Vec<u16>,
  67. }
  68. impl VectorShape {
  69. pub fn new() -> Self {
  70. Self { verts: vec![], indices: vec![] }
  71. }
  72. pub fn eval(&self, w: f32, h: f32) -> Result<Vec<Vertex>> {
  73. let mut verts = vec![];
  74. for shape_vert in &self.verts {
  75. let mut pos = [0.; 2];
  76. for (i, shape_X) in [(0, &shape_vert.x), (1, &shape_vert.y)] {
  77. let mut machine = SExprMachine {
  78. globals: vec![
  79. ("w".to_string(), SExprVal::Float32(w)),
  80. ("h".to_string(), SExprVal::Float32(h)),
  81. ],
  82. stmts: shape_X,
  83. };
  84. pos[i] = machine.call()?.as_f32()?;
  85. }
  86. let vert = Vertex { pos, color: shape_vert.color.clone(), uv: [0., 0.] };
  87. verts.push(vert);
  88. }
  89. Ok(verts)
  90. }
  91. pub fn add_filled_box(
  92. &mut self,
  93. x1: SExprCode,
  94. y1: SExprCode,
  95. x2: SExprCode,
  96. y2: SExprCode,
  97. color: Color,
  98. ) {
  99. let mut verts = vec![
  100. ShapeVertex::new(x1.clone(), y1.clone(), color.clone()),
  101. ShapeVertex::new(x2.clone(), y1.clone(), color.clone()),
  102. ShapeVertex::new(x1.clone(), y2.clone(), color.clone()),
  103. ShapeVertex::new(x2, y2, color),
  104. ];
  105. let i = self.verts.len() as u16;
  106. let mut indices = vec![i + 0, i + 2, i + 1, i + 1, i + 2, i + 3];
  107. self.verts.append(&mut verts);
  108. self.indices.append(&mut indices);
  109. }
  110. // s-expr surgery
  111. fn sexpr_add(mut x: SExprCode, border_px: f32) -> Option<SExprCode> {
  112. let eqn = x.pop()?;
  113. x.push(Op::Add((Box::new(eqn), Box::new(Op::ConstFloat32(border_px)))));
  114. Some(x)
  115. }
  116. pub fn add_outline(
  117. &mut self,
  118. x1: SExprCode,
  119. y1: SExprCode,
  120. x2: SExprCode,
  121. y2: SExprCode,
  122. border_px: f32,
  123. color: Color,
  124. ) {
  125. // LHS
  126. self.add_filled_box(
  127. x1.clone(),
  128. y1.clone(),
  129. Self::sexpr_add(x1.clone(), border_px).unwrap(),
  130. y2.clone(),
  131. color.clone(),
  132. );
  133. // THS
  134. self.add_filled_box(
  135. x1.clone(),
  136. y1.clone(),
  137. x2.clone(),
  138. Self::sexpr_add(y1.clone(), border_px).unwrap(),
  139. color.clone(),
  140. );
  141. // RHS
  142. self.add_filled_box(
  143. Self::sexpr_add(x2.clone(), -border_px).unwrap(),
  144. y1.clone(),
  145. x2.clone(),
  146. y2.clone(),
  147. color.clone(),
  148. );
  149. // BHS
  150. self.add_filled_box(
  151. x1.clone(),
  152. Self::sexpr_add(y2.clone(), -border_px).unwrap(),
  153. x2.clone(),
  154. y2.clone(),
  155. color.clone(),
  156. );
  157. }
  158. pub fn scaled(self, scale: f32) -> Self {
  159. Self {
  160. verts: self.verts.into_iter().map(|v| v.scale(scale)).collect(),
  161. indices: self.indices
  162. }
  163. }
  164. }