@rbxts/gizmos 1.0.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -41,7 +41,7 @@ Gizmos.log("Frame:", tick());
41
41
 
42
42
  ## Features
43
43
 
44
- - **Shapes**: Lines, rays, paths, points, cubes, circles, spheres, pyramids
44
+ - **Shapes**: Lines, rays, paths, points, cubes, circles, spheres, pyramids, cones
45
45
  - **Raycasts**: Visualize raycasts, spherecasts, and blockcasts with hit detection
46
46
  - **Text**: World-space and on-screen text rendering
47
47
  - **Colors**: Built-in color presets (red, green, blue, yellow, cyan, magenta, orange, purple, white, gray, black)
@@ -62,6 +62,7 @@ Gizmos.log("Frame:", tick());
62
62
  - `drawCircle(position: Vector3, radius: number, normal?: Vector3)` - Draw circle
63
63
  - `drawSphere(position: Vector3 | CFrame, radius: number)` - Draw sphere
64
64
  - `drawPyramid(position: Vector3 | CFrame, size: number, height: number)` - Draw pyramid
65
+ - `drawCone(apex: Vector3, direction: Vector3, range: number, halfAngleDeg: number, segments?: number)` - Draw cone (apex + axis + slant range + half-angle); resolution adapts to the cone's shape, with an optional `segments` override
65
66
  - `drawCFrame(cf: CFrame, size?: number, color?: Color3)` - Draw CFrame axes
66
67
 
67
68
  ### Raycasts
