ohzi-core 13.3.0 → 15.0.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.
Files changed (226) hide show
  1. package/README.md +2 -1
  2. package/build/index.mjs +1 -1
  3. package/build/index.mjs.map +1 -1
  4. package/package.json +12 -6
  5. package/src/Capabilities.ts +0 -2
  6. package/src/Debug.ts +38 -33
  7. package/src/Graphics.ts +2 -2
  8. package/src/Initializer.ts +2 -1
  9. package/src/SceneManager.ts +4 -5
  10. package/src/action_sequencer/NumberInterpolator.ts +2 -0
  11. package/src/blitter_index.ts +1 -2
  12. package/src/camera_controller/CameraController.ts +106 -63
  13. package/src/camera_controller/states/common/CommonCameraState.ts +2 -1
  14. package/src/components/AxisHelper.ts +1 -0
  15. package/src/components/Line.ts +35 -27
  16. package/src/components/PlaneHelper.ts +1 -1
  17. package/src/components/Text2D.ts +3 -1
  18. package/src/components/WorldImage.ts +27 -20
  19. package/src/components/sdf_text/SDFTextBatch.ts +16 -26
  20. package/src/dev_bridge/CameraBridge.ts +363 -0
  21. package/src/dev_bridge/CaptureService.ts +256 -0
  22. package/src/dev_bridge/CommandDispatcher.ts +114 -0
  23. package/src/dev_bridge/ConsoleBuffer.ts +286 -0
  24. package/src/dev_bridge/DebugDrawer.ts +399 -0
  25. package/src/dev_bridge/DevBridge.ts +195 -0
  26. package/src/dev_bridge/InputSynthesizer.ts +287 -0
  27. package/src/dev_bridge/PerformanceProbe.ts +118 -0
  28. package/src/dev_bridge/RenderModeRegistry.ts +66 -0
  29. package/src/dev_bridge/SceneEditor.ts +288 -0
  30. package/src/dev_bridge/SceneInspector.ts +388 -0
  31. package/src/dev_bridge/ViewNavigator.ts +101 -0
  32. package/src/dev_bridge/protocol.ts +31 -0
  33. package/src/index.ts +21 -14
  34. package/src/materials/AddMaterial.ts +14 -7
  35. package/src/materials/BlitNodeMaterial.ts +85 -0
  36. package/src/materials/BloomComposeMaterial.ts +21 -9
  37. package/src/materials/BoxBlurMaterial.ts +26 -6
  38. package/src/materials/ClearDepthNormalMaterial.ts +12 -6
  39. package/src/materials/DepthNormalMaterial.ts +25 -14
  40. package/src/materials/DualFilteringBlurMaterial.ts +32 -5
  41. package/src/materials/GaussianBlurMaterial.ts +36 -14
  42. package/src/materials/LineMaterial.ts +52 -0
  43. package/src/materials/LuminosityHighPassMaterial.ts +23 -10
  44. package/src/materials/NormalMaterial.ts +10 -11
  45. package/src/materials/SDFTextMaterial.ts +63 -16
  46. package/src/materials/SSAOComposeMaterial.ts +14 -5
  47. package/src/materials/SSAOMaterial.ts +123 -24
  48. package/src/materials/ScreenSpaceTextureMaterial.ts +19 -31
  49. package/src/materials/UnrealBloomComposeMaterial.ts +41 -32
  50. package/src/materials/WorldImageMaterial.ts +51 -0
  51. package/src/materials/deferred/DeferredPointLightMaterial.ts +45 -14
  52. package/src/materials/deferred/depth_normal_encoding.ts +36 -0
  53. package/src/primitives/Cube.ts +1 -1
  54. package/src/primitives/Sphere.ts +1 -1
  55. package/src/raycast/GroupRaycaster.ts +2 -2
  56. package/src/render_mode/BloomRender.ts +18 -4
  57. package/src/render_mode/DebugNormalsRender.ts +6 -1
  58. package/src/render_mode/DeferredRender.ts +5 -34
  59. package/src/render_mode/NormalAORender.ts +9 -19
  60. package/src/render_mode/UnrealBloomRender.ts +2 -1
  61. package/src/render_mode/VRRender.ts +6 -3
  62. package/src/render_utilities/Blitter.ts +4 -4
  63. package/src/render_utilities/Blurrer.ts +7 -0
  64. package/src/render_utilities/DualFilteringBlurrer.ts +26 -10
  65. package/src/resource_loader/AudioLoader.ts +5 -3
  66. package/src/resource_loader/HDRTextureLoader.ts +1 -1
  67. package/src/scenes/AbstractScene.ts +7 -3
  68. package/src/scenes/Compilator.ts +5 -1
  69. package/src/scenes/loading_states/LoadingState.ts +15 -7
  70. package/src/scenes/loading_states/RegularLoadingState.ts +2 -1
  71. package/src/utilities/CameraUtilities.ts +57 -79
  72. package/src/utilities/HTMLUtilities.ts +2 -1
  73. package/src/utilities/MeshSampler.ts +8 -1
  74. package/src/utilities/OrthographicFrustumPointFitter.ts +53 -4
  75. package/src/view_components/ApplicationView.ts +1 -1
  76. package/src/view_components/ViewComponent.ts +1 -1
  77. package/src/view_components/ViewManager.ts +7 -1
  78. package/src/view_components/transition/DrawIOAnimationSheet.ts +1 -1
  79. package/types/Capabilities.d.ts +0 -1
  80. package/types/SceneManager.d.ts +1 -1
  81. package/types/blitter_index.d.ts +1 -2
  82. package/types/camera_controller/CameraController.d.ts +9 -0
  83. package/types/components/Line.d.ts +3 -2
  84. package/types/components/WorldImage.d.ts +3 -2
  85. package/types/index.d.ts +2 -7
  86. package/types/materials/AddMaterial.d.ts +2 -2
  87. package/types/materials/BlitNodeMaterial.d.ts +18 -0
  88. package/types/materials/BloomComposeMaterial.d.ts +2 -2
  89. package/types/materials/BoxBlurMaterial.d.ts +2 -2
  90. package/types/materials/ClearDepthNormalMaterial.d.ts +2 -2
  91. package/types/materials/DepthNormalMaterial.d.ts +2 -2
  92. package/types/materials/DualFilteringBlurMaterial.d.ts +2 -2
  93. package/types/materials/GaussianBlurMaterial.d.ts +2 -2
  94. package/types/materials/LuminosityHighPassMaterial.d.ts +2 -2
  95. package/types/materials/NormalMaterial.d.ts +2 -2
  96. package/types/materials/SDFTextMaterial.d.ts +2 -2
  97. package/types/materials/SSAOComposeMaterial.d.ts +2 -2
  98. package/types/materials/SSAOMaterial.d.ts +2 -2
  99. package/types/materials/ScreenSpaceTextureMaterial.d.ts +2 -2
  100. package/types/materials/UnrealBloomComposeMaterial.d.ts +2 -2
  101. package/types/materials/deferred/DeferredPointLightMaterial.d.ts +2 -2
  102. package/types/render_mode/DeferredRender.d.ts +0 -2
  103. package/types/render_mode/NormalAORender.d.ts +0 -2
  104. package/types/render_utilities/Blitter.d.ts +2 -2
  105. package/types/render_utilities/DualFilteringBlurrer.d.ts +0 -2
  106. package/types/utilities/CameraUtilities.d.ts +0 -1
  107. package/types/utilities/OrthographicFrustumPointFitter.d.ts +14 -8
  108. package/build/index.module.js +0 -2
  109. package/build/index.module.js.map +0 -1
  110. package/src/components/EdgeMesh.ts +0 -150
  111. package/src/components/GeometryEdgeVisualizer.ts +0 -49
  112. package/src/components/MultiLinePath.ts +0 -25
  113. package/src/components/MultiLineText2D.ts +0 -65
  114. package/src/components/Shape2D.ts +0 -42
  115. package/src/components/Shape3D.ts +0 -38
  116. package/src/gpu_particles/GPUParticleSystem.ts +0 -122
  117. package/src/gpu_particles/ParticleAttribute.ts +0 -110
  118. package/src/gpu_particles/ParticlePositionAttribute.ts +0 -46
  119. package/src/materials/AlphaFilterMaterial.ts +0 -21
  120. package/src/materials/BaseShaderMaterial.ts +0 -20
  121. package/src/materials/BlitMaterial.ts +0 -27
  122. package/src/materials/DeferredRendererComposeMaterial.ts +0 -36
  123. package/src/materials/DisplayNormalTextureMaterial.ts +0 -18
  124. package/src/materials/FXAAMaterial.ts +0 -12
  125. package/src/materials/MedianFilterMaterial.ts +0 -46
  126. package/src/materials/SDFScreenTextMaterial.ts +0 -32
  127. package/src/materials/UnrealBlurMaterial.ts +0 -20
  128. package/src/materials/UnrealComposeMaterial.ts +0 -27
  129. package/src/materials/ViewPositionMaterial.ts +0 -19
  130. package/src/materials/gpu_particles/AttributeUpdateMaterial.ts +0 -35
  131. package/src/materials/gpu_particles/BasicParticleMaterial.ts +0 -25
  132. package/src/materials/gpu_particles/ParticleStorageMaterial.ts +0 -36
  133. package/src/materials/gpu_particles/PositionStorageMaterial.ts +0 -27
  134. package/src/render_utilities/MedianFilter.ts +0 -72
  135. package/src/render_utilities/ViewPositionRenderer.ts +0 -53
  136. package/src/shaders/add/add.frag +0 -28
  137. package/src/shaders/anti_aliasing/fxaa.frag +0 -72
  138. package/src/shaders/basic_color/basic_color.frag +0 -6
  139. package/src/shaders/basic_color/basic_color.vert +0 -10
  140. package/src/shaders/basic_line/basic_line.frag +0 -37
  141. package/src/shaders/basic_line/basic_line.vert +0 -37
  142. package/src/shaders/basic_texture/basic_texture.frag +0 -10
  143. package/src/shaders/basic_texture/basic_texture.vert +0 -17
  144. package/src/shaders/bloom/bloom_compose.frag +0 -22
  145. package/src/shaders/bloom/cheap_bloom_compose.frag +0 -13
  146. package/src/shaders/box_blur/box_blur.frag +0 -24
  147. package/src/shaders/box_blur/compose.frag +0 -31
  148. package/src/shaders/clear/clear_depth_normal.frag +0 -25
  149. package/src/shaders/copy/copy.frag +0 -7
  150. package/src/shaders/copy/copy.vert +0 -6
  151. package/src/shaders/deferred/blit_copy.vert +0 -11
  152. package/src/shaders/deferred/deferred_compose.frag +0 -59
  153. package/src/shaders/deferred/point_light.frag +0 -66
  154. package/src/shaders/deferred/point_light.vert +0 -13
  155. package/src/shaders/depth_normals/debug_normals.frag +0 -48
  156. package/src/shaders/depth_normals/depth_normals.frag +0 -30
  157. package/src/shaders/depth_normals/depth_normals.vert +0 -13
  158. package/src/shaders/dual_filter_blur/alpha_filter.frag +0 -14
  159. package/src/shaders/dual_filter_blur/downsample.frag +0 -21
  160. package/src/shaders/dual_filter_blur/upsample.frag +0 -24
  161. package/src/shaders/edge_visualizer/edge_visualizer.frag +0 -18
  162. package/src/shaders/edge_visualizer/edge_visualizer.vert +0 -16
  163. package/src/shaders/edges/corners.frag +0 -11
  164. package/src/shaders/edges/corners.vert +0 -31
  165. package/src/shaders/edges/edges.frag +0 -7
  166. package/src/shaders/edges/edges.vert +0 -27
  167. package/src/shaders/gaussian_blur/gaussian_blur.frag +0 -44
  168. package/src/shaders/gaussian_blur/unreal_bloom_compose.frag +0 -36
  169. package/src/shaders/gpu_particles/common_utils.glsl +0 -13
  170. package/src/shaders/gpu_particles/generic_storage.frag +0 -6
  171. package/src/shaders/gpu_particles/store/store_position.vert +0 -14
  172. package/src/shaders/gpu_particles/update/basic_update.frag +0 -21
  173. package/src/shaders/gpu_particles/visualize/visualize.frag +0 -11
  174. package/src/shaders/gpu_particles/visualize/visualize.vert +0 -12
  175. package/src/shaders/grid/grid.frag +0 -17
  176. package/src/shaders/grid/grid.vert +0 -10
  177. package/src/shaders/luminosity_high_pass/luminosity_high_pass.frag +0 -38
  178. package/src/shaders/median_filter/median_filter.frag +0 -134
  179. package/src/shaders/normal/normal.frag +0 -6
  180. package/src/shaders/normal/normal.vert +0 -6
  181. package/src/shaders/sdf_text/sdf_screen_text.frag +0 -51
  182. package/src/shaders/sdf_text/sdf_screen_text.vert +0 -42
  183. package/src/shaders/sdf_text/sdf_text.frag +0 -53
  184. package/src/shaders/sdf_text/sdf_text.vert +0 -42
  185. package/src/shaders/ssao/hbao.frag +0 -264
  186. package/src/shaders/ssao/ssao.frag +0 -95
  187. package/src/shaders/ssao/ssao.vert +0 -11
  188. package/src/shaders/ssao/ssao_compose.frag +0 -14
  189. package/src/shaders/transparent_mix/copy.frag +0 -7
  190. package/src/shaders/transparent_mix/transparent_mix.frag +0 -19
  191. package/src/shaders/transparent_mix/transparent_mix.vert +0 -8
  192. package/src/shaders/ui/ss_texture.frag +0 -11
  193. package/src/shaders/ui/ss_texture.vert +0 -32
  194. package/src/shaders/ui/ws_texture.vert +0 -39
  195. package/src/shaders/unreal_blur/unreal_blur.frag +0 -25
  196. package/src/shaders/unreal_blur/unreal_compose.frag +0 -24
  197. package/src/shaders/write_view_position/write_view_position.frag +0 -7
  198. package/src/shaders/write_view_position/write_view_position.vert +0 -9
  199. package/src/types.d.ts +0 -14
  200. package/types/components/EdgeMesh.d.ts +0 -16
  201. package/types/components/GeometryEdgeVisualizer.d.ts +0 -8
  202. package/types/components/MultiLinePath.d.ts +0 -8
  203. package/types/components/MultiLineText2D.d.ts +0 -12
  204. package/types/components/Shape2D.d.ts +0 -7
  205. package/types/components/Shape3D.d.ts +0 -6
  206. package/types/gpu_particles/GPUParticleSystem.d.ts +0 -19
  207. package/types/gpu_particles/ParticleAttribute.d.ts +0 -20
  208. package/types/gpu_particles/ParticlePositionAttribute.d.ts +0 -6
  209. package/types/materials/AlphaFilterMaterial.d.ts +0 -7
  210. package/types/materials/BaseShaderMaterial.d.ts +0 -4
  211. package/types/materials/BlitMaterial.d.ts +0 -4
  212. package/types/materials/DeferredRendererComposeMaterial.d.ts +0 -10
  213. package/types/materials/DisplayNormalTextureMaterial.d.ts +0 -4
  214. package/types/materials/FXAAMaterial.d.ts +0 -5
  215. package/types/materials/MedianFilterMaterial.d.ts +0 -8
  216. package/types/materials/SDFScreenTextMaterial.d.ts +0 -8
  217. package/types/materials/UIElementMaterial.d.ts +0 -4
  218. package/types/materials/UnrealBlurMaterial.d.ts +0 -5
  219. package/types/materials/UnrealComposeMaterial.d.ts +0 -5
  220. package/types/materials/ViewPositionMaterial.d.ts +0 -5
  221. package/types/materials/gpu_particles/AttributeUpdateMaterial.d.ts +0 -8
  222. package/types/materials/gpu_particles/BasicParticleMaterial.d.ts +0 -5
  223. package/types/materials/gpu_particles/ParticleStorageMaterial.d.ts +0 -5
  224. package/types/materials/gpu_particles/PositionStorageMaterial.d.ts +0 -5
  225. package/types/render_utilities/MedianFilter.d.ts +0 -12
  226. package/types/render_utilities/ViewPositionRenderer.d.ts +0 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ohzi-core",
