@zephyr3d/scene 0.9.25 → 0.9.26

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 (262) hide show
  1. package/dist/animation/hair/gpu_hair_simulation.js +1090 -0
  2. package/dist/animation/hair/gpu_hair_simulation.js.map +1 -0
  3. package/dist/animation/joint_dynamics/controller.js +7 -5
  4. package/dist/animation/joint_dynamics/controller.js.map +1 -1
  5. package/dist/animation/joint_dynamics/joint_dynamics_system.js +81 -5
  6. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
  7. package/dist/animation/morphtrack.js +3 -4
  8. package/dist/animation/morphtrack.js.map +1 -1
  9. package/dist/animation/skeleton.js +58 -24
  10. package/dist/animation/skeleton.js.map +1 -1
  11. package/dist/animation/spring/multi_chain_spring_system.js +577 -179
  12. package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
  13. package/dist/animation/spring/spring_collider.js +4 -3
  14. package/dist/animation/spring/spring_collider.js.map +1 -1
  15. package/dist/animation/spring/spring_node_pose_tracker.js +40 -0
  16. package/dist/animation/spring/spring_node_pose_tracker.js.map +1 -0
  17. package/dist/animation/spring/spring_particle.js +2 -0
  18. package/dist/animation/spring/spring_particle.js.map +1 -1
  19. package/dist/animation/spring/spring_system.js +11 -3
  20. package/dist/animation/spring/spring_system.js.map +1 -1
  21. package/dist/animation/spring_modifier.js +10 -0
  22. package/dist/animation/spring_modifier.js.map +1 -1
  23. package/dist/app/engine.js +53 -43
  24. package/dist/app/engine.js.map +1 -1
  25. package/dist/app/scriptingsystem.js +119 -6
  26. package/dist/app/scriptingsystem.js.map +1 -1
  27. package/dist/app/scriptregistry.js +3 -2
  28. package/dist/app/scriptregistry.js.map +1 -1
  29. package/dist/asset/assetmanager.js +284 -67
  30. package/dist/asset/assetmanager.js.map +1 -1
  31. package/dist/asset/loaders/zhair/zhair_format.js +288 -0
  32. package/dist/asset/loaders/zhair/zhair_format.js.map +1 -0
  33. package/dist/asset/loaders/zhair/zhair_loader.js +221 -0
  34. package/dist/asset/loaders/zhair/zhair_loader.js.map +1 -0
  35. package/dist/asset/model.js +178 -67
  36. package/dist/asset/model.js.map +1 -1
  37. package/dist/camera/camera.js +193 -21
  38. package/dist/camera/camera.js.map +1 -1
  39. package/dist/camera/perspectivecamera.js +3 -1
  40. package/dist/camera/perspectivecamera.js.map +1 -1
  41. package/dist/index.d.ts +4019 -1278
  42. package/dist/index.js +15 -5
  43. package/dist/index.js.map +1 -1
  44. package/dist/material/eye.js +932 -0
  45. package/dist/material/eye.js.map +1 -0
  46. package/dist/material/hair.js +917 -0
  47. package/dist/material/hair.js.map +1 -0
  48. package/dist/material/hairstrand.js +842 -0
  49. package/dist/material/hairstrand.js.map +1 -0
  50. package/dist/material/hairstrand_data.js +162 -0
  51. package/dist/material/hairstrand_data.js.map +1 -0
  52. package/dist/material/lambert.js +5 -2
  53. package/dist/material/lambert.js.map +1 -1
  54. package/dist/material/material.js +338 -300
  55. package/dist/material/material.js.map +1 -1
  56. package/dist/material/meshmaterial.js +120 -19
  57. package/dist/material/meshmaterial.js.map +1 -1
  58. package/dist/material/mixins/albedocolor.js +1 -1
  59. package/dist/material/mixins/albedocolor.js.map +1 -1
  60. package/dist/material/mixins/lightmodel/blinnphong.js +5 -3
  61. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  62. package/dist/material/mixins/lightmodel/lambert.js +5 -4
  63. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  64. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +3 -3
  65. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  66. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +5 -5
  67. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  68. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +3 -3
  69. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  70. package/dist/material/mixins/lit.js +73 -18
  71. package/dist/material/mixins/lit.js.map +1 -1
  72. package/dist/material/mixins/pbr/common.js +4 -4
  73. package/dist/material/mixins/pbr/common.js.map +1 -1
  74. package/dist/material/mixins/texture.js +48 -11
  75. package/dist/material/mixins/texture.js.map +1 -1
  76. package/dist/material/mtoon.js +6 -5
  77. package/dist/material/mtoon.js.map +1 -1
  78. package/dist/material/pbrblueprint.js +146 -28
  79. package/dist/material/pbrblueprint.js.map +1 -1
  80. package/dist/material/pbrblueprint_instance.js +501 -0
  81. package/dist/material/pbrblueprint_instance.js.map +1 -0
  82. package/dist/material/pbrmr.js +15 -16
  83. package/dist/material/pbrmr.js.map +1 -1
  84. package/dist/material/shader/helper.js +330 -20
  85. package/dist/material/shader/helper.js.map +1 -1
  86. package/dist/material/shader/terrain_blend.js +55 -0
  87. package/dist/material/shader/terrain_blend.js.map +1 -0
  88. package/dist/material/skin.js +192 -32
  89. package/dist/material/skin.js.map +1 -1
  90. package/dist/material/spriteblueprint.js +16 -1
  91. package/dist/material/spriteblueprint.js.map +1 -1
  92. package/dist/material/subsurfaceprofile.js +86 -23
  93. package/dist/material/subsurfaceprofile.js.map +1 -1
  94. package/dist/material/water.js +3 -1
  95. package/dist/material/water.js.map +1 -1
  96. package/dist/posteffect/bloom.js +167 -7
  97. package/dist/posteffect/bloom.js.map +1 -1
  98. package/dist/posteffect/coloradjust.js +2 -1
  99. package/dist/posteffect/coloradjust.js.map +1 -1
  100. package/dist/posteffect/compositor.js.map +1 -1
  101. package/dist/posteffect/fxaa.js +2 -1
  102. package/dist/posteffect/fxaa.js.map +1 -1
  103. package/dist/posteffect/grayscale.js +3 -1
  104. package/dist/posteffect/grayscale.js.map +1 -1
  105. package/dist/posteffect/motionblur.js +4 -1
  106. package/dist/posteffect/motionblur.js.map +1 -1
  107. package/dist/posteffect/posteffect.js.map +1 -1
  108. package/dist/posteffect/skinsss.js +368 -69
  109. package/dist/posteffect/skinsss.js.map +1 -1
  110. package/dist/posteffect/ssgi.js +16 -9
  111. package/dist/posteffect/ssgi.js.map +1 -1
  112. package/dist/posteffect/ssr.js +3 -0
  113. package/dist/posteffect/ssr.js.map +1 -1
  114. package/dist/posteffect/sss.js +91 -34
  115. package/dist/posteffect/sss.js.map +1 -1
  116. package/dist/posteffect/taa.js.map +1 -1
  117. package/dist/posteffect/tonemap.js +44 -1
  118. package/dist/posteffect/tonemap.js.map +1 -1
  119. package/dist/render/abuffer_oit.js +45 -39
  120. package/dist/render/abuffer_oit.js.map +1 -1
  121. package/dist/render/cull_visitor.js +19 -0
  122. package/dist/render/cull_visitor.js.map +1 -1
  123. package/dist/render/depthpass.js +36 -2
  124. package/dist/render/depthpass.js.map +1 -1
  125. package/dist/render/drawable_mixin.js +26 -1
  126. package/dist/render/drawable_mixin.js.map +1 -1
  127. package/dist/render/dualdepthpeeling_oit.js +52 -51
  128. package/dist/render/dualdepthpeeling_oit.js.map +1 -1
  129. package/dist/render/envlight.js +1 -1
  130. package/dist/render/envlight.js.map +1 -1
  131. package/dist/render/fbm_wavegenerator.js +3 -0
  132. package/dist/render/fbm_wavegenerator.js.map +1 -1
  133. package/dist/render/gerstner_wavegenerator.js +3 -0
  134. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  135. package/dist/render/globalbindgroup_allocator.js +3 -0
  136. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  137. package/dist/render/oit.js +29 -0
  138. package/dist/render/oit.js.map +1 -0
  139. package/dist/render/render_queue.js +3 -0
  140. package/dist/render/render_queue.js.map +1 -1
  141. package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
  142. package/dist/render/rendergraph/executor.js +2 -0
  143. package/dist/render/rendergraph/executor.js.map +1 -1
  144. package/dist/render/rendergraph/forward_plus_builder.js +61 -1
  145. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  146. package/dist/render/rendergraph/rendergraph.js.map +1 -1
  147. package/dist/render/rendergraph/texture_affinity_cache.js +1 -1
  148. package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -1
  149. package/dist/render/rendergraph/types.js.map +1 -1
  150. package/dist/render/shadow_mask_pass.js +73 -8
  151. package/dist/render/shadow_mask_pass.js.map +1 -1
  152. package/dist/render/sky.js +166 -126
  153. package/dist/render/sky.js.map +1 -1
  154. package/dist/render/weightedblended_oit.js +36 -35
  155. package/dist/render/weightedblended_oit.js.map +1 -1
  156. package/dist/scene/basesprite.js +8 -0
  157. package/dist/scene/basesprite.js.map +1 -1
  158. package/dist/scene/batchgroup.js +3 -0
  159. package/dist/scene/batchgroup.js.map +1 -1
  160. package/dist/scene/environment.js +4 -1
  161. package/dist/scene/environment.js.map +1 -1
  162. package/dist/scene/hair.js +963 -0
  163. package/dist/scene/hair.js.map +1 -0
  164. package/dist/scene/light.js +5 -1
  165. package/dist/scene/light.js.map +1 -1
  166. package/dist/scene/mesh.js +481 -47
  167. package/dist/scene/mesh.js.map +1 -1
  168. package/dist/scene/meshdrawable.js +6 -0
  169. package/dist/scene/meshdrawable.js.map +1 -1
  170. package/dist/scene/msdftext.js +3 -0
  171. package/dist/scene/msdftext.js.map +1 -1
  172. package/dist/scene/msdftextsprite.js +3 -0
  173. package/dist/scene/msdftextsprite.js.map +1 -1
  174. package/dist/scene/particlesys.js +6 -0
  175. package/dist/scene/particlesys.js.map +1 -1
  176. package/dist/scene/scene.js +3 -0
  177. package/dist/scene/scene.js.map +1 -1
  178. package/dist/scene/scene_node.js +6 -1
  179. package/dist/scene/scene_node.js.map +1 -1
  180. package/dist/scene/terrain-cm/grass.js +3 -0
  181. package/dist/scene/terrain-cm/grass.js.map +1 -1
  182. package/dist/scene/terrain-cm/grassmaterial.js +3 -0
  183. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  184. package/dist/scene/terrain-cm/terrain-cm.js +6 -0
  185. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  186. package/dist/scene/terrain-cm/texture_cache.js +309 -0
  187. package/dist/scene/terrain-cm/texture_cache.js.map +1 -0
  188. package/dist/scene/water.js +6 -0
  189. package/dist/scene/water.js.map +1 -1
  190. package/dist/shaders/atmosphere.js.map +1 -1
  191. package/dist/shaders/diffusion.js +54 -0
  192. package/dist/shaders/diffusion.js.map +1 -0
  193. package/dist/shaders/shadow.js +33 -21
  194. package/dist/shaders/shadow.js.map +1 -1
  195. package/dist/shaders/temporal.js +71 -33
  196. package/dist/shaders/temporal.js.map +1 -1
  197. package/dist/shadow/dom.js +546 -0
  198. package/dist/shadow/dom.js.map +1 -0
  199. package/dist/shadow/pcf_opt.js +3 -5
  200. package/dist/shadow/pcf_opt.js.map +1 -1
  201. package/dist/shadow/pcf_pd.js +1 -1
  202. package/dist/shadow/pcf_pd.js.map +1 -1
  203. package/dist/shadow/receiver_bias.js +41 -0
  204. package/dist/shadow/receiver_bias.js.map +1 -0
  205. package/dist/shadow/shader.js +20 -60
  206. package/dist/shadow/shader.js.map +1 -1
  207. package/dist/shadow/shadow_impl.js +89 -0
  208. package/dist/shadow/shadow_impl.js.map +1 -1
  209. package/dist/shadow/shadow_region.js +50 -50
  210. package/dist/shadow/shadow_region.js.map +1 -1
  211. package/dist/shadow/shadowmapper.js +150 -37
  212. package/dist/shadow/shadowmapper.js.map +1 -1
  213. package/dist/shapes/shape.js +11 -2
  214. package/dist/shapes/shape.js.map +1 -1
  215. package/dist/shapes/sphere.js +50 -9
  216. package/dist/shapes/sphere.js.map +1 -1
  217. package/dist/utility/blueprint/common/constants.js +112 -2
  218. package/dist/utility/blueprint/common/constants.js.map +1 -1
  219. package/dist/utility/blueprint/material/func.js +142 -49
  220. package/dist/utility/blueprint/material/func.js.map +1 -1
  221. package/dist/utility/blueprint/material/ir.js +490 -25
  222. package/dist/utility/blueprint/material/ir.js.map +1 -1
  223. package/dist/utility/blueprint/material/texture.js +898 -4
  224. package/dist/utility/blueprint/material/texture.js.map +1 -1
  225. package/dist/utility/serialization/manager.js +431 -100
  226. package/dist/utility/serialization/manager.js.map +1 -1
  227. package/dist/utility/serialization/scene/animation.js +370 -3
  228. package/dist/utility/serialization/scene/animation.js.map +1 -1
  229. package/dist/utility/serialization/scene/batch.js +4 -0
  230. package/dist/utility/serialization/scene/batch.js.map +1 -1
  231. package/dist/utility/serialization/scene/camera.js +133 -1
  232. package/dist/utility/serialization/scene/camera.js.map +1 -1
  233. package/dist/utility/serialization/scene/common.js +26 -5
  234. package/dist/utility/serialization/scene/common.js.map +1 -1
  235. package/dist/utility/serialization/scene/hair.js +1141 -0
  236. package/dist/utility/serialization/scene/hair.js.map +1 -0
  237. package/dist/utility/serialization/scene/light.js +84 -4
  238. package/dist/utility/serialization/scene/light.js.map +1 -1
  239. package/dist/utility/serialization/scene/material.js +1867 -166
  240. package/dist/utility/serialization/scene/material.js.map +1 -1
  241. package/dist/utility/serialization/scene/mesh.js +231 -14
  242. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  243. package/dist/utility/serialization/scene/node.js +141 -7
  244. package/dist/utility/serialization/scene/node.js.map +1 -1
  245. package/dist/utility/serialization/scene/particle.js +4 -0
  246. package/dist/utility/serialization/scene/particle.js.map +1 -1
  247. package/dist/utility/serialization/scene/primitive.js +18 -0
  248. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  249. package/dist/utility/serialization/scene/sprite.js +4 -0
  250. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  251. package/dist/utility/serialization/scene/terrain.js +4 -0
  252. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  253. package/dist/utility/serialization/scene/text.js +4 -0
  254. package/dist/utility/serialization/scene/text.js.map +1 -1
  255. package/dist/utility/serialization/scene/water.js +4 -0
  256. package/dist/utility/serialization/scene/water.js.map +1 -1
  257. package/dist/utility/serialization/types.js.map +1 -1
  258. package/dist/utility/shprojector.js +96 -95
  259. package/dist/utility/shprojector.js.map +1 -1
  260. package/dist/values.js +49 -2
  261. package/dist/values.js.map +1 -1
  262. package/package.json +3 -3
