@pascal-app/editor 0.7.0 → 0.9.1

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.
Files changed (244) hide show
  1. package/package.json +12 -13
  2. package/src/components/editor/alignment-3d-guide-layer.tsx +160 -0
  3. package/src/components/editor/custom-camera-controls.tsx +755 -25
  4. package/src/components/editor/editor-layout-mobile.tsx +3 -3
  5. package/src/components/editor/editor-layout-v2.tsx +62 -54
  6. package/src/components/editor/export-manager.tsx +32 -3
  7. package/src/components/editor/first-person/build-collider-world.test.ts +149 -0
  8. package/src/components/editor/first-person/build-collider-world.ts +203 -87
  9. package/src/components/editor/first-person/bvh-ecctrl.tsx +127 -62
  10. package/src/components/editor/first-person-controls.tsx +836 -31
  11. package/src/components/editor/floating-action-menu.tsx +287 -196
  12. package/src/components/editor/floating-building-action-menu.tsx +1 -1
  13. package/src/components/editor/floorplan-panel.tsx +5837 -12006
  14. package/src/components/editor/grid.tsx +51 -17
  15. package/src/components/editor/group-move-handle.tsx +316 -0
  16. package/src/components/editor/group-rotate-handle.tsx +382 -0
  17. package/src/components/editor/group-transform-shared.test.ts +205 -0
  18. package/src/components/editor/group-transform-shared.ts +256 -0
  19. package/src/components/editor/handles/handle-arrow.tsx +523 -0
  20. package/src/components/editor/handles/use-handle-drag.ts +213 -0
  21. package/src/components/editor/index.tsx +234 -190
  22. package/src/components/editor/measurement-pill.tsx +75 -0
  23. package/src/components/editor/node-arrow-handles.tsx +1453 -0
  24. package/src/components/editor/selection-manager.tsx +435 -158
  25. package/src/components/editor/site-edge-labels.tsx +44 -20
  26. package/src/components/editor/slab-hole-highlights.tsx +466 -0
  27. package/src/components/editor/snapshot-capture-overlay.tsx +539 -0
  28. package/src/components/editor/thumbnail-generator.tsx +27 -64
  29. package/src/components/editor/use-floorplan-background-placement.ts +122 -35
  30. package/src/components/editor/use-floorplan-hit-testing.ts +24 -0
  31. package/src/components/editor/use-floorplan-scene-data.ts +14 -2
  32. package/src/components/editor/wall-measurement-label.tsx +11 -6
  33. package/src/components/editor/wall-move-side-handles.tsx +855 -0
  34. package/src/components/editor/wall-opening-highlights.tsx +181 -0
  35. package/src/components/editor/wall-snap-beacon-layer.tsx +150 -0
  36. package/src/components/editor-2d/floorplan-action-menu-layer.tsx +6 -1
  37. package/src/components/editor-2d/floorplan-alignment-guide-layer.tsx +142 -0
  38. package/src/components/editor-2d/floorplan-cursor-indicator-overlay.tsx +5 -3
  39. package/src/components/editor-2d/floorplan-registry-action-menu.tsx +227 -0
  40. package/src/components/editor-2d/floorplan-registry-move-overlay.tsx +616 -0
  41. package/src/components/editor-2d/floorplan-render-context.tsx +62 -0
  42. package/src/components/editor-2d/floorplan-snap-beacon-layer.tsx +75 -0
  43. package/src/components/editor-2d/floorplan-wall-move-ghost-layer.tsx +47 -0
  44. package/src/components/editor-2d/renderers/floorplan-draft-layer.tsx +6 -1
  45. package/src/components/editor-2d/renderers/floorplan-geometry-renderer.tsx +266 -0
  46. package/src/components/editor-2d/renderers/floorplan-measurements-layer.tsx +108 -61
  47. package/src/components/editor-2d/renderers/floorplan-placement-preview-layer.tsx +59 -0
  48. package/src/components/editor-2d/renderers/floorplan-registry-layer.tsx +1963 -0
  49. package/src/components/editor-2d/renderers/floorplan-stair-layer.tsx +29 -14
  50. package/src/components/editor-2d/svg-paths.ts +10 -2
  51. package/src/components/systems/ceiling/ceiling-selection-affordance-system.tsx +30 -9
  52. package/src/components/systems/ceiling/ceiling-system.tsx +12 -8
  53. package/src/components/systems/roof/roof-edit-system.tsx +86 -12
  54. package/src/components/systems/stair/stair-edit-system.tsx +2 -2
  55. package/src/components/systems/zone/zone-label-editor-system.tsx +0 -0
  56. package/src/components/systems/zone/zone-system.tsx +0 -0
  57. package/src/components/tools/elevator/elevator-defaults.ts +8 -0
  58. package/src/components/tools/elevator/elevator-tool.tsx +349 -0
  59. package/src/components/tools/elevator/move-elevator-tool.tsx +252 -0
  60. package/src/components/tools/fence/fence-drafting.ts +64 -22
  61. package/src/components/tools/item/move-tool.tsx +40 -107
  62. package/src/components/tools/item/placement-math.test.ts +10 -0
  63. package/src/components/tools/item/placement-math.ts +33 -9
  64. package/src/components/tools/item/placement-strategies.ts +201 -25
  65. package/src/components/tools/item/placement-types.ts +10 -1
  66. package/src/components/tools/item/use-draft-node.ts +20 -2
  67. package/src/components/tools/item/use-placement-coordinator.tsx +700 -299
  68. package/src/components/tools/registry/move-registry-node-tool.tsx +602 -0
  69. package/src/components/tools/roof/roof-tool.tsx +108 -12
  70. package/src/components/tools/select/box-select-state.ts +77 -0
  71. package/src/components/tools/select/box-select-tool.tsx +324 -543
  72. package/src/components/tools/select/plane-box-select-tool.tsx +577 -0
  73. package/src/components/tools/select/screen-rectangle-selection.ts +84 -0
  74. package/src/components/tools/select/select-candidates.test.ts +109 -0
  75. package/src/components/tools/select/select-candidates.ts +85 -0
  76. package/src/components/tools/shared/affordance-dispatch.ts +30 -0
  77. package/src/components/tools/shared/drag-bounding-box.tsx +171 -0
  78. package/src/components/tools/shared/floor-stack-preview.ts +25 -0
  79. package/src/components/tools/shared/fresh-placement-visibility.ts +61 -0
  80. package/src/components/tools/shared/placement-box-geometry.ts +123 -0
  81. package/src/components/tools/shared/placement-box.tsx +123 -0
  82. package/src/components/tools/shared/polygon-editor.tsx +617 -167
  83. package/src/components/tools/shared/segment-angle.ts +57 -1
  84. package/src/components/tools/site/site-boundary-editor.tsx +464 -12
  85. package/src/components/tools/site/site-flag-model.ts +18 -0
  86. package/src/components/tools/stair/stair-defaults.ts +1 -1
  87. package/src/components/tools/stair/stair-tool.tsx +269 -35
  88. package/src/components/tools/tool-manager.tsx +172 -56
  89. package/src/components/tools/wall/wall-drafting.ts +98 -98
  90. package/src/components/tools/wall/wall-snap-geometry.test.ts +79 -0
  91. package/src/components/tools/wall/wall-snap-geometry.ts +270 -0
  92. package/src/components/tools/zone/zone-tool.tsx +36 -11
  93. package/src/components/ui/action-menu/action-button.tsx +21 -1
  94. package/src/components/ui/action-menu/camera-actions.tsx +0 -0
  95. package/src/components/ui/action-menu/control-modes.tsx +5 -76
  96. package/src/components/ui/action-menu/furnish-tools.tsx +6 -92
  97. package/src/components/ui/action-menu/index.tsx +33 -196
  98. package/src/components/ui/action-menu/structure-tools.tsx +13 -88
  99. package/src/components/ui/action-menu/view-toggles.tsx +262 -37
  100. package/src/components/ui/command-palette/editor-commands.tsx +24 -17
  101. package/src/components/ui/command-palette/index.tsx +6 -256
  102. package/src/components/ui/controls/material-paint-panel.tsx +83 -0
  103. package/src/components/ui/controls/material-picker.tsx +17 -35
  104. package/src/components/ui/controls/metric-control.tsx +33 -11
  105. package/src/components/ui/floating-level-selector.tsx +48 -11
  106. package/src/components/ui/helpers/helper-manager.tsx +21 -17
  107. package/src/components/ui/helpers/registered-tool-helper.tsx +25 -0
  108. package/src/components/ui/item-catalog/catalog-items.tsx +1743 -315
  109. package/src/components/ui/item-catalog/item-catalog.tsx +91 -46
  110. package/src/components/ui/level-duplicate-dialog.tsx +5 -6
  111. package/src/components/ui/panels/node-display.ts +1 -0
  112. package/src/components/ui/panels/paint-panel.tsx +66 -41
  113. package/src/components/ui/panels/panel-manager.tsx +33 -74
  114. package/src/components/ui/panels/panel-wrapper.tsx +217 -12
  115. package/src/components/ui/panels/parametric-inspector.tsx +469 -0
  116. package/src/components/ui/panels/reference-panel.tsx +28 -13
  117. package/src/components/ui/primitives/dropdown-menu.tsx +12 -8
  118. package/src/components/ui/primitives/number-input.tsx +1 -1
  119. package/src/components/ui/primitives/sidebar.tsx +0 -0
  120. package/src/components/ui/scene-loader.tsx +1 -3
  121. package/src/components/ui/sidebar/app-sidebar.tsx +0 -0
  122. package/src/components/ui/sidebar/icon-rail.tsx +0 -0
  123. package/src/components/ui/sidebar/panels/items-panel/function-tree-panel.tsx +263 -0
  124. package/src/components/ui/sidebar/panels/items-panel/index.tsx +404 -0
  125. package/src/components/ui/sidebar/panels/settings-panel/index.tsx +59 -9
  126. package/src/components/ui/sidebar/panels/settings-panel/keyboard-shortcuts-dialog.tsx +6 -1
  127. package/src/components/ui/sidebar/panels/settings-panel/load-build-dialog.tsx +259 -0
  128. package/src/components/ui/sidebar/panels/site-panel/building-tree-node.tsx +3 -1
  129. package/src/components/ui/sidebar/panels/site-panel/ceiling-tree-node.tsx +5 -2
  130. package/src/components/ui/sidebar/panels/site-panel/chimney-tree-node.tsx +83 -0
  131. package/src/components/ui/sidebar/panels/site-panel/dormer-tree-node.tsx +89 -0
  132. package/src/components/ui/sidebar/panels/site-panel/elevator-tree-node.tsx +75 -0
  133. package/src/components/ui/sidebar/panels/site-panel/fence-tree-node.tsx +2 -2
  134. package/src/components/ui/sidebar/panels/site-panel/gutter-tree-node.tsx +83 -0
  135. package/src/components/ui/sidebar/panels/site-panel/index.tsx +8 -12
  136. package/src/components/ui/sidebar/panels/site-panel/level-tree-node.tsx +2 -1
  137. package/src/components/ui/sidebar/panels/site-panel/registry-tree-node.tsx +93 -0
  138. package/src/components/ui/sidebar/panels/site-panel/roof-tree-node.tsx +41 -5
  139. package/src/components/ui/sidebar/panels/site-panel/shelf-tree-node.tsx +128 -0
  140. package/src/components/ui/sidebar/panels/site-panel/slab-tree-node.tsx +5 -2
  141. package/src/components/ui/sidebar/panels/site-panel/solar-panel-tree-node.tsx +83 -0
  142. package/src/components/ui/sidebar/panels/site-panel/spawn-tree-node.tsx +1 -1
  143. package/src/components/ui/sidebar/panels/site-panel/tree-node.tsx +68 -34
  144. package/src/components/ui/sidebar/panels/site-panel/zone-tree-node.tsx +3 -1
  145. package/src/components/ui/sidebar/panels/zone-panel/index.tsx +52 -3
  146. package/src/components/ui/sidebar/tab-bar.tsx +61 -1
  147. package/src/components/ui/slider.tsx +1 -1
  148. package/src/components/viewer-overlay.tsx +169 -52
  149. package/src/components/viewer-zone-system.tsx +1 -1
  150. package/src/hooks/use-auto-save.ts +24 -3
  151. package/src/hooks/use-ceiling-events.ts +175 -0
  152. package/src/hooks/use-drag-action.ts +124 -0
  153. package/src/hooks/use-keyboard.ts +125 -62
  154. package/src/hooks/use-selection.ts +64 -0
  155. package/src/index.tsx +243 -4
  156. package/src/lib/constants.ts +6 -2
  157. package/src/lib/editor-api.ts +62 -0
  158. package/src/lib/elevator-support.ts +96 -0
  159. package/src/lib/floorplan/apply-alignment.ts +111 -0
  160. package/src/lib/floorplan/index.ts +7 -0
  161. package/src/lib/floorplan/selection-tool.ts +40 -0
  162. package/src/lib/floorplan/stairs.ts +12 -1
  163. package/src/lib/fresh-planar-placement.test.ts +102 -0
  164. package/src/lib/fresh-planar-placement.ts +63 -0
  165. package/src/lib/history.ts +2 -1
  166. package/src/lib/level-duplication.test.ts +0 -2
  167. package/src/lib/level-duplication.ts +55 -43
  168. package/src/lib/level-name.ts +11 -0
  169. package/src/lib/material-paint.ts +212 -20
  170. package/src/lib/placement-metadata.ts +29 -0
  171. package/src/lib/planar-cursor-placement.test.ts +43 -0
  172. package/src/lib/planar-cursor-placement.ts +42 -0
  173. package/src/lib/roof-duplication.ts +2 -2
  174. package/src/lib/scene-bounds.ts +1 -1
  175. package/src/lib/scene-clipboard.ts +267 -0
  176. package/src/lib/scene.ts +13 -4
  177. package/src/lib/sfx-bus.ts +25 -1
  178. package/src/lib/sfx-player.ts +75 -27
  179. package/src/lib/site-boundary.ts +1 -0
  180. package/src/lib/stair-duplication.ts +2 -2
  181. package/src/lib/stair-levels.test.ts +146 -0
  182. package/src/lib/stair-levels.ts +177 -0
  183. package/src/lib/world-grid-snap.ts +199 -0
  184. package/src/lib/zone-content.ts +130 -0
  185. package/src/store/use-alignment-guides.ts +21 -0
  186. package/src/store/use-editor.tsx +342 -91
  187. package/src/store/use-placement-preview.ts +31 -0
  188. package/src/store/use-wall-move-ghosts.ts +36 -0
  189. package/src/store/use-wall-snap-indicator.ts +32 -0
  190. package/tsconfig.json +2 -1
  191. package/src/components/editor/preset-thumbnail-generator.tsx +0 -125
  192. package/src/components/editor-2d/renderers/floorplan-roof-layer.tsx +0 -113
  193. package/src/components/feedback-dialog.tsx +0 -265
  194. package/src/components/pascal-radio.tsx +0 -280
  195. package/src/components/preview-button.tsx +0 -16
  196. package/src/components/tools/building/move-building-tool.tsx +0 -157
  197. package/src/components/tools/ceiling/ceiling-boundary-editor.tsx +0 -43
  198. package/src/components/tools/ceiling/ceiling-hole-editor.tsx +0 -49
  199. package/src/components/tools/ceiling/ceiling-tool.tsx +0 -465
  200. package/src/components/tools/ceiling/move-ceiling-tool.tsx +0 -257
  201. package/src/components/tools/column/column-tool.tsx +0 -97
  202. package/src/components/tools/column/move-column-tool.tsx +0 -105
  203. package/src/components/tools/door/door-math.ts +0 -110
  204. package/src/components/tools/door/door-tool.tsx +0 -324
  205. package/src/components/tools/door/move-door-tool.tsx +0 -412
  206. package/src/components/tools/fence/curve-fence-tool.tsx +0 -179
  207. package/src/components/tools/fence/fence-tool.tsx +0 -346
  208. package/src/components/tools/fence/move-fence-endpoint-tool.tsx +0 -438
  209. package/src/components/tools/fence/move-fence-tool.tsx +0 -298
  210. package/src/components/tools/item/item-tool.tsx +0 -26
  211. package/src/components/tools/roof/move-roof-tool.tsx +0 -359
  212. package/src/components/tools/slab/move-slab-tool.tsx +0 -182
  213. package/src/components/tools/slab/slab-boundary-editor.tsx +0 -43
  214. package/src/components/tools/slab/slab-hole-editor.tsx +0 -49
  215. package/src/components/tools/slab/slab-tool.tsx +0 -322
  216. package/src/components/tools/spawn/move-spawn-tool.tsx +0 -101
  217. package/src/components/tools/spawn/spawn-tool.tsx +0 -130
  218. package/src/components/tools/wall/curve-wall-tool.tsx +0 -176
  219. package/src/components/tools/wall/move-wall-endpoint-tool.tsx +0 -423
  220. package/src/components/tools/wall/move-wall-tool.tsx +0 -356
  221. package/src/components/tools/wall/wall-tool.tsx +0 -332
  222. package/src/components/tools/window/move-window-tool.tsx +0 -447
  223. package/src/components/tools/window/window-math.ts +0 -117
  224. package/src/components/tools/window/window-tool.tsx +0 -332
  225. package/src/components/ui/helpers/ceiling-helper.tsx +0 -20
  226. package/src/components/ui/helpers/slab-helper.tsx +0 -20
  227. package/src/components/ui/helpers/wall-helper.tsx +0 -20
  228. package/src/components/ui/panels/ceiling-panel.tsx +0 -250
  229. package/src/components/ui/panels/column-panel.tsx +0 -715
  230. package/src/components/ui/panels/door-panel.tsx +0 -1292
  231. package/src/components/ui/panels/fence-panel.tsx +0 -227
  232. package/src/components/ui/panels/item-panel.tsx +0 -306
  233. package/src/components/ui/panels/presets/presets-popover.tsx +0 -511
  234. package/src/components/ui/panels/roof-panel.tsx +0 -230
  235. package/src/components/ui/panels/roof-segment-panel.tsx +0 -311
  236. package/src/components/ui/panels/slab-panel.tsx +0 -250
  237. package/src/components/ui/panels/spawn-panel.tsx +0 -155
  238. package/src/components/ui/panels/stair-panel.tsx +0 -525
  239. package/src/components/ui/panels/stair-segment-panel.tsx +0 -325
  240. package/src/components/ui/panels/wall-panel.tsx +0 -177
  241. package/src/components/ui/panels/window-panel.tsx +0 -960
  242. package/src/components/ui/viewer-toolbar.tsx +0 -436
  243. package/src/contexts/presets-context.tsx +0 -121
  244. package/src/hooks/use-contextual-tools.ts +0 -61