3
- "version": "13.3.0",
3
+ "version": "15.0.0",
4
4
  "description": "OHZI Interactive Core Library",
5
5
  "type": "module",
6
6
  "source": "src/index.ts",
@@ -21,12 +21,16 @@
21
21
  "build": "rollup -c",
22
22
  "create-tag": "node tasks/app/create_tag.mjs",
23
23
  "fix-syntax": "npx eslint src --fix || echo 'Done.'",
24
+ "test": "vitest run",
25
+ "test-watch": "vitest",
24
26
  "generate-types": "npx -p typescript tsc",
25
27
  "upload": "yarn build && npm publish && yarn create-tag",
26
28
  "create-view": "node ./tasks/create_view/create_view.mjs",
27
29
  "create-scene": "node ./tasks/create_scene/create_scene.mjs",
28
30
  "create-component": "node ./tasks/create_component/create_component.mjs",
29
- "create-transition": "node ./tasks/create_transition/create_transition.mjs"
31
+ "create-transition": "node ./tasks/create_transition/create_transition.mjs",
32
+ "test-unit": "vitest run --project unit",
33
+ "test-browser": "vitest run --project browser"
30
34
  },
31
35
  "repository": {
32
36
  "type": "git",
@@ -46,22 +50,24 @@
46
50
  "registry": "https://registry.npmjs.org/"
47
51
  },