@@ -9,7 +9,8 @@ import { Shape } from './shape.js';
9
9
  ...Shape._defaultOptions,
10
10
  radius: 1,
11
11
  verticalDetail: 20,
12
- horizonalDetail: 20
12
+ horizonalDetail: 20,
13
+ eyeCompatible: false
13
14
  };
14
15
  /**
15
16
  * Creates an instance of sphere shape
@@ -56,8 +57,10 @@ import { Shape } from './shape.js';
56
57
  const radius = options.radius ?? 1;
57
58
  const verticalDetail = options.verticalDetail ?? 20;
58
59
  const horizonalDetail = options.horizonalDetail ?? 20;
60
+ const eyeCompatible = options.eyeCompatible ?? false;
59
61
  const vTheta = Math.PI / verticalDetail;
60
62
  const hTheta = Math.PI * 2 / horizonalDetail;
63
+ const invR = 1 / radius;
61
64
  for(let i = 0; i <= verticalDetail; i++){
62
65
  const v = i * vTheta;
63
66
  const sinV = Math.sin(v);
@@ -66,19 +69,57 @@ import { Shape } from './shape.js';
66
69
  const h = j * hTheta;
67
70
  const sinH = Math.sin(h);
68
71
  const cosH = Math.cos(h);
69
- const x = radius * sinV * sinH;
70
- const y = radius * cosV;
71
- const z = radius * sinV * cosH;
72
+ // Eye UVs are centred on +Z, so put the mesh poles on the gaze axis as
73
+ // well. Besides giving the rear projection a proper seam at -Z, this
74
+ // keeps the vertex rings concentric with the iris instead of placing
75
+ // its centre on the legacy longitude seam.
76
+ const x = radius * sinV * (eyeCompatible ? cosH : sinH);
77
+ const y = eyeCompatible ? radius * sinV * sinH : radius * cosV;
78
+ const z = eyeCompatible ? radius * cosV : radius * sinV * cosH;
72
79
  vertices.push(x, y, z);
73
- uvs?.push(j / horizonalDetail, i / verticalDetail);
80
+ if (eyeCompatible) {
81
+ // Preserve the planar projection over the visible hemisphere. On
82
+ // the rear hemisphere, continue from the equator into an outer
83
+ // annulus rather than folding back to (0.5, 0.5); the old fold was
84
+ // what produced a second iris and pupil at -Z.
85
+ const uvRadius = cosV >= 0 ? sinV * 0.5 : 1 - sinV * 0.5;
86
+ uvs?.push(0.5 + cosH * uvRadius, 0.5 + sinH * uvRadius);
87
+ } else {
88
+ uvs?.push(j / horizonalDetail, i / verticalDetail);
89
+ }
74
90
  if (normals) {
75
- const invR = 1 / radius;
76
91
  normals.push(x * invR, y * invR, z * invR);
77
92
  }
78
93
  if (tangents) {
79
- const w = 1;
94
+ let w = 1;
80
95
  let tx, ty, tz;
81
- if (sinV > 1e-6) {
96
+ if (eyeCompatible) {
97
+ // Project +X onto the local tangent plane. This is the +U
98
+ // direction of the planar eye projection; an azimuth tangent
99
+ // would rotate the refraction frame around the iris.
100
+ const nx = x * invR;
101
+ const ny = y * invR;
102
+ const nz = z * invR;
103
+ tx = 1 - nx * nx;
104
+ ty = -ny * nx;
105
+ tz = -nz * nx;
106
+ const len = Math.hypot(tx, ty, tz);
107
+ if (len > 1e-8) {
108
+ tx /= len;
109
+ ty /= len;
110
+ tz /= len;
111
+ } else {
112
+ // At +/-X the projected +X direction degenerates. Use its
113
+ // limiting direction from the front hemisphere instead of a
114
+ // vector parallel to the normal.
115
+ tx = 0;
116
+ ty = 0;
117
+ tz = nx >= 0 ? -1 : 1;
118
+ }
119
+ // The rear annulus reverses its radial direction, so its tangent
120
+ // frame has the opposite handedness.
121
+ w = cosV >= 0 ? 1 : -1;
122
+ } else if (sinV > 1e-6) {
82
123
  tx = cosH;
83
124
  ty = 0.0;
84
125
  tz = -sinH;
@@ -106,7 +147,7 @@ import { Shape } from './shape.js';
106
147
  indices.push(stripIndices[i], stripIndices[i + 2], stripIndices[i + 1]);
107
148
  }
108
149
  }
109
- Shape._transform(options.transform, vertices, normals, start);
150
+ Shape._transform(options.transform, vertices, normals, start, tangents);
110
151
  if (bbox) {
111
152
  for(let i = start; i < vertices.length - 2; i += 3){
112
153
  if (bbox) {
@@ -1 +1 @@
1
- {"version":3,"file":"sphere.js","sources":["../../src/shapes/sphere.ts"],"sourcesContent":["import type { Clonable, Ray } from '@zephyr3d/base';\r\nimport type { AABB } from '@zephyr3d/base';\r\nimport { Vector3 } from '@zephyr3d/base';\r\nimport type { ShapeCreationOptions } from './shape';\r\nimport { Shape } from './shape';\r\n\r\n/**\r\n * Creation options for sphere shape\r\n * @public\r\n */\r\nexport interface SphereCreationOptions extends ShapeCreationOptions {\r\n /** Radius of the sphere, default 1 */\r\n radius?: number;\r\n /** The vertical detail level, default 20 */\r\n verticalDetail?: number;\r\n /** The horizonal detail level, default 20 */\r\n horizonalDetail?: number;\r\n}\r\n\r\n/**\r\n * Sphere shape\r\n * @public\r\n */\r\nexport class SphereShape extends Shape<SphereCreationOptions> implements Clonable<SphereShape> {\r\n static _defaultOptions = {\r\n ...Shape._defaultOptions,\r\n radius: 1,\r\n verticalDetail: 20,\r\n horizonalDetail: 20\r\n };\r\n /**\r\n * Creates an instance of sphere shape\r\n * @param options - The creation options\r\n */\r\n constructor(options?: SphereCreationOptions) {\r\n super(options);\r\n }\r\n clone() {\r\n return new SphereShape(this._options) as this;\r\n }\r\n /** type of the shape */\r\n get type() {\r\n return 'Sphere' as const;\r\n }\r\n /**\r\n * {@inheritDoc Primitive.raycast}\r\n * @override\r\n */\r\n raycast(ray: Ray) {\r\n const rSquared = this._options.radius * this._options.radius;\r\n const eSquared = Vector3.dot(ray.origin, ray.origin);\r\n if (eSquared < rSquared) {\r\n return null;\r\n }\r\n const a = -Vector3.dot(ray.origin, ray.direction);\r\n const bSquared = eSquared - a * a;\r\n if (rSquared < bSquared) {\r\n return null;\r\n }\r\n return a - Math.sqrt(rSquared - bSquared);\r\n }\r\n /** Sphere radius */\r\n get radius() {\r\n return this._options.radius ?? 1;\r\n }\r\n /**\r\n * Generates the data for the sphere shape\r\n * @param vertices - vertex positions\r\n * @param normals - vertex normals\r\n * @param uvs - vertex uvs\r\n * @param indices - vertex indices\r\n */\r\n static generateData(\r\n opt: SphereCreationOptions,\r\n vertices: number[],\r\n normals: number[],\r\n tangents: number[],\r\n uvs: number[],\r\n indices: number[],\r\n bbox?: AABB,\r\n indexOffset?: number,\r\n vertexCallback?: (index: number, x: number, y: number, z: number) => void\r\n ) {\r\n const options = Object.assign({}, this._defaultOptions, opt ?? {});\r\n indexOffset = indexOffset ?? 0;\r\n const start = vertices.length;\r\n const stripIndices: number[] = [];\r\n const radius = options.radius ?? 1;\r\n const verticalDetail = options.verticalDetail ?? 20;\r\n const horizonalDetail = options.horizonalDetail ?? 20;\r\n const vTheta = Math.PI / verticalDetail;\r\n const hTheta = (Math.PI * 2) / horizonalDetail;\r\n for (let i = 0; i <= verticalDetail; i++) {\r\n const v = i * vTheta;\r\n const sinV = Math.sin(v);\r\n const cosV = Math.cos(v);\r\n for (let j = 0; j <= horizonalDetail; j++) {\r\n const h = j * hTheta;\r\n const sinH = Math.sin(h);\r\n const cosH = Math.cos(h);\r\n\r\n const x = radius * sinV * sinH;\r\n const y = radius * cosV;\r\n const z = radius * sinV * cosH;\r\n vertices.push(x, y, z);\r\n uvs?.push(j / horizonalDetail, i / verticalDetail);\r\n if (normals) {\r\n const invR = 1 / radius;\r\n normals.push(x * invR, y * invR, z * invR);\r\n }\r\n if (tangents) {\r\n const w = 1;\r\n let tx: number, ty: number, tz: number;\r\n if (sinV > 1e-6) {\r\n tx = cosH;\r\n ty = 0.0;\r\n tz = -sinH;\r\n } else {\r\n tx = 1.0;\r\n ty = 0.0;\r\n tz = 0.0;\r\n }\r\n tangents.push(tx, ty, tz, w);\r\n }\r\n }\r\n }\r\n for (let i = 0; i < verticalDetail; i++) {\r\n for (let j = 0; j <= horizonalDetail; j++) {\r\n const startIndex = i * (horizonalDetail + 1);\r\n stripIndices.push(startIndex + j + indexOffset, startIndex + j + horizonalDetail + 1 + indexOffset);\r\n }\r\n stripIndices.push(stripIndices[stripIndices.length - 1]);\r\n stripIndices.push((i + 1) * (horizonalDetail + 1) + indexOffset);\r\n }\r\n for (let i = 0; i < stripIndices.length - 2; i++) {\r\n if (i % 2 === 0) {\r\n indices.push(stripIndices[i], stripIndices[i + 1], stripIndices[i + 2]);\r\n } else {\r\n indices.push(stripIndices[i], stripIndices[i + 2], stripIndices[i + 1]);\r\n }\r\n }\r\n Shape._transform(options.transform, vertices, normals, start);\r\n if (bbox) {\r\n for (let i = start; i < vertices.length - 2; i += 3) {\r\n if (bbox) {\r\n bbox.minPoint.x = Math.min(bbox.minPoint.x, vertices[i]);\r\n bbox.minPoint.y = Math.min(bbox.minPoint.y, vertices[i + 1]);\r\n bbox.minPoint.z = Math.min(bbox.minPoint.z, vertices[i + 2]);\r\n bbox.maxPoint.x = Math.max(bbox.maxPoint.x, vertices[i]);\r\n bbox.maxPoint.y = Math.max(bbox.maxPoint.y, vertices[i + 1]);\r\n bbox.maxPoint.z = Math.max(bbox.maxPoint.z, vertices[i + 2]);\r\n }\r\n vertexCallback?.((i - start) / 3, vertices[i], vertices[i + 1], vertices[i + 2]);\r\n }\r\n }\r\n return 'triangle-list' as const;\r\n }\r\n}\r\n"],"names":["SphereShape","Shape","_defaultOptions","radius","verticalDetail","horizonalDetail","options","clone","_options","type","raycast","ray","rSquared","eSquared","Vector3","dot","origin","a","direction","bSquared","Math","sqrt","generateData","opt","vertices","normals","tangents","uvs","indices","bbox","indexOffset","vertexCallback","Object","assign","start","length","stripIndices","vTheta","PI","hTheta","i","v","sinV","sin","cosV","cos","j","h","sinH","cosH","x","y","z","push","invR","w","tx","ty","tz","startIndex","_transform","transform","minPoint","min","maxPoint","max"],"mappings":"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"}
1
+ {"version":3,"file":"sphere.js","sources":["../../src/shapes/sphere.ts"],"sourcesContent":["import type { Clonable, Ray } from '@zephyr3d/base';\r\nimport type { AABB } from '@zephyr3d/base';\r\nimport { Vector3 } from '@zephyr3d/base';\r\nimport type { ShapeCreationOptions } from './shape';\r\nimport { Shape } from './shape';\r\n\r\n/**\r\n * Creation options for sphere shape\r\n * @public\r\n */\r\nexport interface SphereCreationOptions extends ShapeCreationOptions {\r\n /** Radius of the sphere, default 1 */\r\n radius?: number;\r\n /** The vertical detail level, default 20 */\r\n verticalDetail?: number;\r\n /** The horizonal detail level, default 20 */\r\n horizonalDetail?: number;\r\n /**\r\n * Generate UVs and tangents for {@link EyeMaterial}.\r\n *\r\n * When enabled, the sphere's polar axis follows Z and the front hemisphere\r\n * uses a planar projection along +Z, with its centre at (0.5, 0.5). The rear\r\n * hemisphere is unwrapped outside that front disc so it cannot produce a\r\n * second iris at -Z. The tangent follows +U. The sphere topology is otherwise\r\n * unchanged, so this option remains compatible with the analytical raycast\r\n * and with existing sphere consumers. The material must still opt into the\r\n * tangent frame with `EyeMaterial.vertexTangent = true`.\r\n *\r\n * @defaultValue `false`\r\n */\r\n eyeCompatible?: boolean;\r\n}\r\n\r\n/**\r\n * Sphere shape\r\n * @public\r\n */\r\nexport class SphereShape extends Shape<SphereCreationOptions> implements Clonable<SphereShape> {\r\n static _defaultOptions = {\r\n ...Shape._defaultOptions,\r\n radius: 1,\r\n verticalDetail: 20,\r\n horizonalDetail: 20,\r\n eyeCompatible: false\r\n };\r\n /**\r\n * Creates an instance of sphere shape\r\n * @param options - The creation options\r\n */\r\n constructor(options?: SphereCreationOptions) {\r\n super(options);\r\n }\r\n clone() {\r\n return new SphereShape(this._options) as this;\r\n }\r\n /** type of the shape */\r\n get type() {\r\n return 'Sphere' as const;\r\n }\r\n /**\r\n * {@inheritDoc Primitive.raycast}\r\n * @override\r\n */\r\n raycast(ray: Ray) {\r\n const rSquared = this._options.radius * this._options.radius;\r\n const eSquared = Vector3.dot(ray.origin, ray.origin);\r\n if (eSquared < rSquared) {\r\n return null;\r\n }\r\n const a = -Vector3.dot(ray.origin, ray.direction);\r\n const bSquared = eSquared - a * a;\r\n if (rSquared < bSquared) {\r\n return null;\r\n }\r\n return a - Math.sqrt(rSquared - bSquared);\r\n }\r\n /** Sphere radius */\r\n get radius() {\r\n return this._options.radius ?? 1;\r\n }\r\n /**\r\n * Generates the data for the sphere shape\r\n * @param vertices - vertex positions\r\n * @param normals - vertex normals\r\n * @param uvs - vertex uvs\r\n * @param indices - vertex indices\r\n */\r\n static generateData(\r\n opt: SphereCreationOptions,\r\n vertices: number[],\r\n normals: number[],\r\n tangents: number[],\r\n uvs: number[],\r\n indices: number[],\r\n bbox?: AABB,\r\n indexOffset?: number,\r\n vertexCallback?: (index: number, x: number, y: number, z: number) => void\r\n ) {\r\n const options = Object.assign({}, this._defaultOptions, opt ?? {});\r\n indexOffset = indexOffset ?? 0;\r\n const start = vertices.length;\r\n const stripIndices: number[] = [];\r\n const radius = options.radius ?? 1;\r\n const verticalDetail = options.verticalDetail ?? 20;\r\n const horizonalDetail = options.horizonalDetail ?? 20;\r\n const eyeCompatible = options.eyeCompatible ?? false;\r\n const vTheta = Math.PI / verticalDetail;\r\n const hTheta = (Math.PI * 2) / horizonalDetail;\r\n const invR = 1 / radius;\r\n for (let i = 0; i <= verticalDetail; i++) {\r\n const v = i * vTheta;\r\n const sinV = Math.sin(v);\r\n const cosV = Math.cos(v);\r\n for (let j = 0; j <= horizonalDetail; j++) {\r\n const h = j * hTheta;\r\n const sinH = Math.sin(h);\r\n const cosH = Math.cos(h);\r\n\r\n // Eye UVs are centred on +Z, so put the mesh poles on the gaze axis as\r\n // well. Besides giving the rear projection a proper seam at -Z, this\r\n // keeps the vertex rings concentric with the iris instead of placing\r\n // its centre on the legacy longitude seam.\r\n const x = radius * sinV * (eyeCompatible ? cosH : sinH);\r\n const y = eyeCompatible ? radius * sinV * sinH : radius * cosV;\r\n const z = eyeCompatible ? radius * cosV : radius * sinV * cosH;\r\n vertices.push(x, y, z);\r\n if (eyeCompatible) {\r\n // Preserve the planar projection over the visible hemisphere. On\r\n // the rear hemisphere, continue from the equator into an outer\r\n // annulus rather than folding back to (0.5, 0.5); the old fold was\r\n // what produced a second iris and pupil at -Z.\r\n const uvRadius = cosV >= 0 ? sinV * 0.5 : 1 - sinV * 0.5;\r\n uvs?.push(0.5 + cosH * uvRadius, 0.5 + sinH * uvRadius);\r\n } else {\r\n uvs?.push(j / horizonalDetail, i / verticalDetail);\r\n }\r\n if (normals) {\r\n normals.push(x * invR, y * invR, z * invR);\r\n }\r\n if (tangents) {\r\n let w = 1;\r\n let tx: number, ty: number, tz: number;\r\n if (eyeCompatible) {\r\n // Project +X onto the local tangent plane. This is the +U\r\n // direction of the planar eye projection; an azimuth tangent\r\n // would rotate the refraction frame around the iris.\r\n const nx = x * invR;\r\n const ny = y * invR;\r\n const nz = z * invR;\r\n tx = 1 - nx * nx;\r\n ty = -ny * nx;\r\n tz = -nz * nx;\r\n const len = Math.hypot(tx, ty, tz);\r\n if (len > 1e-8) {\r\n tx /= len;\r\n ty /= len;\r\n tz /= len;\r\n } else {\r\n // At +/-X the projected +X direction degenerates. Use its\r\n // limiting direction from the front hemisphere instead of a\r\n // vector parallel to the normal.\r\n tx = 0;\r\n ty = 0;\r\n tz = nx >= 0 ? -1 : 1;\r\n }\r\n // The rear annulus reverses its radial direction, so its tangent\r\n // frame has the opposite handedness.\r\n w = cosV >= 0 ? 1 : -1;\r\n } else if (sinV > 1e-6) {\r\n tx = cosH;\r\n ty = 0.0;\r\n tz = -sinH;\r\n } else {\r\n tx = 1.0;\r\n ty = 0.0;\r\n tz = 0.0;\r\n }\r\n tangents.push(tx, ty, tz, w);\r\n }\r\n }\r\n }\r\n for (let i = 0; i < verticalDetail; i++) {\r\n for (let j = 0; j <= horizonalDetail; j++) {\r\n const startIndex = i * (horizonalDetail + 1);\r\n stripIndices.push(startIndex + j + indexOffset, startIndex + j + horizonalDetail + 1 + indexOffset);\r\n }\r\n stripIndices.push(stripIndices[stripIndices.length - 1]);\r\n stripIndices.push((i + 1) * (horizonalDetail + 1) + indexOffset);\r\n }\r\n for (let i = 0; i < stripIndices.length - 2; i++) {\r\n if (i % 2 === 0) {\r\n indices.push(stripIndices[i], stripIndices[i + 1], stripIndices[i + 2]);\r\n } else {\r\n indices.push(stripIndices[i], stripIndices[i + 2], stripIndices[i + 1]);\r\n }\r\n }\r\n Shape._transform(options.transform, vertices, normals, start, tangents);\r\n if (bbox) {\r\n for (let i = start; i < vertices.length - 2; i += 3) {\r\n if (bbox) {\r\n bbox.minPoint.x = Math.min(bbox.minPoint.x, vertices[i]);\r\n bbox.minPoint.y = Math.min(bbox.minPoint.y, vertices[i + 1]);\r\n bbox.minPoint.z = Math.min(bbox.minPoint.z, vertices[i + 2]);\r\n bbox.maxPoint.x = Math.max(bbox.maxPoint.x, vertices[i]);\r\n bbox.maxPoint.y = Math.max(bbox.maxPoint.y, vertices[i + 1]);\r\n bbox.maxPoint.z = Math.max(bbox.maxPoint.z, vertices[i + 2]);\r\n }\r\n vertexCallback?.((i - start) / 3, vertices[i], vertices[i + 1], vertices[i + 2]);\r\n }\r\n }\r\n return 'triangle-list' as const;\r\n }\r\n}\r\n"],"names":["SphereShape","Shape","_defaultOptions","radius","verticalDetail","horizonalDetail","eyeCompatible","options","clone","_options","type","raycast","ray","rSquared","eSquared","Vector3","dot","origin","a","direction","bSquared","Math","sqrt","generateData","opt","vertices","normals","tangents","uvs","indices","bbox","indexOffset","vertexCallback","Object","assign","start","length","stripIndices","vTheta","PI","hTheta","invR","i","v","sinV","sin","cosV","cos","j","h","sinH","cosH","x","y","z","push","uvRadius","w","tx","ty","tz","nx","ny","nz","len","hypot","startIndex","_transform","transform","minPoint","min","maxPoint","max"],"mappings":"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"}
@@ -10,6 +10,9 @@ import { BaseGraphNode } from '../node.js';
10
10
  /** The scalar float value */ _value;