@@ -1,15 +1,8 @@
1
1
  import '../../../three-types'
2
2
  import { TransformControls, useKeyboardControls } from '@react-three/drei'
3
- import { useFrame, useThree, type ThreeElements } from '@react-three/fiber'
4
- import {
5
- Suspense,
6
- forwardRef,
7
- useCallback,
8
- useImperativeHandle,
9
- useMemo,
10
- useRef,
11
- } from 'react'
3
+ import { type ThreeElements, useFrame, useThree } from '@react-three/fiber'
12
4
  import type { ReactNode } from 'react'
5
+ import { forwardRef, Suspense, useCallback, useImperativeHandle, useMemo, useRef } from 'react'
13
6
  import * as THREE from 'three'
14
7
  import { clamp } from 'three/src/math/MathUtils.js'
15
8
 
@@ -156,16 +149,7 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
156
149
  const moveDirRef = useRef<THREE.ArrowHelper | null>(null)
157
150
  const elapsedRef = useRef(0)
158
151
 
159
- function useIsInsideKeyboardControls() {
160
- try {
161
- return !!useKeyboardControls()
162
- } catch {
163
- return false
164
- }
165
- }
166
-
167
- const isInsideKeyboardControls = useIsInsideKeyboardControls()
168
- const [_, getKeys] = isInsideKeyboardControls ? useKeyboardControls() : [null, null]
152
+ const [, getKeys] = useKeyboardControls()
169
153
  const presetKeys = {
170
154
  forward: false,
171
155
  backward: false,
@@ -222,11 +206,11 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
222
206
  const scaledContactRadiusVec = useRef(new THREE.Vector3())
223
207
  const deltaDist = useRef(new THREE.Vector3())
224
208
  const currSlopeAngle = useRef(0)
225
- const localMinDistance = useRef(Infinity)
209
+ const localMinDistance = useRef(Number.POSITIVE_INFINITY)
226
210
  const localClosestPoint = useRef(new THREE.Vector3())
227
211
  const localHitNormal = useRef(new THREE.Vector3())
228
212
  const triNormal = useRef(new THREE.Vector3())
229
- const globalMinDistance = useRef(Infinity)
213
+ const globalMinDistance = useRef(Number.POSITIVE_INFINITY)
230
214
  const globalClosestPoint = useRef(new THREE.Vector3())
231
215
  const triHitPoint = useRef(new THREE.Vector3())
232
216
  const segHitPoint = useRef(new THREE.Vector3())
@@ -286,7 +270,13 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
286
270
  const moving = currentLinVel.current.lengthSq() > 1e-6
287
271
  const platformIsMoving = totalPlatformDeltaPos.current.lengthSq() > 1e-6
288
272
 
289
- if (!moving && isOnGround.current && !jump && !isOnMovingPlatform.current && !platformIsMoving) {
273
+ if (
274
+ !moving &&
275
+ isOnGround.current &&
276
+ !jump &&
277
+ !isOnMovingPlatform.current &&
278
+ !platformIsMoving
279
+ ) {
290
280
  idleTime.current += delta
291
281
  if (idleTime.current > sleepTimeout) isSleeping.current = true
292
282
  } else {
@@ -340,7 +330,10 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
340
330
  upAxis.current,
341
331
  )
342
332
  characterModelTargetQuat.current.setFromRotationMatrix(characterModelLookMatrix.current)
343
- characterModelRef.current.quaternion.slerp(characterModelTargetQuat.current, delta * turnSpeed)
333
+ characterModelRef.current.quaternion.slerp(
334
+ characterModelTargetQuat.current,
335
+ delta * turnSpeed,
336
+ )
344
337
  }
345
338
 
346
339
  const maxSpeed = run ? maxRunSpeed : maxWalkSpeed
@@ -358,18 +351,33 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
358
351
  )