48
52
  "dependencies": {
49
- "three": "0.183.0"
53
+ "three": "0.186.0"
50
54
  },
51
55
  "devDependencies": {
52
56
  "@rollup/plugin-typescript": "^12.3.0",
53
57
  "@types/node": "^25.0.3",
54
- "@types/three": "0.183.0",
58
+ "@types/three": "0.186.0",
55
59
  "@typescript-eslint/eslint-plugin": "^8.18.2",
56
60
  "@typescript-eslint/parser": "^8.18.2",
61
+ "@vitest/browser-playwright": "4.1.11",
57
62
  "eslint": "^8.57.0",
58
63
  "eslint-config-prettier": "^10.1.8",
64
+ "playwright": "^1.63.0",
59
65
  "rollup": "^2.44.0",
60
- "rollup-plugin-glslify": "^1.2.0",
61
66
  "rollup-plugin-sourcemaps": "^0.6.3",
62
67
  "rollup-plugin-terser": "^7.0.2",
63
68
  "tslib": "^2.8.1",
64
69
  "typescript": "^5.9.3",
65
- "typescript-eslint": "^8.18.2"
70
+ "typescript-eslint": "^8.18.2",
71
+ "vitest": "^4.1.11"
66
72
  }
67
73
  }
@@ -1,13 +1,11 @@
1
1
  class Capabilities