11
11
  /** Whether this constant should be exposed as a uniform parameter */ _isUniform;
12
12
  /** The uniform parameter name (only used when isUniform is true) */ _paramName;
13
+ /** Whether the scalar uniform should expose a value range in editor UI */ _useRange;
14
+ /** The minimum allowed value when range limiting is enabled */ _minValue;
15
+ /** The maximum allowed value when range limiting is enabled */ _maxValue;
13
16
  /**
14
17
  * Creates a new constant scalar node
15
18
  *
@@ -20,6 +23,9 @@ import { BaseGraphNode } from '../node.js';
20
23
  this._value = 0;
21
24
  this._isUniform = true;
22
25
  this._paramName = getParamName();
26
+ this._useRange = false;
27
+ this._minValue = 0;
28
+ this._maxValue = 1;
23
29
  this._outputs = [
24
30
  {
25
31
  id: 1,
@@ -27,6 +33,18 @@ import { BaseGraphNode } from '../node.js';
27
33
  }
28
34
  ];
29
35
  }
36
+ clampValue(val) {
37
+ if (!this._useRange) {
38
+ return val;
39
+ }
40
+ return Math.min(this._maxValue, Math.max(this._minValue, val));
41
+ }
42
+ normalizeRange() {
43
+ if (this._minValue > this._maxValue) {
44
+ this._maxValue = this._minValue;
45
+ }
46
+ this._value = this.clampValue(this._value);
47
+ }
30
48
  /**
31
49
  * Generates a string representation of this node
32
50
  *
@@ -78,12 +96,63 @@ import { BaseGraphNode } from '../node.js';
78
96
  {
79
97
  name: 'x',
80
98
  type: 'float',
99
+ options: {
100
+ label: 'DefaultValue'
101
+ },
81
102
  get (value) {
82
103
  value.num[0] = this.x;
83
104
  },
84
105
  set (value) {
85
106
  this.x = value.num[0];
86
107
  }
108
+ },
109
+ {
110
+ name: 'useRange',
111
+ type: 'bool',
112
+ options: {
113
+ label: 'UseRange'
114
+ },
115
+ get (value) {
116
+ value.bool[0] = this.useRange;
117
+ },
118
+ set (value) {
119
+ this.useRange = value.bool[0];
120
+ },
121
+ isHidden () {
122
+ return !this.isUniform;
123
+ }
124
+ },
125
+ {
126
+ name: 'minValue',
127
+ type: 'float',
128
+ options: {
129
+ label: 'MinValue'
130
+ },
131
+ get (value) {
132
+ value.num[0] = this.minValue;
133
+ },
134
+ set (value) {
135
+ this.minValue = value.num[0];
136
+ },
137
+ isHidden () {
138
+ return !this.isUniform || !this.useRange;
139
+ }
140
+ },
141
+ {
142
+ name: 'maxValue',
143
+ type: 'float',
144
+ options: {
145
+ label: 'MaxValue'
146
+ },
147
+ get (value) {
148
+ value.num[0] = this.maxValue;
149
+ },
150
+ set (value) {
151
+ this.maxValue = value.num[0];
152
+ },
153
+ isHidden () {
154
+ return !this.isUniform || !this.useRange;
155
+ }
87
156
  }
88
157
  ]);
89
158
  }
@@ -114,13 +183,54 @@ import { BaseGraphNode } from '../node.js';
114
183
  }
115
184
  }
116
185
  /**
186
+ * Gets whether the scalar parameter uses editor range limits
187
+ */ get useRange() {
188
+ return this._useRange;
189
+ }
190
+ set useRange(val) {
191
+ const next = !!val;
192
+ if (this._useRange !== next) {
193
+ this._useRange = next;
194
+ this._value = this.clampValue(this._value);
195
+ this.dispatchEvent('changed');
196
+ }
197
+ }
198
+ /**
199
+ * Gets the minimum value for this scalar parameter
200
+ */ get minValue() {
201
+ return this._minValue;
202
+ }
203
+ set minValue(val) {
204
+ if (val !== this._minValue) {
205
+ this._minValue = val;
206
+ this.normalizeRange();
207
+ this.dispatchEvent('changed');
208
+ }
209
+ }
210
+ /**
211
+ * Gets the maximum value for this scalar parameter
212
+ */ get maxValue() {
213
+ return this._maxValue;
214
+ }
215
+ set maxValue(val) {
216
+ if (val !== this._maxValue) {
217
+ this._maxValue = val;
218
+ if (this._maxValue < this._minValue) {
219
+ this._minValue = this._maxValue;
220
+ }
221
+ this._value = this.clampValue(this._value);
222
+ this.dispatchEvent('changed');
223
+ }
224
+ }
225
+ /**
117
226
  * Gets the scalar value
118
227
  */ get x() {
119
228
  return this._value;
120
229
  }
121
230
  set x(val) {
122
- if (val !== this._value) {
123
- this._value = val;
231
+ const next = this.clampValue(val);
232
+ if (next !== this._value) {
233
+ this._value = next;
124
234
  this.dispatchEvent('changed');
125
235
  }
126
236
  }