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
@@ -52,69 +52,70 @@ define ([
52
52
  "x_ite/Base/X3DFieldDefinition",
53
53
  "x_ite/Base/FieldDefinitionArray",
54
54
  "x_ite/Components/Shape/X3DShapeNode",
55
+ "x_ite/Browser/ParticleSystems/GeometryTypes",
56
+ "x_ite/Rendering/VertexArray",
55
57
  "x_ite/Rendering/TraverseType",
56
58
  "x_ite/Base/X3DConstants",
57
59
  "x_ite/Base/X3DCast",
58
60
  "x_ite/Browser/Shape/AlphaMode",
59
61
  "standard/Math/Numbers/Vector3",
60
- "standard/Math/Numbers/Vector4",
61
62
  "standard/Math/Numbers/Matrix4",
62
63
  "standard/Math/Numbers/Matrix3",
63
- "standard/Math/Algorithms/QuickSort",
64
- "standard/Math/Algorithm",
65
64
  "standard/Math/Utility/BVH",
66
65
  ],
67
66
  function (Fields,
68
67
  X3DFieldDefinition,
69
68
  FieldDefinitionArray,
70
69
  X3DShapeNode,
70
+ GeometryTypes,
71
+ VertexArray,
71
72
  TraverseType,
72
73
  X3DConstants,
73
74
  X3DCast,
74
75
  AlphaMode,
75
76
  Vector3,
76
- Vector4,
77
77
  Matrix4,
78
78
  Matrix3,
79
- QuickSort,
80
- Algorithm,
81
79
  BVH)
82
80
  {
83
81
  "use strict";
84
82
 
85
- var i = 0;
86
-
87
- const
88
- POINT = i ++,
89
- LINE = i ++,
90
- TRIANGLE = i ++,
91
- QUAD = i ++,
92
- GEOMETRY = i ++,
93
- SPRITE = i ++;
94
-
95
- const GeometryTypes = {
96
- POINT: POINT,
97
- LINE: LINE,
98
- TRIANGLE: TRIANGLE,
99
- QUAD: QUAD,
100
- GEOMETRY: GEOMETRY,
101
- SPRITE: SPRITE,
102
- };
103
-
104
- const
105
- invModelViewMatrix = new Matrix4 (),
106
- billboardToScreen = new Vector3 (0, 0, 0),
107
- viewerYAxis = new Vector3 (0, 0, 0),
108
- vector = new Vector3 (0, 0, 0),
109
- normal = new Vector3 (0, 0, 0),
110
- s1 = new Vector3 (0, 0, 0),
111
- s2 = new Vector3 (0, 0, 0),
112
- s3 = new Vector3 (0, 0, 0),
113
- s4 = new Vector3 (0, 0, 0),
114
- x = new Vector3 (0, 0, 0),
115
- y = new Vector3 (0, 0, 0);
116
-
117
- function compareDistance (lhs, rhs) { return lhs .distance < rhs .distance; }
83
+ const PointGeometry = new Float32Array ([0, 0, 0, 1]);
84
+
85
+ const LineGeometry = new Float32Array ([
86
+ // TexCoords
87
+ 0, 0, 0, 1,
88
+ 1, 0, 0, 1,
89
+ // Vertices
90
+ 0, 0, -0.5, 1,
91
+ 0, 0, 0.5, 1,
92
+ ]);
93
+
94
+ // p4 ------ p3
95
+ // | / |
96
+ // | / |
97
+ // | / |
98
+ // | / |
99
+ // p1 ------ p2
100
+
101
+ const QuadGeometry = new Float32Array ([
102
+ // TexCoords
103
+ 0, 0, 0, 1,
104
+ 1, 0, 0, 1,
105
+ 1, 1, 0, 1,
106
+ 0, 0, 0, 1,
107
+ 1, 1, 0, 1,
108
+ 0, 1, 0, 1,
109
+ // Normal
110
+ 0, 0, 1,
111
+ // Vertices
112
+ -0.5, -0.5, 0, 1,
113
+ 0.5, -0.5, 0, 1,
114
+ 0.5, 0.5, 0, 1,
115
+ -0.5, -0.5, 0, 1,
116
+ 0.5, 0.5, 0, 1,
117
+ -0.5, 0.5, 0, 1,
118
+ ]);
118
119
 
119
120
  function ParticleSystem (executionContext)
120
121
  {
@@ -124,39 +125,25 @@ function (Fields,
124
125
 
125
126
  this ._particleSize .setUnit ("length");
126
127
 
127
- this .createParticles = true;
128
- this .particles = [ ];
129
- this .velocities = [ ];
130
- this .speeds = [ ];
131
- this .turbulences = [ ];
132
- this .geometryType = POINT;
133
128
  this .maxParticles = 0;
134
129
  this .numParticles = 0;
135
- this .particleLifetime = 0;
136
- this .lifetimeVariation = 0;
137
- this .emitterNode = null;
138
130
  this .forcePhysicsModelNodes = [ ];
131
+ this .forces = new Float32Array (4);
139
132
  this .boundedPhysicsModelNodes = [ ];
140
133
  this .boundedNormals = [ ];
141
134
  this .boundedVertices = [ ];
142
- this .boundedVolume = null;
135
+ this .colorRamp = new Float32Array ();
136
+ this .texCoordRamp = new Float32Array ();
137
+ this .geometryContext = { };
143
138
  this .creationTime = 0;
144
139
  this .pauseTime = 0;
145
140
  this .deltaTime = 0;
146
- this .numForces = 0;
147
- this .colorKeys = [ ];
148
- this .colorRamppNode = null;
149
- this .colorRamp = [ ];
150
- this .texCoordKeys = [ ];
151
- this .texCoordRampNode = null;
152
- this .texCoordRamp = [ ];
153
- this .texCoordAnim = false;
154
- this .vertexCount = 0;
155
- this .shaderNode = null;
156
- this .rotation = new Matrix3 ();
157
- this .particleSorter = new QuickSort (this .particles, compareDistance);
158
- this .sortParticles = false;
159
- this .geometryContext = { };
141
+ this .particleStride = Float32Array .BYTES_PER_ELEMENT * 7 * 4; // 7 x vec4
142
+ this .particleOffsets = Array .from ({length: 7}, (_, i) => Float32Array .BYTES_PER_ELEMENT * 4 * i); // i x vec4
143
+ this .particleOffset = this .particleOffsets [0];
144
+ this .colorOffset = this .particleOffsets [1];
145
+ this .matrixOffset = this .particleOffsets [3];
146
+ this .texCoordOffset = 0;
160
147
  }
161
148
 
162
149
  ParticleSystem .prototype = Object .assign (Object .create (X3DShapeNode .prototype),
@@ -206,6 +193,9 @@ function (Fields,
206
193
  browser = this .getBrowser (),
207
194
  gl = browser .getContext ();
208
195
 
196
+ if (browser .getContext () .getVersion () < 2)
197
+ return;
198
+
209
199
  this .isLive () .addInterest ("set_live__", this);
210
200
 
211
201
  browser .getBrowserOptions () ._Shading .addInterest ("set_shader__", this);
@@ -213,6 +203,7 @@ function (Fields,
213
203
  this ._enabled .addInterest ("set_enabled__", this);
214
204
  this ._createParticles .addInterest ("set_createParticles__", this);
215
205
  this ._geometryType .addInterest ("set_geometryType__", this);
206
+ this ._geometryType .addInterest ("set_texCoord__", this);
216
207
  this ._maxParticles .addInterest ("set_enabled__", this);
217
208
  this ._particleLifetime .addInterest ("set_particleLifetime__", this);
218
209
  this ._lifetimeVariation .addInterest ("set_lifetimeVariation__", this);
@@ -223,38 +214,42 @@ function (Fields,
223
214
  this ._texCoordKey .addInterest ("set_texCoord__", this);
224
215
  this ._texCoordRamp .addInterest ("set_texCoordRamp__", this);
225
216
 
226
- this .idBuffer = gl .createBuffer ();
227
- this .positionBuffer = gl .createBuffer ();
228
- this .elapsedTimeBuffer = gl .createBuffer ();
229
- this .lifeBuffer = gl .createBuffer ();
230
- this .colorBuffer = gl .createBuffer ();
231
- this .texCoordBuffers = [ gl .createBuffer () ];
232
- this .normalBuffer = gl .createBuffer ();
233
- this .vertexBuffer = gl .createBuffer ();
234
-
235
- for (var i = 1, channels = this .getBrowser () .getMaxTextures (); i < channels; ++ i)
236
- this .texCoordBuffers .push (this .texCoordBuffers [0]);
237
-
238
- this .idArray = new Float32Array ();
239
- this .positionArray = new Float32Array ();
240
- this .elapsedTimeArray = new Float32Array ();
241
- this .lifeArray = new Float32Array ();
242
- this .colorArray = new Float32Array ();
243
- this .texCoordArray = new Float32Array ();
244
- this .normalArray = new Float32Array ();
245
- this .vertexArray = new Float32Array ();
246
-
247
- this .primitiveMode = gl .TRIANGLES;
217
+ // Create particles stuff.
218
+
219
+ this .inputParticles = this .createBuffer ();
220
+ this .outputParticles = this .createBuffer ();
221
+
222
+ this .inputParticles . emitterArrayObject = new VertexArray ();
223
+ this .inputParticles . vertexArrayObject = new VertexArray ();
224
+ this .inputParticles .shadowArrayObject = new VertexArray ();
225
+ this .outputParticles .emitterArrayObject = new VertexArray ();
226
+ this .outputParticles .vertexArrayObject = new VertexArray ();
227
+ this .outputParticles .shadowArrayObject = new VertexArray ();
228
+
229
+ // Create forces stuff.
230
+
231
+ this .forcesTexture = this .createTexture ();
232
+ this .boundedTexture = this .createTexture ();
233
+ this .colorRampTexture = this .createTexture ();
234
+ this .texCoordRampTexture = this .createTexture ();
235
+
236
+ // Create GL stuff.
237
+
238
+ this .geometryBuffer = this .createBuffer ();
239
+ this .texCoordBuffers = new Array (browser .getMaxTextures ()) .fill (this .geometryBuffer);
248
240
 
249
241
  // Geometry context
250
242
 
251
- this .geometryContext .fogCoords = false;
243
+ this .geometryContext .fogCoords = false;
252
244
  this .geometryContext .textureCoordinateNode = browser .getDefaultTextureCoordinate ();
253
245
  this .geometryContext .textureCoordinateMapping = new Map ();
254
246
 
255
- // Call order is higly important at startup.
247
+ // Init fields.
248
+ // Call order is very important at startup.
249
+
256
250
  this .set_emitter__ ();
257
251
  this .set_enabled__ ();
252
+ this .set_geometryType__ ();
258
253
  this .set_createParticles__ ();
259
254
  this .set_particleLifetime__ ();
260
255
  this .set_lifetimeVariation__ ();
@@ -278,7 +273,7 @@ function (Fields,
278
273
  {
279
274
  switch (this .geometryType)
280
275
  {
281
- case POINT:
276
+ case GeometryTypes .POINT:
282
277
  {
283
278
  this .setTransparent (true);
284
279
  break;
@@ -287,7 +282,7 @@ function (Fields,
287
282
  {
288
283
  this .setTransparent (this .getAppearance () .getTransparent () ||
289
284
  (this .colorRampNode && this .colorRampNode .getTransparent ()) ||
290
- (this .geometryType === GEOMETRY && this .geometryNode && this .geometryNode .getTransparent ()));
285
+ (this .geometryType === GeometryTypes .GEOMETRY && this .geometryNode && this .geometryNode .getTransparent ()));
291
286
  break;
292
287
  }
293
288
  }
@@ -327,7 +322,7 @@ function (Fields,
327
322
  {
328
323
  if (this ._enabled .getValue () && this ._maxParticles .getValue ())
329
324
  {
330
- if (! this ._isActive .getValue ())
325
+ if (!this ._isActive .getValue ())
331
326
  {
332
327
  if (this .isLive () .getValue ())
333
328
  {
@@ -339,6 +334,8 @@ function (Fields,
339
334
  this .pauseTime = performance .now () / 1000;
340
335
 
341
336
  this ._isActive = true;
337
+
338
+ delete this .traverse;
342
339
  }
343
340
  }
344
341
  else
@@ -353,6 +350,7 @@ function (Fields,
353
350
  this ._isActive = false;
354
351
 
355
352
  this .numParticles = 0;
353
+ this .traverse = Function .prototype;
356
354
  }
357
355
  }
358
356
 
@@ -364,161 +362,86 @@ function (Fields,
364
362
  },
365
363
  set_geometryType__: function ()
366
364
  {
367
- var
368
- gl = this .getBrowser () .getContext (),
369
- maxParticles = this .maxParticles;
370
-
371
- // geometryType
365
+ const
366
+ browser = this .getBrowser (),
367
+ gl = browser .getContext ();
372
368
 
373
- this .geometryType = GeometryTypes [this ._geometryType .getValue ()];
369
+ // Set geometryType.
374
370
 
375
- if (! this .geometryType)
376
- this .geometryType = POINT;
371
+ this .geometryType = GeometryTypes .hasOwnProperty (this ._geometryType .getValue ())
372
+ ? GeometryTypes [this ._geometryType .getValue ()]
373
+ : GeometryTypes .QUAD;
377
374
 
378
- // Create buffers
375
+ // Create buffers.
379
376
 
380
377
  switch (this .geometryType)
381
378
  {
382
- case POINT:
379
+ case GeometryTypes .POINT:
383
380
  {
384
- this .idArray = new Float32Array (maxParticles);
385
- this .positionArray = new Float32Array (3 * maxParticles);
386
- this .elapsedTimeArray = new Float32Array (maxParticles);
387
- this .lifeArray = new Float32Array (maxParticles);
388
- this .colorArray = new Float32Array (4 * maxParticles);
389
- this .texCoordArray = new Float32Array ();
390
- this .normalArray = new Float32Array ();
391
- this .vertexArray = new Float32Array (4 * maxParticles);
392
-
393
- for (var i = 0, a = this .idArray, l = a .length; i < l; ++ i)
394
- a [i] = i;
395
-
396
- this .colorArray .fill (1);
397
- this .vertexArray .fill (1);
381
+ this .geometryContext .geometryType = 0;
398
382
 
399
- this .testWireframe = false;
400
- this .primitiveMode = gl .POINTS;
401
383
  this .texCoordCount = 0;
402
384
  this .vertexCount = 1;
385
+ this .hasNormals = false;
386
+ this .testWireframe = false;
387
+ this .primitiveMode = gl .POINTS;
388
+
389
+ this .verticesOffset = 0;
390
+
391
+ gl .bindBuffer (gl .ARRAY_BUFFER, this .geometryBuffer);
392
+ gl .bufferData (gl .ARRAY_BUFFER, PointGeometry, gl .DYNAMIC_DRAW);
403
393
 
404
- this .geometryContext .geometryType = 0;
405
394
  break;
406
395
  }
407
- case LINE:
396
+ case GeometryTypes .LINE:
408
397
  {
409
- this .idArray = new Float32Array (2 * maxParticles);
410
- this .positionArray = new Float32Array (2 * 3 * maxParticles);
411
- this .elapsedTimeArray = new Float32Array (2 * maxParticles);
412
- this .lifeArray = new Float32Array (2 * maxParticles);
413
- this .colorArray = new Float32Array (2 * 4 * maxParticles);
414
- this .texCoordArray = new Float32Array ();
415
- this .normalArray = new Float32Array ();
416
- this .vertexArray = new Float32Array (2 * 4 * maxParticles);
417
-
418
- for (var i = 0, a = this .idArray, l = a .length; i < l; ++ i)
419
- a [i] = Math .floor (i / 2);
420
-
421
- this .colorArray .fill (1);
422
- this .vertexArray .fill (1);
398
+ this .geometryContext .geometryType = 1;
423
399
 
424
- this .testWireframe = false;
425
- this .primitiveMode = gl .LINES;
426
400
  this .texCoordCount = 2;
427
401
  this .vertexCount = 2;
402
+ this .hasNormals = false;
403
+ this .testWireframe = false;
404
+ this .primitiveMode = gl .LINES;
405
+
406
+ this .texCoordsOffset = 0;
407
+ this .verticesOffset = Float32Array .BYTES_PER_ELEMENT * 8;
408
+
409
+ gl .bindBuffer (gl .ARRAY_BUFFER, this .geometryBuffer);
410
+ gl .bufferData (gl .ARRAY_BUFFER, LineGeometry, gl .DYNAMIC_DRAW);
428
411
 
429
- this .geometryContext .geometryType = 1;
430
412
  break;
431
413
  }
432
- case TRIANGLE:
433
- case QUAD:
434
- case SPRITE:
414
+ case GeometryTypes .TRIANGLE:
415
+ case GeometryTypes .QUAD:
416
+ case GeometryTypes .SPRITE:
435
417
  {
436
- this .idArray = new Float32Array (6 * maxParticles);
437
- this .positionArray = new Float32Array (6 * 3 * maxParticles);
438
- this .elapsedTimeArray = new Float32Array (6 * maxParticles);
439
- this .lifeArray = new Float32Array (6 * maxParticles);
440
- this .colorArray = new Float32Array (6 * 4 * maxParticles);
441
- this .texCoordArray = new Float32Array (6 * 4 * maxParticles);
442
- this .normalArray = new Float32Array (6 * 3 * maxParticles);
443
- this .vertexArray = new Float32Array (6 * 4 * maxParticles);
444
-
445
- for (var i = 0, a = this .idArray, l = a .length; i < l; ++ i)
446
- a [i] = Math .floor (i / 6);
447
-
448
- this .colorArray .fill (1);
449
- this .vertexArray .fill (1);
450
-
451
- var
452
- texCoordArray = this .texCoordArray,
453
- normalArray = this .normalArray;
454
-
455
- for (var i = 0, length = 6 * 3 * maxParticles; i < length; i += 3)
456
- {
457
- normalArray [i] = 0;
458
- normalArray [i + 1] = 0;
459
- normalArray [i + 2] = 1;
460
- }
461
-
462
- gl .bindBuffer (gl .ARRAY_BUFFER, this .normalBuffer);
463
- gl .bufferData (gl .ARRAY_BUFFER, this .normalArray, gl .STATIC_DRAW);
464
-
465
- for (var i = 0; i < maxParticles; ++ i)
466
- {
467
- var i24 = i * 24;
468
-
469
- // p4 ------ p3
470
- // | / |
471
- // | / |
472
- // | / |
473
- // | / |
474
- // p1 ------ p2
475
-
476
- // p1
477
- texCoordArray [i24] = texCoordArray [i24 + 12] = 0;
478
- texCoordArray [i24 + 1] = texCoordArray [i24 + 13] = 0;
479
- texCoordArray [i24 + 2] = texCoordArray [i24 + 14] = 0;
480
- texCoordArray [i24 + 3] = texCoordArray [i24 + 15] = 1;
481
-
482
- // p2
483
- texCoordArray [i24 + 4] = 1;
484
- texCoordArray [i24 + 5] = 0;
485
- texCoordArray [i24 + 6] = 0;
486
- texCoordArray [i24 + 7] = 1;
487
-
488
- // p3
489
- texCoordArray [i24 + 8] = texCoordArray [i24 + 16] = 1;
490
- texCoordArray [i24 + 9] = texCoordArray [i24 + 17] = 1;
491
- texCoordArray [i24 + 10] = texCoordArray [i24 + 18] = 0;
492
- texCoordArray [i24 + 11] = texCoordArray [i24 + 19] = 1;
493
-
494
- // p4
495
- texCoordArray [i24 + 20] = 0;
496
- texCoordArray [i24 + 21] = 1;
497
- texCoordArray [i24 + 22] = 0;
498
- texCoordArray [i24 + 23] = 1;
499
- }
500
-
501
- gl .bindBuffer (gl .ARRAY_BUFFER, this .texCoordBuffers [0]);
502
- gl .bufferData (gl .ARRAY_BUFFER, this .texCoordArray, gl .STATIC_DRAW);
418
+ this .geometryContext .geometryType = 2;
503
419
 
504
- this .testWireframe = true;
505
- this .primitiveMode = gl .TRIANGLES;
506
420
  this .texCoordCount = 4;
507
421
  this .vertexCount = 6;
422
+ this .hasNormals = true;
423
+ this .testWireframe = true;
424
+ this .primitiveMode = gl .TRIANGLES;
425
+
426
+ this .texCoordsOffset = 0;
427
+ this .normalOffset = Float32Array .BYTES_PER_ELEMENT * 24;
428
+ this .verticesOffset = Float32Array .BYTES_PER_ELEMENT * 27;
429
+
430
+ gl .bindBuffer (gl .ARRAY_BUFFER, this .geometryBuffer);
431
+ gl .bufferData (gl .ARRAY_BUFFER, QuadGeometry, gl .DYNAMIC_DRAW);
508
432
 
509
- this .geometryContext .geometryType = 2;
510
433
  break;
511
434
  }
512
- case GEOMETRY:
435
+ case GeometryTypes .GEOMETRY:
513
436
  {
514
437
  this .texCoordCount = 0;
515
438
  this .vertexCount = 0;
439
+
516
440
  break;
517
441
  }
518
442
  }
519
443
 
520
- gl .bindBuffer (gl .ARRAY_BUFFER, this .idBuffer);
521
- gl .bufferData (gl .ARRAY_BUFFER, this .idArray, gl .STATIC_DRAW);
444
+ this .updateVertexArrays ();
522
445
 
523
446
  this .set_shader__ ();
524
447
  this .set_transparent__ ();
@@ -527,20 +450,17 @@ function (Fields,
527
450
  {
528
451
  switch (this .geometryType)
529
452
  {
530
- case POINT:
453
+ case GeometryTypes .POINT:
531
454
  {
532
455
  this .shaderNode = this .getBrowser () .getPointShader ();
533
456
  break;
534
457
  }
535
- case LINE:
458
+ case GeometryTypes .LINE:
536
459
  {
537
460
  this .shaderNode = this .getBrowser () .getLineShader ();
538
461
  break;
539
462
  }
540
- case TRIANGLE:
541
- case QUAD:
542
- case SPRITE:
543
- case GEOMETRY:
463
+ default:
544
464
  {
545
465
  this .shaderNode = null;
546
466
  break;
@@ -549,37 +469,18 @@ function (Fields,
549
469
  },
550
470
  set_maxParticles__: function ()
551
471
  {
552
- var
553
- particles = this .particles,
554
- maxParticles = Math .max (0, this ._maxParticles .getValue ());
555
-
556
- for (var i = this .numParticles, length = Math .min (particles .length, maxParticles); i < length; ++ i)
557
- {
558
- particles [i] .life = 1;
559
- particles [i] .lifetime = -1;
560
- }
561
-
562
- for (var i = particles .length, length = maxParticles; i < length; ++ i)
563
- {
564
- particles [i] = {
565
- id: i,
566
- life: 1,
567
- lifetime: -1,
568
- elapsedTime: 0,
569
- position: new Vector3 (0, 0, 0),
570
- velocity: new Vector3 (0, 0, 0),
571
- color: new Vector4 (1, 1, 1, 1),
572
- distance: 0,
573
- };
574
- }
472
+ const
473
+ lastNumParticles = this .numParticles,
474
+ maxParticles = Math .max (0, this ._maxParticles .getValue ());
575
475
 
576
476
  this .maxParticles = maxParticles;
577
- this .numParticles = Math .min (this .numParticles, maxParticles);
477
+ this .numParticles = Math .min (lastNumParticles, maxParticles);
578
478
 
579
- if (! this .emitterNode .isExplosive ())
479
+ if (!this .emitterNode .isExplosive ())
580
480
  this .creationTime = performance .now () / 1000;
581
481
 
582
- this .set_geometryType__ ();
482
+ this .resizeBuffers (lastNumParticles);
483
+ this .updateVertexArrays ();
583
484
  },
584
485
  set_particleLifetime__: function ()
585
486
  {
@@ -593,33 +494,33 @@ function (Fields,
593
494
  {
594
495
  this .emitterNode = X3DCast (X3DConstants .X3DParticleEmitterNode, this ._emitter);
595
496
 
596
- if (! this .emitterNode)
497
+ if (!this .emitterNode)
597
498
  this .emitterNode = this .getBrowser () .getDefaultEmitter ();
598
499
 
599
500
  this .createParticles = this ._createParticles .getValue ();
600
501
  },
601
502
  set_physics__: function ()
602
503
  {
603
- var
504
+ const
604
505
  physics = this ._physics .getValue (),
605
506
  forcePhysicsModelNodes = this .forcePhysicsModelNodes,
606
507
  boundedPhysicsModelNodes = this .boundedPhysicsModelNodes;
607
508
 
608
- for (var i = 0, length = boundedPhysicsModelNodes .length; i < length; ++ i)
509
+ for (let i = 0, length = boundedPhysicsModelNodes .length; i < length; ++ i)
609
510
  boundedPhysicsModelNodes [i] .removeInterest ("set_boundedPhysics__", this);
610
511
 
611
512
  forcePhysicsModelNodes .length = 0;
612
513
  boundedPhysicsModelNodes .length = 0;
613
514
 
614
- for (var i = 0, length = physics .length; i < length; ++ i)
515
+ for (let i = 0, length = physics .length; i < length; ++ i)
615
516
  {
616
517
  try
617
518
  {
618
- var
519
+ const
619
520
  innerNode = physics [i] .getValue () .getInnerNode (),
620
521
  type = innerNode .getType ();
621
522
 
622
- for (var t = type .length - 1; t >= 0; -- t)
523
+ for (let t = type .length - 1; t >= 0; -- t)
623
524
  {
624
525
  switch (type [t])
625
526
  {
@@ -650,7 +551,8 @@ function (Fields,
650
551
  },
651
552
  set_boundedPhysics__: function ()
652
553
  {
653
- var
554
+ const
555
+ gl = this .getBrowser () .getContext (),
654
556
  boundedPhysicsModelNodes = this .boundedPhysicsModelNodes,
655
557
  boundedNormals = this .boundedNormals,
656
558
  boundedVertices = this .boundedVertices;
@@ -658,13 +560,43 @@ function (Fields,
658
560
  boundedNormals .length = 0;
659
561
  boundedVertices .length = 0;
660
562
 
661
- for (var i = 0, length = boundedPhysicsModelNodes .length; i < length; ++ i)
563
+ for (let i = 0, length = boundedPhysicsModelNodes .length; i < length; ++ i)
662
564
  {
663
565
  boundedPhysicsModelNodes [i] .addGeometry (boundedNormals, boundedVertices);
664
566
  }
665
567
 
666
- this .boundedVolume = new BVH (boundedVertices, boundedNormals);
667
- },
568
+ // Texture
569
+
570
+ const
571
+ boundedHierarchy = new BVH (boundedVertices, boundedNormals) .toArray ([ ]),
572
+ numBoundedVertices = boundedVertices .length / 4,
573
+ numBoundedNormals = boundedNormals .length / 3,
574
+ boundedHierarchyLength = boundedHierarchy .length / 4,
575
+ boundedArraySize = Math .ceil (Math .sqrt (numBoundedVertices + numBoundedNormals + boundedHierarchyLength)),
576
+ boundedArray = new Float32Array (boundedArraySize * boundedArraySize * 4);
577
+
578
+ this .boundedVerticesIndex = 0;
579
+ this .boundedNormalsIndex = numBoundedVertices;
580
+ this .boundedHierarchyIndex = this .boundedNormalsIndex + numBoundedNormals;
581
+ this .boundedHierarchyRoot = this .boundedHierarchyIndex + boundedHierarchyLength - 1;
582
+
583
+ boundedArray .set (boundedVertices);
584
+
585
+ for (let s = this .boundedNormalsIndex * 4, n = 0, l = boundedNormals .length; n < l; s += 4, n += 3)
586
+ {
587
+ boundedArray [s + 0] = boundedNormals [n + 0];
588
+ boundedArray [s + 1] = boundedNormals [n + 1];
589
+ boundedArray [s + 2] = boundedNormals [n + 2];
590
+ }
591
+
592
+ boundedArray .set (boundedHierarchy, this .boundedHierarchyIndex * 4);
593
+
594
+ if (boundedArraySize)
595
+ {
596
+ gl .bindTexture (gl .TEXTURE_2D, this .boundedTexture);
597
+ gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, boundedArraySize, boundedArraySize, 0, gl .RGBA, gl .FLOAT, boundedArray);
598
+ }
599
+ },
668
600
  set_colorRamp__: function ()
669
601
  {
670
602
  if (this .colorRampNode)
@@ -680,25 +612,35 @@ function (Fields,
680
612
  },
681
613
  set_color__: function ()
682
614
  {
683
- var
684
- colorKey = this ._colorKey,
685
- colorKeys = this .colorKeys,
686
- colorRamp = this .colorRamp;
615
+ const
616
+ gl = this .getBrowser () .getContext (),
617
+ colorKey = this ._colorKey,
618
+ numColors = colorKey .length,
619
+ textureSize = Math .ceil (Math .sqrt (numColors * 2));
620
+
621
+ let colorRamp = this .colorRamp;
687
622
 
688
- for (var i = 0, length = colorKey .length; i < length; ++ i)
689
- colorKeys [i] = colorKey [i];
623
+ if (textureSize * textureSize * 4 > colorRamp .length)
624
+ colorRamp = this .colorRamp = new Float32Array (textureSize * textureSize * 4);
690
625
 
691
- colorKeys .length = length;
626
+ for (let i = 0; i < numColors; ++ i)
627
+ colorRamp [i * 4] = colorKey [i];
692
628
 
693
629
  if (this .colorRampNode)
694
- this .colorRampNode .getVectors (this .colorRamp);
630
+ colorRamp .set (this .colorRampNode .addColors ([ ], numColors) .slice (0, numColors * 4), numColors * 4);
631
+ else
632
+ colorRamp .fill (1, numColors * 4);
695
633
 
696
- for (var i = colorRamp .length, length = colorKey .length; i < length; ++ i)
697
- colorRamp [i] = new Vector4 (1, 1, 1, 1);
634
+ if (textureSize)
635
+ {
636
+ gl .bindTexture (gl .TEXTURE_2D, this .colorRampTexture);
637
+ gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, textureSize, textureSize, 0, gl .RGBA, gl .FLOAT, colorRamp);
638
+ }
698
639
 
699
- colorRamp .length = length;
640
+ this .numColors = numColors;
641
+ this .geometryContext .colorMaterial = !! (numColors && this .colorRampNode);
700
642
 
701
- this .geometryContext .colorMaterial = !! (colorKeys .length && this .colorRampNode);
643
+ this .updateVertexArrays ();
702
644
  },
703
645
  set_texCoordRamp__: function ()
704
646
  {
@@ -714,48 +656,117 @@ function (Fields,
714
656
  },
715
657
  set_texCoord__: function ()
716
658
  {
717
- var
659
+ const
660
+ gl = this .getBrowser () .getContext (),
718
661
  texCoordKey = this ._texCoordKey,
719
- texCoordKeys = this .texCoordKeys,
720
- texCoordRamp = this .texCoordRamp;
662
+ numTexCoords = texCoordKey .length,
663
+ textureSize = Math .ceil (Math .sqrt (numTexCoords + numTexCoords * this .texCoordCount));
721
664
 
722
- for (var i = 0, length = texCoordKey .length; i < length; ++ i)
723
- texCoordKeys [i] = texCoordKey [i];
665
+ let texCoordRamp = this .texCoordRamp;
724
666
 
725
- texCoordKeys .length = length;
667
+ if (textureSize * textureSize * 4 > texCoordRamp .length)
668
+ texCoordRamp = this .texCoordRamp = new Float32Array (textureSize * textureSize * 4);
669
+ else
670
+ texCoordRamp .fill (0);
671
+
672
+ for (let i = 0; i < numTexCoords; ++ i)
673
+ texCoordRamp [i * 4] = texCoordKey [i];
726
674
 
727
675
  if (this .texCoordRampNode)
728
- this .texCoordRampNode .getTexCoord (texCoordRamp);
676
+ texCoordRamp .set (this .texCoordRampNode .getTexCoord ([ ]) .slice (0, numTexCoords * this .texCoordCount * 4), numTexCoords * 4);
729
677
 
730
- for (var i = texCoordRamp .length, length = texCoordKey .length * this .texCoordCount; i < length; ++ i)
731
- texCoordRamp [i] = new Vector4 (0, 0, 0, 0);
678
+ if (textureSize)
679
+ {
680
+ gl .bindTexture (gl .TEXTURE_2D, this .texCoordRampTexture);
681
+ gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, textureSize, textureSize, 0, gl .RGBA, gl .FLOAT, texCoordRamp);
682
+ }
732
683
 
733
- texCoordRamp .length = length;
684
+ this .numTexCoords = this .texCoordRampNode ? numTexCoords : 0;
734
685
 
735
- this .texCoordAnim = !! (texCoordKeys .length && this .texCoordRampNode);
686
+ this .updateVertexArrays ();
736
687
  },
737
- intersectsBox: function (box, clipPlanes)
688
+ updateVertexArrays: function ()
689
+ {
690
+ this .inputParticles .vertexArrayObject .update ();
691
+ this .inputParticles .shadowArrayObject .update ();
692
+ this .inputParticles .emitterArrayObject .update ();
693
+ this .outputParticles .vertexArrayObject .update ();
694
+ this .outputParticles .shadowArrayObject .update ();
695
+ this .outputParticles .emitterArrayObject .update ();
696
+ },
697
+ createTexture: function ()
698
+ {
699
+ const
700
+ gl = this .getBrowser () .getContext (),
701
+ texture = gl .createTexture ();
702
+
703
+ gl .bindTexture (gl .TEXTURE_2D, texture);
704
+
705
+ gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_WRAP_S, gl .CLAMP_TO_EDGE);
706
+ gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_WRAP_T, gl .CLAMP_TO_EDGE);
707
+ gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_MAG_FILTER, gl .NEAREST);
708
+ gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_MIN_FILTER, gl .NEAREST);
709
+
710
+ gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, 1, 1, 0, gl .RGBA, gl .FLOAT, new Float32Array (4));
711
+
712
+ return texture;
713
+ },
714
+ createBuffer: function ()
715
+ {
716
+ const
717
+ gl = this .getBrowser () .getContext (),
718
+ buffer = gl .createBuffer ();
719
+
720
+ gl .bindBuffer (gl .ARRAY_BUFFER, buffer);
721
+ gl .bufferData (gl .ARRAY_BUFFER, new Uint32Array (), gl .DYNAMIC_DRAW);
722
+
723
+ return buffer;
724
+ },
725
+ resizeBuffers: function (lastNumParticles)
738
726
  {
739
- // TODO: implement me.
727
+ const
728
+ gl = this .getBrowser () .getContext (),
729
+ maxParticles = this .maxParticles,
730
+ particleStride = this .particleStride,
731
+ outputParticles = Object .assign (gl .createBuffer (), this .outputParticles),
732
+ data = new Uint8Array (maxParticles * particleStride);
733
+
734
+ // Resize input buffer.
735
+
736
+ gl .bindBuffer (gl .ARRAY_BUFFER, this .inputParticles);
737
+ gl .bufferData (gl .ARRAY_BUFFER, data, gl .DYNAMIC_DRAW);
738
+
739
+ // Resize output buffer.
740
+
741
+ gl .bindBuffer (gl .COPY_READ_BUFFER, this .outputParticles);
742
+ gl .bindBuffer (gl .ARRAY_BUFFER, outputParticles);
743
+ gl .bufferData (gl .ARRAY_BUFFER, data, gl .DYNAMIC_DRAW);
744
+ gl .copyBufferSubData (gl .COPY_READ_BUFFER, gl .ARRAY_BUFFER, 0, 0, Math .min (maxParticles * particleStride, lastNumParticles * particleStride));
745
+ gl .deleteBuffer (this .outputParticles);
746
+
747
+ this .outputParticles = outputParticles;
740
748
  },
741
749
  animateParticles: function ()
742
750
  {
743
- var emitterNode = this .emitterNode;
751
+ const
752
+ browser = this .getBrowser (),
753
+ gl = browser .getContext (),
754
+ emitterNode = this .emitterNode;
744
755
 
745
756
  // Determine delta time
746
757
 
747
- var
748
- DELAY = 15, // Delay in frames when dt full applys.
758
+ const
759
+ DELAY = 15, // Delay in frames when dt fully applies.
749
760
  dt = 1 / Math .max (10, this .getBrowser () .getCurrentFrameRate ());
750
761
 
751
- // var deltaTime is only for the emitter, this.deltaTime is for the forces.
752
- var deltaTime = this .deltaTime = ((DELAY - 1) * this .deltaTime + dt) / DELAY; // Moving average about DELAY frames.
762
+ // let deltaTime is only for the emitter, this.deltaTime is for the forces.
763
+ let deltaTime = this .deltaTime = ((DELAY - 1) * this .deltaTime + dt) / DELAY; // Moving average about DELAY frames.
753
764
 
754
765
  // Determine numParticles
755
766
 
756
767
  if (emitterNode .isExplosive ())
757
768
  {
758
- var
769
+ const
759
770
  now = performance .now () / 1000,
760
771
  particleLifetime = this .particleLifetime + this .particleLifetime * this .lifetimeVariation;
761
772
 
@@ -774,7 +785,7 @@ function (Fields,
774
785
  {
775
786
  if (this .numParticles < this .maxParticles)
776
787
  {
777
- var
788
+ const
778
789
  now = performance .now () / 1000,
779
790
  newParticles = Math .max (0, Math .floor ((now - this .creationTime) * this .maxParticles / this .particleLifetime));
780
791
 
@@ -789,548 +800,98 @@ function (Fields,
789
800
 
790
801
  if (emitterNode .getMass ())
791
802
  {
792
- var
793
- forcePhysicsModelNodes = this .forcePhysicsModelNodes,
794
- velocities = this .velocities,
795
- speeds = this .speeds,
796
- turbulences = this .turbulences,
797
- deltaMass = this .deltaTime / emitterNode .getMass ();
803
+ const forcePhysicsModelNodes = this .forcePhysicsModelNodes;
798
804
 
799
- // Collect forces in velocities and collect turbulences.
805
+ let
806
+ numForces = forcePhysicsModelNodes .length,
807
+ forces = this .forces,
808
+ timeByMass = deltaTime / emitterNode .getMass ();
800
809
 
801
- for (var i = velocities .length, length = forcePhysicsModelNodes .length; i < length; ++ i)
802
- velocities [i] = new Vector3 (0, 0, 0);
810
+ // Collect forces in velocities and collect turbulences.
803
811
 
804
- for (var i = 0, length = forcePhysicsModelNodes .length; i < length; ++ i)
805
- forcePhysicsModelNodes [i] .addForce (i, emitterNode, velocities, turbulences);
812
+ if (numForces * 4 > forces .length)
813
+ forces = this .forces = new Float32Array (numForces * 4);
806
814
 
807
- // Determine velocities from forces and determine speed.
815
+ let disabledForces = 0;
808
816
 
809
- for (var i = 0, length = velocities .length; i < length; ++ i)
817
+ for (let i = 0; i < numForces; ++ i)
810
818
  {
811
- velocities [i] .multiply (deltaMass);
812
- speeds [i] = velocities [i] .abs ();
819
+ disabledForces += !forcePhysicsModelNodes [i] .addForce (i - disabledForces, emitterNode, timeByMass, forces);
813
820
  }
814
821
 
815
- this .numForces = length;
816
- }
817
- else
818
- {
819
- this .numForces = 0;
820
- }
821
-
822
- // Determine particle position, velocity and colors
823
-
824
- emitterNode .animate (this, deltaTime);
825
-
826
- this .updateGeometry (null);
822
+ this .numForces = numForces -= disabledForces;
827
823
 
828
- this .getBrowser () .addBrowserEvent ();
829
- },
830
- updateGeometry: function (modelViewMatrix)
831
- {
832
- switch (this .geometryType)
833
- {
834
- case POINT:
835
- if (! modelViewMatrix)
836
- this .updatePoint ();
837
- break;
838
- case LINE:
839
- if (! modelViewMatrix)
840
- this .updateLine ();
841
- break;
842
- case TRIANGLE:
843
- case QUAD:
844
- case SPRITE:
845
- this .updateQuad (modelViewMatrix);
846
- break;
847
- case GEOMETRY:
848
- break;
849
- }
850
- },
851
- updatePoint: function ()
852
- {
853
- var
854
- gl = this .getBrowser () .getContext (),
855
- particles = this .particles,
856
- numParticles = this .numParticles,
857
- positionArray = this .positionArray,
858
- elapsedTimeArray = this .elapsedTimeArray,
859
- lifeArray = this .lifeArray,
860
- colorArray = this .colorArray,
861
- vertexArray = this .vertexArray;
862
-
863
- // Colors
864
-
865
- if (this .geometryContext .colorMaterial)
866
- {
867
- for (var i = 0; i < numParticles; ++ i)
824
+ if (numForces)
868
825
  {
869
- var
870
- color = particles [i] .color,
871
- i4 = i * 4;
872
-
873
- colorArray [i4] = color .x;
874
- colorArray [i4 + 1] = color .y;
875
- colorArray [i4 + 2] = color .z;
876
- colorArray [i4 + 3] = color .w;
826
+ gl .bindTexture (gl .TEXTURE_2D, this .forcesTexture);
827
+ gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, numForces, 1, 0, gl .RGBA, gl .FLOAT, forces);
877
828
  }
878
-
879
- gl .bindBuffer (gl .ARRAY_BUFFER, this .colorBuffer);
880
- gl .bufferData (gl .ARRAY_BUFFER, this .colorArray, gl .STATIC_DRAW);
881
829
  }
882
-
883
- // Vertices
884
-
885
- for (var i = 0; i < numParticles; ++ i)
830
+ else
886
831
  {
887
- var
888
- position = particles [i] .position,
889
- elapsedTime = particles [i] .elapsedTime / particles [i] .lifetime,
890
- i3 = i * 3,
891
- i4 = i * 4;
892
-
893
- positionArray [i3] = position .x;
894
- positionArray [i3 + 1] = position .y;
895
- positionArray [i3 + 2] = position .z;
896
-
897
- elapsedTimeArray [i] = elapsedTime;
898
- lifeArray [i] = particles [i] .life;
899
-
900
- vertexArray [i4] = position .x;
901
- vertexArray [i4 + 1] = position .y;
902
- vertexArray [i4 + 2] = position .z;
832
+ this .numForces = 0;
903
833
  }
904
834
 
905
- gl .bindBuffer (gl .ARRAY_BUFFER, this .positionBuffer);
906
- gl .bufferData (gl .ARRAY_BUFFER, this .positionArray, gl .STATIC_DRAW);
907
- gl .bindBuffer (gl .ARRAY_BUFFER, this .elapsedTimeBuffer);
908
- gl .bufferData (gl .ARRAY_BUFFER, this .elapsedTimeArray, gl .STATIC_DRAW);
909
- gl .bindBuffer (gl .ARRAY_BUFFER, this .lifeBuffer);
910
- gl .bufferData (gl .ARRAY_BUFFER, this .lifeArray, gl .STATIC_DRAW);
911
- gl .bindBuffer (gl .ARRAY_BUFFER, this .vertexBuffer);
912
- gl .bufferData (gl .ARRAY_BUFFER, this .vertexArray, gl .STATIC_DRAW);
913
- },
914
- updateLine: function ()
915
- {
916
- var
917
- gl = this .getBrowser () .getContext (),
918
- particles = this .particles,
919
- numParticles = this .numParticles,
920
- positionArray = this .positionArray,
921
- elapsedTimeArray = this .elapsedTimeArray,
922
- lifeArray = this .lifeArray,
923
- colorArray = this .colorArray,
924
- vertexArray = this .vertexArray,
925
- sy1_2 = this ._particleSize .y / 2;
926
-
927
- // Colors
928
-
929
- if (this .geometryContext .colorMaterial)
930
- {
931
- for (var i = 0; i < numParticles; ++ i)
932
- {
933
- var
934
- color = particles [i] .color,
935
- i8 = i * 8;
936
-
937
- colorArray [i8] = color .x;
938
- colorArray [i8 + 1] = color .y;
939
- colorArray [i8 + 2] = color .z;
940
- colorArray [i8 + 3] = color .w;
941
-
942
- colorArray [i8 + 4] = color .x;
943
- colorArray [i8 + 5] = color .y;
944
- colorArray [i8 + 6] = color .z;
945
- colorArray [i8 + 7] = color .w;
946
- }
835
+ // Swap buffers.
947
836
 
948
- gl .bindBuffer (gl .ARRAY_BUFFER, this .colorBuffer);
949
- gl .bufferData (gl .ARRAY_BUFFER, this .colorArray, gl .STATIC_DRAW);
950
- }
837
+ const inputParticles = this .outputParticles;
838
+ this .outputParticles = this .inputParticles;
839
+ this .inputParticles = inputParticles;
951
840
 
952
- // Vertices
841
+ // Determine particle position, velocity and colors.
953
842
 
954
- for (var i = 0; i < numParticles; ++ i)
955
- {
956
- var
957
- particle = particles [i],
958
- position = particle .position,
959
- elapsedTime = particles [i] .elapsedTime / particles [i] .lifetime,
960
- life = particles [i] .life,
961
- x = position .x,
962
- y = position .y,
963
- z = position .z,
964
- i2 = i * 2,
965
- i6 = i * 6,
966
- i8 = i * 8;
967
-
968
- positionArray [i6] = x;
969
- positionArray [i6 + 1] = y;
970
- positionArray [i6 + 2] = z;
971
- positionArray [i6 + 3] = x;
972
- positionArray [i6 + 4] = y;
973
- positionArray [i6 + 5] = z;
974
-
975
- elapsedTimeArray [i2] = elapsedTime;
976
- elapsedTimeArray [i2 + 1] = elapsedTime;
977
-
978
- lifeArray [i2] = life;
979
- lifeArray [i2 + 1] = life;
980
-
981
- // Length of line / 2.
982
- normal .assign (particle .velocity) .normalize () .multiply (sy1_2);
983
-
984
- vertexArray [i8] = x - normal .x;
985
- vertexArray [i8 + 1] = y - normal .y;
986
- vertexArray [i8 + 2] = z - normal .z;
987
-
988
- vertexArray [i8 + 4] = x + normal .x;
989
- vertexArray [i8 + 5] = y + normal .y;
990
- vertexArray [i8 + 6] = z + normal .z;
991
- }
843
+ emitterNode .animate (this, deltaTime);
992
844
 
993
- gl .bindBuffer (gl .ARRAY_BUFFER, this .positionBuffer);
994
- gl .bufferData (gl .ARRAY_BUFFER, this .positionArray, gl .STATIC_DRAW);
995
- gl .bindBuffer (gl .ARRAY_BUFFER, this .elapsedTimeBuffer);
996
- gl .bufferData (gl .ARRAY_BUFFER, this .elapsedTimeArray, gl .STATIC_DRAW);
997
- gl .bindBuffer (gl .ARRAY_BUFFER, this .lifeBuffer);
998
- gl .bufferData (gl .ARRAY_BUFFER, this .lifeArray, gl .STATIC_DRAW);
999
- gl .bindBuffer (gl .ARRAY_BUFFER, this .vertexBuffer);
1000
- gl .bufferData (gl .ARRAY_BUFFER, this .vertexArray, gl .STATIC_DRAW);
845
+ browser .addBrowserEvent ();
1001
846
  },
1002
- updateQuad: function (modelViewMatrix)
847
+ updateSprite: (function ()
1003
848
  {
1004
- try
1005
- {
1006
- var
1007
- gl = this .getBrowser () .getContext (),
1008
- particles = this .particles,
1009
- maxParticles = this .maxParticles,
1010
- numParticles = this .numParticles,
1011
- positionArray = this .positionArray,
1012
- elapsedTimeArray = this .elapsedTimeArray,
1013
- lifeArray = this .lifeArray,
1014
- colorArray = this .colorArray,
1015
- texCoordArray = this .texCoordArray,
1016
- normalArray = this .normalArray,
1017
- vertexArray = this .vertexArray,
1018
- sx1_2 = this ._particleSize .x / 2,
1019
- sy1_2 = this ._particleSize .y / 2;
1020
-
1021
- // Sort particles
1022
-
1023
- // if (this .sortParticles) // always false
1024
- // {
1025
- // for (var i = 0; i < numParticles; ++ i)
1026
- // {
1027
- // var particle = particles [i];
1028
- // particle .distance = modelViewMatrix .getDepth (particle .position);
1029
- // }
1030
- //
1031
- // // Expensisive function!!!
1032
- // this .particleSorter .sort (0, numParticles);
1033
- // }
1034
-
1035
- // Colors
1036
-
1037
- if (! modelViewMatrix) // if called from animateParticles
1038
- {
1039
- if (this .geometryContext .colorMaterial)
1040
- {
1041
- for (var i = 0; i < maxParticles; ++ i)
1042
- {
1043
- var
1044
- color = particles [i] .color,
1045
- i24 = i * 24;
1046
-
1047
- // p4 ------ p3
1048
- // | / |
1049
- // | / |
1050
- // | / |
1051
- // | / |
1052
- // p1 ------ p2
1053
-
1054
- // p1, p2, p3; p1, p3, p4
1055
- colorArray [i24] = colorArray [i24 + 4] = colorArray [i24 + 8] = colorArray [i24 + 12] = colorArray [i24 + 16] = colorArray [i24 + 20] = color .x;
1056
- colorArray [i24 + 1] = colorArray [i24 + 5] = colorArray [i24 + 9] = colorArray [i24 + 13] = colorArray [i24 + 17] = colorArray [i24 + 21] = color .y;
1057
- colorArray [i24 + 2] = colorArray [i24 + 6] = colorArray [i24 + 10] = colorArray [i24 + 14] = colorArray [i24 + 18] = colorArray [i24 + 22] = color .z;
1058
- colorArray [i24 + 3] = colorArray [i24 + 7] = colorArray [i24 + 11] = colorArray [i24 + 15] = colorArray [i24 + 19] = colorArray [i24 + 23] = color .w;
1059
- }
1060
-
1061
- gl .bindBuffer (gl .ARRAY_BUFFER, this .colorBuffer);
1062
- gl .bufferData (gl .ARRAY_BUFFER, this .colorArray, gl .STATIC_DRAW);
1063
- }
1064
-
1065
- if (this .texCoordAnim && this .texCoordArray .length)
1066
- {
1067
- var
1068
- texCoordKeys = this .texCoordKeys,
1069
- texCoordRamp = this .texCoordRamp;
849
+ const data = new Float32Array (QuadGeometry);
1070
850
 
1071
- var
1072
- length = texCoordKeys .length,
1073
- index0 = 0;
1074
-
1075
- for (var i = 0; i < maxParticles; ++ i)
1076
- {
1077
- // Determine index0.
1078
-
1079
- var
1080
- particle = particles [i],
1081
- fraction = particle .elapsedTime / particle .lifetime;
1082
-
1083
- if (length == 1 || fraction <= texCoordKeys [0])
1084
- {
1085
- index0 = 0;
1086
- }
1087
- else if (fraction >= texCoordKeys .at (-1))
1088
- {
1089
- index0 = length - 2;
1090
- }
1091
- else
1092
- {
1093
- var index = Algorithm .upperBound (texCoordKeys, 0, length, fraction, Algorithm .less);
851
+ const quad = [
852
+ new Vector3 (-0.5, -0.5, 0),
853
+ new Vector3 ( 0.5, -0.5, 0),
854
+ new Vector3 ( 0.5, 0.5, 0),
855
+ new Vector3 (-0.5, -0.5, 0),
856
+ new Vector3 ( 0.5, 0.5, 0),
857
+ new Vector3 (-0.5, 0.5, 0),
858
+ ];
1094
859
 
1095
- if (index < length)
1096
- index0 = index - 1;
1097
- else
1098
- index0 = 0;
1099
- }
860
+ const
861
+ vertex = new Vector3 (0, 0, 0),
862
+ size = new Vector3 (0, 0, 0);
1100
863
 
1101
- // Set texCoord.
1102
-
1103
- index0 *= this .texCoordCount;
1104
-
1105
- var
1106
- texCoord1 = texCoordRamp [index0],
1107
- texCoord2 = texCoordRamp [index0 + 1],
1108
- texCoord3 = texCoordRamp [index0 + 2],
1109
- texCoord4 = texCoordRamp [index0 + 3],
1110
- i24 = i * 24;
1111
-
1112
- // p4 ------ p3
1113
- // | / |
1114
- // | / |
1115
- // | / |
1116
- // | / |
1117
- // p1 ------ p2
1118
-
1119
- // p1
1120
- texCoordArray [i24] = texCoordArray [i24 + 12] = texCoord1 .x;
1121
- texCoordArray [i24 + 1] = texCoordArray [i24 + 13] = texCoord1 .y;
1122
- texCoordArray [i24 + 2] = texCoordArray [i24 + 14] = texCoord1 .z;
1123
- texCoordArray [i24 + 3] = texCoordArray [i24 + 15] = texCoord1 .w;
1124
-
1125
- // p2
1126
- texCoordArray [i24 + 4] = texCoord2 .x;
1127
- texCoordArray [i24 + 5] = texCoord2 .y;
1128
- texCoordArray [i24 + 6] = texCoord2 .z;
1129
- texCoordArray [i24 + 7] = texCoord2 .w;
1130
-
1131
- // p3
1132
- texCoordArray [i24 + 8] = texCoordArray [i24 + 16] = texCoord3 .x;
1133
- texCoordArray [i24 + 9] = texCoordArray [i24 + 17] = texCoord3 .y;
1134
- texCoordArray [i24 + 10] = texCoordArray [i24 + 18] = texCoord3 .z;
1135
- texCoordArray [i24 + 11] = texCoordArray [i24 + 19] = texCoord3 .w;
1136
-
1137
- // p4
1138
- texCoordArray [i24 + 20] = texCoord4 .x;
1139
- texCoordArray [i24 + 21] = texCoord4 .y;
1140
- texCoordArray [i24 + 22] = texCoord4 .z;
1141
- texCoordArray [i24 + 23] = texCoord4 .w;
1142
- }
864
+ return function (gl, rotation)
865
+ {
866
+ // Normal
1143
867
 
1144
- gl .bindBuffer (gl .ARRAY_BUFFER, this .texCoordBuffers [0]);
1145
- gl .bufferData (gl .ARRAY_BUFFER, this .texCoordArray, gl .STATIC_DRAW);
1146
- }
1147
- }
868
+ for (let i = 0; i < 3; ++ i)
869
+ data [24 + i] = rotation [i + 6];
1148
870
 
1149
871
  // Vertices
1150
872
 
1151
- if (this .geometryType === SPRITE)
1152
- {
1153
- if (modelViewMatrix) // if called from depth or draw
1154
- {
1155
- // Normals
1156
-
1157
- var rotation = this .getScreenAlignedRotation (modelViewMatrix);
1158
-
1159
- normal
1160
- .set (rotation [0], rotation [1], rotation [2])
1161
- .cross (vector .set (rotation [3], rotation [4], rotation [5]))
1162
- .normalize ();
1163
-
1164
- var
1165
- nx = normal .x,
1166
- ny = normal .y,
1167
- nz = normal .z;
1168
-
1169
- for (var i = 0, length = 6 * 3 * maxParticles; i < length; i += 3)
1170
- {
1171
- normalArray [i] = nx;
1172
- normalArray [i + 1] = ny;
1173
- normalArray [i + 2] = nz;
1174
- }
1175
-
1176
- gl .bindBuffer (gl .ARRAY_BUFFER, this .normalBuffer);
1177
- gl .bufferData (gl .ARRAY_BUFFER, this .normalArray, gl .STATIC_DRAW);
1178
-
1179
- // Vertices
873
+ size .set (this ._particleSize .x, this ._particleSize .y, 1);
1180
874
 
1181
- s1 .set (-sx1_2, -sy1_2, 0);
1182
- s2 .set ( sx1_2, -sy1_2, 0);
1183
- s3 .set ( sx1_2, sy1_2, 0);
1184
- s4 .set (-sx1_2, sy1_2, 0);
875
+ for (let i = 0; i < 6; ++ i)
876
+ data .set (rotation .multVecMatrix (vertex .assign (quad [i]) .multVec (size)), 27 + i * 4);
1185
877
 
1186
- rotation .multVecMatrix (s1);
1187
- rotation .multVecMatrix (s2);
1188
- rotation .multVecMatrix (s3);
1189
- rotation .multVecMatrix (s4);
1190
-
1191
- for (var i = 0; i < numParticles; ++ i)
1192
- {
1193
- var
1194
- position = particles [i] .position,
1195
- elapsedTime = particles [i] .elapsedTime / particles [i] .lifetime,
1196
- x = position .x,
1197
- y = position .y,
1198
- z = position .z,
1199
- i6 = i * 6,
1200
- i18 = i * 18,
1201
- i24 = i * 24;
1202
-
1203
- // p4 ------ p3
1204
- // | / |
1205
- // | / |
1206
- // | / |
1207
- // | / |
1208
- // p1 ------ p2
1209
-
1210
-
1211
- positionArray [i18] = positionArray [i18 + 3] = positionArray [i18 + 6] = positionArray [i18 + 9] = positionArray [i18 + 12] = positionArray [i18 + 15] = x;
1212
- positionArray [i18 + 1] = positionArray [i18 + 4] = positionArray [i18 + 7] = positionArray [i18 + 10] = positionArray [i18 + 13] = positionArray [i18 + 16] = y;
1213
- positionArray [i18 + 2] = positionArray [i18 + 5] = positionArray [i18 + 8] = positionArray [i18 + 11] = positionArray [i18 + 14] = positionArray [i18 + 17] = z;
1214
-
1215
- elapsedTimeArray [i6] = elapsedTimeArray [i6 + 1] = elapsedTimeArray [i6 + 2] = elapsedTimeArray [i6 + 3] = elapsedTimeArray [i6 + 4] = elapsedTimeArray [i6 + 5] = elapsedTime;
1216
- lifeArray [i6] = lifeArray [i6 + 1] = lifeArray [i6 + 2] = lifeArray [i6 + 3] = lifeArray [i6 + 4] = lifeArray [i6 + 5] = particles [i] .life;
1217
-
1218
- // p1
1219
- vertexArray [i24] = vertexArray [i24 + 12] = x + s1 .x;
1220
- vertexArray [i24 + 1] = vertexArray [i24 + 13] = y + s1 .y;
1221
- vertexArray [i24 + 2] = vertexArray [i24 + 14] = z + s1 .z;
1222
-
1223
- // p2
1224
- vertexArray [i24 + 4] = x + s2 .x;
1225
- vertexArray [i24 + 5] = y + s2 .y;
1226
- vertexArray [i24 + 6] = z + s2 .z;
1227
-
1228
- // p3
1229
- vertexArray [i24 + 8] = vertexArray [i24 + 16] = x + s3 .x;
1230
- vertexArray [i24 + 9] = vertexArray [i24 + 17] = y + s3 .y;
1231
- vertexArray [i24 + 10] = vertexArray [i24 + 18] = z + s3 .z;
1232
-
1233
- // p4
1234
- vertexArray [i24 + 20] = x + s4 .x;
1235
- vertexArray [i24 + 21] = y + s4 .y;
1236
- vertexArray [i24 + 22] = z + s4 .z;
1237
- }
1238
-
1239
- gl .bindBuffer (gl .ARRAY_BUFFER, this .positionBuffer);
1240
- gl .bufferData (gl .ARRAY_BUFFER, this .positionArray, gl .STATIC_DRAW);
1241
- gl .bindBuffer (gl .ARRAY_BUFFER, this .elapsedTimeBuffer);
1242
- gl .bufferData (gl .ARRAY_BUFFER, this .elapsedTimeArray, gl .STATIC_DRAW);
1243
- gl .bindBuffer (gl .ARRAY_BUFFER, this .lifeBuffer);
1244
- gl .bufferData (gl .ARRAY_BUFFER, this .lifeArray, gl .STATIC_DRAW);
1245
- gl .bindBuffer (gl .ARRAY_BUFFER, this .vertexBuffer);
1246
- gl .bufferData (gl .ARRAY_BUFFER, this .vertexArray, gl .STATIC_DRAW);
1247
- }
1248
- }
1249
- else
1250
- {
1251
- if (! modelViewMatrix) // if called from animateParticles
1252
- {
1253
- for (var i = 0; i < numParticles; ++ i)
1254
- {
1255
- var
1256
- position = particles [i] .position,
1257
- elapsedTime = particles [i] .elapsedTime / particles [i] .lifetime,
1258
- x = position .x,
1259
- y = position .y,
1260
- z = position .z,
1261
- i6 = i * 6,
1262
- i18 = i * 18,
1263
- i24 = i * 24;
1264
-
1265
- // p4 ------ p3
1266
- // | / |
1267
- // | / |
1268
- // | / |
1269
- // | / |
1270
- // p1 ------ p2
1271
-
1272
- positionArray [i18] = positionArray [i18 + 3] = positionArray [i18 + 6] = positionArray [i18 + 9] = positionArray [i18 + 12] = positionArray [i18 + 15] = x;
1273
- positionArray [i18 + 1] = positionArray [i18 + 4] = positionArray [i18 + 7] = positionArray [i18 + 10] = positionArray [i18 + 13] = positionArray [i18 + 16] = y;
1274
- positionArray [i18 + 2] = positionArray [i18 + 5] = positionArray [i18 + 8] = positionArray [i18 + 11] = positionArray [i18 + 14] = positionArray [i18 + 17] = z;
1275
-
1276
- elapsedTimeArray [i6] = elapsedTimeArray [i6 + 1] = elapsedTimeArray [i6 + 2] = elapsedTimeArray [i6 + 3] = elapsedTimeArray [i6 + 4] = elapsedTimeArray [i6 + 5] = elapsedTime;
1277
- lifeArray [i6] = lifeArray [i6 + 1] = lifeArray [i6 + 2] = lifeArray [i6 + 3] = lifeArray [i6 + 4] = lifeArray [i6 + 5] = particles [i] .life;
1278
-
1279
- // p1
1280
- vertexArray [i24] = vertexArray [i24 + 12] = x - sx1_2;
1281
- vertexArray [i24 + 1] = vertexArray [i24 + 13] = y - sy1_2;
1282
- vertexArray [i24 + 2] = vertexArray [i24 + 14] = z;
1283
-
1284
- // p2
1285
- vertexArray [i24 + 4] = x + sx1_2;
1286
- vertexArray [i24 + 5] = y - sy1_2;
1287
- vertexArray [i24 + 6] = z;
1288
-
1289
- // p3
1290
- vertexArray [i24 + 8] = vertexArray [i24 + 16] = x + sx1_2;
1291
- vertexArray [i24 + 9] = vertexArray [i24 + 17] = y + sy1_2;
1292
- vertexArray [i24 + 10] = vertexArray [i24 + 18] = z;
1293
-
1294
- // p4
1295
- vertexArray [i24 + 20] = x - sx1_2;
1296
- vertexArray [i24 + 21] = y + sy1_2;
1297
- vertexArray [i24 + 22] = z;
1298
- }
1299
-
1300
- gl .bindBuffer (gl .ARRAY_BUFFER, this .positionBuffer);
1301
- gl .bufferData (gl .ARRAY_BUFFER, this .positionArray, gl .STATIC_DRAW);
1302
- gl .bindBuffer (gl .ARRAY_BUFFER, this .elapsedTimeBuffer);
1303
- gl .bufferData (gl .ARRAY_BUFFER, this .elapsedTimeArray, gl .STATIC_DRAW);
1304
- gl .bindBuffer (gl .ARRAY_BUFFER, this .lifeBuffer);
1305
- gl .bufferData (gl .ARRAY_BUFFER, this .lifeArray, gl .STATIC_DRAW);
1306
- gl .bindBuffer (gl .ARRAY_BUFFER, this .vertexBuffer);
1307
- gl .bufferData (gl .ARRAY_BUFFER, this .vertexArray, gl .STATIC_DRAW);
1308
- }
1309
- }
1310
- }
1311
- catch (error)
1312
- {
1313
- console .error (error);
1314
- }
1315
- },
878
+ gl .bindBuffer (gl .ARRAY_BUFFER, this .geometryBuffer);
879
+ gl .bufferData (gl .ARRAY_BUFFER, data, gl .DYNAMIC_DRAW);
880
+ };
881
+ })(),
882
+ intersectsBox: function (box, clipPlanes)
883
+ { },
1316
884
  traverse: function (type, renderObject)
1317
885
  {
1318
- if (! this ._isActive .getValue ())
886
+ if (this .numParticles === 0)
1319
887
  return;
1320
888
 
1321
889
  switch (type)
1322
890
  {
1323
891
  case TraverseType .POINTER:
1324
- {
1325
- break;
1326
- }
1327
892
  case TraverseType .PICKING:
1328
- {
1329
- break;
1330
- }
1331
893
  case TraverseType .COLLISION:
1332
894
  {
1333
- // TODO: to be implemented.
1334
895
  break;
1335
896
  }
1336
897
  case TraverseType .SHADOW:
@@ -1349,7 +910,7 @@ function (Fields,
1349
910
  }
1350
911
  }
1351
912
 
1352
- if (this .geometryType === GEOMETRY)
913
+ if (this .geometryType === GeometryTypes .GEOMETRY)
1353
914
  {
1354
915
  if (this .getGeometry ())
1355
916
  this .getGeometry () .traverse (type, renderObject); // Currently used for ScreenText.
@@ -1357,64 +918,75 @@ function (Fields,
1357
918
  },
1358
919
  depth: function (gl, context, shaderNode)
1359
920
  {
1360
- // Update geometry if SPRITE.
1361
-
1362
- this .updateGeometry (context .modelViewMatrix);
1363
-
1364
921
  // Display geometry.
1365
922
 
1366
- if (this .geometryType === GEOMETRY)
923
+ switch (this .geometryType)
1367
924
  {
1368
- var geometryNode = this .getGeometry ();
925
+ case GeometryTypes .GEOMETRY:
926
+ {
927
+ const geometryNode = this .getGeometry ();
1369
928
 
1370
- if (geometryNode)
1371
- geometryNode .displayParticlesDepth (gl, context, shaderNode, this .particles, this .numParticles);
1372
- }
1373
- else
1374
- {
1375
- if (this .numParticles <= 0)
1376
- return;
929
+ if (geometryNode)
930
+ geometryNode .displayParticlesDepth (gl, context, shaderNode, this);
1377
931
 
1378
- if (shaderNode .getValid ())
932
+ break;
933
+ }
934
+ case GeometryTypes .SPRITE:
935
+ {
936
+ this .updateSprite (gl, this .getScreenAlignedRotation (context .modelViewMatrix));
937
+ // [fall trough]
938
+ }
939
+ default:
1379
940
  {
1380
- // Setup vertex attributes.
941
+ const outputParticles = this .outputParticles;
942
+
943
+ if (outputParticles .shadowArrayObject .enable (gl, shaderNode))
944
+ {
945
+ const particleStride = this .particleStride;
1381
946
 
1382
- shaderNode .enableFloatAttrib (gl, "x3d_ParticleId", this .idBuffer, 1);
1383
- shaderNode .enableFloatAttrib (gl, "x3d_ParticlePosition", this .positionBuffer, 3);
1384
- shaderNode .enableFloatAttrib (gl, "x3d_ParticleElapsedTime", this .elapsedTimeBuffer, 1);
1385
- shaderNode .enableFloatAttrib (gl, "x3d_ParticleLife", this .lifeBuffer, 1);
1386
- shaderNode .enableVertexAttribute (gl, this .vertexBuffer);
947
+ shaderNode .enableParticleAttribute (gl, outputParticles, particleStride, this .particleOffset, 1);
948
+ shaderNode .enableParticleMatrixAttribute (gl, outputParticles, particleStride, this .matrixOffset, 1);
949
+ shaderNode .enableVertexAttribute (gl, this .geometryBuffer, 0, this .verticesOffset);
950
+ }
1387
951
 
1388
- gl .drawArrays (this .primitiveMode, 0, this .numParticles * this .vertexCount);
952
+ gl .drawArraysInstanced (this .primitiveMode, 0, this .vertexCount, this .numParticles);
1389
953
 
1390
- shaderNode .disableFloatAttrib (gl, "x3d_ParticleId");
1391
- shaderNode .disableFloatAttrib (gl, "x3d_ParticlePosition");
1392
- shaderNode .disableFloatAttrib (gl, "x3d_ParticleElapsedTime");
1393
- shaderNode .disableFloatAttrib (gl, "x3d_ParticleLife");
954
+ break;
1394
955
  }
1395
956
  }
1396
957
  },
1397
958
  display: function (gl, context)
1398
959
  {
1399
- try
1400
- {
1401
- if (this .numParticles <= 0)
1402
- return;
1403
-
1404
- // Update geometry if SPRITE.
1405
-
1406
- this .updateGeometry (context .modelViewMatrix);
1407
-
1408
- // Display geometry.
960
+ // Display geometry.
1409
961
 
1410
- if (this .geometryType === GEOMETRY)
962
+ switch (this .geometryType)
963
+ {
964
+ case GeometryTypes .GEOMETRY:
1411
965
  {
1412
966
  const geometryNode = this .getGeometry ();
1413
967
 
1414
968
  if (geometryNode)
1415
- geometryNode .displayParticles (gl, context, this .particles, this .numParticles);
969
+ geometryNode .displayParticles (gl, context, this);
970
+
971
+ break;
1416
972
  }
1417
- else
973
+ case GeometryTypes .SPRITE:
974
+ {
975
+ this .updateSprite (gl, this .getScreenAlignedRotation (context .modelViewMatrix));
976
+ // [fall trough]
977
+ }
978
+ case GeometryTypes .QUAD:
979
+ case GeometryTypes .TRIANGLE:
980
+ {
981
+ const positiveScale = Matrix4 .prototype .determinant3 .call (context .modelViewMatrix) > 0;
982
+
983
+ gl .frontFace (positiveScale ? gl .CCW : gl .CW);
984
+ gl .enable (gl .CULL_FACE);
985
+ gl .cullFace (gl .BACK);
986
+
987
+ // [fall trough]
988
+ }
989
+ default:
1418
990
  {
1419
991
  const
1420
992
  appearanceNode = this .getAppearance (),
@@ -1422,7 +994,7 @@ function (Fields,
1422
994
 
1423
995
  // Setup shader.
1424
996
 
1425
- if (shaderNode .getValid ())
997
+ if (shaderNode .isValid ())
1426
998
  {
1427
999
  context .geometryContext = this .geometryContext;
1428
1000
 
@@ -1434,85 +1006,98 @@ function (Fields,
1434
1006
  shaderNode .enable (gl);
1435
1007
  shaderNode .setLocalUniforms (gl, context);
1436
1008
 
1009
+ if (this .numTexCoords)
1010
+ {
1011
+ const textureUnit = context .browser .getTexture2DUnit ();
1012
+
1013
+ gl .activeTexture (gl .TEXTURE0 + textureUnit);
1014
+ gl .bindTexture (gl .TEXTURE_2D, this .texCoordRampTexture);
1015
+ gl .uniform1i (shaderNode .x3d_TexCoordRamp, textureUnit);
1016
+ }
1017
+
1437
1018
  // Setup vertex attributes.
1438
1019
 
1439
- shaderNode .enableFloatAttrib (gl, "x3d_ParticleId", this .idBuffer, 1);
1440
- shaderNode .enableFloatAttrib (gl, "x3d_ParticlePosition", this .positionBuffer, 3);
1441
- shaderNode .enableFloatAttrib (gl, "x3d_ParticleElapsedTime", this .elapsedTimeBuffer, 1);
1442
- shaderNode .enableFloatAttrib (gl, "x3d_ParticleLife", this .lifeBuffer, 1);
1020
+ const outputParticles = this .outputParticles;
1443
1021
 
1444
- if (this .geometryContext .colorMaterial)
1445
- shaderNode .enableColorAttribute (gl, this .colorBuffer);
1022
+ if (outputParticles .vertexArrayObject .enable (gl, shaderNode))
1023
+ {
1024
+ const particleStride = this .particleStride;
1446
1025
 
1447
- if (this .texCoordArray .length)
1448
- shaderNode .enableTexCoordAttribute (gl, this .texCoordBuffers);
1026
+ shaderNode .enableParticleAttribute (gl, outputParticles, particleStride, this .particleOffset, 1);
1027
+ shaderNode .enableParticleMatrixAttribute (gl, outputParticles, particleStride, this .matrixOffset, 1);
1449
1028
 
1450
- if (this .normalArray .length)
1451
- shaderNode .enableNormalAttribute (gl, this .normalBuffer);
1029
+ if (this .geometryContext .colorMaterial)
1030
+ {
1031
+ shaderNode .enableColorAttribute (gl, outputParticles, particleStride, this .colorOffset);
1032
+ shaderNode .colorAttributeDivisor (gl, 1);
1033
+ }
1452
1034
 
1453
- shaderNode .enableVertexAttribute (gl, this .vertexBuffer);
1035
+ if (this .texCoordCount)
1036
+ shaderNode .enableTexCoordAttribute (gl, this .texCoordBuffers, 0, this .texCoordOffset);
1037
+
1038
+ if (this .hasNormals)
1039
+ {
1040
+ shaderNode .enableNormalAttribute (gl, this .geometryBuffer, 0, this .normalOffset);
1041
+ shaderNode .normalAttributeDivisor (gl, this .maxParticles);
1042
+ }
1043
+
1044
+ shaderNode .enableVertexAttribute (gl, this .geometryBuffer, 0, this .verticesOffset);
1045
+ }
1454
1046
 
1455
1047
  if (shaderNode .wireframe && this .testWireframe)
1456
1048
  {
1457
1049
  // Wireframes are always solid so only one drawing call is needed.
1458
1050
 
1459
- for (var i = 0, length = this .numParticles * this .vertexCount; i < length; i += 3)
1051
+ for (let i = 0, length = this .numParticles * this .vertexCount; i < length; i += 3)
1460
1052
  gl .drawArrays (shaderNode .primitiveMode, i, 3);
1461
1053
  }
1462
1054
  else
1463
1055
  {
1464
- const positiveScale = Matrix4 .prototype .determinant3 .call (context .modelViewMatrix) > 0;
1465
-
1466
- gl .frontFace (positiveScale ? gl .CCW : gl .CW);
1467
- gl .enable (gl .CULL_FACE);
1468
- gl .cullFace (gl .BACK);
1469
-
1470
- gl .drawArrays (this .primitiveMode, 0, this .numParticles * this .vertexCount);
1056
+ gl .drawArraysInstanced (this .primitiveMode, 0, this .vertexCount, this .numParticles);
1471
1057
  }
1472
1058
 
1473
- shaderNode .disableFloatAttrib (gl, "x3d_ParticleId");
1474
- shaderNode .disableFloatAttrib (gl, "x3d_ParticlePosition");
1475
- shaderNode .disableFloatAttrib (gl, "x3d_ParticleElapsedTime");
1476
- shaderNode .disableFloatAttrib (gl, "x3d_ParticleLife");
1477
-
1478
- shaderNode .disableColorAttribute (gl);
1479
- shaderNode .disableTexCoordAttribute (gl);
1480
- shaderNode .disableNormalAttribute (gl);
1481
-
1482
1059
  if (blendModeNode)
1483
1060
  blendModeNode .disable (gl);
1484
1061
 
1485
- context .geometryContext = null;
1062
+ delete context .geometryContext;
1486
1063
  }
1064
+
1065
+ break;
1487
1066
  }
1488
1067
  }
1489
- catch (error)
1490
- {
1491
- // Catch error from setLocalUniforms.
1492
- console .error (error);
1493
- }
1494
1068
  },
1495
- getScreenAlignedRotation: function (modelViewMatrix)
1069
+ getScreenAlignedRotation: (function ()
1496
1070
  {
1497
- invModelViewMatrix .assign (modelViewMatrix) .inverse ();
1071
+ const
1072
+ invModelViewMatrix = new Matrix4 (),
1073
+ billboardToScreen = new Vector3 (0, 0, 0),
1074
+ viewerYAxis = new Vector3 (0, 0, 0),
1075
+ y = new Vector3 (0, 0, 0),
1076
+ rotation = new Matrix3 (9);
1077
+
1078
+ return function (modelViewMatrix)
1079
+ {
1080
+ invModelViewMatrix .assign (modelViewMatrix) .inverse ();
1081
+ invModelViewMatrix .multDirMatrix (billboardToScreen .assign (Vector3 .zAxis));
1082
+ invModelViewMatrix .multDirMatrix (viewerYAxis .assign (Vector3 .yAxis));
1498
1083
 
1499
- invModelViewMatrix .multDirMatrix (billboardToScreen .assign (Vector3 .zAxis));
1500
- invModelViewMatrix .multDirMatrix (viewerYAxis .assign (Vector3 .yAxis));
1084
+ const x = viewerYAxis .cross (billboardToScreen);
1085
+ y .assign (billboardToScreen) .cross (x);
1086
+ const z = billboardToScreen;
1501
1087
 
1502
- x .assign (viewerYAxis) .cross (billboardToScreen);
1503
- y .assign (billboardToScreen) .cross (x);
1504
- var z = billboardToScreen;
1088
+ // Compose rotation matrix.
1505
1089
 
1506
- // Compose rotation
1090
+ x .normalize ();
1091
+ y .normalize ();
1092
+ z .normalize ();
1507
1093
 
1508
- x .normalize ();
1509
- y .normalize ();
1510
- z .normalize ();
1094
+ rotation .set (x .x, x .y, x .z,
1095
+ y .x, y .y, y .z,
1096
+ z .x, z .y, z .z);
1511
1097
 
1512
- return this .rotation .set (x .x, x .y, x .z,
1513
- y .x, y .y, y .z,
1514
- z .x, z .y, z .z);
1515
- },
1098
+ return rotation;
1099
+ };
1100
+ })(),
1516
1101
  });
1517
1102
 
1518
1103
  return ParticleSystem;