2
2
  {
3
- fp_textures_available: boolean;
4
3
  max_anisotropy: number;
5
4
  vertex_texture_sampler_available: boolean;
6
5
  init()
7
6
  {
8
7
  this.max_anisotropy = 0;
9
8
  this.vertex_texture_sampler_available = false;
10
- this.fp_textures_available = false;
11
9
  }
12
10
  }
13
11
 
package/src/Debug.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { AxisHelper } from './components/AxisHelper';
2
+ import { Text2D } from './components/Text2D';
2
3
 
3
4
  import { ScreenSpaceTextureMaterial } from './materials/ScreenSpaceTextureMaterial';
4
5
  import { OScreen } from './OScreen';
@@ -8,12 +9,17 @@ import { Cube } from './primitives/Cube';
8
9
  import { Sphere } from './primitives/Sphere';
9
10
  import { SceneManager } from './SceneManager';
10
11
 
11
- import type { RenderTarget, Texture, Vector2 } from 'three';
12
- import { Box3, Box3Helper, BufferGeometry, CatmullRomCurve3, Line, LineBasicMaterial, Mesh, MeshBasicMaterial, PlaneGeometry, Scene, ShaderMaterial, SphereGeometry, Vector3, Vector4 } from 'three';
12
+ import type { RenderTarget, Texture } from 'three';
13
+ import { Box3, Box3Helper, BufferGeometry, CatmullRomCurve3, Color, Line, LineBasicMaterial, Mesh, MeshBasicMaterial, PlaneGeometry, Scene, SphereGeometry, Vector2, Vector3 } from 'three';
14
+ import { MeshBasicNodeMaterial } from 'three/webgpu';
13
15
  import { CameraManager } from './CameraManager';
14
- import type { AbstractScene, Graphics } from './index';
15
- import basic_color_frag from './shaders/basic_color/basic_color.frag';
16
- import basic_color_vert from './shaders/basic_color/basic_color.vert';
16
+ import type { Graphics } from './index';
17
+
18
+ // 20% opaque, and never hides what is drawn after it.
19
+ function see_through_material(color: number | string): MeshBasicNodeMaterial
20
+ {
21
+ return new MeshBasicNodeMaterial({ color, opacity: 0.2, transparent: true, depthWrite: false });
22
+ }
17
23
 
18
24
  class Debug