package/out/index.d.ts CHANGED
@@ -91,6 +91,20 @@ interface Gizmos {
91
91
  */
92
92
  drawPyramid(position: Vector3 | CFrame, size: number, height: number): void;
93
93
 
94
+ /**
95
+ * Draw a wireframe cone with its apex at a point, opening along a direction.
96
+ *
97
+ * Wider cones automatically get more slant lines and intermediate cross-section
98
+ * rings so short/wide shapes (e.g. a melee hit volume) read as a solid 3D cone
99
+ * rather than a sparse X.
100
+ * @param apex Tip of the cone (e.g. the attacker's position)
101
+ * @param direction Axis the cone opens along (need not be normalized)
102
+ * @param range Slant length — straight-line distance from the apex to the base rim
103
+ * @param halfAngleDeg Half-angle of the cone in degrees (axis to slant edge)
104
+ * @param segments Optional base-rim resolution override; defaults to a value adapted to the rim size (clamped 16–48)
105
+ */
106
+ drawCone(apex: Vector3, direction: Vector3, range: number, halfAngleDeg: number, segments?: number): void;
107
+
94
108
  /**
95
109
  * Draw a CFrame as colored axes (red = right, green = up, blue = -look)
96
110
  * @param cf CFrame to visualize
package/out/init.lua CHANGED
@@ -175,19 +175,20 @@ local function drawCube(pos: Vector3 | CFrame, size: Vector3)
175
175
  })
176
176
  end
177
177
 
178
- local function drawCircle(pos: Vector3, radius: number, normal: Vector3?)
179
- local segments = 16
180
- normal = normal or Vector3.yAxis
181
- local cf = CFrame.lookAlong(pos, normal)
178
+ local function helper_circlePoints(cf: CFrame, radius: number, segments: number): {Vector3}
182
179
  local angle = 2 * math.pi / segments
183
-
184
180
  local points = {}
185
181
  for i = 1, segments do
186
182
  local localpoint = Vector3.new(math.cos(i * angle), math.sin(i * angle), 0) * radius
187
- local point = cf:PointToWorldSpace(localpoint)
188
- table.insert(points, point)
183
+ table.insert(points, cf:PointToWorldSpace(localpoint))
189
184
  end
190
- wfh:AddPath(points, true)
185
+ return points
186
+ end
187
+
188
+ local function drawCircle(pos: Vector3, radius: number, normal: Vector3?)
189
+ normal = normal or Vector3.yAxis
190
+ local cf = CFrame.lookAlong(pos, normal)
191
+ wfh:AddPath(helper_circlePoints(cf, radius, 16), true)
191
192
  end
192
193
 
193
194
  local function drawSphere(pos: Vector3 | CFrame, radius: number)
@@ -211,6 +212,40 @@ local function drawPyramid(pos: Vector3 | CFrame, size: number, height: number)
211
212
  wfh:AddPath({points[3], points[5], points[4]}, false)
212
213
  end
213
214
 
215
+ local function drawCone(apex: Vector3, direction: Vector3, range: number, halfAngleDeg: number, segments: number?)
216
+ local dir = direction.Unit
217
+ local halfAngle = math.rad(halfAngleDeg)
218
+ local height = range * math.cos(halfAngle)
219
+ local radius = range * math.sin(halfAngle)
220
+ local baseCenter = apex + dir * height
221
+ local cf = CFrame.lookAlong(baseCenter, dir)
222
+
223
+ -- Base resolution scales with the rim size so wide cones stay smooth,
224
+ -- clamped so tiny cones aren't overdrawn and huge ones aren't sparse.
225
+ segments = segments or math.clamp(math.round(radius * 6), 16, 48)
226
+
227
+ -- Base rim.
228
+ local rim = helper_circlePoints(cf, radius, segments)
229
+ wfh:AddPath(rim, true)
230
+
231
+ -- Slant lines (rim -> apex). Wider cones get more so the volume reads as a
232
+ -- cone rather than a sparse X; narrow cones fall back to 4 like before.
233
+ local slantCount = math.clamp(math.round(halfAngleDeg / 3.75), 4, 16)
234
+ for j = 0, slantCount - 1 do
235
+ wfh:AddLine(apex, rim[math.floor(j / slantCount * segments) + 1])
236
+ end
237
+
238
+ -- Intermediate cross-section rings help a wide/short cone read as a solid
239
+ -- volume; narrow cones get none. Each ring sits at fraction t of the height,
240
+ -- where the cone radius is t * radius.
241
+ local ringCount = math.clamp(math.floor(halfAngleDeg / 22.5), 0, 3)
242
+ for k = 1, ringCount do
243
+ local t = k / (ringCount + 1)
244
+ local ringCf = CFrame.lookAlong(apex + dir * height * t, dir)
245
+ wfh:AddPath(helper_circlePoints(ringCf, radius * t, segments), true)
246
+ end
247
+ end
248
+
214
249
  local function drawCFrame(cf: CFrame, size: number, color: Color3)
215
250
  size = size or 1
216
251
  local color3 = wfh.Color3
@@ -369,6 +404,12 @@ function Gizmos:drawPyramid(position: Vector3 | CFrame, size: number, height: nu
369
404
  end)
370
405
  end
371
406
 
407
+ function Gizmos:drawCone(apex: Vector3, direction: Vector3, range: number, halfAngleDeg: number, segments: number?)
408
+ table.insert(commands, function()
409
+ drawCone(apex, direction, range, halfAngleDeg, segments)
410
+ end)
411
+ end
412
+
372
413
  function Gizmos:drawCFrame(cf: CFrame, size: number?, color: Color3?)
373
414
  table.insert(commands, function()
374
415
  drawCFrame(cf, size, color)
@@ -443,6 +484,7 @@ function Gizmos:test()
443
484
  Gizmos:drawCircle(p, 0.5) n()
444
485
  Gizmos:drawSphere(p+y*0.5, 0.5) n()
445
486
  Gizmos:drawPyramid(p, 1, 1) n()
487
+ Gizmos:drawCone(p, y, 1, 30) n()
446
488
  Gizmos:drawCFrame(CFrame.new(p)) n()
447
489
  Gizmos:drawText(p, 'Hello') n()
448
490
  Gizmos:drawRaycast(p, z, nil) n()
@@ -457,6 +499,14 @@ function Gizmos:test()
457
499
  Gizmos:drawCircle(p, 0.15)
458
500
  p += Vector3.xAxis*1
459
501
  end
502
+
503
+ -- Cones from narrow/long to wide/short, including the melee hit-volume case
504
+ -- (range 7, halfAngle 45). Each should read clearly as a 3D cone.
505
+ Gizmos:setColor('cyan')
506
+ Gizmos:drawCone(Vector3.new(0, 0, 16), y, 4, 10) -- narrow / long
507
+ Gizmos:drawCone(Vector3.new(8, 0, 16), y, 4, 30)
508
+ Gizmos:drawCone(Vector3.new(20, 0, 16), y, 7, 45) -- wide / short (melee)
509
+ Gizmos:drawCone(Vector3.new(34, 0, 16), y, 4, 60) -- very wide
460
510
  end
461
511
 
462
512
  findOrMakeGizmos()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rbxts/gizmos",
3
- "version": "1.0.1",
3
+ "version": "1.2.0",
4
4
  "description": "TypeScript port of sg3cko's Gizmos library - Debug drawing utilities for Roblox including shapes, raycasts, paths, and world-space text.",
5
5
  "main": "out/init.lua",
6
6
  "scripts": {