Guest User

example

a guest
Jul 23rd, 2025
17
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.39 KB | None | 0 0
  1. package main
  2. import rl "vendor:raylib"
  3. import rlgl "vendor:raylib/rlgl"
  4.  
  5.  
  6. Point :: struct {
  7. pos: rl.Vector2,
  8. prevPos: rl.Vector2,
  9. initPos: rl.Vector2,
  10. isPinned: bool,
  11. isSelected: bool,
  12. }
  13.  
  14. Stick :: struct {
  15. p0: int, // index
  16. p1: int,
  17. isTeared: bool
  18. }
  19.  
  20. Cloth :: struct {
  21. points: #soa[dynamic]Point,
  22. sticks: #soa[dynamic]Stick,
  23. }
  24.  
  25.  
  26. main :: proc() {
  27. rl.InitWindow(800, 500, cstring("Some libreary"))
  28.  
  29. screenWidth := rl.GetScreenWidth()
  30. screenHeight := rl.GetScreenHeight()
  31.  
  32. //rl.SetTargetFPS(60)
  33.  
  34. clothWidth :: 50
  35. clothHeight :: 50
  36. clothSpacing :: 10
  37. startX := (screenWidth - (clothWidth * clothSpacing)) / 2
  38. startY := screenHeight/12
  39.  
  40. cloth := MakeCloth(clothWidth, clothHeight, clothSpacing, startX, startY)
  41.  
  42. defer delete(cloth.points)
  43. defer delete(cloth.sticks)
  44.  
  45.  
  46. particleShader := rl.LoadShader("shader.vert", "shader.frag")
  47.  
  48. ssbo0 := rlgl.LoadShaderBuffer(u32(len(cloth.points)) * size_of(Point), &cloth.points, rlgl.DYNAMIC_COPY)
  49. particleVao := rlgl.LoadVertexArray()
  50. rlgl.EnableVertexArray(particleVao)
  51. rlgl.EnableVertexArray(0)
  52.  
  53.  
  54. drag :: f32(0.005)
  55. gravity :: rl.Vector2{0, 980}
  56. elasticity :: f32(100.0)
  57. fixedDeltaTime :: f32(1.0 / 300)
  58. accumulator: f32 = 0.0
  59. cursorSize: f32 = 30.0
  60.  
  61.  
  62. for !rl.WindowShouldClose() {
  63.  
  64. HandleMouseInteraction(&cloth, &cursorSize)
  65.  
  66. accumulator += rl.GetFrameTime()
  67. for accumulator >= fixedDeltaTime {
  68. UpdateCloth(&cloth, fixedDeltaTime, clothSpacing, drag, gravity, elasticity)
  69. accumulator -= fixedDeltaTime
  70. }
  71.  
  72. rl.BeginDrawing()
  73. rl.ClearBackground({33, 40, 48, 255})
  74. //rl.ClearBackground(rl.ORANGE)
  75.  
  76. DrawCloth(&cloth, clothSpacing, elasticity)
  77. rl.DrawFPS(50 , 50)
  78. rl.EndDrawing()
  79. }
  80.  
  81. rl.CloseWindow();
  82.  
  83.  
  84. }
  85.  
  86.  
  87.  
  88.  
  89. MakeCloth :: proc(width, height, spacing, startX, startY: i32) -> Cloth {
  90. cloth: Cloth
  91.  
  92. cloth.points = make(#soa[dynamic]Point, 0)
  93. cloth.sticks = make(#soa[dynamic]Stick, 0)
  94.  
  95.  
  96. for y := i32(0); y <= height; y += 1 {
  97. for x := i32(0); x <= width; x += 1 {
  98. point: Point
  99. point.initPos = { f32(startX + x * spacing), f32(startY + y * spacing) }
  100. point.pos = point.initPos
  101. point.prevPos = point.initPos
  102. point.isPinned = y == 0
  103. append(&cloth.points, point)
  104.  
  105. if x != 0 {
  106. stick: Stick
  107.  
  108. stick.p0 = len(cloth.points) - 2
  109. stick.p1 = len(cloth.points) - 1
  110. append(&cloth.sticks, stick)
  111. }
  112. if y != 0 {
  113. stick: Stick
  114.  
  115. stick.p0 = int((y - 1) * (width + 1) + x)
  116. stick.p1 = int( y * (width + 1) + x)
  117. append(&cloth.sticks, stick)
  118. }
  119. }
  120.  
  121. }
  122.  
  123. return cloth
  124. }
  125.  
  126. UpdateCloth :: proc(cloth: ^Cloth, deltatime: f32, spacing: i32, drag: f32, accerlation: rl.Vector2, elasticity: f32) {
  127.  
  128. for &point in cloth.points {
  129. if point.isPinned {
  130. point.pos = point.initPos
  131. continue
  132. }
  133. currentPos := point.pos
  134. point.pos += (point.pos - point.prevPos) * (1.0 - drag) + accerlation * deltatime * deltatime
  135. point.prevPos = currentPos
  136. }
  137. for &stick in cloth.sticks {
  138.  
  139. p0 := &cloth.points[ stick.p0]
  140. p1 := &cloth.points[ stick.p1]
  141.  
  142. delta := p1.pos - p0.pos
  143. distance := rl.Vector2Length(delta)
  144. if distance > elasticity {
  145. stick.isTeared = true
  146. continue
  147. }
  148.  
  149. correction: rl.Vector2 = delta * ((distance - f32(spacing)) / distance * 0.5) * 0.5
  150.  
  151. if !p0.isPinned && !stick.isTeared {
  152. p0.pos += correction
  153. }
  154. if !p1.isPinned && !stick.isTeared {
  155. p1.pos -= correction
  156. }
  157. }
  158. }
  159.  
  160. DrawCloth :: proc(cloth: ^Cloth, spacing: int, elasticity: f32) {
  161. for stick in cloth.sticks {
  162. DrawStick( cloth, stick, spacing, elasticity)
  163. }
  164.  
  165. DrawStick :: proc(cloth: ^Cloth, stick: Stick, spacing: int, elasticity: f32) {
  166. if (stick.isTeared) {
  167. return
  168. }
  169.  
  170. p0 := cloth.points[stick.p0]
  171. p1 := cloth.points[stick.p1]
  172. distance := rl.Vector2Distance(p0.pos, p1.pos)
  173. color := p0.isSelected || p1.isSelected ? rl.BLUE : GetColorFromTension(distance, elasticity, spacing)
  174. rl.DrawLineV( p0.pos, p1.pos, color)
  175. }
  176. }
  177.  
  178. GetColorFromTension :: proc(distance: f32, elasticity: f32, spacing: int) -> rl.Color {
  179. if distance <= f32(spacing) {
  180. return {
  181. 44,
  182. 222,
  183. 130,
  184. 255
  185. } // Green
  186. } else if distance <= f32(spacing) * 1.33 {
  187. t := (distance - f32(spacing)) / (f32(spacing) * 0.33)
  188. return {
  189. Lerp(44, 255, t),
  190. Lerp(222, 255, t),
  191. Lerp(130, 0, t),
  192. 255
  193. } // Gradual transition to yellow
  194. } else {
  195. t := (distance - f32(spacing) * 1.33) / (elasticity - f32(spacing) * 1.33)
  196. return {
  197. Lerp(255, 222, t),
  198. Lerp(255, 44, t),
  199. Lerp(0, 44, t),
  200. 255
  201. } // Gradual transition to red
  202. }
  203.  
  204. Lerp :: proc(a: f32, b: f32, t: f32) -> u8 {
  205. return u8(a + ((b - a) * t))
  206. }
  207. }
  208.  
  209. HandleMouseInteraction :: proc(cloth: ^Cloth, cursorSize: ^f32) {
  210.  
  211. stepSize :: 5
  212. if rl.GetMouseWheelMove() > 0 {
  213. cursorSize^ += stepSize
  214. } else if rl.GetMouseWheelMove() < 0 && cursorSize^ > stepSize {
  215. cursorSize^ -= stepSize
  216. }
  217.  
  218. @(static)prevMousePos: rl.Vector2
  219.  
  220. mousePos := rl.GetMousePosition()
  221. maxDelta := rl.Vector2(100)
  222. mouseDelta := rl.Vector2Clamp(mousePos - prevMousePos, rl.Vector2(0), maxDelta)
  223.  
  224. for &point in cloth.points {
  225. distance := rl.Vector2Distance(mousePos, point.pos)
  226. if distance < cursorSize^ {
  227. if rl.IsMouseButtonDown(.LEFT) {
  228. point.prevPos = point.prevPos + mouseDelta
  229. point.pos = point.pos + mouseDelta
  230. }
  231. point.isSelected = true
  232. } else {
  233. point.isSelected = false
  234.  
  235. }
  236. }
  237. prevMousePos = mousePos
  238.  
  239. }
  240.  
Advertisement
Add Comment
Please, Sign In to add comment