19
25
  {
@@ -22,9 +28,9 @@ class Debug
22
28
  camera: PerspectiveCamera;
23
29
  canvas_renderer: any;
24
30
  ctx: any;
25
- display_texture_meshes: Mesh[];
31
+ display_texture_meshes: Mesh<PlaneGeometry, ScreenSpaceTextureMaterial>[];
26
32
  rt_debug: RenderTarget;
27
- scene: AbstractScene;
33
+ scene: Scene;
28
34
 
29
35
  init()
30
36
  {
@@ -104,7 +110,7 @@ class Debug
104
110
  draw_cube(pos?: Vector3, size?: number, color?: number | string)
105
111
  {
106
112
  size = size || 1;
107
- color = color || 0xff0000;
113
+ color = color ?? 0xff0000;
108
114
  pos = pos || new Vector3();
109
115
 
110
116
  const cube = new Cube(new Vector3(size, size, size), undefined, color);
@@ -135,18 +141,10 @@ class Debug
135
141
  return cube;
136
142
  }
137
143
 
138
- draw_plane(width?: number, height?: number, color?: number | string)
144
+ draw_plane(width?: number, height?: number, color: number | string = 0x00ff00)
139
145
  {
140
146
  const geometry = new PlaneGeometry(width, height);
141
- const material = new ShaderMaterial({
142
- uniforms: {
143
- _Color: { value: new Vector4(0, 1, 0, 0.2) }
144
- },
145
- vertexShader: basic_color_vert,
146
- fragmentShader: basic_color_frag,
147
- transparent: true,
148
- depthWrite: false
149
- });
147
+ const material = see_through_material(color);
150
148
 
151
149
  const plane = new Mesh(geometry, material);
152
150
  plane.renderOrder = -10000;
@@ -157,7 +155,7 @@ class Debug
157
155
  draw_empty_cube(pos: Vector3, size: number, color: number | string)
158
156
  {
159
157
  size = size || 1;
160
- color = color || 0xff0000;
158
+ color = color ?? 0xff0000;
161
159
 
162
160
  const box = new Box3().setFromCenterAndSize(new Vector3(), new Vector3(size, size, size));
163
161
  const helper = new Box3Helper(box, color);
@@ -168,7 +166,7 @@ class Debug
168
166
  draw_sphere(pos: Vector3, size: number, color: number | string)
169
167
  {
170
168
  size = size || 1;
171
- color = color || 0xff0000;
169
+ color = color ?? 0xff0000;
172
170
  pos = pos || new Vector3();
173
171
 
174
172
  const sphere = new Sphere(size, color);
@@ -189,7 +187,7 @@ class Debug
189
187
 
190
188
  draw_sphere_helper(sphere: any, color: number | string)
191
189
  {
192
- color = color || 0xff0000;
190
+ color = color ?? 0xff0000;
193
191
  const geometry = new SphereGeometry(sphere.radius, 32, 32);
194
192
  const material = new MeshBasicMaterial({ color: color });
195
193
  const sphere_mesh = new Mesh(geometry, material);
@@ -198,27 +196,21 @@ class Debug
198
196
  return sphere_mesh;
199
197
  }
200
198
 
201
- draw_math_sphere(sphere: any)
199
+ draw_math_sphere(sphere: any, color: number | string = 0xff0000)
202
200
  {
203
201
  const geometry = new SphereGeometry(sphere.radius, 32, 32);
204
- const material = new ShaderMaterial({
205
- uniforms: {
206
- _Color: { value: new Vector4(1, 0, 0, 0.2) }
207
- },
208
- vertexShader: basic_color_vert,
209
- fragmentShader: basic_color_frag,
210
- transparent: true
211
- });
212
- // var material = new MeshBasicMaterial( {color: 0xff0000, transparent = true} );
202
+ const material = see_through_material(color);
213
203
  const sphere1 = new Mesh(geometry, material);
214
204
  sphere1.position.copy(sphere.center);
215
205
  SceneManager.current.add(sphere1);
206
+ return sphere1;
216
207
  }
217
208
 
218
- draw_bounding_box(bb: Box3)
209
+ draw_bounding_box(bb: Box3, color: number | string = 0xffff00)
219
210
  {
220
- const helper = new Box3Helper(bb, 0xffff00);
211
+ const helper = new Box3Helper(bb, color);
221
212
  SceneManager.current.add(helper);
213
+ return helper;
222
214
  }
223
215
 
224
216
  draw_curve(curve: Vector3[], options: { offset: number })
@@ -238,6 +230,8 @@ class Debug
238
230
  draw_texture(tex: Texture, w: number, h: number)
239
231
  {
240
232
  const mesh = new Mesh(new PlaneGeometry(1, 1), new ScreenSpaceTextureMaterial());
233
+ // Placed in screen space by its material, so the camera frustum says nothing about it.
234
+ mesh.frustumCulled = false;
241
235
  this.display_texture_meshes.push(mesh);
242
236
  this.scene.add(mesh);
243
237
 
@@ -245,6 +239,17 @@ class Debug
245
239
  return mesh;
246
240
  }
247
241
 
242
+ // Text that always faces the camera, size world units tall, centered on pos.
243
+ draw_label(text: string, pos?: Vector3, size: number = 1, color: number | string = 0xffffff)
244
+ {
245
+ const label = new Text2D(text, 'bold 48px Arial', new Color(color).getStyle(), new Vector2());
246
+ label.size = new Vector3(size, size, size);
247
+ label.screen_aligned = true;
248
+ label.position.copy(pos || new Vector3());
249
+ this.scene.add(label);
250
+ return label;
251
+ }
252
+
248
253
  render(graphics: typeof Graphics)
249
254
  {
250
255
  for (let i = 0; i < this.display_texture_meshes.length; i++)
package/src/Graphics.ts CHANGED
@@ -124,7 +124,7 @@ class Graphics
124
124
  }
125
125
  }
126
126
 
127
- render(scene?: AbstractScene, camera?: PerspectiveCamera | OrthographicCamera, RT?: RenderTarget, override_mat?: Material): void
127
+ render(scene?: Scene, camera?: PerspectiveCamera | OrthographicCamera, RT?: RenderTarget, override_mat?: Material): void
128
128
  {
129
129
  this.__apply_override_material(scene, override_mat);
130
130
 
@@ -181,7 +181,7 @@ class Graphics
181
181
  }
182
182
  }
183
183
 
184
- __apply_override_material(scene: AbstractScene, mat: Material): void
184
+ __apply_override_material(scene: Scene, mat: Material): void
185
185
  {
186
186
  mat = mat === undefined ? null : mat;
187
187
  if (scene)
@@ -10,6 +10,7 @@ import { OScreen } from './OScreen';
10
10
  import { ReflectionPlaneContext } from './ReflectionPlaneContext';
11
11
  import { ResourceContainer } from './ResourceContainer';
12
12
  import { SceneManager } from './SceneManager';
13
+ import { AbstractScene } from './scenes/AbstractScene';
13
14
  import { Time } from './Time';
14
15
  import { CameraUtilities } from './utilities/CameraUtilities';
15
16
 
@@ -29,7 +30,7 @@ class Initializer
29
30
  Browser.init();
30
31
  ReflectionPlaneContext.init();
31
32
  ResourceContainer.init();
32
- SceneManager.init();
33
+ SceneManager.init(new AbstractScene({ name: 'default_scene', compilators: {} }));
33
34
  OScreen.init();
34
35
  Time.init();
35
36
 
@@ -1,14 +1,13 @@
1
1
  import type { Mesh } from 'three';
2
- import { AbstractScene } from './scenes/AbstractScene';
2
+ import type { AbstractScene } from './scenes/AbstractScene';
3
3
 
4
4
  class SceneManager
5
5
  {
6
6
  _current: AbstractScene;
7
-
8
- init(): void
7
+
8
+ init(default_scene: AbstractScene): void
9
9
  {
10
- this._current = new AbstractScene({ name: 'default_scene', compilators: {} });
11
- this._current.name = 'default_scene';
10
+ this._current = default_scene;
12
11
  }
13
12
 
14
13
  add_scene(name: string): void
@@ -3,6 +3,8 @@ import { ActionInterpolator } from './ActionInterpolator';
3
3
 
4
4
  class NumberInterpolator extends ActionInterpolator
5
5
  {
6
+ declare from: number;
7
+ declare to: number;
6
8
  initial: boolean;
7
9
 
8
10
  constructor(attribute_name: string, from: number = 0, to: number = 1, initial: boolean = false, easing_function: string = 'linear')
@@ -1,9 +1,8 @@
1
1
  import { Blitter } from './render_utilities/Blitter';
2
2
  import { Blurrer } from './render_utilities/Blurrer';
3
3
  import { GaussianBlurrer } from './render_utilities/GaussianBlurrer';
4
- import { MedianFilter } from './render_utilities/MedianFilter';
5
4
 
6
5
  import { DualFilteringBlurMaterial } from './materials/DualFilteringBlurMaterial';
7
6
  export {
8
- Blitter, Blurrer, DualFilteringBlurMaterial, GaussianBlurrer, MedianFilter
7
+ Blitter, Blurrer, DualFilteringBlurMaterial, GaussianBlurrer
9
8
  };
@@ -1,6 +1,6 @@
1
1
  import { ImmediateMode } from './movement_mode/ImmediateMode';
2
2
 
3
- import type { Camera, Points } from 'three';
3
+ import type { OrthographicCamera, PerspectiveCamera, Points } from 'three';
4
4
  import { PlaneHelper, Quaternion, Vector3 } from 'three';
5
5
  // import { PlaneHelper } from 'three';
6
6
  import { Plane } from 'three';
@@ -8,8 +8,6 @@ import { Plane } from 'three';
8
8
  import { Box3, Ray } from 'three';
9
9
 
10
10
  import { OScreen } from '../OScreen';
11
- import type { OrthographicCamera } from '../OrthographicCamera';
12
- import type { PerspectiveCamera } from '../PerspectiveCamera';
13
11
  import type { Input } from '../lib/Input';
14
12
  import type { Cube } from '../primitives/Cube';
15
13
  import type { Sphere } from '../primitives/Sphere';
@@ -22,7 +20,7 @@ import { AbstractCameraState } from './states/common/AbstractCameraState';
22
20
  export class CameraController
23
21
  {
24
22
  __last_reference_position: Vector3;
25
- camera: PerspectiveCamera;
23
+ camera: PerspectiveCamera | OrthographicCamera;
26
24
  camera_initial_pos: Vector3;
27
25
  camera_initial_rot: Quaternion;
28
26
  current_azimuth: number;
@@ -119,7 +117,7 @@ export class CameraController
119
117
  this.input_enabled = false;
120
118
  }
121
119
 
122
- set_camera(camera: Camera)
120
+ set_camera(camera: PerspectiveCamera | OrthographicCamera)
123
121
  {
124
122
  this.camera = camera;
125
123
  this.camera_initial_rot = camera.quaternion.clone();
@@ -185,13 +183,15 @@ export class CameraController
185
183
  return this.normalized_zoom < 0.2;
186
184
  }
187
185
 
188
- set_rotation(tilt: number, orientation: number, azimuth = 0)
186
+ // Arguments are nullish-checked, not falsy-checked: a falsy check discards a
187
+ // value of 0, which made it impossible to return any angle to zero.
188
+ set_rotation(tilt?: number, orientation?: number, azimuth?: number)
189
189
  {
190
190
  this.old_orientation = this.current_orientation;
191
191
 
192
- this.current_tilt = tilt || this.current_tilt;
193
- this.current_orientation = orientation || this.current_orientation;
194
- this.current_azimuth = azimuth || this.current_azimuth;
192
+ this.current_tilt = tilt ?? this.current_tilt;
193
+ this.current_orientation = orientation ?? this.current_orientation;
194
+ this.current_azimuth = azimuth ?? this.current_azimuth;
195
195
 
196
196
  this.set_quaternion(this.build_rotation(this.current_tilt, this.current_orientation)); //, this.current_azimuth
197
197
  }
@@ -220,8 +220,11 @@ export class CameraController
220
220
  const xΘ = Math.atan2(q.x, q.w) * 2;
221
221
  const yΘ = Math.atan2(q.y, q.w) * 2;
222
222
 
223
- this.current_orientation = OMath.radToDeg(yΘ) % 360;
224
- this.current_tilt = OMath.radToDeg(xΘ) * -1;
223
+ // Both angles come out up to 360 degrees off: past an orientation of 180,
224
+ // and for -q, which is the same rotation. Orientation is kept in [0, 360),
225
+ // like build_rotation, and tilt in (-180, 180].
226
+ this.current_orientation = OMath.euclideanModulo(OMath.radToDeg(yΘ), 360);
227
+ this.current_tilt = 180 - OMath.euclideanModulo(180 + OMath.radToDeg(xΘ), 360);
225
228
 
226
229
  this.reference_rotation.copy(q);
227
230
  }
@@ -283,42 +286,21 @@ export class CameraController
283
286
 
284
287
  focus_on_bounding_box(bb: Box3, scale = 1)
285
288
  {
286
- if ((this.camera as OrthographicCamera).isOrthographicCamera)
287
- {
288
- bb.getSize(this.tmp_size);
289
-
290
- const obj_x = this.tmp_size.x;
291
- const obj_y = this.tmp_size.y;
292
- const object_aspect = obj_x / obj_y;
293
- if (OScreen.aspect_ratio / object_aspect > 1)
294
- {
295
- (this.camera).zoom = OScreen.height / obj_y;
296
- }
297
- else
298
- {
299
- (this.camera).zoom = OScreen.width / obj_x;
300
- }
301
-
302
- bb.getCenter(this.reference_position);
303
- }
304
- else
305
- {
306
- const dir = new Vector3();
307
- dir.copy(bb.max).sub(bb.min);
289
+ const dir = new Vector3();
290
+ dir.copy(bb.max).sub(bb.min);
308
291
 
309
- const p1 = bb.min.clone();
292
+ const p1 = bb.min.clone();
310
293
 
311
- const p2 = p1.clone().add(new Vector3(dir.x, 0, 0));
312
- const p3 = p1.clone().add(new Vector3(0, dir.y, 0));
313
- const p4 = p1.clone().add(new Vector3(0, 0, dir.z));
294
+ const p2 = p1.clone().add(new Vector3(dir.x, 0, 0));
295
+ const p3 = p1.clone().add(new Vector3(0, dir.y, 0));
296
+ const p4 = p1.clone().add(new Vector3(0, 0, dir.z));
314
297
 
315
- const p5 = p1.clone().add(new Vector3(dir.x, 0, dir.z));
316
- const p6 = p1.clone().add(new Vector3(0, dir.y, dir.z));
317
- const p7 = bb.max.clone();
318
- const p8 = p1.clone().add(new Vector3(dir.x, dir.y, 0));
298
+ const p5 = p1.clone().add(new Vector3(dir.x, 0, dir.z));
299
+ const p6 = p1.clone().add(new Vector3(0, dir.y, dir.z));
300
+ const p7 = bb.max.clone();
301
+ const p8 = p1.clone().add(new Vector3(dir.x, dir.y, 0));
319
302
 
320
- this.focus_camera_on_points([p1, p2, p3, p4, p5, p6, p7, p8], scale);
321
- }
303
+ this.focus_camera_on_points([p1, p2, p3, p4, p5, p6, p7, p8], scale);
322
304
  }
323
305
 
324
306
  // get_zoom_to_focus_on_bounding_box(bb, tilt, orientation)
@@ -345,6 +327,11 @@ export class CameraController
345
327
 
346
328
  get_zoom_to_focus_on_points(points: Vector3[], scale: number)
347
329
  {
330
+ if (this.__is_orthographic())
331
+ {
332
+ return this.__fit_orthographic(this.reference_rotation, points, scale).zoom;
333
+ }
334
+
348
335
  const old_zoom = this.reference_zoom;
349
336
  const old_pos = new Vector3().copy(this.reference_position);
350
337
  this.focus_camera_on_points(points, scale);
@@ -356,6 +343,11 @@ export class CameraController
356
343
 
357
344
  get_target_pos_to_focus_on_points(points: Vector3[], scale: number)
358
345
  {
346
+ if (this.__is_orthographic())
347
+ {
348
+ return this.__fit_orthographic(this.reference_rotation, points, scale).center;
349
+ }
350
+
359
351
  const old_zoom = this.reference_zoom;
360
352
  const old_pos = new Vector3().copy(this.reference_position);
361
353
  this.focus_camera_on_points(points, scale);
@@ -369,14 +361,29 @@ export class CameraController
369
361
 
370
362
  focus_camera_on_sphere(sphere: Sphere, debug: boolean)
371
363
  {
372
- this.reference_zoom = this.get_zoom_to_sphere(sphere, debug);
364
+ if (this.__is_orthographic())
365
+ {
366
+ this.__set_orthographic_zoom(this.get_zoom_to_sphere(sphere, debug));
367
+ this.reference_zoom = this.__get_orthographic_distance(sphere.radius);
368
+ }
369
+ else
370
+ {
371
+ this.reference_zoom = this.get_zoom_to_sphere(sphere, debug);
372
+ }
373
373
  this.reference_position.copy(sphere.center);
374
374
  }
375
375
 
376
+ // For a perspective camera this is a distance; for an orthographic camera it
377
+ // is the camera zoom.
376
378
  get_zoom_to_sphere(sphere: Sphere, debug: boolean)
377
379
  {
378
- const v_fov = ((this.camera).fov / 2) * Math.PI / 180;
379
- const h_fov = (2 * Math.atan(Math.tan(v_fov) * (this.camera).aspect)) / 2;
380
+ if (this.__is_orthographic())
381
+ {
382
+ return this.__get_orthographic_zoom(sphere.radius * 2, sphere.radius * 2);
383
+ }
384
+
385
+ const v_fov = ((this.camera as PerspectiveCamera).fov / 2) * Math.PI / 180;
386
+ const h_fov = (2 * Math.atan(Math.tan(v_fov) * (this.camera as PerspectiveCamera).aspect)) / 2;
380
387
 
381
388
  // if(debug )
382
389
  // {
@@ -425,7 +432,7 @@ export class CameraController
425
432
 
426
433
  fit_points(quaternion: Quaternion, points: Vector3[], zoom_scale = 1)
427
434
  {
428
- if ((this.camera).isPerspectiveCamera)
435
+ if ((this.camera as PerspectiveCamera).isPerspectiveCamera)
429
436
  {
430
437
  const camera_forward_dir = new Vector3(0, 0, -1).applyQuaternion(quaternion);
431
438
  const camera_backward_dir = camera_forward_dir.clone().multiplyScalar(-1);
@@ -434,7 +441,7 @@ export class CameraController
434
441
 
435
442
  const aspect_ratio = OScreen.aspect_ratio;
436
443
 
437
- const camera_pos = fitter.fit_points(points, quaternion, ((this.camera).fov * zoom_scale), aspect_ratio);
444
+ const camera_pos = fitter.fit_points(points, quaternion, ((this.camera as PerspectiveCamera).fov * zoom_scale), aspect_ratio);
438
445
  const box = new Box3().setFromPoints(points);
439
446
  const center = new Vector3();
440
447
  box.getCenter(center);
@@ -456,24 +463,20 @@ export class CameraController
456
463
  }
457
464
  else
458
465
  {
459
- const fitter = new OrthographicFrustumPointFitter();
460
- const result = fitter.fit_points(points, this.reference_rotation, ((this.camera).fov * zoom_scale), OScreen.aspect_ratio);
461
-
462
- this.reference_position.copy(result.center);
463
- this.reference_zoom = result.distance_to_center;
466
+ const result = this.__fit_orthographic(quaternion, points, zoom_scale);
467
+ const camera_backward_dir = new Vector3(0, 0, 1).applyQuaternion(quaternion);
464
468
 
465
- const forward = new Vector3(0, 0, 1).applyQuaternion(quaternion);
466
469
  return {
467
- zoom: result.distance_to_center,
470
+ zoom: result.zoom,
468
471
  reference_position: result.center,
469
- camera_position: forward.multiplyScalar(result.distance_to_center)
472
+ camera_position: result.center.clone().add(camera_backward_dir.multiplyScalar(result.distance))
470
473
  };
471
474
  }
472
475
  }
473
476
 
474
477
  focus_camera_on_points(points: Vector3[], zoom_scale = 1)
475
478
  {
476
- if ((this.camera).isPerspectiveCamera)
479
+ if ((this.camera as PerspectiveCamera).isPerspectiveCamera)
477
480
  {
478
481
  const camera_forward_dir = new Vector3(0, 0, -1).applyQuaternion(this.reference_rotation);
479
482
  const camera_backward_dir = camera_forward_dir.clone().multiplyScalar(-1);
@@ -482,7 +485,7 @@ export class CameraController
482
485
 
483
486
  const aspect_ratio = OScreen.aspect_ratio;
484
487
 
485
- const camera_pos = fitter.fit_points(points, this.reference_rotation, ((this.camera).fov * zoom_scale), aspect_ratio);
488
+ const camera_pos = fitter.fit_points(points, this.reference_rotation, ((this.camera as PerspectiveCamera).fov * zoom_scale), aspect_ratio);
486
489
  const box = new Box3().setFromPoints(points);
487
490
  const center = new Vector3();
488
491
  box.getCenter(center);
@@ -501,11 +504,11 @@ export class CameraController
501
504
  }
502
505
  else
503
506
  {
504
- const fitter = new OrthographicFrustumPointFitter();
505
- const result = fitter.fit_points(points, this.reference_rotation, ((this.camera).fov * zoom_scale), OScreen.aspect_ratio);
507
+ const result = this.__fit_orthographic(this.reference_rotation, points, zoom_scale);
506
508
 
509
+ this.__set_orthographic_zoom(result.zoom);
510
+ this.reference_zoom = result.distance;
507
511
  this.reference_position.copy(result.center);
508
- this.reference_zoom = result.distance_to_center;
509
512
  }
510
513
  }
511
514
 
@@ -526,12 +529,52 @@ export class CameraController
526
529
 
527
530
  __get_zoom_to_show_rect(width: number, height: number, scale = 1)
528
531
  {
532
+ if (this.__is_orthographic())
533
+ {
534
+ return this.__get_orthographic_zoom(width * 2, height * 2, scale);
535
+ }
536
+
529
537
  // let v_fov = (this.camera.fov/2) * Math.PI/180;
530
- const v_fov = OMath.degToRad((this.camera).fov / 2);
531
- const h_fov = (2 * Math.atan(Math.tan(v_fov) * (this.camera).aspect)) / 2;
538
+ const v_fov = OMath.degToRad((this.camera as PerspectiveCamera).fov / 2);
539
+ const h_fov = (2 * Math.atan(Math.tan(v_fov) * (this.camera as PerspectiveCamera).aspect)) / 2;
532
540
 
533
541
  const distV = height / Math.tan(v_fov * scale);
534
542
  const distH = width / Math.tan(h_fov * scale);
535
543
  return Math.max(Math.abs(distH), Math.abs(distV));
536
544
  }
545
+
546
+ __is_orthographic()
547
+ {
548
+ return (this.camera as OrthographicCamera).isOrthographicCamera === true;
549
+ }
550
+
551
+ __fit_orthographic(quaternion: Quaternion, points: Vector3[], zoom_scale: number)
552
+ {
553
+ const bounds = new OrthographicFrustumPointFitter().get_view_bounds(points, quaternion);
554
+
555
+ return {
556
+ zoom: this.__get_orthographic_zoom(bounds.size.x, bounds.size.y, zoom_scale),
557
+ center: bounds.center,
558
+ distance: this.__get_orthographic_distance(bounds.size.z / 2)
559
+ };
560
+ }
561
+
562
+ // The current distance is kept when it fits the depth. ImmediateMode still
563
+ // clamps it to max_zoom, which must cover half the depth plus near.
564
+ __get_orthographic_distance(half_depth: number)
565
+ {
566
+ return new OrthographicFrustumPointFitter().get_distance_to_fit_depth(this.camera as OrthographicCamera, half_depth, this.reference_zoom);
567
+ }
568
+
569
+ __get_orthographic_zoom(width: number, height: number, scale = 1)
570
+ {
571
+ return new OrthographicFrustumPointFitter().get_zoom_to_fit_size(this.camera as OrthographicCamera, width, height, scale);
572
+ }
573
+
574
+ __set_orthographic_zoom(zoom: number)
575
+ {
576
+ const camera = this.camera as OrthographicCamera;
577
+ camera.zoom = zoom;
578
+ camera.updateProjectionMatrix();
579
+ }
537
580
  }
@@ -1,3 +1,4 @@
1
+ import type { PerspectiveCamera } from 'three';
1
2
  import { Vector2 } from 'three';
2
3
 
3
4
  import type { Input } from '../../../lib/Input';
@@ -70,7 +71,7 @@ export class CommonCameraState extends AbstractCameraState
70
71
  tilt: camera_controller.current_tilt,
71
72
  azimuth: camera_controller.current_azimuth,
72
73
  zoom: camera_controller.reference_zoom,
73
- fov: (camera_controller.camera).fov
74
+ fov: (camera_controller.camera as PerspectiveCamera).fov
74
75
  });
75
76
  }
76
77
  }
@@ -48,6 +48,7 @@ class AxisHelper extends Object3D
48
48
 
49
49
  dispose(): void
50
50
  {
51
+ super.dispose();
51
52
  }
52
53
  }
53
54