x_ite 5.0.2 → 6.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 (340) hide show
  1. package/.vscode/settings.json +12 -5
  2. package/.vscode/tasks.json +21 -0
  3. package/Makefile +10 -15
  4. package/README.md +6 -11
  5. package/build/bin/dist.pl +0 -6
  6. package/build/bin/version.pl +1 -4
  7. package/dist/assets/components/annotation.js +2 -2
  8. package/dist/assets/components/annotation.min.js +1 -1
  9. package/dist/assets/components/cad-geometry.js +2 -2
  10. package/dist/assets/components/cad-geometry.min.js +1 -1
  11. package/dist/assets/components/cube-map-texturing.js +6 -19
  12. package/dist/assets/components/cube-map-texturing.min.js +1 -1
  13. package/dist/assets/components/dis.js +2 -2
  14. package/dist/assets/components/dis.min.js +1 -1
  15. package/dist/assets/components/event-utilities.js +3 -3
  16. package/dist/assets/components/event-utilities.min.js +1 -1
  17. package/dist/assets/components/geometry2d.js +4 -4
  18. package/dist/assets/components/geometry2d.min.js +1 -1
  19. package/dist/assets/components/geospatial.js +32 -1685
  20. package/dist/assets/components/geospatial.min.js +1 -1
  21. package/dist/assets/components/h-anim.js +70 -77
  22. package/dist/assets/components/h-anim.min.js +1 -1
  23. package/dist/assets/components/key-device-sensor.js +3 -3
  24. package/dist/assets/components/key-device-sensor.min.js +1 -1
  25. package/dist/assets/components/layout.js +38 -52
  26. package/dist/assets/components/layout.min.js +1 -1
  27. package/dist/assets/components/nurbs.js +277 -194
  28. package/dist/assets/components/nurbs.min.js +1 -1
  29. package/dist/assets/components/particle-systems.js +1918 -1658
  30. package/dist/assets/components/particle-systems.min.js +1 -1
  31. package/dist/assets/components/picking.js +33 -41
  32. package/dist/assets/components/picking.min.js +1 -1
  33. package/dist/assets/components/projective-texture-mapping.js +72 -86
  34. package/dist/assets/components/projective-texture-mapping.min.js +1 -1
  35. package/dist/assets/components/rigid-body-physics.js +36 -57
  36. package/dist/assets/components/rigid-body-physics.min.js +1 -1
  37. package/dist/assets/components/scripting.js +2 -2
  38. package/dist/assets/components/scripting.min.js +1 -1
  39. package/dist/assets/components/texturing-3d.js +26 -75
  40. package/dist/assets/components/texturing-3d.min.js +3 -3
  41. package/dist/assets/components/volume-rendering.js +10 -10
  42. package/dist/assets/components/volume-rendering.min.js +1 -1
  43. package/dist/assets/components/x_ite.js +2 -2
  44. package/dist/assets/components/x_ite.min.js +1 -1
  45. package/dist/assets/linetype/1.png +0 -0
  46. package/dist/assets/linetype/10.png +0 -0
  47. package/dist/assets/linetype/11.png +0 -0
  48. package/dist/assets/linetype/12.png +0 -0
  49. package/dist/assets/linetype/13.png +0 -0
  50. package/dist/assets/linetype/14.png +0 -0
  51. package/dist/assets/linetype/15.png +0 -0
  52. package/dist/assets/linetype/16.png +0 -0
  53. package/dist/assets/linetype/2.png +0 -0
  54. package/dist/assets/linetype/3.png +0 -0
  55. package/dist/assets/linetype/4.png +0 -0
  56. package/dist/assets/linetype/5.png +0 -0
  57. package/dist/assets/linetype/6.png +0 -0
  58. package/dist/assets/linetype/7.png +0 -0
  59. package/dist/assets/linetype/8.png +0 -0
  60. package/dist/assets/linetype/9.png +0 -0
  61. package/dist/assets/shaders/webgl1/Line.fs +0 -21
  62. package/dist/assets/shaders/webgl1/Line.vs +0 -10
  63. package/dist/assets/shaders/webgl1/PBR.vs +1 -1
  64. package/dist/assets/shaders/webgl2/Depth.vs +29 -1
  65. package/dist/assets/shaders/webgl2/Gouraud.vs +31 -3
  66. package/dist/assets/shaders/webgl2/Line.fs +24 -12
  67. package/dist/assets/shaders/webgl2/Line.vs +36 -11
  68. package/dist/assets/shaders/webgl2/LineTransform.fs +4 -0
  69. package/dist/assets/shaders/webgl2/LineTransform.vs +57 -0
  70. package/dist/assets/shaders/webgl2/PBR.vs +35 -7
  71. package/dist/assets/shaders/webgl2/Phong.vs +31 -3
  72. package/dist/assets/shaders/webgl2/Point.vs +29 -1
  73. package/dist/assets/shaders/webgl2/Unlit.vs +31 -3
  74. package/dist/example.html +6 -6
  75. package/dist/x_ite.css +180 -208
  76. package/dist/x_ite.js +16477 -16629
  77. package/dist/x_ite.min.js +17 -17
  78. package/dist/x_ite.zip +0 -0
  79. package/docs/404.md +6 -0
  80. package/docs/Accessing-the-External-Browser.md +20 -14
  81. package/docs/Browser-Support.md +6 -0
  82. package/docs/Custom-Shaders.md +17 -24
  83. package/docs/Features.md +7 -1
  84. package/docs/Gemfile +44 -0
  85. package/docs/Gemfile.lock +122 -0
  86. package/docs/Glossary.md +6 -0
  87. package/docs/How-To-Configure-Your-Web-Server.md +6 -0
  88. package/docs/Supported-Nodes.md +9 -1
  89. package/docs/What's-New.md +31 -0
  90. package/docs/XHTML-DOM-Integration.md +6 -0
  91. package/docs/_config.yml +1 -1
  92. package/docs/assets/css/main.scss +26 -0
  93. package/docs/index.md +38 -46
  94. package/docs/reference/Browser-Services.md +9 -3
  95. package/docs/reference/Constants-Services.md +6 -0
  96. package/docs/reference/ECMAScript-Object-and-Function-Definitions.md +6 -0
  97. package/docs/reference/Field-Services-and-Objects.md +6 -0
  98. package/docs/reference/Prototype-Services.md +6 -0
  99. package/docs/reference/Route-Services.md +6 -0
  100. package/docs/reference/Scene-Services.md +8 -2
  101. package/docs/reference/Script-Node-Authoring-Interface.md +7 -1
  102. package/docs/tutorials/Adding-backgrounds.md +6 -0
  103. package/docs/tutorials/Adding-fog.md +6 -0
  104. package/docs/tutorials/Adding-sound.md +6 -0
  105. package/docs/tutorials/Animating-transforms.md +6 -0
  106. package/docs/tutorials/Basic-Nodes.md +6 -0
  107. package/docs/tutorials/Building-a-X3D-world.md +6 -0
  108. package/docs/tutorials/Building-elevation-grids.md +6 -0
  109. package/docs/tutorials/Building-extruded-shapes.md +6 -0
  110. package/docs/tutorials/Building-primitive-shapes.md +6 -0
  111. package/docs/tutorials/Building-shapes-out-of-points,-lines,-and-faces.md +6 -0
  112. package/docs/tutorials/Controlling-appearance-with-materials.md +6 -0
  113. package/docs/tutorials/Controlling-color-on-coordinate-based-geometry.md +6 -0
  114. package/docs/tutorials/Controlling-detail.md +6 -0
  115. package/docs/tutorials/Controlling-how-textures-are-mapped.md +6 -0
  116. package/docs/tutorials/Controlling-navigation.md +6 -0
  117. package/docs/tutorials/Controlling-shading-on-coordinate-based-geometry.md +6 -0
  118. package/docs/tutorials/Controlling-the-viewpoint.md +6 -0
  119. package/docs/tutorials/Creating-new-node-types.md +6 -0
  120. package/docs/tutorials/Grouping-nodes.md +6 -0
  121. package/docs/tutorials/Hello,-World!.md +6 -0
  122. package/docs/tutorials/Improving-Performance.md +6 -0
  123. package/docs/tutorials/Increasing-Rendering-Speed.md +6 -0
  124. package/docs/tutorials/Introducing-X3D.md +6 -0
  125. package/docs/tutorials/Introducing-animation.md +6 -0
  126. package/docs/tutorials/Introducing-script-use.md +6 -0
  127. package/docs/tutorials/Lighting-your-world.md +6 -0
  128. package/docs/tutorials/Mapping-textures.md +6 -0
  129. package/docs/tutorials/Naming-nodes.md +6 -0
  130. package/docs/tutorials/Providing-information-about-your-world.md +6 -0
  131. package/docs/tutorials/Sensing-the-viewer.md +6 -0
  132. package/docs/tutorials/Sensing-viewer-actions.md +6 -0
  133. package/docs/tutorials/Transforming-Shapes.md +6 -0
  134. package/docs/tutorials/Writing-program-scripts-with-ECMAScript.md +6 -0
  135. package/docs/tutorials/index.md +6 -0
  136. package/package.json +6 -7
  137. package/src/assets/components/geometry2d.js +1 -1
  138. package/src/assets/components/key-device-sensor.js +1 -1
  139. package/src/assets/components/layout.js +1 -1
  140. package/src/assets/components/particle-systems.js +1 -1
  141. package/src/assets/components/volume-rendering.js +1 -1
  142. package/src/assets/linetype/1.png +0 -0
  143. package/src/assets/linetype/10.png +0 -0
  144. package/src/assets/linetype/11.png +0 -0
  145. package/src/assets/linetype/12.png +0 -0
  146. package/src/assets/linetype/13.png +0 -0
  147. package/src/assets/linetype/14.png +0 -0
  148. package/src/assets/linetype/15.png +0 -0
  149. package/src/assets/linetype/16.png +0 -0
  150. package/src/assets/linetype/2.png +0 -0
  151. package/src/assets/linetype/3.png +0 -0
  152. package/src/assets/linetype/4.png +0 -0
  153. package/src/assets/linetype/5.png +0 -0
  154. package/src/assets/linetype/6.png +0 -0
  155. package/src/assets/linetype/7.png +0 -0
  156. package/src/assets/linetype/8.png +0 -0
  157. package/src/assets/linetype/9.png +0 -0
  158. package/src/assets/shaders/Types.glsl +1 -9
  159. package/src/assets/shaders/webgl1/Line.fs +3 -28
  160. package/src/assets/shaders/webgl1/Line.vs +5 -19
  161. package/src/assets/shaders/webgl1/PBR.vs +1 -1
  162. package/src/assets/shaders/webgl1/Point.vs +2 -3
  163. package/src/assets/shaders/webgl2/Depth.vs +4 -1
  164. package/src/assets/shaders/webgl2/Gouraud.vs +5 -3
  165. package/src/assets/shaders/webgl2/Line.fs +11 -17
  166. package/src/assets/shaders/webgl2/Line.vs +16 -20
  167. package/src/assets/shaders/webgl2/LineTransform.fs +6 -0
  168. package/src/assets/shaders/webgl2/LineTransform.vs +77 -0
  169. package/src/assets/shaders/webgl2/PBR.vs +10 -7
  170. package/src/assets/shaders/webgl2/Phong.vs +6 -3
  171. package/src/assets/shaders/webgl2/Point.vs +6 -6
  172. package/src/assets/shaders/webgl2/Unlit.vs +6 -3
  173. package/src/assets/shaders/webgl2/include/Line2.glsl +20 -0
  174. package/src/assets/shaders/webgl2/include/Particle.glsl +36 -0
  175. package/src/example.html +6 -6
  176. package/src/standard/Math/Algorithm.js +12 -28
  177. package/src/standard/Math/Geometry/Plane3.js +0 -2
  178. package/src/standard/Math/Geometry/ViewVolume.js +88 -83
  179. package/src/standard/Math/Numbers/Color3.js +6 -0
  180. package/src/standard/Math/Numbers/Color4.js +7 -0
  181. package/src/standard/Math/Numbers/Complex.js +5 -0
  182. package/src/standard/Math/Numbers/Matrix2.js +20 -2
  183. package/src/standard/Math/Numbers/Matrix3.js +129 -110
  184. package/src/standard/Math/Numbers/Matrix4.js +138 -119
  185. package/src/standard/Math/Numbers/Quaternion.js +7 -0
  186. package/src/standard/Math/Numbers/Rotation4.js +7 -0
  187. package/src/standard/Math/Numbers/Vector2.js +8 -5
  188. package/src/standard/Math/Numbers/Vector3.js +16 -10
  189. package/src/standard/Math/Numbers/Vector4.js +12 -7
  190. package/src/standard/Math/Utility/BVH.js +45 -17
  191. package/src/tests.js +6 -1
  192. package/src/x_ite/Base/X3DBaseNode.js +22 -11
  193. package/src/x_ite/Base/X3DField.js +1 -1
  194. package/src/x_ite/Browser/Core/BrowserOptions.js +2 -2
  195. package/src/x_ite/Browser/Core/BrowserTimings.js +4 -2
  196. package/src/x_ite/Browser/Core/Context.js +185 -0
  197. package/src/x_ite/Browser/Core/ContextMenu.js +299 -193
  198. package/src/x_ite/Browser/Core/Notification.js +1 -0
  199. package/src/x_ite/Browser/Core/X3DCoreContext.js +35 -146
  200. package/src/x_ite/Browser/Layout/ScreenText.js +11 -4
  201. package/src/x_ite/Browser/Layout/X3DLayoutContext.js +4 -15
  202. package/src/x_ite/Browser/Navigation/ExamineViewer.js +12 -19
  203. package/src/x_ite/Browser/Navigation/LookAtViewer.js +0 -3
  204. package/src/x_ite/Browser/Navigation/PlaneViewer.js +0 -3
  205. package/src/x_ite/Browser/Navigation/X3DFlyViewer.js +14 -7
  206. package/src/x_ite/Browser/Navigation/X3DViewer.js +12 -20
  207. package/src/x_ite/Browser/Networking/X3DNetworkingContext.js +11 -7
  208. package/src/x_ite/Browser/ParticleSystems/BVH.glsl +183 -0
  209. package/src/x_ite/Browser/ParticleSystems/Box3.glsl +47 -0
  210. package/src/x_ite/Browser/ParticleSystems/GeometryTypes.js +66 -0
  211. package/src/x_ite/Browser/ParticleSystems/Line3.glsl +55 -0
  212. package/src/x_ite/Browser/ParticleSystems/Plane3.glsl +160 -0
  213. package/src/x_ite/Browser/PointingDeviceSensor/PointingDevice.js +27 -3
  214. package/src/x_ite/Browser/PointingDeviceSensor/X3DPointingDeviceSensorContext.js +37 -37
  215. package/src/x_ite/Browser/Rendering/X3DRenderingContext.js +19 -13
  216. package/src/x_ite/Browser/Shaders/Shader.js +33 -12
  217. package/src/x_ite/Browser/Shaders/ShaderSource.js +6 -0
  218. package/src/x_ite/Browser/Shaders/ShaderTest.js +16 -10
  219. package/src/x_ite/Browser/Shape/X3DShapeContext.js +50 -9
  220. package/src/x_ite/Browser/Text/X3DTextContext.js +4 -13
  221. package/src/x_ite/Browser/Texturing/X3DTexturingContext.js +23 -33
  222. package/src/x_ite/Browser/Texturing3D/DICOMParser.js +2 -2
  223. package/src/x_ite/Browser/Time/X3DTimeContext.js +3 -1
  224. package/src/x_ite/Browser/VERSION.js +1 -1
  225. package/src/x_ite/Browser/X3DBrowser.js +7 -6
  226. package/src/x_ite/Browser/X3DBrowserContext.js +35 -10
  227. package/src/x_ite/Components/Core/X3DNode.js +4 -0
  228. package/src/x_ite/Components/Core/X3DPrototypeInstance.js +0 -2
  229. package/src/x_ite/Components/CubeMapTexturing/ComposedCubeMapTexture.js +3 -4
  230. package/src/x_ite/Components/CubeMapTexturing/GeneratedCubeMapTexture.js +1 -12
  231. package/src/x_ite/Components/CubeMapTexturing/ImageCubeMapTexture.js +0 -1
  232. package/src/x_ite/Components/EnvironmentalEffects/TextureBackground.js +1 -1
  233. package/src/x_ite/Components/EnvironmentalEffects/X3DBackgroundNode.js +76 -77
  234. package/src/x_ite/Components/EnvironmentalEffects/X3DFogObject.js +2 -9
  235. package/src/x_ite/Components/EnvironmentalSensor/ProximitySensor.js +51 -65
  236. package/src/x_ite/Components/EventUtilities/X3DSequencerNode.js +1 -1
  237. package/src/x_ite/Components/Followers/X3DChaserNode.js +18 -32
  238. package/src/x_ite/Components/Followers/X3DDamperNode.js +1 -6
  239. package/src/x_ite/Components/Geometry2D/TriangleSet2D.js +1 -1
  240. package/src/x_ite/Components/Geometry3D/ElevationGrid.js +12 -4
  241. package/src/x_ite/Components/Geometry3D/IndexedFaceSet.js +4 -4
  242. package/src/x_ite/Components/Geospatial/GeoCoordinate.js +10 -27
  243. package/src/x_ite/Components/Geospatial/GeoPositionInterpolator.js +5 -10
  244. package/src/x_ite/Components/Geospatial/GeoTouchSensor.js +9 -16
  245. package/src/x_ite/Components/Geospatial/GeoTransform.js +6 -18
  246. package/src/x_ite/Components/Geospatial/X3DGeospatialObject.js +20 -27
  247. package/src/x_ite/Components/Grouping/X3DGroupingNode.js +8 -8
  248. package/src/x_ite/Components/Grouping/X3DTransformNode.js +0 -4
  249. package/src/x_ite/Components/HAnim/HAnimHumanoid.js +68 -75
  250. package/src/x_ite/Components/Interpolation/OrientationInterpolator.js +4 -11
  251. package/src/x_ite/Components/Interpolation/X3DInterpolatorNode.js +1 -1
  252. package/src/x_ite/Components/Layout/LayoutGroup.js +4 -9
  253. package/src/x_ite/Components/Layout/ScreenFontStyle.js +1 -1
  254. package/src/x_ite/Components/Layout/ScreenGroup.js +18 -23
  255. package/src/x_ite/Components/Lighting/DirectionalLight.js +28 -36
  256. package/src/x_ite/Components/Lighting/PointLight.js +32 -47
  257. package/src/x_ite/Components/Lighting/SpotLight.js +33 -48
  258. package/src/x_ite/Components/Navigation/Billboard.js +49 -56
  259. package/src/x_ite/Components/Navigation/LOD.js +1 -1
  260. package/src/x_ite/Components/Navigation/X3DViewpointNode.js +82 -111
  261. package/src/x_ite/Components/Networking/Anchor.js +10 -4
  262. package/src/x_ite/Components/ParticleSystems/BoundedPhysicsModel.js +6 -6
  263. package/src/x_ite/Components/ParticleSystems/ConeEmitter.js +44 -36
  264. package/src/x_ite/Components/ParticleSystems/ExplosionEmitter.js +26 -17
  265. package/src/x_ite/Components/ParticleSystems/ForcePhysicsModel.js +20 -7
  266. package/src/x_ite/Components/ParticleSystems/ParticleSystem.js +461 -876
  267. package/src/x_ite/Components/ParticleSystems/PointEmitter.js +39 -35
  268. package/src/x_ite/Components/ParticleSystems/PolylineEmitter.js +112 -128
  269. package/src/x_ite/Components/ParticleSystems/SurfaceEmitter.js +105 -112
  270. package/src/x_ite/Components/ParticleSystems/VolumeEmitter.js +138 -176
  271. package/src/x_ite/Components/ParticleSystems/WindPhysicsModel.js +16 -11
  272. package/src/x_ite/Components/ParticleSystems/X3DParticleEmitterNode.js +807 -217
  273. package/src/x_ite/Components/Picking/LinePickSensor.js +31 -39
  274. package/src/x_ite/Components/PointingDeviceSensor/CylinderSensor.js +90 -107
  275. package/src/x_ite/Components/PointingDeviceSensor/PlaneSensor.js +48 -55
  276. package/src/x_ite/Components/PointingDeviceSensor/SphereSensor.js +53 -70
  277. package/src/x_ite/Components/PointingDeviceSensor/TouchSensor.js +8 -15
  278. package/src/x_ite/Components/ProjectiveTextureMapping/TextureProjectorParallel.js +43 -50
  279. package/src/x_ite/Components/ProjectiveTextureMapping/TextureProjectorPerspective.js +32 -39
  280. package/src/x_ite/Components/Rendering/ClipPlane.js +3 -11
  281. package/src/x_ite/Components/Rendering/Color.js +12 -37
  282. package/src/x_ite/Components/Rendering/ColorRGBA.js +13 -38
  283. package/src/x_ite/Components/Rendering/IndexedLineSet.js +12 -4
  284. package/src/x_ite/Components/Rendering/LineSet.js +21 -13
  285. package/src/x_ite/Components/Rendering/PointSet.js +21 -13
  286. package/src/x_ite/Components/Rendering/X3DColorNode.js +13 -0
  287. package/src/x_ite/Components/Rendering/X3DComposedGeometryNode.js +13 -5
  288. package/src/x_ite/Components/Rendering/X3DGeometryNode.js +248 -325
  289. package/src/x_ite/Components/Rendering/X3DLineGeometryNode.js +305 -134
  290. package/src/x_ite/Components/Rendering/X3DPointGeometryNode.js +99 -122
  291. package/src/x_ite/Components/RigidBodyPhysics/DoubleAxisHingeJoint.js +24 -38
  292. package/src/x_ite/Components/RigidBodyPhysics/SingleAxisHingeJoint.js +10 -17
  293. package/src/x_ite/Components/Shaders/ComposedShader.js +35 -75
  294. package/src/x_ite/Components/Shaders/FloatVertexAttribute.js +5 -15
  295. package/src/x_ite/Components/Shaders/Matrix3VertexAttribute.js +7 -24
  296. package/src/x_ite/Components/Shaders/Matrix4VertexAttribute.js +7 -24
  297. package/src/x_ite/Components/Shaders/ShaderPart.js +1 -10
  298. package/src/x_ite/Components/Shaders/X3DProgrammableShaderObject.js +219 -209
  299. package/src/x_ite/Components/Shaders/X3DShaderNode.js +1 -1
  300. package/src/x_ite/Components/Shaders/X3DVertexAttributeNode.js +23 -1
  301. package/src/x_ite/Components/Shape/Appearance.js +12 -0
  302. package/src/x_ite/Components/Shape/FillProperties.js +12 -1
  303. package/src/x_ite/Components/Shape/LineProperties.js +33 -1
  304. package/src/x_ite/Components/Shape/PointProperties.js +23 -1
  305. package/src/x_ite/Components/Shape/Shape.js +27 -34
  306. package/src/x_ite/Components/Sound/Sound.js +30 -40
  307. package/src/x_ite/Components/Text/Text.js +6 -20
  308. package/src/x_ite/Components/Texturing/TextureCoordinate.js +5 -26
  309. package/src/x_ite/Components/Texturing/TextureProperties.js +4 -4
  310. package/src/x_ite/Components/Texturing/X3DSingleTextureCoordinateNode.js +21 -0
  311. package/src/x_ite/Components/Texturing/X3DSingleTextureNode.js +5 -4
  312. package/src/x_ite/Components/Texturing/X3DTexture2DNode.js +24 -33
  313. package/src/x_ite/Components/Texturing3D/TextureCoordinate3D.js +5 -26
  314. package/src/x_ite/Components/Texturing3D/TextureCoordinate4D.js +5 -26
  315. package/src/x_ite/Components/Texturing3D/X3DTexture3DNode.js +12 -19
  316. package/src/x_ite/Components/VolumeRendering/X3DVolumeDataNode.js +7 -7
  317. package/src/x_ite/Components.js +2 -2
  318. package/src/x_ite/Fallback.js +9 -3
  319. package/src/x_ite/Fields/SFColor.js +4 -0
  320. package/src/x_ite/Fields/SFColorRGBA.js +4 -0
  321. package/src/x_ite/Fields/SFMatrixPrototypeTemplate.js +4 -0
  322. package/src/x_ite/Fields/SFRotation.js +4 -0
  323. package/src/x_ite/Fields/SFString.js +4 -0
  324. package/src/x_ite/Fields/SFVecPrototypeTemplate.js +4 -0
  325. package/src/x_ite/Parser/XMLParser.js +1 -1
  326. package/src/x_ite/Rendering/TextureBuffer.js +43 -36
  327. package/src/x_ite/Rendering/VertexArray.js +101 -0
  328. package/src/x_ite/Rendering/X3DRenderObject.js +123 -144
  329. package/src/x_ite/X3D.js +32 -26
  330. package/src/x_ite.config.js +0 -5
  331. package/src/x_ite.css +200 -162
  332. package/src/x_ite.html +26 -10
  333. package/src/x_ite.js +42 -0
  334. package/x_ite.min.html +26 -10
  335. package/dist/assets/hatching/0.png +0 -0
  336. package/dist/assets/linetype/0.png +0 -0
  337. package/src/assets/hatching/0.png +0 -0
  338. package/src/assets/linetype/0.png +0 -0
  339. package/src/spinner.css +0 -67
  340. package/src/x_ite/Browser/Shape/LineStipples.xcf +0 -0