359
352
  currentLinVel.current.add(deltaLinVel.current)
360
353
  } else if (isOnGround.current) {
361
- deltaLinVel.current.copy(currentLinVelOnPlane.current).clampLength(0, deceleration * friction * delta)
354
+ deltaLinVel.current
355
+ .copy(currentLinVelOnPlane.current)
356
+ .clampLength(0, deceleration * friction * delta)
362
357
  currentLinVel.current.sub(deltaLinVel.current)
363
358
  }
364
359
  },
365
- [acceleration, airDragFactor, counterAccFactor, deceleration, maxRunSpeed, maxWalkSpeed, turnSpeed, characterOrigin],
360
+ [
361
+ acceleration,
362
+ airDragFactor,
363
+ counterAccFactor,
364
+ deceleration,
365
+ maxRunSpeed,
366
+ maxWalkSpeed,
367
+ turnSpeed,
368
+ characterOrigin,
369
+ ],
366
370
  )
367
371
 
368
372
  const updateSegmentBBox = useCallback(() => {
369
373
  if (!characterGroupRef.current) return
370
374
 
371
- characterSegment.current.start.set(0, capsuleLength / 2, 0).add(characterGroupRef.current.position)
372
- characterSegment.current.end.set(0, -capsuleLength / 2, 0).add(characterGroupRef.current.position)
375
+ characterSegment.current.start
376
+ .set(0, capsuleLength / 2, 0)
377
+ .add(characterGroupRef.current.position)
378
+ characterSegment.current.end
379
+ .set(0, -capsuleLength / 2, 0)
380
+ .add(characterGroupRef.current.position)
373
381
 
374
382
  characterBbox.current
375
383
  .makeEmpty()
@@ -394,11 +402,18 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
394
402
 
395
403
  const collisionCheck = useCallback(
396
404
  (mesh: THREE.Mesh, originMatrix: THREE.Matrix4, delta: number) => {
397
- if (!mesh.visible || !mesh.geometry.boundsTree || mesh.userData.excludeCollisionCheck) return
405
+ if (!(mesh.visible && mesh.geometry.boundsTree) || mesh.userData.excludeCollisionCheck)
406
+ return
398
407
 
399
- originMatrix.decompose(contactTempPos.current, contactTempQuat.current, contactTempScale.current)
408
+ originMatrix.decompose(
409
+ contactTempPos.current,
410
+ contactTempQuat.current,
411
+ contactTempScale.current,
412
+ )
400
413
  collideInvertMatrix.current.copy(originMatrix).invert()
401
- localCharacterSegment.current.copy(characterSegment.current).applyMatrix4(collideInvertMatrix.current)
414
+ localCharacterSegment.current
415
+ .copy(characterSegment.current)
416
+ .applyMatrix4(collideInvertMatrix.current)
402
417
 
403
418
  scaledContactRadiusVec.current.set(
404
419
  capsuleRadius / contactTempScale.current.x,
@@ -445,7 +460,10 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
445
460
  contactDepth.current =
446
461
  capsuleRadius - capsuleContactPoint.current.distanceTo(triContactPoint.current)
447
462
 
448
- accumulatedContactNormal.current.addScaledVector(contactNormal.current, contactDepth.current)
463
+ accumulatedContactNormal.current.addScaledVector(
464
+ contactNormal.current,
465
+ contactDepth.current,
466
+ )
449
467
  accumulatedContactPoint.current.add(triContactPoint.current)
450
468
  totalDepth.current += contactDepth.current
451
469
  triangleCount.current += 1
@@ -492,14 +510,16 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
492
510
 
493
511
  const floatingCheck = useCallback(
494
512
  (mesh: THREE.Mesh, originMatrix: THREE.Matrix4) => {
495
- if (!mesh.visible || !mesh.geometry.boundsTree || mesh.userData.excludeFloatHit) return
513
+ if (!(mesh.visible && mesh.geometry.boundsTree) || mesh.userData.excludeFloatHit) return
496
514
 
497
515
  originMatrix.decompose(floatTempPos.current, floatTempQuat.current, floatTempScale.current)
498
516
  floatInvertMatrix.current.copy(originMatrix).invert()
499
517
  floatNormalInverseMatrix.current.getNormalMatrix(floatInvertMatrix.current)
500
518
  floatNormalMatrix.current.getNormalMatrix(originMatrix)
501
519
 
502
- localFloatSensorSegment.current.copy(floatSensorSegment.current).applyMatrix4(floatInvertMatrix.current)
520
+ localFloatSensorSegment.current
521
+ .copy(floatSensorSegment.current)
522
+ .applyMatrix4(floatInvertMatrix.current)
503
523
  localFloatSensorBboxExpendPoint.current
504
524
  .copy(floatSensorBboxExpendPoint.current)
505
525
  .applyMatrix4(floatInvertMatrix.current)
@@ -517,20 +537,33 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
517
537
  localFloatSensorBbox.current.min.addScaledVector(scaledFloatRadiusVec.current, -1)
518
538
  localFloatSensorBbox.current.max.add(scaledFloatRadiusVec.current)
519
539
 
520
- localMinDistance.current = Infinity
521
- localClosestPoint.current.set(Infinity, Infinity, Infinity)
540
+ localMinDistance.current = Number.POSITIVE_INFINITY
541
+ localClosestPoint.current.set(
542
+ Number.POSITIVE_INFINITY,
543
+ Number.POSITIVE_INFINITY,
544
+ Number.POSITIVE_INFINITY,
545
+ )
522
546
 
523
547
  mesh.geometry.boundsTree.shapecast({
524
548
  intersectsBounds: (box) => box.intersectsBox(localFloatSensorBbox.current),
525
549
  intersectsTriangle: (tri) => {
526
- tri.closestPointToSegment(localFloatSensorSegment.current, triHitPoint.current, segHitPoint.current)
527
- localUpAxis.current.copy(upAxis.current).applyMatrix3(floatNormalInverseMatrix.current).normalize()
550
+ tri.closestPointToSegment(
551
+ localFloatSensorSegment.current,
552
+ triHitPoint.current,
553
+ segHitPoint.current,
554
+ )
555
+ localUpAxis.current
556
+ .copy(upAxis.current)
557
+ .applyMatrix3(floatNormalInverseMatrix.current)
558
+ .normalize()
528
559
  deltaHit.current.subVectors(triHitPoint.current, localFloatSensorSegment.current.start)
529
560
  deltaHit.current.divide(scaledFloatRadiusVec.current)
530
561
 
531
562
  const totalLengthSq = deltaHit.current.lengthSq()
532
563
  const dot = deltaHit.current.dot(localUpAxis.current)
533
- const verticalLength = Math.abs(dot) / ((capsuleRadius + floatHeight + floatPullBackHeight) / floatSensorRadius)
564
+ const verticalLength =
565
+ Math.abs(dot) /
566
+ ((capsuleRadius + floatHeight + floatPullBackHeight) / floatSensorRadius)
534
567
  const horizontalLength = Math.sqrt(Math.max(0, totalLengthSq - dot * dot))
535
568
 
536
569
  if (horizontalLength < 1 && verticalLength < 1) {
@@ -560,9 +593,14 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
560
593
  const handleFloatingResponse = useCallback(
561
594
  (meshes: THREE.Mesh[], jump: boolean, delta: number) => {
562
595
  if (meshes.length === 0) return
596
+ let shouldJump = jump
563
597
 
564
- globalMinDistance.current = Infinity
565
- globalClosestPoint.current.set(Infinity, Infinity, Infinity)
598
+ globalMinDistance.current = Number.POSITIVE_INFINITY
599
+ globalClosestPoint.current.set(
600
+ Number.POSITIVE_INFINITY,
601
+ Number.POSITIVE_INFINITY,
602
+ Number.POSITIVE_INFINITY,
603
+ )
566
604
  floatHitNormal.current.set(0, 1, 0)
567
605
  isOnGround.current = false
568
606
  totalPlatformDeltaPos.current.set(0, 0, 0)
@@ -574,7 +612,11 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
574
612
  }
575
613
  }
576
614
 
577
- if (floatCheckType !== 'SHAPECAST' && floatRaycastCandidates.length > 0 && globalMinDistance.current === Infinity) {
615
+ if (
616
+ floatCheckType !== 'SHAPECAST' &&
617
+ floatRaycastCandidates.length > 0 &&
618
+ globalMinDistance.current === Number.POSITIVE_INFINITY
619
+ ) {
578
620
  floatRaycaster.current.ray.origin.copy(floatSensorSegment.current.start)
579
621
  floatRaycaster.current.ray.direction.copy(gravityDir.current)
580
622
  const hits = floatRaycaster.current.intersectObjects(floatRaycastCandidates, false)
@@ -582,23 +624,28 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
582
624
  if (hit?.point) {
583
625
  globalClosestPoint.current.copy(hit.point)
584
626
  if (hit.face) {
585
- floatHitNormal.current.copy(hit.face.normal).transformDirection(hit.object.matrixWorld).normalize()
627
+ floatHitNormal.current
628
+ .copy(hit.face.normal)
629
+ .transformDirection(hit.object.matrixWorld)
630
+ .normalize()
586
631
  }
587
632
  }
588
633
  }
589
634
 
590
- if (globalClosestPoint.current.x === Infinity) return
635
+ if (globalClosestPoint.current.x === Number.POSITIVE_INFINITY) return
591
636
 
592
- relativeHitPoint.current.copy(globalClosestPoint.current).sub(floatSensorSegment.current.start)
637
+ relativeHitPoint.current
638
+ .copy(globalClosestPoint.current)
639
+ .sub(floatSensorSegment.current.start)
593
640
  const currentDistance = relativeHitPoint.current.length()
594
641
  currSlopeAngle.current = floatHitNormal.current.angleTo(upAxis.current)
595
642
 
596
643
  if (currentDistance < floatHeight + capsuleRadius) {
597
644
  isOnGround.current = true
598
- jump = false
645
+ shouldJump = false
599
646
  }
600
647
 
601
- if (!jump) {
648
+ if (!shouldJump) {
602
649
  const displacement = floatHeight + capsuleRadius - currentDistance
603
650
  const velocityOnHitNormal = currentLinVel.current.dot(floatHitNormal.current)
604
651
  const springForce = displacement * floatSpringK
@@ -608,7 +655,17 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
608
655
  currentLinVel.current.addScaledVector(floatHitNormal.current, (totalForce / mass) * delta)
609
656
  }
610
657
  },
611
- [capsuleRadius, floatCheckType, floatDampingC, floatHeight, floatRaycastCandidates, floatSpringK, floatingCheck, gravity, mass],
658
+ [
659
+ capsuleRadius,
660
+ floatCheckType,
661
+ floatDampingC,
662
+ floatHeight,
663
+ floatRaycastCandidates,
664
+ floatSpringK,
665
+ floatingCheck,
666
+ gravity,
667
+ mass,
668
+ ],
612
669
  )
613
670
 
614
671
  const updateCharacterWithPlatform = useCallback(() => {
@@ -616,7 +673,7 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
616
673
  rotationDeltaPos.current.copy(totalPlatformDeltaPos.current)
617
674
  characterGroupRef.current.position.add(rotationDeltaPos.current)
618
675
  yawQuaternion.current.setFromUnitVectors(upAxis.current, floatHitNormal.current)
619
- }, [upAxis])
676
+ }, [])
620
677
 
621
678
  const updateCharacterAnimation = useCallback(
622
679
  (run: boolean, jump: boolean): CharacterAnimationStatus => {
@@ -646,8 +703,14 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
646
703
  )
647
704
 
648
705
  const resetLinVel = useCallback(() => currentLinVel.current.set(0, 0, 0), [])
649
- const addLinVel = useCallback((velocity: THREE.Vector3) => currentLinVel.current.add(velocity), [])
650
- const setLinVel = useCallback((velocity: THREE.Vector3) => currentLinVel.current.copy(velocity), [])
706
+ const addLinVel = useCallback(
707
+ (velocity: THREE.Vector3) => currentLinVel.current.add(velocity),
708
+ [],
709
+ )
710
+ const setLinVel = useCallback(
711
+ (velocity: THREE.Vector3) => currentLinVel.current.copy(velocity),
712
+ [],
713
+ )
651
714
  const setMovement = useCallback((movement: MovementInput) => {
652
715
  if (movement.forward !== undefined) forwardState.current = movement.forward
653
716
  if (movement.backward !== undefined) backwardState.current = movement.backward
@@ -682,7 +745,9 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
682
745
  debugRaySensorEnd.current?.position.copy(floatSensorSegment.current.end)
683
746
  standPointRef.current?.position.copy(globalClosestPoint.current)
684
747
  if (characterGroupRef.current) {
685
- lookDirRef.current?.position.copy(characterGroupRef.current.position).addScaledVector(upAxis.current, 0.7)
748
+ lookDirRef.current?.position
749
+ .copy(characterGroupRef.current.position)
750
+ .addScaledVector(upAxis.current, 0.7)
686
751
  }
687
752
  lookDirRef.current?.lookAt(lookDirRef.current.position.clone().add(camProjDir.current))
688
753
  inputDirRef.current?.position.copy(characterSegment.current.end)
@@ -691,20 +756,20 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
691
756
  moveDirRef.current?.position.copy(characterSegment.current.end)
692
757
  moveDirRef.current?.setDirection(currentLinVel.current)
693
758
  moveDirRef.current?.setLength(currentLinVel.current.length() / maxWalkSpeed)
694
- }, [characterSegment, maxWalkSpeed])
759
+ }, [maxWalkSpeed])
695
760
 
696
761
  useFrame((_, delta) => {
697
762
  elapsedRef.current += delta
698
763
  if (paused || elapsedRef.current < delay) return
699
764
 
700
765
  const deltaTime = Math.min(1 / 45, delta) * slowMotionFactor
701
- const keys = isInsideKeyboardControls && getKeys ? getKeys() : presetKeys
702
- const forward = forwardState.current || keys.forward
703
- const backward = backwardState.current || keys.backward
704
- const leftward = leftwardState.current || keys.leftward
705
- const rightward = rightwardState.current || keys.rightward
706
- const run = runState.current || keys.run
707
- const jump = jumpState.current || keys.jump
766
+ const keys = getKeys() ?? presetKeys
767
+ const forward = forwardState.current || (keys.forward ?? false)
768
+ const backward = backwardState.current || (keys.backward ?? false)
769
+ const leftward = leftwardState.current || (keys.leftward ?? false)
770
+ const rightward = rightwardState.current || (keys.rightward ?? false)
771
+ const run = runState.current || (keys.run ?? false)
772
+ const jump = jumpState.current || (keys.jump ?? false)
708
773
 
709
774
  setInputDirection({
710
775
  forward,
@@ -740,7 +805,7 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
740
805
 
741
806
  return (
742
807
  <Suspense fallback={null}>
743
- <group {...props} ref={characterGroupRef} dispose={null}>
808
+ <group {...props} dispose={null} ref={characterGroupRef}>
744
809
  {debug && (
745
810
  <mesh ref={characterColliderRef}>
746
811
  <capsuleGeometry args={colliderCapsuleArgs} />
@@ -777,8 +842,8 @@ const BVHEcctrl = forwardRef<BVHEcctrlApi, EcctrlProps>(
777
842
  <octahedronGeometry args={[0.1, 0]} />
778
843
  <meshNormalMaterial />
779
844
  </mesh>
780
- <arrowHelper ref={inputDirRef} args={[undefined, undefined, undefined, '#00f']} />
781
- <arrowHelper ref={moveDirRef} args={[undefined, undefined, undefined, '#f00']} />
845
+ <arrowHelper args={[undefined, undefined, undefined, '#00f']} ref={inputDirRef} />
846
+ <arrowHelper args={[undefined, undefined, undefined, '#f00']} ref={moveDirRef} />
782
847
  <mesh ref={standPointRef}>
783
848
  <octahedronGeometry args={[0.12, 0]} />
784
849
  <meshBasicMaterial color="red" opacity={0.2} transparent />