@@ -49,41 +49,23 @@
49
49
 
50
50
  define ([
51
51
  "x_ite/Components/Core/X3DNode",
52
+ "x_ite/Browser/ParticleSystems/GeometryTypes",
52
53
  "x_ite/Base/X3DConstants",
53
- "standard/Math/Numbers/Vector3",
54
- "standard/Math/Numbers/Rotation4",
55
- "standard/Math/Geometry/Line3",
56
- "standard/Math/Geometry/Plane3",
57
- "standard/Math/Algorithm",
58
- "standard/Math/Algorithms/QuickSort",
54
+ "text!x_ite/Browser/ParticleSystems/Line3.glsl",
55
+ "text!x_ite/Browser/ParticleSystems/Plane3.glsl",
56
+ "text!x_ite/Browser/ParticleSystems/Box3.glsl",
57
+ "text!x_ite/Browser/ParticleSystems/BVH.glsl",
59
58
  ],
60
59
  function (X3DNode,
60
+ GeometryTypes,
61
61
  X3DConstants,
62
- Vector3,
63
- Rotation4,
64
- Line3,
65
- Plane3,
66
- Algorithm,
67
- QuickSort)
62
+ Line3Source,
63
+ Plane3Source,
64
+ Box3Source,
65
+ BVHSource)
68
66
  {
69
67
  "use strict";
70
68
 
71
- var
72
- normal = new Vector3 (0, 0, 0),
73
- fromPosition = new Vector3 (0, 0, 0),
74
- line = new Line3 (Vector3 .Zero, Vector3 .zAxis),
75
- plane = new Plane3 (Vector3 .Zero, Vector3 .zAxis);
76
-
77
- function PlaneCompare (a, b)
78
- {
79
- return plane .getDistanceToPoint (a) < plane .getDistanceToPoint (b);
80
- }
81
-
82
- function PlaneCompareValue (a, b)
83
- {
84
- return a < plane .getDistanceToPoint (b);
85
- }
86
-
87
69
  function X3DParticleEmitterNode (executionContext)
88
70
  {
89
71
  X3DNode .call (this, executionContext);
@@ -94,10 +76,23 @@ function (X3DNode,
94
76
  this ._mass .setUnit ("mass");
95
77
  this ._surfaceArea .setUnit ("area");
96
78
 
97
- this .rotations = [ ];
98
- this .intersections = [ ];
99
- this .intersectionNormals = [ ];
100
- this .sorter = new QuickSort (this .intersections, PlaneCompare);
79
+ this .samplers = [ ];
80
+ this .uniforms = { };
81
+ this .functions = [ ];
82
+ this .program = null;
83
+
84
+ this .addSampler ("forces");
85
+ this .addSampler ("boundedVolume");
86
+ this .addSampler ("colorRamp");
87
+ this .addSampler ("texCoordRamp");
88
+
89
+ this .addUniform ("speed", "uniform float speed;");
90
+ this .addUniform ("variation", "uniform float variation;");
91
+
92
+ this .addFunction (Line3Source);
93
+ this .addFunction (Plane3Source);
94
+ this .addFunction (Box3Source);
95
+ this .addFunction (BVHSource);
101
96
  }
102
97
 
103
98
  X3DParticleEmitterNode .prototype = Object .assign (Object .create (X3DNode .prototype),
@@ -107,26 +102,28 @@ function (X3DNode,
107
102
  {
108
103
  X3DNode .prototype .initialize .call (this);
109
104
 
110
- this ._speed .addInterest ("set_speed__", this);
105
+ const gl = this .getBrowser () .getContext ();
106
+
107
+ if (gl .getVersion () < 2)
108
+ return;
109
+
110
+ // Create program.
111
+
112
+ this .program = this .createProgram ();
113
+ this .transformFeedback = gl .createTransformFeedback ();
114
+
115
+ // Initialize fields.
116
+
117
+ this ._on .addInterest ("set_on__", this);
118
+ this ._speed .addInterest ("set_speed__", this);
111
119
  this ._variation .addInterest ("set_variation__", this);
112
- this ._mass .addInterest ("set_mass__", this);
120
+ this ._mass .addInterest ("set_mass__", this);
113
121
 
122
+ this .set_on__ ();
114
123
  this .set_speed__ ();
115
124
  this .set_variation__ ();
116
125
  this .set_mass__ ();
117
126
  },
118
- set_speed__: function ()
119
- {
120
- this .speed = this ._speed .getValue ();
121
- },
122
- set_variation__: function ()
123
- {
124
- this .variation = this ._variation .getValue ();
125
- },
126
- set_mass__: function ()
127
- {
128
- this .mass = this ._mass .getValue ();
129
- },
130
127
  isExplosive: function ()
131
128
  {
132
129
  return false;
@@ -135,28 +132,21 @@ function (X3DNode,
135
132
  {
136
133
  return this .mass;
137
134
  },
138
- getRandomLifetime: function (particleLifetime, lifetimeVariation)
135
+ set_on__: function ()
139
136
  {
140
- var
141
- v = particleLifetime * lifetimeVariation,
142
- min = Math .max (0, particleLifetime - v),
143
- max = particleLifetime + v;
144
-
145
- return Math .random () * (max - min) + min;
137
+ this .on = this ._on .getValue ();
146
138
  },
147
- getRandomSpeed: function ()
139
+ set_speed__: function ()
148
140
  {
149
- var
150
- speed = this .speed,
151
- v = speed * this .variation,
152
- min = Math .max (0, speed - v),
153
- max = speed + v;
154
-
155
- return Math .random () * (max - min) + min;
141
+ this .setUniform ("uniform1f", "speed", this ._speed .getValue ());
156
142
  },
157
- getSphericalRandomVelocity: function (velocity)
143
+ set_variation__: function ()
158
144
  {
159
- return this .getRandomNormal (velocity) .multiply (this .getRandomSpeed ());
145
+ this .setUniform ("uniform1f", "variation", this ._variation .getValue ());
146
+ },
147
+ set_mass__: function ()
148
+ {
149
+ this .mass = this ._mass .getValue ();
160
150
  },
161
151
  getRandomValue: function (min, max)
162
152
  {
@@ -164,7 +154,7 @@ function (X3DNode,
164
154
  },
165
155
  getRandomNormal: function (normal)
166
156
  {
167
- var
157
+ const
168
158
  theta = this .getRandomValue (-1, 1) * Math .PI,
169
159
  cphi = this .getRandomValue (-1, 1),
170
160
  phi = Math .acos (cphi),
@@ -174,234 +164,834 @@ function (X3DNode,
174
164
  Math .cos (theta) * r,
175
165
  cphi);
176
166
  },
177
- getRandomNormalWithAngle: function (angle, normal)
167
+ animate: function (particleSystem, deltaTime)
178
168
  {
179
- var
180
- theta = (Math .random () * 2 - 1) * Math .PI,
181
- cphi = this .getRandomValue (Math .cos (angle), 1),
182
- phi = Math .acos (cphi),
183
- r = Math .sin (phi);
169
+ const
170
+ browser = this .getBrowser (),
171
+ gl = browser .getContext (),
172
+ inputParticles = particleSystem .inputParticles,
173
+ particleStride = particleSystem .particleStride,
174
+ particleOffsets = particleSystem .particleOffsets,
175
+ program = this .program;
184
176
 
185
- return normal .set (Math .sin (theta) * r,
186
- Math .cos (theta) * r,
187
- cphi);
177
+ // Start
178
+
179
+ gl .useProgram (program);
180
+
181
+ // Uniforms
182
+
183
+ gl .uniform1i (program .randomSeed, Math .random () * 0xffffffff);
184
+ gl .uniform1i (program .geometryType, particleSystem .geometryType);
185
+ gl .uniform1i (program .createParticles, particleSystem .createParticles && this .on);
186
+ gl .uniform1f (program .particleLifetime, particleSystem .particleLifetime);
187
+ gl .uniform1f (program .lifetimeVariation, particleSystem .lifetimeVariation);
188
+ gl .uniform1f (program .deltaTime, deltaTime);
189
+ gl .uniform2f (program .particleSize, particleSystem ._particleSize .x, particleSystem ._particleSize .y);
190
+
191
+ // Forces
192
+
193
+ gl .uniform1i (program .numForces, particleSystem .numForces);
194
+
195
+ if (particleSystem .numForces)
196
+ {
197
+ gl .activeTexture (gl .TEXTURE0 + program .forcesTextureUnit);
198
+ gl .bindTexture (gl .TEXTURE_2D, particleSystem .forcesTexture);
199
+ }
200
+
201
+ // Bounded Physics
202
+
203
+ if (particleSystem .boundedHierarchyRoot < 0)
204
+ {
205
+ gl .uniform1i (program .boundedHierarchyRoot, -1);
206
+ }
207
+ else
208
+ {
209
+ gl .uniform1i (program .boundedVerticesIndex, particleSystem .boundedVerticesIndex);
210
+ gl .uniform1i (program .boundedNormalsIndex, particleSystem .boundedNormalsIndex);
211
+ gl .uniform1i (program .boundedHierarchyIndex, particleSystem .boundedHierarchyIndex);
212
+ gl .uniform1i (program .boundedHierarchyRoot, particleSystem .boundedHierarchyRoot);
213
+
214
+ gl .activeTexture (gl .TEXTURE0 + program .boundedVolumeTextureUnit);
215
+ gl .bindTexture (gl .TEXTURE_2D, particleSystem .boundedTexture);
216
+ }
217
+
218
+ // Colors
219
+
220
+ gl .uniform1i (program .numColors, particleSystem .numColors);
221
+
222
+ if (particleSystem .numColors)
223
+ {
224
+ gl .activeTexture (gl .TEXTURE0 + program .colorRampTextureUnit);
225
+ gl .bindTexture (gl .TEXTURE_2D, particleSystem .colorRampTexture);
226
+ }
227
+
228
+ // TexCoords
229
+
230
+ gl .uniform1i (program .numTexCoords, particleSystem .numTexCoords);
231
+
232
+ if (particleSystem .numTexCoords)
233
+ {
234
+ gl .uniform1i (program .texCoordCount, particleSystem .texCoordCount);
235
+
236
+ gl .activeTexture (gl .TEXTURE0 + program .texCoordRampTextureUnit);
237
+ gl .bindTexture (gl .TEXTURE_2D, particleSystem .texCoordRampTexture);
238
+ }
239
+
240
+ // Other textures
241
+
242
+ this .activateTextures (gl, program);
243
+
244
+ // Input attributes
245
+
246
+ if (inputParticles .emitterArrayObject .enable (gl, program))
247
+ {
248
+ for (const [i, attribute] of program .inputs)
249
+ {
250
+ gl .bindBuffer (gl .ARRAY_BUFFER, inputParticles);
251
+ gl .enableVertexAttribArray (attribute);
252
+ gl .vertexAttribPointer (attribute, 4, gl .FLOAT, false, particleStride, particleOffsets [i]);
253
+ }
254
+
255
+ gl .bindBuffer (gl .ARRAY_BUFFER, null);
256
+ }
257
+
258
+ // Transform particles.
259
+
260
+ gl .bindTransformFeedback (gl .TRANSFORM_FEEDBACK, this .transformFeedback);
261
+ gl .bindBufferBase (gl .TRANSFORM_FEEDBACK_BUFFER, 0, particleSystem .outputParticles);
262
+ gl .enable (gl .RASTERIZER_DISCARD);
263
+ gl .beginTransformFeedback (gl .POINTS);
264
+ gl .drawArrays (gl .POINTS, 0, particleSystem .numParticles);
265
+ gl .endTransformFeedback ();
266
+ gl .disable (gl .RASTERIZER_DISCARD);
267
+ gl .bindTransformFeedback (gl .TRANSFORM_FEEDBACK, null);
268
+
269
+ // DEBUG
270
+
271
+ // const data = new Float32Array (particleSystem .numParticles * (particleStride / 4));
272
+ // gl .bindBuffer (gl .ARRAY_BUFFER, particleSystem .outputParticles);
273
+ // gl .getBufferSubData (gl .ARRAY_BUFFER, 0, data);
274
+ // console .log (data .slice (0, particleStride / 4));
188
275
  },
189
- getRandomNormalWithDirectionAndAngle: function (direction, angle, normal)
276
+ addSampler: function (name)
190
277
  {
191
- rotation .setFromToVec (Vector3 .zAxis, direction);
192
-
193
- return rotation .multVecRot (this .getRandomNormalWithAngle (angle, normal));
278
+ this .samplers .push (name);
194
279
  },
195
- getRandomSurfaceNormal: function (normal)
280
+ addUniform: function (name, uniform)
196
281
  {
197
- var
198
- theta = this .getRandomValue (-1, 1) * Math .PI,
199
- cphi = Math .pow (Math .random (), 1/3),
200
- phi = Math .acos (cphi),
201
- r = Math .sin (phi);
282
+ this .uniforms [name] = uniform;
283
+ },
284
+ setUniform: function (func, name, value1, value2, value3)
285
+ {
286
+ const
287
+ gl = this .getBrowser () .getContext (),
288
+ program = this .program;
202
289
 
203
- return normal .set (Math .sin (theta) * r,
204
- Math .cos (theta) * r,
205
- cphi);
290
+ gl .useProgram (program);
291
+ gl [func] (program [name], value1, value2, value3);
206
292
  },
207
- animate: function (particleSystem, deltaTime)
293
+ addFunction: function (func)
208
294
  {
209
- var
210
- particles = particleSystem .particles,
211
- numParticles = particleSystem .numParticles,
212
- createParticles = particleSystem .createParticles,
213
- particleLifetime = particleSystem .particleLifetime,
214
- lifetimeVariation = particleSystem .lifetimeVariation,
215
- speeds = particleSystem .speeds, // speed of velocities
216
- velocities = particleSystem .velocities, // resulting velocities from forces
217
- turbulences = particleSystem .turbulences, // turbulences
218
- rotations = this .rotations, // rotation to direction of force
219
- numForces = particleSystem .numForces, // number of forces
220
- boundedPhysics = particleSystem .boundedVertices .length,
221
- boundedVolume = particleSystem .boundedVolume;
222
-
223
- for (var i = rotations .length; i < numForces; ++ i)
224
- rotations [i] = new Rotation4 (0, 0, 1, 0);
225
-
226
- for (var i = 0; i < numForces; ++ i)
227
- rotations [i] .setFromToVec (Vector3 .zAxis, velocities [i]);
228
-
229
- for (var i = 0; i < numParticles; ++ i)
295
+ this .functions .push (func);
296
+ },
297
+ createProgram: function ()
298
+ {
299
+ const
300
+ browser = this .getBrowser (),
301
+ gl = browser .getContext ();
302
+
303
+ const vertexShaderSource = /* glsl */ `#version 300 es
304
+
305
+ precision highp float;
306
+ precision highp int;
307
+ precision highp sampler2D;
308
+
309
+ uniform int randomSeed;
310
+ uniform int geometryType;
311
+ uniform bool createParticles;
312
+ uniform float particleLifetime;
313
+ uniform float lifetimeVariation;
314
+ uniform float deltaTime;
315
+ uniform vec2 particleSize;
316
+
317
+ uniform int numForces;
318
+ uniform sampler2D forces;
319
+
320
+ uniform int boundedVerticesIndex;
321
+ uniform int boundedNormalsIndex;
322
+ uniform int boundedHierarchyIndex;
323
+ uniform int boundedHierarchyRoot;
324
+ uniform sampler2D boundedVolume;
325
+
326
+ uniform int numColors;
327
+ uniform sampler2D colorRamp;
328
+
329
+ uniform int texCoordCount;
330
+ uniform int numTexCoords;
331
+ uniform sampler2D texCoordRamp;
332
+
333
+ ${Object .values (this .uniforms) .join ("\n")}
334
+
335
+ in vec4 input0;
336
+ in vec4 input2;
337
+ in vec4 input6;
338
+
339
+ out vec4 output0;
340
+ out vec4 output1;
341
+ out vec4 output2;
342
+
343
+ out vec4 output3;
344
+ out vec4 output4;
345
+ out vec4 output5;
346
+ out vec4 output6;
347
+
348
+ // Constants
349
+
350
+ ${Object .entries (GeometryTypes) .map (([k, v]) => `#define ${k} ${v}`) .join ("\n")}
351
+
352
+ const int ARRAY_SIZE = 32;
353
+ const float M_PI = 3.14159265359;
354
+
355
+ uniform float NaN;
356
+
357
+ // Texture
358
+
359
+ vec4
360
+ texelFetch (const in sampler2D sampler, const in int index, const in int lod)
230
361
  {
231
- var
232
- particle = particles [i],
233
- elapsedTime = particle .elapsedTime + deltaTime;
362
+ int x = textureSize (sampler, lod) .x;
363
+ ivec2 p = ivec2 (index % x, index / x);
364
+ vec4 t = texelFetch (sampler, p, lod);
234
365
 
235
- if (elapsedTime > particle .lifetime)
236
- {
237
- // Create new particle or hide particle.
366
+ return t;
367
+ }
238
368
 
239
- particle .lifetime = this .getRandomLifetime (particleLifetime, lifetimeVariation);
240
- particle .elapsedTime = 0;
369
+ // Math
241
370
 
242
- if (createParticles)
371
+ // Save normalize, that will not divide by zero.
372
+ vec3
373
+ save_normalize (const in vec3 vector)
374
+ {
375
+ float l = length (vector);
376
+
377
+ if (l == 0.0)
378
+ return vec3 (0.0);
379
+
380
+ return vector / l;
381
+ }
382
+
383
+ // Quaternion
384
+
385
+ vec4
386
+ Quaternion (const in vec3 fromVector, const in vec3 toVector)
387
+ {
388
+ vec3 from = save_normalize (fromVector);
389
+ vec3 to = save_normalize (toVector);
390
+
391
+ float cos_angle = dot (from, to);
392
+ vec3 cross_vec = cross (from, to);
393
+ float cross_len = length (cross_vec);
394
+
395
+ if (cross_len == 0.0)
396
+ {
397
+ if (cos_angle > 0.0)
243
398
  {
244
- ++ particle .life;
245
- this .getRandomPosition (particle .position);
246
- this .getRandomVelocity (particle .velocity);
399
+ return vec4 (0.0, 0.0, 0.0, 1.0);
247
400
  }
248
401
  else
249
- particle .position .set (Number .POSITIVE_INFINITY, Number .POSITIVE_INFINITY, Number .POSITIVE_INFINITY);
402
+ {
403
+ vec3 t = cross (from, vec3 (1.0, 0.0, 0.0));
404
+
405
+ if (dot (t, t) == 0.0)
406
+ t = cross (from, vec3 (0.0, 1.0, 0.0));
407
+
408
+ t = save_normalize (t);
409
+
410
+ return vec4 (t, 0.0);
411
+ }
250
412
  }
251
413
  else
252
414
  {
253
- // Animate particle.
415
+ float s = sqrt (abs (1.0 - cos_angle) * 0.5);
416
+
417
+ cross_vec = save_normalize (cross_vec);
418
+
419
+ return vec4 (cross_vec * s, sqrt (abs (1.0 + cos_angle) * 0.5));
420
+ }
421
+ }
422
+
423
+ vec3
424
+ multVecQuat (const in vec3 v, const in vec4 q)
425
+ {
426
+ float a = q .w * q .w - q .x * q .x - q .y * q .y - q .z * q .z;
427
+ float b = 2.0 * (v .x * q .x + v .y * q .y + v .z * q .z);
428
+ float c = 2.0 * q .w;
429
+ vec3 r = a * v .xyz + b * q .xyz + c * (q .yzx * v .zxy - q .zxy * v .yzx);
430
+
431
+ return r;
432
+ }
433
+
434
+ mat3
435
+ Matrix3 (const in vec4 quaternion)
436
+ {
437
+ float x = quaternion .x;
438
+ float y = quaternion .y;
439
+ float z = quaternion .z;
440
+ float w = quaternion .w;
441
+ float A = y * y;
442
+ float B = z * z;
443
+ float C = x * y;
444
+ float D = z * w;
445
+ float E = z * x;
446
+ float F = y * w;
447
+ float G = x * x;
448
+ float H = y * z;
449
+ float I = x * w;
450
+
451
+ return mat3 (1.0 - 2.0 * (A + B),
452
+ 2.0 * (C + D),
453
+ 2.0 * (E - F),
454
+ 2.0 * (C - D),
455
+ 1.0 - 2.0 * (B + G),
456
+ 2.0 * (H + I),
457
+ 2.0 * (E + F),
458
+ 2.0 * (H - I),
459
+ 1.0 - 2.0 * (A + G));
460
+ }
461
+
462
+ /* Random number generation */
463
+
464
+ uint seed = 1u;
465
+
466
+ void
467
+ srand (const in int value)
468
+ {
469
+ seed = uint (value);
470
+ }
471
+
472
+ // Return a uniform distributed random floating point number in the interval [0, 1].
473
+ float
474
+ random ()
475
+ {
476
+ seed = seed * 1103515245u + 12345u;
477
+
478
+ return float (seed) / 4294967295.0;
479
+ }
480
+
481
+ float
482
+ getRandomValue (const in float min, const in float max)
483
+ {
484
+ return min + random () * (max - min);
485
+ }
486
+
487
+ float
488
+ getRandomLifetime ()
489
+ {
490
+ float v = particleLifetime * lifetimeVariation;
491
+ float min_ = max (0.0, particleLifetime - v);
492
+ float max_ = particleLifetime + v;
254
493
 
255
- var
256
- position = particle .position,
257
- velocity = particle .velocity;
494
+ return getRandomValue (min_, max_);
495
+ }
496
+
497
+ float
498
+ getRandomSpeed ()
499
+ {
500
+ float v = speed * variation;
501
+ float min_ = max (0.0, speed - v);
502
+ float max_ = speed + v;
503
+
504
+ return getRandomValue (min_, max_);
505
+ }
506
+
507
+ vec3
508
+ getRandomNormal ()
509
+ {
510
+ float theta = getRandomValue (-M_PI, M_PI);
511
+ float cphi = getRandomValue (-1.0, 1.0);
512
+ float r = sqrt (1.0 - cphi * cphi); // sin (acos (cphi));
513
+
514
+ return vec3 (sin (theta) * r, cos (theta) * r, cphi);
515
+ }
516
+
517
+ vec3
518
+ getRandomNormalWithAngle (const in float angle)
519
+ {
520
+ float theta = getRandomValue (-M_PI, M_PI);
521
+ float cphi = getRandomValue (cos (angle), 1.0);
522
+ float r = sqrt (1.0 - cphi * cphi); // sin (acos (cphi));
523
+
524
+ return vec3 (sin (theta) * r, cos (theta) * r, cphi);
525
+ }
526
+
527
+ vec3
528
+ getRandomNormalWithDirectionAndAngle (const in vec3 direction, const in float angle)
529
+ {
530
+ vec4 rotation = Quaternion (vec3 (0.0, 0.0, 1.0), direction);
531
+ vec3 normal = getRandomNormalWithAngle (angle);
258
532
 
259
- for (var f = 0; f < numForces; ++ f)
533
+ return multVecQuat (normal, rotation);
534
+ }
535
+
536
+ vec3
537
+ getRandomSurfaceNormal (const in vec3 direction)
538
+ {
539
+ float theta = getRandomValue (-M_PI, M_PI);
540
+ float cphi = pow (random (), 1.0 / 3.0);
541
+ float r = sqrt (1.0 - cphi * cphi); // sin (acos (cphi));
542
+ vec3 normal = vec3 (sin (theta) * r, cos (theta) * r, cphi);
543
+ vec4 rotation = Quaternion (vec3 (0.0, 0.0, 1.0), direction);
544
+
545
+ return multVecQuat (normal, rotation);
546
+ }
547
+
548
+ vec3
549
+ getRandomSphericalVelocity ()
550
+ {
551
+ vec3 normal = getRandomNormal ();
552
+ float speed = getRandomSpeed ();
553
+
554
+ return normal * speed;
555
+ }
556
+
557
+ // Algorithms
558
+
559
+ int
560
+ upperBound (const in sampler2D sampler, in int count, const in float value)
561
+ {
562
+ int first = 0;
563
+ int step = 0;
564
+
565
+ while (count > 0)
566
+ {
567
+ int index = first;
568
+
569
+ step = count >> 1;
570
+
571
+ index += step;
572
+
573
+ if (value < texelFetch (sampler, index, 0) .x)
260
574
  {
261
- velocity .add (rotations [f] .multVecRot (this .getRandomNormalWithAngle (turbulences [f], normal)) .multiply (speeds [f]));
575
+ count = step;
262
576
  }
577
+ else
578
+ {
579
+ first = ++ index;
580
+ count -= step + 1;
581
+ }
582
+ }
263
583
 
264
- if (boundedPhysics)
584
+ return first;
585
+ }
586
+
587
+ void
588
+ interpolate (const in sampler2D sampler, const in int count, const in float fraction, out int index0, out int index1, out float weight)
589
+ {
590
+ // Determine index0, index1 and weight.
591
+
592
+ if (count == 1 || fraction <= texelFetch (sampler, 0, 0) .x)
593
+ {
594
+ index0 = 0;
595
+ index1 = 0;
596
+ weight = 0.0;
597
+ }
598
+ else if (fraction >= texelFetch (sampler, count - 1, 0) .x)
599
+ {
600
+ index0 = count - 2;
601
+ index1 = count - 1;
602
+ weight = 1.0;
603
+ }
604
+ else
605
+ {
606
+ int index = upperBound (sampler, count, fraction);
607
+
608
+ if (index < count)
265
609
  {
266
- fromPosition .x = position .x;
267
- fromPosition .y = position .y;
268
- fromPosition .z = position .z;
610
+ index1 = index;
611
+ index0 = index - 1;
269
612
 
270
- position .x += velocity .x * deltaTime;
271
- position .y += velocity .y * deltaTime;
272
- position .z += velocity .z * deltaTime;
613
+ float key0 = texelFetch (sampler, index0, 0) .x;
614
+ float key1 = texelFetch (sampler, index1, 0) .x;
273
615
 
274
- this .bounce (boundedVolume, fromPosition, position, velocity);
616
+ weight = clamp ((fraction - key0) / (key1 - key0), 0.0, 1.0);
275
617
  }
276
618
  else
277
619
  {
278
- position .x += velocity .x * deltaTime;
279
- position .y += velocity .y * deltaTime;
280
- position .z += velocity .z * deltaTime;
620
+ index0 = 0;
621
+ index1 = 0;
622
+ weight = 0.0;
281
623
  }
624
+ }
625
+ }
626
+
627
+ void
628
+ interpolate (const in sampler2D sampler, const in int count, const in float fraction, out int index0)
629
+ {
630
+ // Determine index0.
282
631
 
283
- particle .elapsedTime = elapsedTime;
632
+ if (count == 1 || fraction <= texelFetch (sampler, 0, 0) .x)
633
+ {
634
+ index0 = 0;
635
+ }
636
+ else if (fraction >= texelFetch (sampler, count - 1, 0) .x)
637
+ {
638
+ index0 = count - 2;
639
+ }
640
+ else
641
+ {
642
+ int index = upperBound (sampler, count, fraction);
643
+
644
+ if (index < count)
645
+ index0 = index - 1;
646
+ else
647
+ index0 = 0;
284
648
  }
285
649
  }
286
650
 
287
- // Animate color if needed.
651
+ vec3
652
+ getRandomBarycentricCoord ()
653
+ {
654
+ // Random barycentric coordinates.
288
655
 
289
- if (particleSystem .geometryContext .colorMaterial)
290
- this .getColors (particles, particleSystem .colorKeys, particleSystem .colorRamp, numParticles);
291
- },
292
- bounce: function (boundedVolume, fromPosition, toPosition, velocity)
293
- {
294
- normal .assign (velocity) .normalize ();
656
+ float u = random ();
657
+ float v = random ();
658
+
659
+ if (u + v > 1.0)
660
+ {
661
+ u = 1.0 - u;
662
+ v = 1.0 - v;
663
+ }
295
664
 
296
- line .set (fromPosition, normal);
665
+ float t = 1.0 - u - v;
297
666
 
298
- var
299
- intersections = this .intersections,
300
- intersectionNormals = this .intersectionNormals,
301
- numIntersections = boundedVolume .intersectsLine (line, intersections, intersectionNormals);
667
+ return vec3 (t, u, v);
668
+ }
302
669
 
303
- if (numIntersections)
670
+ void
671
+ getRandomPointOnSurface (const in sampler2D surface, const in int verticesIndex, const in int normalsIndex, out vec4 position, out vec3 normal)
304
672
  {
305
- for (var i = 0; i < numIntersections; ++ i)
306
- intersections [i] .index = i;
673
+ // Determine index0, index1 and weight.
674
+
675
+ float lastAreaSoFar = texelFetch (surface, verticesIndex - 1, 0) .x;
676
+ float fraction = random () * lastAreaSoFar;
307
677
 
308
- plane .set (fromPosition, normal);
678
+ int index0;
679
+ int index1;
680
+ int index2;
681
+ float weight;
309
682
 
310
- this .sorter .sort (0, numIntersections);
683
+ interpolate (surface, verticesIndex, fraction, index0, index1, weight);
311
684
 
312
- var index = Algorithm .upperBound (intersections, 0, numIntersections, 0, PlaneCompareValue);
685
+ // Interpolate and return position.
313
686
 
314
- if (index < numIntersections)
687
+ index0 *= 3;
688
+ index1 = index0 + 1;
689
+ index2 = index0 + 2;
690
+
691
+ vec4 vertex0 = texelFetch (surface, verticesIndex + index0, 0);
692
+ vec4 vertex1 = texelFetch (surface, verticesIndex + index1, 0);
693
+ vec4 vertex2 = texelFetch (surface, verticesIndex + index2, 0);
694
+
695
+ vec3 normal0 = texelFetch (surface, normalsIndex + index0, 0) .xyz;
696
+ vec3 normal1 = texelFetch (surface, normalsIndex + index1, 0) .xyz;
697
+ vec3 normal2 = texelFetch (surface, normalsIndex + index2, 0) .xyz;
698
+
699
+ // Random barycentric coordinates.
700
+
701
+ vec3 r = getRandomBarycentricCoord ();
702
+
703
+ // Calculate position and direction.
704
+
705
+ position = r .z * vertex0 + r .x * vertex1 + r .y * vertex2;
706
+ normal = save_normalize (r .z * normal0 + r .x * normal1 + r .y * normal2);
707
+ }
708
+
709
+ // Functions
710
+
711
+ ${this .functions .join ("\n")}
712
+
713
+ // Current values
714
+
715
+ vec4
716
+ getColor (const in float lifetime, const in float elapsedTime)
717
+ {
718
+ if (numColors > 0)
315
719
  {
316
- var
317
- intersection = intersections [index],
318
- intersectionNormal = intersectionNormals [intersection .index];
720
+ // Determine index0, index1 and weight.
319
721
 
320
- plane .set (intersection, intersectionNormal);
722
+ float fraction = elapsedTime / lifetime;
321
723
 
322
- if (plane .getDistanceToPoint (fromPosition) * plane .getDistanceToPoint (toPosition) < 0)
323
- {
324
- var dot2 = 2 * intersectionNormal .dot (velocity);
724
+ int index0;
725
+ int index1;
726
+ float weight;
325
727
 
326
- velocity .x -= intersectionNormal .x * dot2;
327
- velocity .y -= intersectionNormal .y * dot2;
328
- velocity .z -= intersectionNormal .z * dot2;
728
+ interpolate (colorRamp, numColors, fraction, index0, index1, weight);
329
729
 
330
- normal .assign (velocity) .normalize ();
730
+ // Interpolate and return color.
331
731
 
332
- var distance = intersection .distance (fromPosition);
732
+ vec4 color0 = texelFetch (colorRamp, numColors + index0, 0);
733
+ vec4 color1 = texelFetch (colorRamp, numColors + index1, 0);
333
734
 
334
- toPosition .x = intersection .x + normal .x * distance;
335
- toPosition .y = intersection .y + normal .y * distance;
336
- toPosition .z = intersection .z + normal .z * distance;
337
- }
735
+ return mix (color0, color1, weight);
736
+ }
737
+ else
738
+ {
739
+ return vec4 (1.0);
338
740
  }
339
741
  }
340
- },
341
- getColors: function (particles, colorKeys, colorRamp, numParticles)
342
- {
343
- var
344
- length = colorKeys .length,
345
- index0 = 0,
346
- index1 = 0,
347
- weight = 0;
348
742
 
349
- for (var i = 0; i < numParticles; ++ i)
743
+ void
744
+ bounce (const in vec4 fromPosition, inout vec4 toPosition, inout vec3 velocity)
350
745
  {
351
- // Determine index0, index1 and weight.
746
+ if (boundedHierarchyRoot < 0)
747
+ return;
748
+
749
+ Line3 line = Line3 (fromPosition .xyz, save_normalize (velocity));
352
750
 
353
- var
354
- particle = particles [i],
355
- fraction = particle .elapsedTime / particle .lifetime,
356
- color = particle .color;
751
+ vec4 points [ARRAY_SIZE];
752
+ vec3 normals [ARRAY_SIZE];
357
753
 
358
- if (length == 1 || fraction <= colorKeys [0])
754
+ int numIntersections = getIntersections (boundedVolume, boundedVerticesIndex, boundedNormalsIndex, boundedHierarchyIndex, boundedHierarchyRoot, line, points, normals);
755
+
756
+ if (numIntersections == 0)
757
+ return;
758
+
759
+ Plane3 plane1 = plane3 (line .point, line .direction);
760
+
761
+ int index = min_index (points, numIntersections, 0.0, plane1);
762
+
763
+ if (index == -1)
764
+ return;
765
+
766
+ Plane3 plane2 = plane3 (points [index] .xyz, normals [index]);
767
+
768
+ if (sign (plane_distance (plane2, fromPosition .xyz)) == sign (plane_distance (plane2, toPosition .xyz)))
769
+ return;
770
+
771
+ velocity = reflect (velocity, normals [index]);
772
+ toPosition = vec4 (points [index] .xyz + reflect (points [index] .xyz - fromPosition .xyz, normals [index]), 1.0);
773
+ }
774
+
775
+ int
776
+ getTexCoordIndex0 (const in float lifetime, const in float elapsedTime)
777
+ {
778
+ if (numTexCoords == 0)
359
779
  {
360
- index0 = 0;
361
- index1 = 0;
362
- weight = 0;
780
+ return -1;
781
+ }
782
+ else
783
+ {
784
+ float fraction = elapsedTime / lifetime;
785
+ int index0 = 0;
786
+
787
+ interpolate (texCoordRamp, numTexCoords, fraction, index0);
788
+
789
+ return numTexCoords + index0 * texCoordCount;
363
790
  }
364
- else if (fraction >= colorKeys [length - 1])
791
+ }
792
+
793
+ void
794
+ main ()
795
+ {
796
+ int life = int (input0 [0]);
797
+ float lifetime = input0 [1];
798
+ float elapsedTime = input0 [2] + deltaTime;
799
+
800
+ srand ((gl_VertexID + randomSeed) * randomSeed);
801
+
802
+ if (elapsedTime > lifetime)
365
803
  {
366
- index0 = length - 2;
367
- index1 = length - 1;
368
- weight = 1;
804
+ // Create new particle or hide particle.
805
+
806
+ lifetime = getRandomLifetime ();
807
+ elapsedTime = 0.0;
808
+
809
+ output0 = vec4 (max (life + 1, 1), lifetime, elapsedTime, getTexCoordIndex0 (lifetime, elapsedTime));
810
+
811
+ if (createParticles)
812
+ {
813
+ output1 = getColor (lifetime, elapsedTime);
814
+ output2 = vec4 (getRandomVelocity (), 0.0);
815
+ output6 = getRandomPosition ();
816
+ }
817
+ else
818
+ {
819
+ output1 = vec4 (0.0);
820
+ output2 = vec4 (0.0);
821
+ output6 = vec4 (NaN);
822
+ }
369
823
  }
370
824
  else
371
825
  {
372
- var index = Algorithm .upperBound (colorKeys, 0, length, fraction, Algorithm .less);
826
+ // Animate particle.
827
+
828
+ vec3 velocity = input2 .xyz;
829
+ vec4 position = input6;
373
830
 
374
- if (index < length)
831
+ for (int i = 0; i < numForces; ++ i)
375
832
  {
376
- index1 = index;
377
- index0 = index - 1;
833
+ vec4 force = texelFetch (forces, i, 0);
834
+ float turbulence = force .w;
835
+ vec3 normal = getRandomNormalWithDirectionAndAngle (force .xyz, turbulence);
836
+ float speed = length (force .xyz);
837
+
838
+ velocity += normal * speed;
839
+ }
840
+
841
+ position .xyz += velocity * deltaTime;
378
842
 
379
- var
380
- key0 = colorKeys [index0],
381
- key1 = colorKeys [index1];
843
+ bounce (input6, position, velocity);
382
844
 
383
- weight = Algorithm .clamp ((fraction - key0) / (key1 - key0), 0, 1);
845
+ output0 = vec4 (life, lifetime, elapsedTime, getTexCoordIndex0 (lifetime, elapsedTime));
846
+ output1 = getColor (lifetime, elapsedTime);
847
+ output2 = vec4 (velocity, 0.0);
848
+ output6 = position;
849
+ }
850
+
851
+ switch (geometryType)
852
+ {
853
+ case POINT:
854
+ case SPRITE:
855
+ case GEOMETRY:
856
+ {
857
+ output3 = vec4 (1.0, 0.0, 0.0, 0.0);
858
+ output4 = vec4 (0.0, 1.0, 0.0, 0.0);
859
+ output5 = vec4 (0.0, 0.0, 1.0, 0.0);
860
+ break;
384
861
  }
385
- else
862
+ case LINE:
386
863
  {
387
- index0 = 0;
388
- index1 = 0;
389
- weight = 0;
864
+ mat3 r = Matrix3 (Quaternion (vec3 (0.0, 0.0, 1.0), output2 .xyz));
865
+ mat3 s = mat3 (1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, particleSize .y);
866
+ mat3 m = r * s;
867
+
868
+ output3 = vec4 (m [0], 0.0);
869
+ output4 = vec4 (m [1], 0.0);
870
+ output5 = vec4 (m [2], 0.0);
871
+ break;
872
+ }
873
+ default: // QUAD, TRIANGLE
874
+ {
875
+ output3 = vec4 (particleSize .x, 0.0, 0.0, 0.0);
876
+ output4 = vec4 (0.0, particleSize .y, 0.0, 0.0);
877
+ output5 = vec4 (0.0, 0.0, 1.0, 0.0);
878
+ break;
390
879
  }
391
880
  }
881
+ }
882
+ `;
883
+
884
+ const fragmentShaderSource = /* glsl */ `#version 300 es
885
+
886
+ precision highp float;
887
+
888
+ void
889
+ main () { }
890
+ `;
891
+
892
+ // Vertex shader
893
+
894
+ const vertexShader = gl .createShader (gl .VERTEX_SHADER);
895
+
896
+ gl .shaderSource (vertexShader, vertexShaderSource);
897
+ gl .compileShader (vertexShader);
898
+
899
+ // Fragment shader
900
+
901
+ const fragmentShader = gl .createShader (gl .FRAGMENT_SHADER);
902
+
903
+ gl .shaderSource (fragmentShader, fragmentShaderSource);
904
+ gl .compileShader (fragmentShader);
905
+
906
+ // Program
907
+
908
+ const program = gl .createProgram ();
909
+
910
+ gl .attachShader (program, vertexShader);
911
+ gl .attachShader (program, fragmentShader);
912
+ gl .transformFeedbackVaryings (program, Array .from ({length: 7}, (_, i) => "output" + i), gl .INTERLEAVED_ATTRIBS);
913
+ gl .linkProgram (program);
914
+
915
+ if (!gl .getProgramParameter (program, gl .LINK_STATUS))
916
+ console .error ("Couldn't initialize particle shader: " + gl .getProgramInfoLog (program));
917
+
918
+ program .inputs = [
919
+ [0, gl .getAttribLocation (program, "input0")],
920
+ [2, gl .getAttribLocation (program, "input2")],
921
+ [6, gl .getAttribLocation (program, "input6")],
922
+ ];
392
923
 
393
- // Interpolate and set color.
924
+ program .randomSeed = gl .getUniformLocation (program, "randomSeed");
925
+ program .geometryType = gl .getUniformLocation (program, "geometryType");
926
+ program .createParticles = gl .getUniformLocation (program, "createParticles");
927
+ program .particleLifetime = gl .getUniformLocation (program, "particleLifetime");
928
+ program .lifetimeVariation = gl .getUniformLocation (program, "lifetimeVariation");
929
+ program .deltaTime = gl .getUniformLocation (program, "deltaTime");
930
+ program .particleSize = gl .getUniformLocation (program, "particleSize");
394
931
 
395
- var
396
- color0 = colorRamp [index0],
397
- color1 = colorRamp [index1];
932
+ program .numForces = gl .getUniformLocation (program, "numForces");
933
+ program .forces = gl .getUniformLocation (program, "forces");
398
934
 
399
- // Algorithm .lerp (color0, color1, weight);
400
- color .x = color0 .x + weight * (color1 .x - color0 .x);
401
- color .y = color0 .y + weight * (color1 .y - color0 .y);
402
- color .z = color0 .z + weight * (color1 .z - color0 .z);
403
- color .w = color0 .w + weight * (color1 .w - color0 .w);
935
+ program .boundedVerticesIndex = gl .getUniformLocation (program, "boundedVerticesIndex");
936
+ program .boundedNormalsIndex = gl .getUniformLocation (program, "boundedNormalsIndex");
937
+ program .boundedHierarchyIndex = gl .getUniformLocation (program, "boundedHierarchyIndex");
938
+ program .boundedHierarchyRoot = gl .getUniformLocation (program, "boundedHierarchyRoot");
939
+ program .boundedVolume = gl .getUniformLocation (program, "boundedVolume");
940
+
941
+ program .numColors = gl .getUniformLocation (program, "numColors");
942
+ program .colorRamp = gl .getUniformLocation (program, "colorRamp");
943
+
944
+ program .texCoordCount = gl .getUniformLocation (program, "texCoordCount");
945
+ program .numTexCoords = gl .getUniformLocation (program, "numTexCoords");
946
+ program .texCoordRamp = gl .getUniformLocation (program, "texCoordRamp");
947
+
948
+ for (const name of Object .keys (this .uniforms))
949
+ program [name] = gl .getUniformLocation (program, name);
950
+
951
+ program .NaN = gl .getUniformLocation (program, "NaN");
952
+
953
+ gl .useProgram (program);
954
+
955
+ for (const name of this .samplers)
956
+ {
957
+ const location = gl .getUniformLocation (program, name);
958
+
959
+ gl .uniform1i (location, program [name + "TextureUnit"] = browser .getTexture2DUnit ());
404
960
  }
961
+
962
+ gl .uniform1f (program .NaN, NaN);
963
+
964
+ browser .resetTextureUnits ();
965
+
966
+ return program;
967
+ },
968
+ activateTextures: function ()
969
+ { },
970
+ createTexture: function ()
971
+ {
972
+ const
973
+ gl = this .getBrowser () .getContext (),
974
+ texture = gl .createTexture ();
975
+
976
+ gl .bindTexture (gl .TEXTURE_2D, texture);
977
+
978
+ gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_WRAP_S, gl .CLAMP_TO_EDGE);
979
+ gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_WRAP_T, gl .CLAMP_TO_EDGE);
980
+ gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_MAG_FILTER, gl .NEAREST);
981
+ gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_MIN_FILTER, gl .NEAREST);
982
+
983
+ gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, 1, 1, 0, gl .RGBA, gl .FLOAT, new Float32Array (4));
984
+
985
+ return texture;
986
+ },
987
+ getTexture2DUnit: function (browser, object, property)
988
+ {
989
+ const textureUnit = object [property];
990
+
991
+ if (textureUnit === undefined)
992
+ return object [property] = browser .getTexture2DUnit ();
993
+
994
+ return textureUnit;
405
995
  },
406
996
  });
407
997