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.
- package/.vscode/settings.json +12 -5
- package/.vscode/tasks.json +21 -0
- package/Makefile +10 -15
- package/README.md +6 -11
- package/build/bin/dist.pl +0 -6
- package/build/bin/version.pl +1 -4
- package/dist/assets/components/annotation.js +2 -2
- package/dist/assets/components/annotation.min.js +1 -1
- package/dist/assets/components/cad-geometry.js +2 -2
- package/dist/assets/components/cad-geometry.min.js +1 -1
- package/dist/assets/components/cube-map-texturing.js +6 -19
- package/dist/assets/components/cube-map-texturing.min.js +1 -1
- package/dist/assets/components/dis.js +2 -2
- package/dist/assets/components/dis.min.js +1 -1
- package/dist/assets/components/event-utilities.js +3 -3
- package/dist/assets/components/event-utilities.min.js +1 -1
- package/dist/assets/components/geometry2d.js +4 -4
- package/dist/assets/components/geometry2d.min.js +1 -1
- package/dist/assets/components/geospatial.js +32 -1685
- package/dist/assets/components/geospatial.min.js +1 -1
- package/dist/assets/components/h-anim.js +70 -77
- package/dist/assets/components/h-anim.min.js +1 -1
- package/dist/assets/components/key-device-sensor.js +3 -3
- package/dist/assets/components/key-device-sensor.min.js +1 -1
- package/dist/assets/components/layout.js +38 -52
- package/dist/assets/components/layout.min.js +1 -1
- package/dist/assets/components/nurbs.js +277 -194
- package/dist/assets/components/nurbs.min.js +1 -1
- package/dist/assets/components/particle-systems.js +1918 -1658
- package/dist/assets/components/particle-systems.min.js +1 -1
- package/dist/assets/components/picking.js +33 -41
- package/dist/assets/components/picking.min.js +1 -1
- package/dist/assets/components/projective-texture-mapping.js +72 -86
- package/dist/assets/components/projective-texture-mapping.min.js +1 -1
- package/dist/assets/components/rigid-body-physics.js +36 -57
- package/dist/assets/components/rigid-body-physics.min.js +1 -1
- package/dist/assets/components/scripting.js +2 -2
- package/dist/assets/components/scripting.min.js +1 -1
- package/dist/assets/components/texturing-3d.js +26 -75
- package/dist/assets/components/texturing-3d.min.js +3 -3
- package/dist/assets/components/volume-rendering.js +10 -10
- package/dist/assets/components/volume-rendering.min.js +1 -1
- package/dist/assets/components/x_ite.js +2 -2
- package/dist/assets/components/x_ite.min.js +1 -1
- package/dist/assets/linetype/1.png +0 -0
- package/dist/assets/linetype/10.png +0 -0
- package/dist/assets/linetype/11.png +0 -0
- package/dist/assets/linetype/12.png +0 -0
- package/dist/assets/linetype/13.png +0 -0
- package/dist/assets/linetype/14.png +0 -0
- package/dist/assets/linetype/15.png +0 -0
- package/dist/assets/linetype/16.png +0 -0
- package/dist/assets/linetype/2.png +0 -0
- package/dist/assets/linetype/3.png +0 -0
- package/dist/assets/linetype/4.png +0 -0
- package/dist/assets/linetype/5.png +0 -0
- package/dist/assets/linetype/6.png +0 -0
- package/dist/assets/linetype/7.png +0 -0
- package/dist/assets/linetype/8.png +0 -0
- package/dist/assets/linetype/9.png +0 -0
- package/dist/assets/shaders/webgl1/Line.fs +0 -21
- package/dist/assets/shaders/webgl1/Line.vs +0 -10
- package/dist/assets/shaders/webgl1/PBR.vs +1 -1
- package/dist/assets/shaders/webgl2/Depth.vs +29 -1
- package/dist/assets/shaders/webgl2/Gouraud.vs +31 -3
- package/dist/assets/shaders/webgl2/Line.fs +24 -12
- package/dist/assets/shaders/webgl2/Line.vs +36 -11
- package/dist/assets/shaders/webgl2/LineTransform.fs +4 -0
- package/dist/assets/shaders/webgl2/LineTransform.vs +57 -0
- package/dist/assets/shaders/webgl2/PBR.vs +35 -7
- package/dist/assets/shaders/webgl2/Phong.vs +31 -3
- package/dist/assets/shaders/webgl2/Point.vs +29 -1
- package/dist/assets/shaders/webgl2/Unlit.vs +31 -3
- package/dist/example.html +6 -6
- package/dist/x_ite.css +180 -208
- package/dist/x_ite.js +16477 -16629
- package/dist/x_ite.min.js +17 -17
- package/dist/x_ite.zip +0 -0
- package/docs/404.md +6 -0
- package/docs/Accessing-the-External-Browser.md +20 -14
- package/docs/Browser-Support.md +6 -0
- package/docs/Custom-Shaders.md +17 -24
- package/docs/Features.md +7 -1
- package/docs/Gemfile +44 -0
- package/docs/Gemfile.lock +122 -0
- package/docs/Glossary.md +6 -0
- package/docs/How-To-Configure-Your-Web-Server.md +6 -0
- package/docs/Supported-Nodes.md +9 -1
- package/docs/What's-New.md +31 -0
- package/docs/XHTML-DOM-Integration.md +6 -0
- package/docs/_config.yml +1 -1
- package/docs/assets/css/main.scss +26 -0
- package/docs/index.md +38 -46
- package/docs/reference/Browser-Services.md +9 -3
- package/docs/reference/Constants-Services.md +6 -0
- package/docs/reference/ECMAScript-Object-and-Function-Definitions.md +6 -0
- package/docs/reference/Field-Services-and-Objects.md +6 -0
- package/docs/reference/Prototype-Services.md +6 -0
- package/docs/reference/Route-Services.md +6 -0
- package/docs/reference/Scene-Services.md +8 -2
- package/docs/reference/Script-Node-Authoring-Interface.md +7 -1
- package/docs/tutorials/Adding-backgrounds.md +6 -0
- package/docs/tutorials/Adding-fog.md +6 -0
- package/docs/tutorials/Adding-sound.md +6 -0
- package/docs/tutorials/Animating-transforms.md +6 -0
- package/docs/tutorials/Basic-Nodes.md +6 -0
- package/docs/tutorials/Building-a-X3D-world.md +6 -0
- package/docs/tutorials/Building-elevation-grids.md +6 -0
- package/docs/tutorials/Building-extruded-shapes.md +6 -0
- package/docs/tutorials/Building-primitive-shapes.md +6 -0
- package/docs/tutorials/Building-shapes-out-of-points,-lines,-and-faces.md +6 -0
- package/docs/tutorials/Controlling-appearance-with-materials.md +6 -0
- package/docs/tutorials/Controlling-color-on-coordinate-based-geometry.md +6 -0
- package/docs/tutorials/Controlling-detail.md +6 -0
- package/docs/tutorials/Controlling-how-textures-are-mapped.md +6 -0
- package/docs/tutorials/Controlling-navigation.md +6 -0
- package/docs/tutorials/Controlling-shading-on-coordinate-based-geometry.md +6 -0
- package/docs/tutorials/Controlling-the-viewpoint.md +6 -0
- package/docs/tutorials/Creating-new-node-types.md +6 -0
- package/docs/tutorials/Grouping-nodes.md +6 -0
- package/docs/tutorials/Hello,-World!.md +6 -0
- package/docs/tutorials/Improving-Performance.md +6 -0
- package/docs/tutorials/Increasing-Rendering-Speed.md +6 -0
- package/docs/tutorials/Introducing-X3D.md +6 -0
- package/docs/tutorials/Introducing-animation.md +6 -0
- package/docs/tutorials/Introducing-script-use.md +6 -0
- package/docs/tutorials/Lighting-your-world.md +6 -0
- package/docs/tutorials/Mapping-textures.md +6 -0
- package/docs/tutorials/Naming-nodes.md +6 -0
- package/docs/tutorials/Providing-information-about-your-world.md +6 -0
- package/docs/tutorials/Sensing-the-viewer.md +6 -0
- package/docs/tutorials/Sensing-viewer-actions.md +6 -0
- package/docs/tutorials/Transforming-Shapes.md +6 -0
- package/docs/tutorials/Writing-program-scripts-with-ECMAScript.md +6 -0
- package/docs/tutorials/index.md +6 -0
- package/package.json +6 -7
- package/src/assets/components/geometry2d.js +1 -1
- package/src/assets/components/key-device-sensor.js +1 -1
- package/src/assets/components/layout.js +1 -1
- package/src/assets/components/particle-systems.js +1 -1
- package/src/assets/components/volume-rendering.js +1 -1
- package/src/assets/linetype/1.png +0 -0
- package/src/assets/linetype/10.png +0 -0
- package/src/assets/linetype/11.png +0 -0
- package/src/assets/linetype/12.png +0 -0
- package/src/assets/linetype/13.png +0 -0
- package/src/assets/linetype/14.png +0 -0
- package/src/assets/linetype/15.png +0 -0
- package/src/assets/linetype/16.png +0 -0
- package/src/assets/linetype/2.png +0 -0
- package/src/assets/linetype/3.png +0 -0
- package/src/assets/linetype/4.png +0 -0
- package/src/assets/linetype/5.png +0 -0
- package/src/assets/linetype/6.png +0 -0
- package/src/assets/linetype/7.png +0 -0
- package/src/assets/linetype/8.png +0 -0
- package/src/assets/linetype/9.png +0 -0
- package/src/assets/shaders/Types.glsl +1 -9
- package/src/assets/shaders/webgl1/Line.fs +3 -28
- package/src/assets/shaders/webgl1/Line.vs +5 -19
- package/src/assets/shaders/webgl1/PBR.vs +1 -1
- package/src/assets/shaders/webgl1/Point.vs +2 -3
- package/src/assets/shaders/webgl2/Depth.vs +4 -1
- package/src/assets/shaders/webgl2/Gouraud.vs +5 -3
- package/src/assets/shaders/webgl2/Line.fs +11 -17
- package/src/assets/shaders/webgl2/Line.vs +16 -20
- package/src/assets/shaders/webgl2/LineTransform.fs +6 -0
- package/src/assets/shaders/webgl2/LineTransform.vs +77 -0
- package/src/assets/shaders/webgl2/PBR.vs +10 -7
- package/src/assets/shaders/webgl2/Phong.vs +6 -3
- package/src/assets/shaders/webgl2/Point.vs +6 -6
- package/src/assets/shaders/webgl2/Unlit.vs +6 -3
- package/src/assets/shaders/webgl2/include/Line2.glsl +20 -0
- package/src/assets/shaders/webgl2/include/Particle.glsl +36 -0
- package/src/example.html +6 -6
- package/src/standard/Math/Algorithm.js +12 -28
- package/src/standard/Math/Geometry/Plane3.js +0 -2
- package/src/standard/Math/Geometry/ViewVolume.js +88 -83
- package/src/standard/Math/Numbers/Color3.js +6 -0
- package/src/standard/Math/Numbers/Color4.js +7 -0
- package/src/standard/Math/Numbers/Complex.js +5 -0
- package/src/standard/Math/Numbers/Matrix2.js +20 -2
- package/src/standard/Math/Numbers/Matrix3.js +129 -110
- package/src/standard/Math/Numbers/Matrix4.js +138 -119
- package/src/standard/Math/Numbers/Quaternion.js +7 -0
- package/src/standard/Math/Numbers/Rotation4.js +7 -0
- package/src/standard/Math/Numbers/Vector2.js +8 -5
- package/src/standard/Math/Numbers/Vector3.js +16 -10
- package/src/standard/Math/Numbers/Vector4.js +12 -7
- package/src/standard/Math/Utility/BVH.js +45 -17
- package/src/tests.js +6 -1
- package/src/x_ite/Base/X3DBaseNode.js +22 -11
- package/src/x_ite/Base/X3DField.js +1 -1
- package/src/x_ite/Browser/Core/BrowserOptions.js +2 -2
- package/src/x_ite/Browser/Core/BrowserTimings.js +4 -2
- package/src/x_ite/Browser/Core/Context.js +185 -0
- package/src/x_ite/Browser/Core/ContextMenu.js +299 -193
- package/src/x_ite/Browser/Core/Notification.js +1 -0
- package/src/x_ite/Browser/Core/X3DCoreContext.js +35 -146
- package/src/x_ite/Browser/Layout/ScreenText.js +11 -4
- package/src/x_ite/Browser/Layout/X3DLayoutContext.js +4 -15
- package/src/x_ite/Browser/Navigation/ExamineViewer.js +12 -19
- package/src/x_ite/Browser/Navigation/LookAtViewer.js +0 -3
- package/src/x_ite/Browser/Navigation/PlaneViewer.js +0 -3
- package/src/x_ite/Browser/Navigation/X3DFlyViewer.js +14 -7
- package/src/x_ite/Browser/Navigation/X3DViewer.js +12 -20
- package/src/x_ite/Browser/Networking/X3DNetworkingContext.js +11 -7
- package/src/x_ite/Browser/ParticleSystems/BVH.glsl +183 -0
- package/src/x_ite/Browser/ParticleSystems/Box3.glsl +47 -0
- package/src/x_ite/Browser/ParticleSystems/GeometryTypes.js +66 -0
- package/src/x_ite/Browser/ParticleSystems/Line3.glsl +55 -0
- package/src/x_ite/Browser/ParticleSystems/Plane3.glsl +160 -0
- package/src/x_ite/Browser/PointingDeviceSensor/PointingDevice.js +27 -3
- package/src/x_ite/Browser/PointingDeviceSensor/X3DPointingDeviceSensorContext.js +37 -37
- package/src/x_ite/Browser/Rendering/X3DRenderingContext.js +19 -13
- package/src/x_ite/Browser/Shaders/Shader.js +33 -12
- package/src/x_ite/Browser/Shaders/ShaderSource.js +6 -0
- package/src/x_ite/Browser/Shaders/ShaderTest.js +16 -10
- package/src/x_ite/Browser/Shape/X3DShapeContext.js +50 -9
- package/src/x_ite/Browser/Text/X3DTextContext.js +4 -13
- package/src/x_ite/Browser/Texturing/X3DTexturingContext.js +23 -33
- package/src/x_ite/Browser/Texturing3D/DICOMParser.js +2 -2
- package/src/x_ite/Browser/Time/X3DTimeContext.js +3 -1
- package/src/x_ite/Browser/VERSION.js +1 -1
- package/src/x_ite/Browser/X3DBrowser.js +7 -6
- package/src/x_ite/Browser/X3DBrowserContext.js +35 -10
- package/src/x_ite/Components/Core/X3DNode.js +4 -0
- package/src/x_ite/Components/Core/X3DPrototypeInstance.js +0 -2
- package/src/x_ite/Components/CubeMapTexturing/ComposedCubeMapTexture.js +3 -4
- package/src/x_ite/Components/CubeMapTexturing/GeneratedCubeMapTexture.js +1 -12
- package/src/x_ite/Components/CubeMapTexturing/ImageCubeMapTexture.js +0 -1
- package/src/x_ite/Components/EnvironmentalEffects/TextureBackground.js +1 -1
- package/src/x_ite/Components/EnvironmentalEffects/X3DBackgroundNode.js +76 -77
- package/src/x_ite/Components/EnvironmentalEffects/X3DFogObject.js +2 -9
- package/src/x_ite/Components/EnvironmentalSensor/ProximitySensor.js +51 -65
- package/src/x_ite/Components/EventUtilities/X3DSequencerNode.js +1 -1
- package/src/x_ite/Components/Followers/X3DChaserNode.js +18 -32
- package/src/x_ite/Components/Followers/X3DDamperNode.js +1 -6
- package/src/x_ite/Components/Geometry2D/TriangleSet2D.js +1 -1
- package/src/x_ite/Components/Geometry3D/ElevationGrid.js +12 -4
- package/src/x_ite/Components/Geometry3D/IndexedFaceSet.js +4 -4
- package/src/x_ite/Components/Geospatial/GeoCoordinate.js +10 -27
- package/src/x_ite/Components/Geospatial/GeoPositionInterpolator.js +5 -10
- package/src/x_ite/Components/Geospatial/GeoTouchSensor.js +9 -16
- package/src/x_ite/Components/Geospatial/GeoTransform.js +6 -18
- package/src/x_ite/Components/Geospatial/X3DGeospatialObject.js +20 -27
- package/src/x_ite/Components/Grouping/X3DGroupingNode.js +8 -8
- package/src/x_ite/Components/Grouping/X3DTransformNode.js +0 -4
- package/src/x_ite/Components/HAnim/HAnimHumanoid.js +68 -75
- package/src/x_ite/Components/Interpolation/OrientationInterpolator.js +4 -11
- package/src/x_ite/Components/Interpolation/X3DInterpolatorNode.js +1 -1
- package/src/x_ite/Components/Layout/LayoutGroup.js +4 -9
- package/src/x_ite/Components/Layout/ScreenFontStyle.js +1 -1
- package/src/x_ite/Components/Layout/ScreenGroup.js +18 -23
- package/src/x_ite/Components/Lighting/DirectionalLight.js +28 -36
- package/src/x_ite/Components/Lighting/PointLight.js +32 -47
- package/src/x_ite/Components/Lighting/SpotLight.js +33 -48
- package/src/x_ite/Components/Navigation/Billboard.js +49 -56
- package/src/x_ite/Components/Navigation/LOD.js +1 -1
- package/src/x_ite/Components/Navigation/X3DViewpointNode.js +82 -111
- package/src/x_ite/Components/Networking/Anchor.js +10 -4
- package/src/x_ite/Components/ParticleSystems/BoundedPhysicsModel.js +6 -6
- package/src/x_ite/Components/ParticleSystems/ConeEmitter.js +44 -36
- package/src/x_ite/Components/ParticleSystems/ExplosionEmitter.js +26 -17
- package/src/x_ite/Components/ParticleSystems/ForcePhysicsModel.js +20 -7
- package/src/x_ite/Components/ParticleSystems/ParticleSystem.js +461 -876
- package/src/x_ite/Components/ParticleSystems/PointEmitter.js +39 -35
- package/src/x_ite/Components/ParticleSystems/PolylineEmitter.js +112 -128
- package/src/x_ite/Components/ParticleSystems/SurfaceEmitter.js +105 -112
- package/src/x_ite/Components/ParticleSystems/VolumeEmitter.js +138 -176
- package/src/x_ite/Components/ParticleSystems/WindPhysicsModel.js +16 -11
- package/src/x_ite/Components/ParticleSystems/X3DParticleEmitterNode.js +807 -217
- package/src/x_ite/Components/Picking/LinePickSensor.js +31 -39
- package/src/x_ite/Components/PointingDeviceSensor/CylinderSensor.js +90 -107
- package/src/x_ite/Components/PointingDeviceSensor/PlaneSensor.js +48 -55
- package/src/x_ite/Components/PointingDeviceSensor/SphereSensor.js +53 -70
- package/src/x_ite/Components/PointingDeviceSensor/TouchSensor.js +8 -15
- package/src/x_ite/Components/ProjectiveTextureMapping/TextureProjectorParallel.js +43 -50
- package/src/x_ite/Components/ProjectiveTextureMapping/TextureProjectorPerspective.js +32 -39
- package/src/x_ite/Components/Rendering/ClipPlane.js +3 -11
- package/src/x_ite/Components/Rendering/Color.js +12 -37
- package/src/x_ite/Components/Rendering/ColorRGBA.js +13 -38
- package/src/x_ite/Components/Rendering/IndexedLineSet.js +12 -4
- package/src/x_ite/Components/Rendering/LineSet.js +21 -13
- package/src/x_ite/Components/Rendering/PointSet.js +21 -13
- package/src/x_ite/Components/Rendering/X3DColorNode.js +13 -0
- package/src/x_ite/Components/Rendering/X3DComposedGeometryNode.js +13 -5
- package/src/x_ite/Components/Rendering/X3DGeometryNode.js +248 -325
- package/src/x_ite/Components/Rendering/X3DLineGeometryNode.js +305 -134
- package/src/x_ite/Components/Rendering/X3DPointGeometryNode.js +99 -122
- package/src/x_ite/Components/RigidBodyPhysics/DoubleAxisHingeJoint.js +24 -38
- package/src/x_ite/Components/RigidBodyPhysics/SingleAxisHingeJoint.js +10 -17
- package/src/x_ite/Components/Shaders/ComposedShader.js +35 -75
- package/src/x_ite/Components/Shaders/FloatVertexAttribute.js +5 -15
- package/src/x_ite/Components/Shaders/Matrix3VertexAttribute.js +7 -24
- package/src/x_ite/Components/Shaders/Matrix4VertexAttribute.js +7 -24
- package/src/x_ite/Components/Shaders/ShaderPart.js +1 -10
- package/src/x_ite/Components/Shaders/X3DProgrammableShaderObject.js +219 -209
- package/src/x_ite/Components/Shaders/X3DShaderNode.js +1 -1
- package/src/x_ite/Components/Shaders/X3DVertexAttributeNode.js +23 -1
- package/src/x_ite/Components/Shape/Appearance.js +12 -0
- package/src/x_ite/Components/Shape/FillProperties.js +12 -1
- package/src/x_ite/Components/Shape/LineProperties.js +33 -1
- package/src/x_ite/Components/Shape/PointProperties.js +23 -1
- package/src/x_ite/Components/Shape/Shape.js +27 -34
- package/src/x_ite/Components/Sound/Sound.js +30 -40
- package/src/x_ite/Components/Text/Text.js +6 -20
- package/src/x_ite/Components/Texturing/TextureCoordinate.js +5 -26
- package/src/x_ite/Components/Texturing/TextureProperties.js +4 -4
- package/src/x_ite/Components/Texturing/X3DSingleTextureCoordinateNode.js +21 -0
- package/src/x_ite/Components/Texturing/X3DSingleTextureNode.js +5 -4
- package/src/x_ite/Components/Texturing/X3DTexture2DNode.js +24 -33
- package/src/x_ite/Components/Texturing3D/TextureCoordinate3D.js +5 -26
- package/src/x_ite/Components/Texturing3D/TextureCoordinate4D.js +5 -26
- package/src/x_ite/Components/Texturing3D/X3DTexture3DNode.js +12 -19
- package/src/x_ite/Components/VolumeRendering/X3DVolumeDataNode.js +7 -7
- package/src/x_ite/Components.js +2 -2
- package/src/x_ite/Fallback.js +9 -3
- package/src/x_ite/Fields/SFColor.js +4 -0
- package/src/x_ite/Fields/SFColorRGBA.js +4 -0
- package/src/x_ite/Fields/SFMatrixPrototypeTemplate.js +4 -0
- package/src/x_ite/Fields/SFRotation.js +4 -0
- package/src/x_ite/Fields/SFString.js +4 -0
- package/src/x_ite/Fields/SFVecPrototypeTemplate.js +4 -0
- package/src/x_ite/Parser/XMLParser.js +1 -1
- package/src/x_ite/Rendering/TextureBuffer.js +43 -36
- package/src/x_ite/Rendering/VertexArray.js +101 -0
- package/src/x_ite/Rendering/X3DRenderObject.js +123 -144
- package/src/x_ite/X3D.js +32 -26
- package/src/x_ite.config.js +0 -5
- package/src/x_ite.css +200 -162
- package/src/x_ite.html +26 -10
- package/src/x_ite.js +42 -0
- package/x_ite.min.html +26 -10
- package/dist/assets/hatching/0.png +0 -0
- package/dist/assets/linetype/0.png +0 -0
- package/src/assets/hatching/0.png +0 -0
- package/src/assets/linetype/0.png +0 -0
- package/src/spinner.css +0 -67
- package/src/x_ite/Browser/Shape/LineStipples.xcf +0 -0
|
@@ -4,8 +4,87 @@
|
|
|
4
4
|
var module = { }, exports, process;
|
|
5
5
|
|
|
6
6
|
const
|
|
7
|
-
define = window [Symbol .for ("X_ITE.X3D-
|
|
8
|
-
require = window [Symbol .for ("X_ITE.X3D-
|
|
7
|
+
define = window [Symbol .for ("X_ITE.X3D-6.0.0")] .define,
|
|
8
|
+
require = window [Symbol .for ("X_ITE.X3D-6.0.0")] .require;
|
|
9
|
+
/* -*- Mode: JavaScript; coding: utf-8; tab-width: 3; indent-tabs-mode: tab; c-basic-offset: 3 -*-
|
|
10
|
+
*******************************************************************************
|
|
11
|
+
*
|
|
12
|
+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
13
|
+
*
|
|
14
|
+
* Copyright create3000, Scheffelstraße 31a, Leipzig, Germany 2011.
|
|
15
|
+
*
|
|
16
|
+
* All rights reserved. Holger Seelig <holger.seelig@yahoo.de>.
|
|
17
|
+
*
|
|
18
|
+
* The copyright notice above does not evidence any actual of intended
|
|
19
|
+
* publication of such source code, and is an unpublished work by create3000.
|
|
20
|
+
* This material contains CONFIDENTIAL INFORMATION that is the property of
|
|
21
|
+
* create3000.
|
|
22
|
+
*
|
|
23
|
+
* No permission is granted to copy, distribute, or create derivative works from
|
|
24
|
+
* the contents of this software, in whole or in part, without the prior written
|
|
25
|
+
* permission of create3000.
|
|
26
|
+
*
|
|
27
|
+
* NON-MILITARY USE ONLY
|
|
28
|
+
*
|
|
29
|
+
* All create3000 software are effectively free software with a non-military use
|
|
30
|
+
* restriction. It is free. Well commented source is provided. You may reuse the
|
|
31
|
+
* source in any way you please with the exception anything that uses it must be
|
|
32
|
+
* marked to indicate is contains 'non-military use only' components.
|
|
33
|
+
*
|
|
34
|
+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
35
|
+
*
|
|
36
|
+
* Copyright 2015, 2016 Holger Seelig <holger.seelig@yahoo.de>.
|
|
37
|
+
*
|
|
38
|
+
* This file is part of the X_ITE Project.
|
|
39
|
+
*
|
|
40
|
+
* X_ITE is free software: you can redistribute it and/or modify it under the
|
|
41
|
+
* terms of the GNU General Public License version 3 only, as published by the
|
|
42
|
+
* Free Software Foundation.
|
|
43
|
+
*
|
|
44
|
+
* X_ITE is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
45
|
+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
46
|
+
* A PARTICULAR PURPOSE. See the GNU General Public License version 3 for more
|
|
47
|
+
* details (a copy is included in the LICENSE file that accompanied this code).
|
|
48
|
+
*
|
|
49
|
+
* You should have received a copy of the GNU General Public License version 3
|
|
50
|
+
* along with X_ITE. If not, see <http://www.gnu.org/licenses/gpl.html> for a
|
|
51
|
+
* copy of the GPLv3 License.
|
|
52
|
+
*
|
|
53
|
+
* For Silvio, Joy and Adi.
|
|
54
|
+
*
|
|
55
|
+
******************************************************************************/
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
define ('x_ite/Browser/ParticleSystems/GeometryTypes',[],function ()
|
|
59
|
+
{
|
|
60
|
+
"use strict";
|
|
61
|
+
|
|
62
|
+
let i = 0;
|
|
63
|
+
|
|
64
|
+
const GeometryTypes = {
|
|
65
|
+
POINT: i ++,
|
|
66
|
+
LINE: i ++,
|
|
67
|
+
TRIANGLE: i ++,
|
|
68
|
+
QUAD: i ++,
|
|
69
|
+
SPRITE: i ++,
|
|
70
|
+
GEOMETRY: i ++,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
return GeometryTypes;
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
define('text!x_ite/Browser/ParticleSystems/Line3.glsl',[],function () { return 'struct Line3 {\n vec3 point;\n vec3 direction;\n};\n\n// Line3\n// line3 (const in vec3 point1, const in vec3 point2)\n// {\n// return Line3 (point1, normalize (point2 - point1));\n// }\n\n/* Line intersect triangle */\n\nbool\nintersects (const in Line3 line, const in vec3 a, const in vec3 b, const in vec3 c, out vec3 r)\n{\n // find vectors for two edges sharing vert0\n vec3 edge1 = b - a;\n vec3 edge2 = c - a;\n\n // begin calculating determinant - also used to calculate U parameter\n vec3 pvec = cross (line .direction, edge2);\n\n // if determinant is near zero, ray lies in plane of triangle\n float det = dot (edge1, pvec);\n\n // Non culling intersection\n\n if (det == 0.0)\n return false;\n\n float inv_det = 1.0 / det;\n\n // calculate distance from vert0 to ray point\n vec3 tvec = line .point - a;\n\n // calculate U parameter and test bounds\n float u = dot (tvec, pvec) * inv_det;\n\n if (u < 0.0 || u > 1.0)\n return false;\n\n // prepare to test V parameter\n vec3 qvec = cross (tvec, edge1);\n\n // calculate V parameter and test bounds\n float v = dot (line .direction, qvec) * inv_det;\n\n if (v < 0.0 || u + v > 1.0)\n return false;\n\n r = vec3 (u, v, 1.0 - u - v);\n\n return true;\n}\n';});
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
define('text!x_ite/Browser/ParticleSystems/Plane3.glsl',[],function () { return 'struct Plane3\n{\n vec3 normal;\n float distanceFromOrigin;\n};\n\nPlane3\nplane3 (const in vec3 point, const in vec3 normal)\n{\n return Plane3 (normal, dot (normal, point));\n}\n\nfloat\nplane_distance (const in Plane3 plane, const in vec3 point)\n{\n return dot (point, plane .normal) - plane .distanceFromOrigin;\n}\n\n/* Plane intersect line */\nbool\nintersects (const in Plane3 plane, const in Line3 line, out vec3 point)\n{\n // Check if the line is parallel to the plane.\n float theta = dot (line .direction, plane .normal);\n\n // Plane and line are parallel.\n if (theta == 0.0)\n return false;\n\n // Plane and line are not parallel. The intersection point can be calculated now.\n float t = (plane .distanceFromOrigin - dot (plane .normal, line .point)) / theta;\n\n point = line .point + line .direction * t;\n\n return true;\n}\n\n/* Find find the first point that is farther to the plane than value. */\n// int\n// upper_bound (const in vec4 points [ARRAY_SIZE], in int count, const in float value, const in Plane3 plane)\n// {\n// int first = 0;\n// int step = 0;\n\n// while (count > 0)\n// {\n// int index = first;\n\n// step = count >> 1;\n\n// index += step;\n\n// if (value < plane_distance (plane, points [index] .xyz))\n// {\n// count = step;\n// }\n// else\n// {\n// first = ++ index;\n// count -= step + 1;\n// }\n// }\n\n// return first;\n// }\n\n/* CombSort: sort points in distance to a plane. */\nvoid\nsort (inout vec4 points [ARRAY_SIZE], const in int count, const in Plane3 plane)\n{\n const float shrink = 1.0 / 1.3;\n\n int gap = count;\n bool exchanged = true;\n\n while (exchanged)\n {\n gap = int (float (gap) * shrink);\n\n if (gap <= 1)\n {\n exchanged = false;\n gap = 1;\n }\n\n for (int i = 0, l = count - gap; i < l; ++ i)\n {\n int j = gap + i;\n\n if (plane_distance (plane, points [i] .xyz) > plane_distance (plane, points [j] .xyz))\n {\n vec4 tmp1 = points [i];\n points [i] = points [j];\n points [j] = tmp1;\n\n exchanged = true;\n }\n }\n }\n}\n\n\n// /* CombSort: sort points and normals in distance to a plane. */\n// void\n// sort (inout vec4 points [ARRAY_SIZE], inout vec3 normals [ARRAY_SIZE], const in int count, const in Plane3 plane)\n// {\n// const float shrink = 1.0 / 1.3;\n\n// int gap = count;\n// bool exchanged = true;\n\n// while (exchanged)\n// {\n// gap = int (float (gap) * shrink);\n\n// if (gap <= 1)\n// {\n// exchanged = false;\n// gap = 1;\n// }\n\n// for (int i = 0, l = count - gap; i < l; ++ i)\n// {\n// int j = gap + i;\n\n// if (plane_distance (plane, points [i] .xyz) > plane_distance (plane, points [j] .xyz))\n// {\n// vec4 tmp1 = points [i];\n// points [i] = points [j];\n// points [j] = tmp1;\n\n// vec3 tmp2 = normals [i];\n// normals [i] = normals [j];\n// normals [j] = tmp2;\n\n// exchanged = true;\n// }\n// }\n// }\n// }\n\nint\nmin_index (const in vec4 points [ARRAY_SIZE], const in int count, const in float value, const in Plane3 plane)\n{\n int index = -1;\n float dist = 1000000.0;\n\n for (int i = 0; i < count; ++ i)\n {\n float d = plane_distance (plane, points [i] .xyz);\n\n if (d >= value && d < dist)\n {\n dist = d;\n index = i;\n }\n }\n\n return index;\n}\n';});
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
define('text!x_ite/Browser/ParticleSystems/Box3.glsl',[],function () { return 'bool\nintersects (const in vec3 min, const in vec3 max, const in Line3 line)\n{\n vec3 intersection;\n\n // front\n\n if (intersects (plane3 (max, vec3 (0.0, 0.0, 1.0)), line, intersection))\n {\n if (all (greaterThanEqual (vec4 (intersection .xy, max .xy), vec4 (min .xy, intersection .xy))))\n return true;\n }\n\n // back\n\n if (intersects (plane3 (min, vec3 (0.0, 0.0, -1.0)), line, intersection))\n {\n if (all (greaterThanEqual (vec4 (intersection .xy, max .xy), vec4 (min .xy, intersection .xy))))\n return true;\n }\n\n // top\n\n if (intersects (plane3 (max, vec3 (0.0, 1.0, 0.0)), line, intersection))\n {\n if (all (greaterThanEqual (vec4 (intersection .xz, max .xz), vec4 (min .xz, intersection .xz))))\n return true;\n }\n\n // bottom\n\n if (intersects (plane3 (min, vec3 (0.0, -1.0, 0.0)), line, intersection))\n {\n if (all (greaterThanEqual (vec4 (intersection .xz, max .xz), vec4 (min .xz, intersection .xz))))\n return true;\n }\n\n // right\n\n if (intersects (plane3 (max, vec3 (1.0, 0.0, 0.0)), line, intersection))\n {\n if (all (greaterThanEqual (vec4 (intersection .yz, max .yz), vec4 (min .yz, intersection .yz))))\n return true;\n }\n\n return false;\n}\n';});
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
define('text!x_ite/Browser/ParticleSystems/BVH.glsl',[],function () { return '#define BVH_NODE 0\n#define BVH_TRIANGLE 1\n#define BVH_STACK_SIZE 32\n\nint bvhNodeIndex = 0;\n\nvoid\nsetBVHIndex (const in int index)\n{\n bvhNodeIndex = index;\n}\n\nint\ngetBVHRoot (const in sampler2D volume, const in int hierarchyIndex, const in int rootIndex)\n{\n return int (texelFetch (volume, rootIndex, 0) .x) + hierarchyIndex;\n}\n\nint\ngetBVHType (const in sampler2D volume)\n{\n return int (texelFetch (volume, bvhNodeIndex, 0) .x);\n}\n\nvec3\ngetBVHMin (const in sampler2D volume)\n{\n return texelFetch (volume, bvhNodeIndex + 1, 0) .xyz;\n}\n\nvec3\ngetBVHMax (const in sampler2D volume)\n{\n return texelFetch (volume, bvhNodeIndex + 2, 0) .xyz;\n}\n\nint\ngetBVHLeft (const in sampler2D volume, const in int hierarchyIndex)\n{\n return int (texelFetch (volume, bvhNodeIndex, 0) .y) + hierarchyIndex;\n}\n\nint\ngetBVHRight (const in sampler2D volume, const in int hierarchyIndex)\n{\n return int (texelFetch (volume, bvhNodeIndex, 0) .z) + hierarchyIndex;\n}\n\nint\ngetBVHTriangle (const in sampler2D volume)\n{\n return int (texelFetch (volume, bvhNodeIndex, 0) .y);\n}\n\n/* Ray triangle intersection test */\n\nint\ngetIntersections (const in sampler2D volume, const in int verticesIndex, const in int hierarchyIndex, const in int rootIndex, const in Line3 line, out vec4 points [ARRAY_SIZE])\n{\n int current = getBVHRoot (volume, hierarchyIndex, rootIndex);\n int count = 0;\n int stackIndex = -1;\n int stack [BVH_STACK_SIZE];\n\n while (stackIndex >= 0 || current >= 0)\n {\n if (current >= 0)\n {\n setBVHIndex (current);\n\n if (getBVHType (volume) == BVH_NODE)\n {\n // Node\n\n if (intersects (getBVHMin (volume), getBVHMax (volume), line))\n {\n stack [++ stackIndex] = current;\n\n current = getBVHLeft (volume, hierarchyIndex);\n }\n else\n {\n current = -1;\n }\n }\n else\n {\n // Triangle\n\n int t = getBVHTriangle (volume);\n int v = verticesIndex + t;\n vec3 r = vec3 (0.0);\n\n vec3 a = texelFetch (volume, v, 0) .xyz;\n vec3 b = texelFetch (volume, v + 1, 0) .xyz;\n vec3 c = texelFetch (volume, v + 2, 0) .xyz;\n\n if (intersects (line, a, b, c, r))\n points [count ++] = vec4 (r .z * a + r .x * b + r .y * c, 1.0);\n\n current = -1;\n }\n }\n else\n {\n setBVHIndex (stack [stackIndex --]);\n\n current = getBVHRight (volume, hierarchyIndex);\n }\n }\n\n return count;\n}\n\nint\ngetIntersections (const in sampler2D volume, const in int verticesIndex, const in int normalsIndex, const in int hierarchyIndex, const in int rootIndex, const in Line3 line, out vec4 points [ARRAY_SIZE], out vec3 normals [ARRAY_SIZE])\n{\n int current = getBVHRoot (volume, hierarchyIndex, rootIndex);\n int count = 0;\n int stackIndex = -1;\n int stack [BVH_STACK_SIZE];\n\n while (stackIndex >= 0 || current >= 0)\n {\n if (current >= 0)\n {\n setBVHIndex (current);\n\n if (getBVHType (volume) == BVH_NODE)\n {\n // Node\n\n if (intersects (getBVHMin (volume), getBVHMax (volume), line))\n {\n stack [++ stackIndex] = current;\n\n current = getBVHLeft (volume, hierarchyIndex);\n }\n else\n {\n current = -1;\n }\n }\n else\n {\n // Triangle\n\n int t = getBVHTriangle (volume);\n int v = verticesIndex + t;\n vec3 r = vec3 (0.0);\n\n vec3 a = texelFetch (volume, v, 0) .xyz;\n vec3 b = texelFetch (volume, v + 1, 0) .xyz;\n vec3 c = texelFetch (volume, v + 2, 0) .xyz;\n\n if (intersects (line, a, b, c, r))\n {\n points [count] = vec4 (r .z * a + r .x * b + r .y * c, 1.0);\n\n int n = normalsIndex + t;\n\n vec3 n0 = texelFetch (volume, n, 0) .xyz;\n vec3 n1 = texelFetch (volume, n + 1, 0) .xyz;\n vec3 n2 = texelFetch (volume, n + 2, 0) .xyz;\n\n normals [count] = save_normalize (r .z * n0 + r .x * n1 + r .y * n2);\n\n ++ count;\n }\n\n current = -1;\n }\n }\n else\n {\n setBVHIndex (stack [stackIndex --]);\n\n current = getBVHRight (volume, hierarchyIndex);\n }\n }\n\n return count;\n}\n';});
|
|
87
|
+
|
|
9
88
|
/* -*- Mode: JavaScript; coding: utf-8; tab-width: 3; indent-tabs-mode: tab; c-basic-offset: 3 -*-
|
|
10
89
|
*******************************************************************************
|
|
11
90
|
*
|
|
@@ -57,41 +136,23 @@ const
|
|
|
57
136
|
|
|
58
137
|
define ('x_ite/Components/ParticleSystems/X3DParticleEmitterNode',[
|
|
59
138
|
"x_ite/Components/Core/X3DNode",
|
|
139
|
+
"x_ite/Browser/ParticleSystems/GeometryTypes",
|
|
60
140
|
"x_ite/Base/X3DConstants",
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"standard/Math/Algorithm",
|
|
66
|
-
"standard/Math/Algorithms/QuickSort",
|
|
141
|
+
"text!x_ite/Browser/ParticleSystems/Line3.glsl",
|
|
142
|
+
"text!x_ite/Browser/ParticleSystems/Plane3.glsl",
|
|
143
|
+
"text!x_ite/Browser/ParticleSystems/Box3.glsl",
|
|
144
|
+
"text!x_ite/Browser/ParticleSystems/BVH.glsl",
|
|
67
145
|
],
|
|
68
146
|
function (X3DNode,
|
|
147
|
+
GeometryTypes,
|
|
69
148
|
X3DConstants,
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
Algorithm,
|
|
75
|
-
QuickSort)
|
|
149
|
+
Line3Source,
|
|
150
|
+
Plane3Source,
|
|
151
|
+
Box3Source,
|
|
152
|
+
BVHSource)
|
|
76
153
|
{
|
|
77
154
|
"use strict";
|
|
78
155
|
|
|
79
|
-
var
|
|
80
|
-
normal = new Vector3 (0, 0, 0),
|
|
81
|
-
fromPosition = new Vector3 (0, 0, 0),
|
|
82
|
-
line = new Line3 (Vector3 .Zero, Vector3 .zAxis),
|
|
83
|
-
plane = new Plane3 (Vector3 .Zero, Vector3 .zAxis);
|
|
84
|
-
|
|
85
|
-
function PlaneCompare (a, b)
|
|
86
|
-
{
|
|
87
|
-
return plane .getDistanceToPoint (a) < plane .getDistanceToPoint (b);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function PlaneCompareValue (a, b)
|
|
91
|
-
{
|
|
92
|
-
return a < plane .getDistanceToPoint (b);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
156
|
function X3DParticleEmitterNode (executionContext)
|
|
96
157
|
{
|
|
97
158
|
X3DNode .call (this, executionContext);
|
|
@@ -102,10 +163,23 @@ function (X3DNode,
|
|
|
102
163
|
this ._mass .setUnit ("mass");
|
|
103
164
|
this ._surfaceArea .setUnit ("area");
|
|
104
165
|
|
|
105
|
-
this .
|
|
106
|
-
this .
|
|
107
|
-
this .
|
|
108
|
-
this .
|
|
166
|
+
this .samplers = [ ];
|
|
167
|
+
this .uniforms = { };
|
|
168
|
+
this .functions = [ ];
|
|
169
|
+
this .program = null;
|
|
170
|
+
|
|
171
|
+
this .addSampler ("forces");
|
|
172
|
+
this .addSampler ("boundedVolume");
|
|
173
|
+
this .addSampler ("colorRamp");
|
|
174
|
+
this .addSampler ("texCoordRamp");
|
|
175
|
+
|
|
176
|
+
this .addUniform ("speed", "uniform float speed;");
|
|
177
|
+
this .addUniform ("variation", "uniform float variation;");
|
|
178
|
+
|
|
179
|
+
this .addFunction (Line3Source);
|
|
180
|
+
this .addFunction (Plane3Source);
|
|
181
|
+
this .addFunction (Box3Source);
|
|
182
|
+
this .addFunction (BVHSource);
|
|
109
183
|
}
|
|
110
184
|
|
|
111
185
|
X3DParticleEmitterNode .prototype = Object .assign (Object .create (X3DNode .prototype),
|
|
@@ -115,26 +189,28 @@ function (X3DNode,
|
|
|
115
189
|
{
|
|
116
190
|
X3DNode .prototype .initialize .call (this);
|
|
117
191
|
|
|
118
|
-
this .
|
|
192
|
+
const gl = this .getBrowser () .getContext ();
|
|
193
|
+
|
|
194
|
+
if (gl .getVersion () < 2)
|
|
195
|
+
return;
|
|
196
|
+
|
|
197
|
+
// Create program.
|
|
198
|
+
|
|
199
|
+
this .program = this .createProgram ();
|
|
200
|
+
this .transformFeedback = gl .createTransformFeedback ();
|
|
201
|
+
|
|
202
|
+
// Initialize fields.
|
|
203
|
+
|
|
204
|
+
this ._on .addInterest ("set_on__", this);
|
|
205
|
+
this ._speed .addInterest ("set_speed__", this);
|
|
119
206
|
this ._variation .addInterest ("set_variation__", this);
|
|
120
|
-
this ._mass .addInterest ("set_mass__",
|
|
207
|
+
this ._mass .addInterest ("set_mass__", this);
|
|
121
208
|
|
|
209
|
+
this .set_on__ ();
|
|
122
210
|
this .set_speed__ ();
|
|
123
211
|
this .set_variation__ ();
|
|
124
212
|
this .set_mass__ ();
|
|
125
213
|
},
|
|
126
|
-
set_speed__: function ()
|
|
127
|
-
{
|
|
128
|
-
this .speed = this ._speed .getValue ();
|
|
129
|
-
},
|
|
130
|
-
set_variation__: function ()
|
|
131
|
-
{
|
|
132
|
-
this .variation = this ._variation .getValue ();
|
|
133
|
-
},
|
|
134
|
-
set_mass__: function ()
|
|
135
|
-
{
|
|
136
|
-
this .mass = this ._mass .getValue ();
|
|
137
|
-
},
|
|
138
214
|
isExplosive: function ()
|
|
139
215
|
{
|
|
140
216
|
return false;
|
|
@@ -143,28 +219,21 @@ function (X3DNode,
|
|
|
143
219
|
{
|
|
144
220
|
return this .mass;
|
|
145
221
|
},
|
|
146
|
-
|
|
222
|
+
set_on__: function ()
|
|
147
223
|
{
|
|
148
|
-
|
|
149
|
-
v = particleLifetime * lifetimeVariation,
|
|
150
|
-
min = Math .max (0, particleLifetime - v),
|
|
151
|
-
max = particleLifetime + v;
|
|
152
|
-
|
|
153
|
-
return Math .random () * (max - min) + min;
|
|
224
|
+
this .on = this ._on .getValue ();
|
|
154
225
|
},
|
|
155
|
-
|
|
226
|
+
set_speed__: function ()
|
|
156
227
|
{
|
|
157
|
-
|
|
158
|
-
speed = this .speed,
|
|
159
|
-
v = speed * this .variation,
|
|
160
|
-
min = Math .max (0, speed - v),
|
|
161
|
-
max = speed + v;
|
|
162
|
-
|
|
163
|
-
return Math .random () * (max - min) + min;
|
|
228
|
+
this .setUniform ("uniform1f", "speed", this ._speed .getValue ());
|
|
164
229
|
},
|
|
165
|
-
|
|
230
|
+
set_variation__: function ()
|
|
231
|
+
{
|
|
232
|
+
this .setUniform ("uniform1f", "variation", this ._variation .getValue ());
|
|
233
|
+
},
|
|
234
|
+
set_mass__: function ()
|
|
166
235
|
{
|
|
167
|
-
|
|
236
|
+
this .mass = this ._mass .getValue ();
|
|
168
237
|
},
|
|
169
238
|
getRandomValue: function (min, max)
|
|
170
239
|
{
|
|
@@ -172,7 +241,7 @@ function (X3DNode,
|
|
|
172
241
|
},
|
|
173
242
|
getRandomNormal: function (normal)
|
|
174
243
|
{
|
|
175
|
-
|
|
244
|
+
const
|
|
176
245
|
theta = this .getRandomValue (-1, 1) * Math .PI,
|
|
177
246
|
cphi = this .getRandomValue (-1, 1),
|
|
178
247
|
phi = Math .acos (cphi),
|
|
@@ -182,234 +251,834 @@ function (X3DNode,
|
|
|
182
251
|
Math .cos (theta) * r,
|
|
183
252
|
cphi);
|
|
184
253
|
},
|
|
185
|
-
|
|
254
|
+
animate: function (particleSystem, deltaTime)
|
|
186
255
|
{
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
256
|
+
const
|
|
257
|
+
browser = this .getBrowser (),
|
|
258
|
+
gl = browser .getContext (),
|
|
259
|
+
inputParticles = particleSystem .inputParticles,
|
|
260
|
+
particleStride = particleSystem .particleStride,
|
|
261
|
+
particleOffsets = particleSystem .particleOffsets,
|
|
262
|
+
program = this .program;
|
|
263
|
+
|
|
264
|
+
// Start
|
|
265
|
+
|
|
266
|
+
gl .useProgram (program);
|
|
267
|
+
|
|
268
|
+
// Uniforms
|
|
269
|
+
|
|
270
|
+
gl .uniform1i (program .randomSeed, Math .random () * 0xffffffff);
|
|
271
|
+
gl .uniform1i (program .geometryType, particleSystem .geometryType);
|
|
272
|
+
gl .uniform1i (program .createParticles, particleSystem .createParticles && this .on);
|
|
273
|
+
gl .uniform1f (program .particleLifetime, particleSystem .particleLifetime);
|
|
274
|
+
gl .uniform1f (program .lifetimeVariation, particleSystem .lifetimeVariation);
|
|
275
|
+
gl .uniform1f (program .deltaTime, deltaTime);
|
|
276
|
+
gl .uniform2f (program .particleSize, particleSystem ._particleSize .x, particleSystem ._particleSize .y);
|
|
277
|
+
|
|
278
|
+
// Forces
|
|
279
|
+
|
|
280
|
+
gl .uniform1i (program .numForces, particleSystem .numForces);
|
|
281
|
+
|
|
282
|
+
if (particleSystem .numForces)
|
|
283
|
+
{
|
|
284
|
+
gl .activeTexture (gl .TEXTURE0 + program .forcesTextureUnit);
|
|
285
|
+
gl .bindTexture (gl .TEXTURE_2D, particleSystem .forcesTexture);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Bounded Physics
|
|
289
|
+
|
|
290
|
+
if (particleSystem .boundedHierarchyRoot < 0)
|
|
291
|
+
{
|
|
292
|
+
gl .uniform1i (program .boundedHierarchyRoot, -1);
|
|
293
|
+
}
|
|
294
|
+
else
|
|
295
|
+
{
|
|
296
|
+
gl .uniform1i (program .boundedVerticesIndex, particleSystem .boundedVerticesIndex);
|
|
297
|
+
gl .uniform1i (program .boundedNormalsIndex, particleSystem .boundedNormalsIndex);
|
|
298
|
+
gl .uniform1i (program .boundedHierarchyIndex, particleSystem .boundedHierarchyIndex);
|
|
299
|
+
gl .uniform1i (program .boundedHierarchyRoot, particleSystem .boundedHierarchyRoot);
|
|
300
|
+
|
|
301
|
+
gl .activeTexture (gl .TEXTURE0 + program .boundedVolumeTextureUnit);
|
|
302
|
+
gl .bindTexture (gl .TEXTURE_2D, particleSystem .boundedTexture);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// Colors
|
|
306
|
+
|
|
307
|
+
gl .uniform1i (program .numColors, particleSystem .numColors);
|
|
308
|
+
|
|
309
|
+
if (particleSystem .numColors)
|
|
310
|
+
{
|
|
311
|
+
gl .activeTexture (gl .TEXTURE0 + program .colorRampTextureUnit);
|
|
312
|
+
gl .bindTexture (gl .TEXTURE_2D, particleSystem .colorRampTexture);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// TexCoords
|
|
316
|
+
|
|
317
|
+
gl .uniform1i (program .numTexCoords, particleSystem .numTexCoords);
|
|
318
|
+
|
|
319
|
+
if (particleSystem .numTexCoords)
|
|
320
|
+
{
|
|
321
|
+
gl .uniform1i (program .texCoordCount, particleSystem .texCoordCount);
|
|
322
|
+
|
|
323
|
+
gl .activeTexture (gl .TEXTURE0 + program .texCoordRampTextureUnit);
|
|
324
|
+
gl .bindTexture (gl .TEXTURE_2D, particleSystem .texCoordRampTexture);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Other textures
|
|
328
|
+
|
|
329
|
+
this .activateTextures (gl, program);
|
|
330
|
+
|
|
331
|
+
// Input attributes
|
|
332
|
+
|
|
333
|
+
if (inputParticles .emitterArrayObject .enable (gl, program))
|
|
334
|
+
{
|
|
335
|
+
for (const [i, attribute] of program .inputs)
|
|
336
|
+
{
|
|
337
|
+
gl .bindBuffer (gl .ARRAY_BUFFER, inputParticles);
|
|
338
|
+
gl .enableVertexAttribArray (attribute);
|
|
339
|
+
gl .vertexAttribPointer (attribute, 4, gl .FLOAT, false, particleStride, particleOffsets [i]);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
gl .bindBuffer (gl .ARRAY_BUFFER, null);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Transform particles.
|
|
346
|
+
|
|
347
|
+
gl .bindTransformFeedback (gl .TRANSFORM_FEEDBACK, this .transformFeedback);
|
|
348
|
+
gl .bindBufferBase (gl .TRANSFORM_FEEDBACK_BUFFER, 0, particleSystem .outputParticles);
|
|
349
|
+
gl .enable (gl .RASTERIZER_DISCARD);
|
|
350
|
+
gl .beginTransformFeedback (gl .POINTS);
|
|
351
|
+
gl .drawArrays (gl .POINTS, 0, particleSystem .numParticles);
|
|
352
|
+
gl .endTransformFeedback ();
|
|
353
|
+
gl .disable (gl .RASTERIZER_DISCARD);
|
|
354
|
+
gl .bindTransformFeedback (gl .TRANSFORM_FEEDBACK, null);
|
|
355
|
+
|
|
356
|
+
// DEBUG
|
|
357
|
+
|
|
358
|
+
// const data = new Float32Array (particleSystem .numParticles * (particleStride / 4));
|
|
359
|
+
// gl .bindBuffer (gl .ARRAY_BUFFER, particleSystem .outputParticles);
|
|
360
|
+
// gl .getBufferSubData (gl .ARRAY_BUFFER, 0, data);
|
|
361
|
+
// console .log (data .slice (0, particleStride / 4));
|
|
362
|
+
},
|
|
363
|
+
addSampler: function (name)
|
|
364
|
+
{
|
|
365
|
+
this .samplers .push (name);
|
|
366
|
+
},
|
|
367
|
+
addUniform: function (name, uniform)
|
|
368
|
+
{
|
|
369
|
+
this .uniforms [name] = uniform;
|
|
370
|
+
},
|
|
371
|
+
setUniform: function (func, name, value1, value2, value3)
|
|
372
|
+
{
|
|
373
|
+
const
|
|
374
|
+
gl = this .getBrowser () .getContext (),
|
|
375
|
+
program = this .program;
|
|
376
|
+
|
|
377
|
+
gl .useProgram (program);
|
|
378
|
+
gl [func] (program [name], value1, value2, value3);
|
|
379
|
+
},
|
|
380
|
+
addFunction: function (func)
|
|
381
|
+
{
|
|
382
|
+
this .functions .push (func);
|
|
383
|
+
},
|
|
384
|
+
createProgram: function ()
|
|
385
|
+
{
|
|
386
|
+
const
|
|
387
|
+
browser = this .getBrowser (),
|
|
388
|
+
gl = browser .getContext ();
|
|
389
|
+
|
|
390
|
+
const vertexShaderSource = /* glsl */ `#version 300 es
|
|
391
|
+
|
|
392
|
+
precision highp float;
|
|
393
|
+
precision highp int;
|
|
394
|
+
precision highp sampler2D;
|
|
395
|
+
|
|
396
|
+
uniform int randomSeed;
|
|
397
|
+
uniform int geometryType;
|
|
398
|
+
uniform bool createParticles;
|
|
399
|
+
uniform float particleLifetime;
|
|
400
|
+
uniform float lifetimeVariation;
|
|
401
|
+
uniform float deltaTime;
|
|
402
|
+
uniform vec2 particleSize;
|
|
403
|
+
|
|
404
|
+
uniform int numForces;
|
|
405
|
+
uniform sampler2D forces;
|
|
406
|
+
|
|
407
|
+
uniform int boundedVerticesIndex;
|
|
408
|
+
uniform int boundedNormalsIndex;
|
|
409
|
+
uniform int boundedHierarchyIndex;
|
|
410
|
+
uniform int boundedHierarchyRoot;
|
|
411
|
+
uniform sampler2D boundedVolume;
|
|
412
|
+
|
|
413
|
+
uniform int numColors;
|
|
414
|
+
uniform sampler2D colorRamp;
|
|
415
|
+
|
|
416
|
+
uniform int texCoordCount;
|
|
417
|
+
uniform int numTexCoords;
|
|
418
|
+
uniform sampler2D texCoordRamp;
|
|
419
|
+
|
|
420
|
+
${Object .values (this .uniforms) .join ("\n")}
|
|
421
|
+
|
|
422
|
+
in vec4 input0;
|
|
423
|
+
in vec4 input2;
|
|
424
|
+
in vec4 input6;
|
|
425
|
+
|
|
426
|
+
out vec4 output0;
|
|
427
|
+
out vec4 output1;
|
|
428
|
+
out vec4 output2;
|
|
429
|
+
|
|
430
|
+
out vec4 output3;
|
|
431
|
+
out vec4 output4;
|
|
432
|
+
out vec4 output5;
|
|
433
|
+
out vec4 output6;
|
|
434
|
+
|
|
435
|
+
// Constants
|
|
436
|
+
|
|
437
|
+
${Object .entries (GeometryTypes) .map (([k, v]) => `#define ${k} ${v}`) .join ("\n")}
|
|
438
|
+
|
|
439
|
+
const int ARRAY_SIZE = 32;
|
|
440
|
+
const float M_PI = 3.14159265359;
|
|
441
|
+
|
|
442
|
+
uniform float NaN;
|
|
443
|
+
|
|
444
|
+
// Texture
|
|
445
|
+
|
|
446
|
+
vec4
|
|
447
|
+
texelFetch (const in sampler2D sampler, const in int index, const in int lod)
|
|
448
|
+
{
|
|
449
|
+
int x = textureSize (sampler, lod) .x;
|
|
450
|
+
ivec2 p = ivec2 (index % x, index / x);
|
|
451
|
+
vec4 t = texelFetch (sampler, p, lod);
|
|
452
|
+
|
|
453
|
+
return t;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Math
|
|
457
|
+
|
|
458
|
+
// Save normalize, that will not divide by zero.
|
|
459
|
+
vec3
|
|
460
|
+
save_normalize (const in vec3 vector)
|
|
461
|
+
{
|
|
462
|
+
float l = length (vector);
|
|
463
|
+
|
|
464
|
+
if (l == 0.0)
|
|
465
|
+
return vec3 (0.0);
|
|
466
|
+
|
|
467
|
+
return vector / l;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// Quaternion
|
|
471
|
+
|
|
472
|
+
vec4
|
|
473
|
+
Quaternion (const in vec3 fromVector, const in vec3 toVector)
|
|
474
|
+
{
|
|
475
|
+
vec3 from = save_normalize (fromVector);
|
|
476
|
+
vec3 to = save_normalize (toVector);
|
|
477
|
+
|
|
478
|
+
float cos_angle = dot (from, to);
|
|
479
|
+
vec3 cross_vec = cross (from, to);
|
|
480
|
+
float cross_len = length (cross_vec);
|
|
481
|
+
|
|
482
|
+
if (cross_len == 0.0)
|
|
483
|
+
{
|
|
484
|
+
if (cos_angle > 0.0)
|
|
485
|
+
{
|
|
486
|
+
return vec4 (0.0, 0.0, 0.0, 1.0);
|
|
487
|
+
}
|
|
488
|
+
else
|
|
489
|
+
{
|
|
490
|
+
vec3 t = cross (from, vec3 (1.0, 0.0, 0.0));
|
|
491
|
+
|
|
492
|
+
if (dot (t, t) == 0.0)
|
|
493
|
+
t = cross (from, vec3 (0.0, 1.0, 0.0));
|
|
494
|
+
|
|
495
|
+
t = save_normalize (t);
|
|
496
|
+
|
|
497
|
+
return vec4 (t, 0.0);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
else
|
|
501
|
+
{
|
|
502
|
+
float s = sqrt (abs (1.0 - cos_angle) * 0.5);
|
|
503
|
+
|
|
504
|
+
cross_vec = save_normalize (cross_vec);
|
|
505
|
+
|
|
506
|
+
return vec4 (cross_vec * s, sqrt (abs (1.0 + cos_angle) * 0.5));
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
vec3
|
|
511
|
+
multVecQuat (const in vec3 v, const in vec4 q)
|
|
512
|
+
{
|
|
513
|
+
float a = q .w * q .w - q .x * q .x - q .y * q .y - q .z * q .z;
|
|
514
|
+
float b = 2.0 * (v .x * q .x + v .y * q .y + v .z * q .z);
|
|
515
|
+
float c = 2.0 * q .w;
|
|
516
|
+
vec3 r = a * v .xyz + b * q .xyz + c * (q .yzx * v .zxy - q .zxy * v .yzx);
|
|
517
|
+
|
|
518
|
+
return r;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
mat3
|
|
522
|
+
Matrix3 (const in vec4 quaternion)
|
|
523
|
+
{
|
|
524
|
+
float x = quaternion .x;
|
|
525
|
+
float y = quaternion .y;
|
|
526
|
+
float z = quaternion .z;
|
|
527
|
+
float w = quaternion .w;
|
|
528
|
+
float A = y * y;
|
|
529
|
+
float B = z * z;
|
|
530
|
+
float C = x * y;
|
|
531
|
+
float D = z * w;
|
|
532
|
+
float E = z * x;
|
|
533
|
+
float F = y * w;
|
|
534
|
+
float G = x * x;
|
|
535
|
+
float H = y * z;
|
|
536
|
+
float I = x * w;
|
|
537
|
+
|
|
538
|
+
return mat3 (1.0 - 2.0 * (A + B),
|
|
539
|
+
2.0 * (C + D),
|
|
540
|
+
2.0 * (E - F),
|
|
541
|
+
2.0 * (C - D),
|
|
542
|
+
1.0 - 2.0 * (B + G),
|
|
543
|
+
2.0 * (H + I),
|
|
544
|
+
2.0 * (E + F),
|
|
545
|
+
2.0 * (H - I),
|
|
546
|
+
1.0 - 2.0 * (A + G));
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/* Random number generation */
|
|
550
|
+
|
|
551
|
+
uint seed = 1u;
|
|
552
|
+
|
|
553
|
+
void
|
|
554
|
+
srand (const in int value)
|
|
555
|
+
{
|
|
556
|
+
seed = uint (value);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// Return a uniform distributed random floating point number in the interval [0, 1].
|
|
560
|
+
float
|
|
561
|
+
random ()
|
|
562
|
+
{
|
|
563
|
+
seed = seed * 1103515245u + 12345u;
|
|
564
|
+
|
|
565
|
+
return float (seed) / 4294967295.0;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
float
|
|
569
|
+
getRandomValue (const in float min, const in float max)
|
|
570
|
+
{
|
|
571
|
+
return min + random () * (max - min);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
float
|
|
575
|
+
getRandomLifetime ()
|
|
576
|
+
{
|
|
577
|
+
float v = particleLifetime * lifetimeVariation;
|
|
578
|
+
float min_ = max (0.0, particleLifetime - v);
|
|
579
|
+
float max_ = particleLifetime + v;
|
|
580
|
+
|
|
581
|
+
return getRandomValue (min_, max_);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
float
|
|
585
|
+
getRandomSpeed ()
|
|
586
|
+
{
|
|
587
|
+
float v = speed * variation;
|
|
588
|
+
float min_ = max (0.0, speed - v);
|
|
589
|
+
float max_ = speed + v;
|
|
590
|
+
|
|
591
|
+
return getRandomValue (min_, max_);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
vec3
|
|
595
|
+
getRandomNormal ()
|
|
596
|
+
{
|
|
597
|
+
float theta = getRandomValue (-M_PI, M_PI);
|
|
598
|
+
float cphi = getRandomValue (-1.0, 1.0);
|
|
599
|
+
float r = sqrt (1.0 - cphi * cphi); // sin (acos (cphi));
|
|
600
|
+
|
|
601
|
+
return vec3 (sin (theta) * r, cos (theta) * r, cphi);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
vec3
|
|
605
|
+
getRandomNormalWithAngle (const in float angle)
|
|
606
|
+
{
|
|
607
|
+
float theta = getRandomValue (-M_PI, M_PI);
|
|
608
|
+
float cphi = getRandomValue (cos (angle), 1.0);
|
|
609
|
+
float r = sqrt (1.0 - cphi * cphi); // sin (acos (cphi));
|
|
610
|
+
|
|
611
|
+
return vec3 (sin (theta) * r, cos (theta) * r, cphi);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
vec3
|
|
615
|
+
getRandomNormalWithDirectionAndAngle (const in vec3 direction, const in float angle)
|
|
616
|
+
{
|
|
617
|
+
vec4 rotation = Quaternion (vec3 (0.0, 0.0, 1.0), direction);
|
|
618
|
+
vec3 normal = getRandomNormalWithAngle (angle);
|
|
619
|
+
|
|
620
|
+
return multVecQuat (normal, rotation);
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
vec3
|
|
624
|
+
getRandomSurfaceNormal (const in vec3 direction)
|
|
625
|
+
{
|
|
626
|
+
float theta = getRandomValue (-M_PI, M_PI);
|
|
627
|
+
float cphi = pow (random (), 1.0 / 3.0);
|
|
628
|
+
float r = sqrt (1.0 - cphi * cphi); // sin (acos (cphi));
|
|
629
|
+
vec3 normal = vec3 (sin (theta) * r, cos (theta) * r, cphi);
|
|
630
|
+
vec4 rotation = Quaternion (vec3 (0.0, 0.0, 1.0), direction);
|
|
631
|
+
|
|
632
|
+
return multVecQuat (normal, rotation);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
vec3
|
|
636
|
+
getRandomSphericalVelocity ()
|
|
637
|
+
{
|
|
638
|
+
vec3 normal = getRandomNormal ();
|
|
639
|
+
float speed = getRandomSpeed ();
|
|
640
|
+
|
|
641
|
+
return normal * speed;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
// Algorithms
|
|
645
|
+
|
|
646
|
+
int
|
|
647
|
+
upperBound (const in sampler2D sampler, in int count, const in float value)
|
|
648
|
+
{
|
|
649
|
+
int first = 0;
|
|
650
|
+
int step = 0;
|
|
651
|
+
|
|
652
|
+
while (count > 0)
|
|
653
|
+
{
|
|
654
|
+
int index = first;
|
|
655
|
+
|
|
656
|
+
step = count >> 1;
|
|
657
|
+
|
|
658
|
+
index += step;
|
|
659
|
+
|
|
660
|
+
if (value < texelFetch (sampler, index, 0) .x)
|
|
661
|
+
{
|
|
662
|
+
count = step;
|
|
663
|
+
}
|
|
664
|
+
else
|
|
665
|
+
{
|
|
666
|
+
first = ++ index;
|
|
667
|
+
count -= step + 1;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
return first;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
void
|
|
675
|
+
interpolate (const in sampler2D sampler, const in int count, const in float fraction, out int index0, out int index1, out float weight)
|
|
676
|
+
{
|
|
677
|
+
// Determine index0, index1 and weight.
|
|
678
|
+
|
|
679
|
+
if (count == 1 || fraction <= texelFetch (sampler, 0, 0) .x)
|
|
680
|
+
{
|
|
681
|
+
index0 = 0;
|
|
682
|
+
index1 = 0;
|
|
683
|
+
weight = 0.0;
|
|
684
|
+
}
|
|
685
|
+
else if (fraction >= texelFetch (sampler, count - 1, 0) .x)
|
|
686
|
+
{
|
|
687
|
+
index0 = count - 2;
|
|
688
|
+
index1 = count - 1;
|
|
689
|
+
weight = 1.0;
|
|
690
|
+
}
|
|
691
|
+
else
|
|
692
|
+
{
|
|
693
|
+
int index = upperBound (sampler, count, fraction);
|
|
694
|
+
|
|
695
|
+
if (index < count)
|
|
696
|
+
{
|
|
697
|
+
index1 = index;
|
|
698
|
+
index0 = index - 1;
|
|
699
|
+
|
|
700
|
+
float key0 = texelFetch (sampler, index0, 0) .x;
|
|
701
|
+
float key1 = texelFetch (sampler, index1, 0) .x;
|
|
702
|
+
|
|
703
|
+
weight = clamp ((fraction - key0) / (key1 - key0), 0.0, 1.0);
|
|
704
|
+
}
|
|
705
|
+
else
|
|
706
|
+
{
|
|
707
|
+
index0 = 0;
|
|
708
|
+
index1 = 0;
|
|
709
|
+
weight = 0.0;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
void
|
|
715
|
+
interpolate (const in sampler2D sampler, const in int count, const in float fraction, out int index0)
|
|
716
|
+
{
|
|
717
|
+
// Determine index0.
|
|
718
|
+
|
|
719
|
+
if (count == 1 || fraction <= texelFetch (sampler, 0, 0) .x)
|
|
720
|
+
{
|
|
721
|
+
index0 = 0;
|
|
722
|
+
}
|
|
723
|
+
else if (fraction >= texelFetch (sampler, count - 1, 0) .x)
|
|
724
|
+
{
|
|
725
|
+
index0 = count - 2;
|
|
726
|
+
}
|
|
727
|
+
else
|
|
728
|
+
{
|
|
729
|
+
int index = upperBound (sampler, count, fraction);
|
|
730
|
+
|
|
731
|
+
if (index < count)
|
|
732
|
+
index0 = index - 1;
|
|
733
|
+
else
|
|
734
|
+
index0 = 0;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
vec3
|
|
739
|
+
getRandomBarycentricCoord ()
|
|
740
|
+
{
|
|
741
|
+
// Random barycentric coordinates.
|
|
742
|
+
|
|
743
|
+
float u = random ();
|
|
744
|
+
float v = random ();
|
|
745
|
+
|
|
746
|
+
if (u + v > 1.0)
|
|
747
|
+
{
|
|
748
|
+
u = 1.0 - u;
|
|
749
|
+
v = 1.0 - v;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
float t = 1.0 - u - v;
|
|
753
|
+
|
|
754
|
+
return vec3 (t, u, v);
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
void
|
|
758
|
+
getRandomPointOnSurface (const in sampler2D surface, const in int verticesIndex, const in int normalsIndex, out vec4 position, out vec3 normal)
|
|
759
|
+
{
|
|
760
|
+
// Determine index0, index1 and weight.
|
|
761
|
+
|
|
762
|
+
float lastAreaSoFar = texelFetch (surface, verticesIndex - 1, 0) .x;
|
|
763
|
+
float fraction = random () * lastAreaSoFar;
|
|
764
|
+
|
|
765
|
+
int index0;
|
|
766
|
+
int index1;
|
|
767
|
+
int index2;
|
|
768
|
+
float weight;
|
|
769
|
+
|
|
770
|
+
interpolate (surface, verticesIndex, fraction, index0, index1, weight);
|
|
771
|
+
|
|
772
|
+
// Interpolate and return position.
|
|
773
|
+
|
|
774
|
+
index0 *= 3;
|
|
775
|
+
index1 = index0 + 1;
|
|
776
|
+
index2 = index0 + 2;
|
|
777
|
+
|
|
778
|
+
vec4 vertex0 = texelFetch (surface, verticesIndex + index0, 0);
|
|
779
|
+
vec4 vertex1 = texelFetch (surface, verticesIndex + index1, 0);
|
|
780
|
+
vec4 vertex2 = texelFetch (surface, verticesIndex + index2, 0);
|
|
781
|
+
|
|
782
|
+
vec3 normal0 = texelFetch (surface, normalsIndex + index0, 0) .xyz;
|
|
783
|
+
vec3 normal1 = texelFetch (surface, normalsIndex + index1, 0) .xyz;
|
|
784
|
+
vec3 normal2 = texelFetch (surface, normalsIndex + index2, 0) .xyz;
|
|
785
|
+
|
|
786
|
+
// Random barycentric coordinates.
|
|
787
|
+
|
|
788
|
+
vec3 r = getRandomBarycentricCoord ();
|
|
789
|
+
|
|
790
|
+
// Calculate position and direction.
|
|
791
|
+
|
|
792
|
+
position = r .z * vertex0 + r .x * vertex1 + r .y * vertex2;
|
|
793
|
+
normal = save_normalize (r .z * normal0 + r .x * normal1 + r .y * normal2);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
// Functions
|
|
797
|
+
|
|
798
|
+
${this .functions .join ("\n")}
|
|
799
|
+
|
|
800
|
+
// Current values
|
|
801
|
+
|
|
802
|
+
vec4
|
|
803
|
+
getColor (const in float lifetime, const in float elapsedTime)
|
|
804
|
+
{
|
|
805
|
+
if (numColors > 0)
|
|
806
|
+
{
|
|
807
|
+
// Determine index0, index1 and weight.
|
|
808
|
+
|
|
809
|
+
float fraction = elapsedTime / lifetime;
|
|
810
|
+
|
|
811
|
+
int index0;
|
|
812
|
+
int index1;
|
|
813
|
+
float weight;
|
|
814
|
+
|
|
815
|
+
interpolate (colorRamp, numColors, fraction, index0, index1, weight);
|
|
816
|
+
|
|
817
|
+
// Interpolate and return color.
|
|
818
|
+
|
|
819
|
+
vec4 color0 = texelFetch (colorRamp, numColors + index0, 0);
|
|
820
|
+
vec4 color1 = texelFetch (colorRamp, numColors + index1, 0);
|
|
821
|
+
|
|
822
|
+
return mix (color0, color1, weight);
|
|
823
|
+
}
|
|
824
|
+
else
|
|
825
|
+
{
|
|
826
|
+
return vec4 (1.0);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
void
|
|
831
|
+
bounce (const in vec4 fromPosition, inout vec4 toPosition, inout vec3 velocity)
|
|
832
|
+
{
|
|
833
|
+
if (boundedHierarchyRoot < 0)
|
|
834
|
+
return;
|
|
835
|
+
|
|
836
|
+
Line3 line = Line3 (fromPosition .xyz, save_normalize (velocity));
|
|
837
|
+
|
|
838
|
+
vec4 points [ARRAY_SIZE];
|
|
839
|
+
vec3 normals [ARRAY_SIZE];
|
|
840
|
+
|
|
841
|
+
int numIntersections = getIntersections (boundedVolume, boundedVerticesIndex, boundedNormalsIndex, boundedHierarchyIndex, boundedHierarchyRoot, line, points, normals);
|
|
842
|
+
|
|
843
|
+
if (numIntersections == 0)
|
|
844
|
+
return;
|
|
845
|
+
|
|
846
|
+
Plane3 plane1 = plane3 (line .point, line .direction);
|
|
847
|
+
|
|
848
|
+
int index = min_index (points, numIntersections, 0.0, plane1);
|
|
849
|
+
|
|
850
|
+
if (index == -1)
|
|
851
|
+
return;
|
|
852
|
+
|
|
853
|
+
Plane3 plane2 = plane3 (points [index] .xyz, normals [index]);
|
|
854
|
+
|
|
855
|
+
if (sign (plane_distance (plane2, fromPosition .xyz)) == sign (plane_distance (plane2, toPosition .xyz)))
|
|
856
|
+
return;
|
|
857
|
+
|
|
858
|
+
velocity = reflect (velocity, normals [index]);
|
|
859
|
+
toPosition = vec4 (points [index] .xyz + reflect (points [index] .xyz - fromPosition .xyz, normals [index]), 1.0);
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
int
|
|
863
|
+
getTexCoordIndex0 (const in float lifetime, const in float elapsedTime)
|
|
864
|
+
{
|
|
865
|
+
if (numTexCoords == 0)
|
|
866
|
+
{
|
|
867
|
+
return -1;
|
|
868
|
+
}
|
|
869
|
+
else
|
|
870
|
+
{
|
|
871
|
+
float fraction = elapsedTime / lifetime;
|
|
872
|
+
int index0 = 0;
|
|
192
873
|
|
|
193
|
-
|
|
194
|
-
Math .cos (theta) * r,
|
|
195
|
-
cphi);
|
|
196
|
-
},
|
|
197
|
-
getRandomNormalWithDirectionAndAngle: function (direction, angle, normal)
|
|
198
|
-
{
|
|
199
|
-
rotation .setFromToVec (Vector3 .zAxis, direction);
|
|
874
|
+
interpolate (texCoordRamp, numTexCoords, fraction, index0);
|
|
200
875
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
{
|
|
205
|
-
var
|
|
206
|
-
theta = this .getRandomValue (-1, 1) * Math .PI,
|
|
207
|
-
cphi = Math .pow (Math .random (), 1/3),
|
|
208
|
-
phi = Math .acos (cphi),
|
|
209
|
-
r = Math .sin (phi);
|
|
876
|
+
return numTexCoords + index0 * texCoordCount;
|
|
877
|
+
}
|
|
878
|
+
}
|
|
210
879
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
cphi);
|
|
214
|
-
},
|
|
215
|
-
animate: function (particleSystem, deltaTime)
|
|
216
|
-
{
|
|
217
|
-
var
|
|
218
|
-
particles = particleSystem .particles,
|
|
219
|
-
numParticles = particleSystem .numParticles,
|
|
220
|
-
createParticles = particleSystem .createParticles,
|
|
221
|
-
particleLifetime = particleSystem .particleLifetime,
|
|
222
|
-
lifetimeVariation = particleSystem .lifetimeVariation,
|
|
223
|
-
speeds = particleSystem .speeds, // speed of velocities
|
|
224
|
-
velocities = particleSystem .velocities, // resulting velocities from forces
|
|
225
|
-
turbulences = particleSystem .turbulences, // turbulences
|
|
226
|
-
rotations = this .rotations, // rotation to direction of force
|
|
227
|
-
numForces = particleSystem .numForces, // number of forces
|
|
228
|
-
boundedPhysics = particleSystem .boundedVertices .length,
|
|
229
|
-
boundedVolume = particleSystem .boundedVolume;
|
|
230
|
-
|
|
231
|
-
for (var i = rotations .length; i < numForces; ++ i)
|
|
232
|
-
rotations [i] = new Rotation4 (0, 0, 1, 0);
|
|
233
|
-
|
|
234
|
-
for (var i = 0; i < numForces; ++ i)
|
|
235
|
-
rotations [i] .setFromToVec (Vector3 .zAxis, velocities [i]);
|
|
236
|
-
|
|
237
|
-
for (var i = 0; i < numParticles; ++ i)
|
|
880
|
+
void
|
|
881
|
+
main ()
|
|
238
882
|
{
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
883
|
+
int life = int (input0 [0]);
|
|
884
|
+
float lifetime = input0 [1];
|
|
885
|
+
float elapsedTime = input0 [2] + deltaTime;
|
|
886
|
+
|
|
887
|
+
srand ((gl_VertexID + randomSeed) * randomSeed);
|
|
242
888
|
|
|
243
|
-
if (elapsedTime >
|
|
889
|
+
if (elapsedTime > lifetime)
|
|
244
890
|
{
|
|
245
891
|
// Create new particle or hide particle.
|
|
246
892
|
|
|
247
|
-
|
|
248
|
-
|
|
893
|
+
lifetime = getRandomLifetime ();
|
|
894
|
+
elapsedTime = 0.0;
|
|
895
|
+
|
|
896
|
+
output0 = vec4 (max (life + 1, 1), lifetime, elapsedTime, getTexCoordIndex0 (lifetime, elapsedTime));
|
|
249
897
|
|
|
250
898
|
if (createParticles)
|
|
251
899
|
{
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
900
|
+
output1 = getColor (lifetime, elapsedTime);
|
|
901
|
+
output2 = vec4 (getRandomVelocity (), 0.0);
|
|
902
|
+
output6 = getRandomPosition ();
|
|
255
903
|
}
|
|
256
904
|
else
|
|
257
|
-
|
|
905
|
+
{
|
|
906
|
+
output1 = vec4 (0.0);
|
|
907
|
+
output2 = vec4 (0.0);
|
|
908
|
+
output6 = vec4 (NaN);
|
|
909
|
+
}
|
|
258
910
|
}
|
|
259
911
|
else
|
|
260
912
|
{
|
|
261
913
|
// Animate particle.
|
|
262
914
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
velocity = particle .velocity;
|
|
915
|
+
vec3 velocity = input2 .xyz;
|
|
916
|
+
vec4 position = input6;
|
|
266
917
|
|
|
267
|
-
for (
|
|
918
|
+
for (int i = 0; i < numForces; ++ i)
|
|
268
919
|
{
|
|
269
|
-
|
|
920
|
+
vec4 force = texelFetch (forces, i, 0);
|
|
921
|
+
float turbulence = force .w;
|
|
922
|
+
vec3 normal = getRandomNormalWithDirectionAndAngle (force .xyz, turbulence);
|
|
923
|
+
float speed = length (force .xyz);
|
|
924
|
+
|
|
925
|
+
velocity += normal * speed;
|
|
270
926
|
}
|
|
271
927
|
|
|
272
|
-
|
|
273
|
-
{
|
|
274
|
-
fromPosition .x = position .x;
|
|
275
|
-
fromPosition .y = position .y;
|
|
276
|
-
fromPosition .z = position .z;
|
|
928
|
+
position .xyz += velocity * deltaTime;
|
|
277
929
|
|
|
278
|
-
|
|
279
|
-
position .y += velocity .y * deltaTime;
|
|
280
|
-
position .z += velocity .z * deltaTime;
|
|
930
|
+
bounce (input6, position, velocity);
|
|
281
931
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
932
|
+
output0 = vec4 (life, lifetime, elapsedTime, getTexCoordIndex0 (lifetime, elapsedTime));
|
|
933
|
+
output1 = getColor (lifetime, elapsedTime);
|
|
934
|
+
output2 = vec4 (velocity, 0.0);
|
|
935
|
+
output6 = position;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
switch (geometryType)
|
|
939
|
+
{
|
|
940
|
+
case POINT:
|
|
941
|
+
case SPRITE:
|
|
942
|
+
case GEOMETRY:
|
|
285
943
|
{
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
944
|
+
output3 = vec4 (1.0, 0.0, 0.0, 0.0);
|
|
945
|
+
output4 = vec4 (0.0, 1.0, 0.0, 0.0);
|
|
946
|
+
output5 = vec4 (0.0, 0.0, 1.0, 0.0);
|
|
947
|
+
break;
|
|
289
948
|
}
|
|
949
|
+
case LINE:
|
|
950
|
+
{
|
|
951
|
+
mat3 r = Matrix3 (Quaternion (vec3 (0.0, 0.0, 1.0), output2 .xyz));
|
|
952
|
+
mat3 s = mat3 (1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, particleSize .y);
|
|
953
|
+
mat3 m = r * s;
|
|
290
954
|
|
|
291
|
-
|
|
955
|
+
output3 = vec4 (m [0], 0.0);
|
|
956
|
+
output4 = vec4 (m [1], 0.0);
|
|
957
|
+
output5 = vec4 (m [2], 0.0);
|
|
958
|
+
break;
|
|
959
|
+
}
|
|
960
|
+
default: // QUAD, TRIANGLE
|
|
961
|
+
{
|
|
962
|
+
output3 = vec4 (particleSize .x, 0.0, 0.0, 0.0);
|
|
963
|
+
output4 = vec4 (0.0, particleSize .y, 0.0, 0.0);
|
|
964
|
+
output5 = vec4 (0.0, 0.0, 1.0, 0.0);
|
|
965
|
+
break;
|
|
966
|
+
}
|
|
292
967
|
}
|
|
293
968
|
}
|
|
969
|
+
`;
|
|
294
970
|
|
|
295
|
-
|
|
971
|
+
const fragmentShaderSource = /* glsl */ `#version 300 es
|
|
296
972
|
|
|
297
|
-
|
|
298
|
-
this .getColors (particles, particleSystem .colorKeys, particleSystem .colorRamp, numParticles);
|
|
299
|
-
},
|
|
300
|
-
bounce: function (boundedVolume, fromPosition, toPosition, velocity)
|
|
301
|
-
{
|
|
302
|
-
normal .assign (velocity) .normalize ();
|
|
973
|
+
precision highp float;
|
|
303
974
|
|
|
304
|
-
|
|
975
|
+
void
|
|
976
|
+
main () { }
|
|
977
|
+
`;
|
|
305
978
|
|
|
306
|
-
|
|
307
|
-
intersections = this .intersections,
|
|
308
|
-
intersectionNormals = this .intersectionNormals,
|
|
309
|
-
numIntersections = boundedVolume .intersectsLine (line, intersections, intersectionNormals);
|
|
979
|
+
// Vertex shader
|
|
310
980
|
|
|
311
|
-
|
|
312
|
-
{
|
|
313
|
-
for (var i = 0; i < numIntersections; ++ i)
|
|
314
|
-
intersections [i] .index = i;
|
|
981
|
+
const vertexShader = gl .createShader (gl .VERTEX_SHADER);
|
|
315
982
|
|
|
316
|
-
|
|
983
|
+
gl .shaderSource (vertexShader, vertexShaderSource);
|
|
984
|
+
gl .compileShader (vertexShader);
|
|
317
985
|
|
|
318
|
-
|
|
986
|
+
// Fragment shader
|
|
319
987
|
|
|
320
|
-
|
|
988
|
+
const fragmentShader = gl .createShader (gl .FRAGMENT_SHADER);
|
|
321
989
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
var
|
|
325
|
-
intersection = intersections [index],
|
|
326
|
-
intersectionNormal = intersectionNormals [intersection .index];
|
|
990
|
+
gl .shaderSource (fragmentShader, fragmentShaderSource);
|
|
991
|
+
gl .compileShader (fragmentShader);
|
|
327
992
|
|
|
328
|
-
|
|
993
|
+
// Program
|
|
329
994
|
|
|
330
|
-
|
|
331
|
-
{
|
|
332
|
-
var dot2 = 2 * intersectionNormal .dot (velocity);
|
|
995
|
+
const program = gl .createProgram ();
|
|
333
996
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
997
|
+
gl .attachShader (program, vertexShader);
|
|
998
|
+
gl .attachShader (program, fragmentShader);
|
|
999
|
+
gl .transformFeedbackVaryings (program, Array .from ({length: 7}, (_, i) => "output" + i), gl .INTERLEAVED_ATTRIBS);
|
|
1000
|
+
gl .linkProgram (program);
|
|
337
1001
|
|
|
338
|
-
|
|
1002
|
+
if (!gl .getProgramParameter (program, gl .LINK_STATUS))
|
|
1003
|
+
console .error ("Couldn't initialize particle shader: " + gl .getProgramInfoLog (program));
|
|
339
1004
|
|
|
340
|
-
|
|
1005
|
+
program .inputs = [
|
|
1006
|
+
[0, gl .getAttribLocation (program, "input0")],
|
|
1007
|
+
[2, gl .getAttribLocation (program, "input2")],
|
|
1008
|
+
[6, gl .getAttribLocation (program, "input6")],
|
|
1009
|
+
];
|
|
341
1010
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
getColors: function (particles, colorKeys, colorRamp, numParticles)
|
|
350
|
-
{
|
|
351
|
-
var
|
|
352
|
-
length = colorKeys .length,
|
|
353
|
-
index0 = 0,
|
|
354
|
-
index1 = 0,
|
|
355
|
-
weight = 0;
|
|
1011
|
+
program .randomSeed = gl .getUniformLocation (program, "randomSeed");
|
|
1012
|
+
program .geometryType = gl .getUniformLocation (program, "geometryType");
|
|
1013
|
+
program .createParticles = gl .getUniformLocation (program, "createParticles");
|
|
1014
|
+
program .particleLifetime = gl .getUniformLocation (program, "particleLifetime");
|
|
1015
|
+
program .lifetimeVariation = gl .getUniformLocation (program, "lifetimeVariation");
|
|
1016
|
+
program .deltaTime = gl .getUniformLocation (program, "deltaTime");
|
|
1017
|
+
program .particleSize = gl .getUniformLocation (program, "particleSize");
|
|
356
1018
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
// Determine index0, index1 and weight.
|
|
1019
|
+
program .numForces = gl .getUniformLocation (program, "numForces");
|
|
1020
|
+
program .forces = gl .getUniformLocation (program, "forces");
|
|
360
1021
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
1022
|
+
program .boundedVerticesIndex = gl .getUniformLocation (program, "boundedVerticesIndex");
|
|
1023
|
+
program .boundedNormalsIndex = gl .getUniformLocation (program, "boundedNormalsIndex");
|
|
1024
|
+
program .boundedHierarchyIndex = gl .getUniformLocation (program, "boundedHierarchyIndex");
|
|
1025
|
+
program .boundedHierarchyRoot = gl .getUniformLocation (program, "boundedHierarchyRoot");
|
|
1026
|
+
program .boundedVolume = gl .getUniformLocation (program, "boundedVolume");
|
|
365
1027
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
index0 = 0;
|
|
369
|
-
index1 = 0;
|
|
370
|
-
weight = 0;
|
|
371
|
-
}
|
|
372
|
-
else if (fraction >= colorKeys [length - 1])
|
|
373
|
-
{
|
|
374
|
-
index0 = length - 2;
|
|
375
|
-
index1 = length - 1;
|
|
376
|
-
weight = 1;
|
|
377
|
-
}
|
|
378
|
-
else
|
|
379
|
-
{
|
|
380
|
-
var index = Algorithm .upperBound (colorKeys, 0, length, fraction, Algorithm .less);
|
|
1028
|
+
program .numColors = gl .getUniformLocation (program, "numColors");
|
|
1029
|
+
program .colorRamp = gl .getUniformLocation (program, "colorRamp");
|
|
381
1030
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
index0 = index - 1;
|
|
1031
|
+
program .texCoordCount = gl .getUniformLocation (program, "texCoordCount");
|
|
1032
|
+
program .numTexCoords = gl .getUniformLocation (program, "numTexCoords");
|
|
1033
|
+
program .texCoordRamp = gl .getUniformLocation (program, "texCoordRamp");
|
|
386
1034
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
key1 = colorKeys [index1];
|
|
1035
|
+
for (const name of Object .keys (this .uniforms))
|
|
1036
|
+
program [name] = gl .getUniformLocation (program, name);
|
|
390
1037
|
|
|
391
|
-
|
|
392
|
-
}
|
|
393
|
-
else
|
|
394
|
-
{
|
|
395
|
-
index0 = 0;
|
|
396
|
-
index1 = 0;
|
|
397
|
-
weight = 0;
|
|
398
|
-
}
|
|
399
|
-
}
|
|
1038
|
+
program .NaN = gl .getUniformLocation (program, "NaN");
|
|
400
1039
|
|
|
401
|
-
|
|
1040
|
+
gl .useProgram (program);
|
|
402
1041
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
1042
|
+
for (const name of this .samplers)
|
|
1043
|
+
{
|
|
1044
|
+
const location = gl .getUniformLocation (program, name);
|
|
406
1045
|
|
|
407
|
-
|
|
408
|
-
color .x = color0 .x + weight * (color1 .x - color0 .x);
|
|
409
|
-
color .y = color0 .y + weight * (color1 .y - color0 .y);
|
|
410
|
-
color .z = color0 .z + weight * (color1 .z - color0 .z);
|
|
411
|
-
color .w = color0 .w + weight * (color1 .w - color0 .w);
|
|
1046
|
+
gl .uniform1i (location, program [name + "TextureUnit"] = browser .getTexture2DUnit ());
|
|
412
1047
|
}
|
|
1048
|
+
|
|
1049
|
+
gl .uniform1f (program .NaN, NaN);
|
|
1050
|
+
|
|
1051
|
+
browser .resetTextureUnits ();
|
|
1052
|
+
|
|
1053
|
+
return program;
|
|
1054
|
+
},
|
|
1055
|
+
activateTextures: function ()
|
|
1056
|
+
{ },
|
|
1057
|
+
createTexture: function ()
|
|
1058
|
+
{
|
|
1059
|
+
const
|
|
1060
|
+
gl = this .getBrowser () .getContext (),
|
|
1061
|
+
texture = gl .createTexture ();
|
|
1062
|
+
|
|
1063
|
+
gl .bindTexture (gl .TEXTURE_2D, texture);
|
|
1064
|
+
|
|
1065
|
+
gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_WRAP_S, gl .CLAMP_TO_EDGE);
|
|
1066
|
+
gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_WRAP_T, gl .CLAMP_TO_EDGE);
|
|
1067
|
+
gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_MAG_FILTER, gl .NEAREST);
|
|
1068
|
+
gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_MIN_FILTER, gl .NEAREST);
|
|
1069
|
+
|
|
1070
|
+
gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, 1, 1, 0, gl .RGBA, gl .FLOAT, new Float32Array (4));
|
|
1071
|
+
|
|
1072
|
+
return texture;
|
|
1073
|
+
},
|
|
1074
|
+
getTexture2DUnit: function (browser, object, property)
|
|
1075
|
+
{
|
|
1076
|
+
const textureUnit = object [property];
|
|
1077
|
+
|
|
1078
|
+
if (textureUnit === undefined)
|
|
1079
|
+
return object [property] = browser .getTexture2DUnit ();
|
|
1080
|
+
|
|
1081
|
+
return textureUnit;
|
|
413
1082
|
},
|
|
414
1083
|
});
|
|
415
1084
|
|
|
@@ -488,25 +1157,38 @@ function (Fields,
|
|
|
488
1157
|
|
|
489
1158
|
this .addType (X3DConstants .PointEmitter);
|
|
490
1159
|
|
|
491
|
-
this ._position
|
|
492
|
-
|
|
493
|
-
this .
|
|
494
|
-
this .
|
|
1160
|
+
this ._position .setUnit ("length");
|
|
1161
|
+
|
|
1162
|
+
this .addUniform ("position", "uniform vec3 position;");
|
|
1163
|
+
this .addUniform ("direction", "uniform vec3 direction;");
|
|
1164
|
+
|
|
1165
|
+
this .addFunction (/* glsl */ `vec3 getRandomVelocity ()
|
|
1166
|
+
{
|
|
1167
|
+
if (direction == vec3 (0.0))
|
|
1168
|
+
return getRandomSphericalVelocity ();
|
|
495
1169
|
|
|
496
|
-
|
|
1170
|
+
else
|
|
1171
|
+
return direction * getRandomSpeed ();
|
|
1172
|
+
}`);
|
|
1173
|
+
|
|
1174
|
+
this .addFunction (/* glsl */ `vec4 getRandomPosition ()
|
|
1175
|
+
{
|
|
1176
|
+
return vec4 (position, 1.0);
|
|
1177
|
+
}`);
|
|
497
1178
|
}
|
|
498
1179
|
|
|
499
1180
|
PointEmitter .prototype = Object .assign (Object .create (X3DParticleEmitterNode .prototype),
|
|
500
1181
|
{
|
|
501
1182
|
constructor: PointEmitter,
|
|
502
1183
|
[Symbol .for ("X_ITE.X3DBaseNode.fieldDefinitions")]: new FieldDefinitionArray ([
|
|
503
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
504
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
505
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
506
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
507
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
508
|
-
new X3DFieldDefinition (X3DConstants .
|
|
509
|
-
new X3DFieldDefinition (X3DConstants .
|
|
1184
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "metadata", new Fields .SFNode ()),
|
|
1185
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "on", new Fields .SFBool (true)),
|
|
1186
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "position", new Fields .SFVec3f ()),
|
|
1187
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "direction", new Fields .SFVec3f (0, 1, 0)),
|
|
1188
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "speed", new Fields .SFFloat ()),
|
|
1189
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "variation", new Fields .SFFloat (0.25)),
|
|
1190
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "mass", new Fields .SFFloat ()),
|
|
1191
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "surfaceArea", new Fields .SFFloat ()),
|
|
510
1192
|
]),
|
|
511
1193
|
getTypeName: function ()
|
|
512
1194
|
{
|
|
@@ -524,7 +1206,10 @@ function (Fields,
|
|
|
524
1206
|
{
|
|
525
1207
|
X3DParticleEmitterNode .prototype .initialize .call (this);
|
|
526
1208
|
|
|
527
|
-
this .
|
|
1209
|
+
if (this .getBrowser () .getContext () .getVersion () < 2)
|
|
1210
|
+
return;
|
|
1211
|
+
|
|
1212
|
+
this ._position .addInterest ("set_position__", this);
|
|
528
1213
|
this ._direction .addInterest ("set_direction__", this);
|
|
529
1214
|
|
|
530
1215
|
this .set_position__ ();
|
|
@@ -532,33 +1217,21 @@ function (Fields,
|
|
|
532
1217
|
},
|
|
533
1218
|
set_position__: function ()
|
|
534
1219
|
{
|
|
535
|
-
|
|
536
|
-
},
|
|
537
|
-
set_direction__: function ()
|
|
538
|
-
{
|
|
539
|
-
this .direction .assign (this ._direction .getValue ()) .normalize ();
|
|
1220
|
+
const position = this ._position .getValue ();
|
|
540
1221
|
|
|
541
|
-
|
|
542
|
-
this .getRandomVelocity = this .getSphericalRandomVelocity;
|
|
543
|
-
else
|
|
544
|
-
delete this .getRandomVelocity;
|
|
545
|
-
},
|
|
546
|
-
getRandomPosition: function (position)
|
|
547
|
-
{
|
|
548
|
-
return position .assign (this .position);
|
|
1222
|
+
this .setUniform ("uniform3f", "position", position .x, position .y, position .z);
|
|
549
1223
|
},
|
|
550
|
-
|
|
1224
|
+
set_direction__: (function ()
|
|
551
1225
|
{
|
|
552
|
-
|
|
553
|
-
direction = this .direction,
|
|
554
|
-
speed = this .getRandomSpeed ();
|
|
1226
|
+
const direction = new Vector3 (0, 0, 0);
|
|
555
1227
|
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
1228
|
+
return function ()
|
|
1229
|
+
{
|
|
1230
|
+
direction .assign (this ._direction .getValue ()) .normalize ();
|
|
559
1231
|
|
|
560
|
-
|
|
561
|
-
|
|
1232
|
+
this .setUniform ("uniform3f", "direction", direction .x, direction .y, direction .z);
|
|
1233
|
+
};
|
|
1234
|
+
})(),
|
|
562
1235
|
});
|
|
563
1236
|
|
|
564
1237
|
return PointEmitter;
|
|
@@ -830,17 +1503,17 @@ function (Fields,
|
|
|
830
1503
|
},
|
|
831
1504
|
addGeometry: function (boundedNormals, boundedVertices)
|
|
832
1505
|
{
|
|
833
|
-
if (this .geometryNode)
|
|
1506
|
+
if (this .geometryNode && this ._enabled .getValue ())
|
|
834
1507
|
{
|
|
835
|
-
|
|
1508
|
+
const
|
|
836
1509
|
normals = this .geometryNode .getNormals () .getValue (),
|
|
837
1510
|
vertices = this .geometryNode .getVertices () .getValue ();
|
|
838
1511
|
|
|
839
|
-
for (
|
|
840
|
-
boundedNormals .push (
|
|
1512
|
+
for (const value of normals)
|
|
1513
|
+
boundedNormals .push (value);
|
|
841
1514
|
|
|
842
|
-
for (
|
|
843
|
-
boundedVertices .push (
|
|
1515
|
+
for (const value of vertices)
|
|
1516
|
+
boundedVertices .push (value);
|
|
844
1517
|
}
|
|
845
1518
|
},
|
|
846
1519
|
});
|
|
@@ -903,16 +1576,12 @@ define ('x_ite/Components/ParticleSystems/ConeEmitter',[
|
|
|
903
1576
|
"x_ite/Base/FieldDefinitionArray",
|
|
904
1577
|
"x_ite/Components/ParticleSystems/X3DParticleEmitterNode",
|
|
905
1578
|
"x_ite/Base/X3DConstants",
|
|
906
|
-
"standard/Math/Numbers/Vector3",
|
|
907
|
-
"standard/Math/Numbers/Rotation4",
|
|
908
1579
|
],
|
|
909
1580
|
function (Fields,
|
|
910
1581
|
X3DFieldDefinition,
|
|
911
1582
|
FieldDefinitionArray,
|
|
912
1583
|
X3DParticleEmitterNode,
|
|
913
|
-
X3DConstants
|
|
914
|
-
Vector3,
|
|
915
|
-
Rotation4)
|
|
1584
|
+
X3DConstants)
|
|
916
1585
|
{
|
|
917
1586
|
"use strict";
|
|
918
1587
|
|
|
@@ -922,27 +1591,47 @@ function (Fields,
|
|
|
922
1591
|
|
|
923
1592
|
this .addType (X3DConstants .ConeEmitter);
|
|
924
1593
|
|
|
925
|
-
this ._position
|
|
926
|
-
this ._angle
|
|
927
|
-
|
|
928
|
-
this .
|
|
929
|
-
this .
|
|
1594
|
+
this ._position .setUnit ("length");
|
|
1595
|
+
this ._angle .setUnit ("angle");
|
|
1596
|
+
|
|
1597
|
+
this .addUniform ("position", "uniform vec3 position;");
|
|
1598
|
+
this .addUniform ("direction", "uniform vec3 direction;");
|
|
1599
|
+
this .addUniform ("angle", "uniform float angle;");
|
|
1600
|
+
|
|
1601
|
+
this .addFunction (/* glsl */ `vec3 getRandomVelocity ()
|
|
1602
|
+
{
|
|
1603
|
+
if (direction == vec3 (0.0))
|
|
1604
|
+
{
|
|
1605
|
+
return getRandomSphericalVelocity ();
|
|
1606
|
+
}
|
|
1607
|
+
else
|
|
1608
|
+
{
|
|
1609
|
+
vec3 normal = getRandomNormalWithDirectionAndAngle (direction, angle);
|
|
1610
|
+
float speed = getRandomSpeed ();
|
|
1611
|
+
|
|
1612
|
+
return normal * speed;
|
|
1613
|
+
}
|
|
1614
|
+
}`);
|
|
930
1615
|
|
|
931
|
-
this .
|
|
1616
|
+
this .addFunction (/* glsl */ `vec4 getRandomPosition ()
|
|
1617
|
+
{
|
|
1618
|
+
return vec4 (position, 1.0);
|
|
1619
|
+
}`);
|
|
932
1620
|
}
|
|
933
1621
|
|
|
934
1622
|
ConeEmitter .prototype = Object .assign (Object .create (X3DParticleEmitterNode .prototype),
|
|
935
1623
|
{
|
|
936
1624
|
constructor: ConeEmitter,
|
|
937
1625
|
[Symbol .for ("X_ITE.X3DBaseNode.fieldDefinitions")]: new FieldDefinitionArray ([
|
|
938
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
939
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
940
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
941
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
942
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
943
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
944
|
-
new X3DFieldDefinition (X3DConstants .
|
|
945
|
-
new X3DFieldDefinition (X3DConstants .
|
|
1626
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "metadata", new Fields .SFNode ()),
|
|
1627
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "on", new Fields .SFBool (true)),
|
|
1628
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "position", new Fields .SFVec3f ()),
|
|
1629
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "direction", new Fields .SFVec3f (0, 1, 0)),
|
|
1630
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "angle", new Fields .SFFloat (0.7854)),
|
|
1631
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "speed", new Fields .SFFloat ()),
|
|
1632
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "variation", new Fields .SFFloat (0.25)),
|
|
1633
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "mass", new Fields .SFFloat ()),
|
|
1634
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "surfaceArea", new Fields .SFFloat ()),
|
|
946
1635
|
]),
|
|
947
1636
|
getTypeName: function ()
|
|
948
1637
|
{
|
|
@@ -960,6 +1649,9 @@ function (Fields,
|
|
|
960
1649
|
{
|
|
961
1650
|
X3DParticleEmitterNode .prototype .initialize .call (this);
|
|
962
1651
|
|
|
1652
|
+
if (this .getBrowser () .getContext () .getVersion () < 2)
|
|
1653
|
+
return;
|
|
1654
|
+
|
|
963
1655
|
this ._position .addInterest ("set_position__", this);
|
|
964
1656
|
this ._direction .addInterest ("set_direction__", this);
|
|
965
1657
|
this ._angle .addInterest ("set_angle__", this);
|
|
@@ -970,31 +1662,20 @@ function (Fields,
|
|
|
970
1662
|
},
|
|
971
1663
|
set_position__: function ()
|
|
972
1664
|
{
|
|
973
|
-
|
|
1665
|
+
const position = this ._position .getValue ();
|
|
1666
|
+
|
|
1667
|
+
this .setUniform ("uniform3f", "position", position .x, position .y, position .z);
|
|
974
1668
|
},
|
|
975
1669
|
set_direction__: function ()
|
|
976
1670
|
{
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
this .rotation .setFromToVec (Vector3 .zAxis, direction);
|
|
1671
|
+
const direction = this ._direction .getValue ();
|
|
980
1672
|
|
|
981
|
-
|
|
982
|
-
this .getRandomVelocity = this .getSphericalRandomVelocity;
|
|
983
|
-
else
|
|
984
|
-
delete this .getRandomVelocity;
|
|
1673
|
+
this .setUniform ("uniform3f", "direction", direction .x, direction .y, direction .z);
|
|
985
1674
|
},
|
|
986
1675
|
set_angle__: function ()
|
|
987
1676
|
{
|
|
988
|
-
this .angle
|
|
989
|
-
},
|
|
990
|
-
getRandomPosition: function (position)
|
|
991
|
-
{
|
|
992
|
-
return position .assign (this .position);
|
|
1677
|
+
this .setUniform ("uniform1f", "angle", this ._angle .getValue ());
|
|
993
1678
|
},
|
|
994
|
-
getRandomVelocity: function (velocity)
|
|
995
|
-
{
|
|
996
|
-
return this .rotation .multVecRot (this .getRandomNormalWithAngle (this .angle, velocity) .multiply (this .getRandomSpeed ()));
|
|
997
|
-
},
|
|
998
1679
|
});
|
|
999
1680
|
|
|
1000
1681
|
return ConeEmitter;
|
|
@@ -1070,24 +1751,32 @@ function (Fields,
|
|
|
1070
1751
|
|
|
1071
1752
|
this .addType (X3DConstants .ExplosionEmitter);
|
|
1072
1753
|
|
|
1073
|
-
this ._position
|
|
1074
|
-
this ._speed .setUnit ("speed");
|
|
1075
|
-
this ._mass .setUnit ("mass");
|
|
1076
|
-
this ._surfaceArea .setUnit ("area");
|
|
1754
|
+
this ._position .setUnit ("length");
|
|
1077
1755
|
|
|
1078
|
-
this .
|
|
1756
|
+
this .addUniform ("position", "uniform vec3 position;");
|
|
1757
|
+
|
|
1758
|
+
this .addFunction (/* glsl */ `vec3 getRandomVelocity ()
|
|
1759
|
+
{
|
|
1760
|
+
return getRandomSphericalVelocity ();
|
|
1761
|
+
}`);
|
|
1762
|
+
|
|
1763
|
+
this .addFunction (/* glsl */ `vec4 getRandomPosition ()
|
|
1764
|
+
{
|
|
1765
|
+
return vec4 (position, 1.0);
|
|
1766
|
+
}`);
|
|
1079
1767
|
}
|
|
1080
1768
|
|
|
1081
1769
|
ExplosionEmitter .prototype = Object .assign (Object .create (X3DParticleEmitterNode .prototype),
|
|
1082
1770
|
{
|
|
1083
1771
|
constructor: ExplosionEmitter,
|
|
1084
1772
|
[Symbol .for ("X_ITE.X3DBaseNode.fieldDefinitions")]: new FieldDefinitionArray ([
|
|
1085
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
1086
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
1087
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
1088
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
1089
|
-
new X3DFieldDefinition (X3DConstants .
|
|
1090
|
-
new X3DFieldDefinition (X3DConstants .
|
|
1773
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "metadata", new Fields .SFNode ()),
|
|
1774
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "on", new Fields .SFBool (true)),
|
|
1775
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "position", new Fields .SFVec3f ()),
|
|
1776
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "speed", new Fields .SFFloat ()),
|
|
1777
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "variation", new Fields .SFFloat (0.25)),
|
|
1778
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "mass", new Fields .SFFloat ()),
|
|
1779
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "surfaceArea", new Fields .SFFloat ()),
|
|
1091
1780
|
]),
|
|
1092
1781
|
getTypeName: function ()
|
|
1093
1782
|
{
|
|
@@ -1105,21 +1794,22 @@ function (Fields,
|
|
|
1105
1794
|
{
|
|
1106
1795
|
X3DParticleEmitterNode .prototype .initialize .call (this);
|
|
1107
1796
|
|
|
1797
|
+
if (this .getBrowser () .getContext () .getVersion () < 2)
|
|
1798
|
+
return;
|
|
1799
|
+
|
|
1108
1800
|
this ._position .addInterest ("set_position__", this);
|
|
1109
1801
|
|
|
1110
1802
|
this .set_position__ ();
|
|
1111
1803
|
},
|
|
1112
|
-
set_position__: function ()
|
|
1113
|
-
{
|
|
1114
|
-
this .position = this ._position .getValue ()
|
|
1115
|
-
},
|
|
1116
1804
|
isExplosive: function ()
|
|
1117
1805
|
{
|
|
1118
1806
|
return true;
|
|
1119
1807
|
},
|
|
1120
|
-
|
|
1808
|
+
set_position__: function ()
|
|
1121
1809
|
{
|
|
1122
|
-
|
|
1810
|
+
const position = this ._position .getValue ();
|
|
1811
|
+
|
|
1812
|
+
this .setUniform ("uniform3f", "position", position .x, position .y, position .z);
|
|
1123
1813
|
},
|
|
1124
1814
|
});
|
|
1125
1815
|
|
|
@@ -1181,12 +1871,14 @@ define ('x_ite/Components/ParticleSystems/ForcePhysicsModel',[
|
|
|
1181
1871
|
"x_ite/Base/FieldDefinitionArray",
|
|
1182
1872
|
"x_ite/Components/ParticleSystems/X3DParticlePhysicsModelNode",
|
|
1183
1873
|
"x_ite/Base/X3DConstants",
|
|
1874
|
+
"standard/Math/Numbers/Vector3",
|
|
1184
1875
|
],
|
|
1185
1876
|
function (Fields,
|
|
1186
1877
|
X3DFieldDefinition,
|
|
1187
1878
|
FieldDefinitionArray,
|
|
1188
1879
|
X3DParticlePhysicsModelNode,
|
|
1189
|
-
X3DConstants
|
|
1880
|
+
X3DConstants,
|
|
1881
|
+
Vector3)
|
|
1190
1882
|
{
|
|
1191
1883
|
"use strict";
|
|
1192
1884
|
|
|
@@ -1219,14 +1911,25 @@ function (Fields,
|
|
|
1219
1911
|
{
|
|
1220
1912
|
return "physics";
|
|
1221
1913
|
},
|
|
1222
|
-
addForce: function (
|
|
1914
|
+
addForce: (function ()
|
|
1223
1915
|
{
|
|
1224
|
-
|
|
1916
|
+
const force = new Vector3 (0, 0, 0);
|
|
1917
|
+
|
|
1918
|
+
return function (i, emitterNode, timeByMass, forces)
|
|
1225
1919
|
{
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1920
|
+
if (this ._enabled .getValue ())
|
|
1921
|
+
{
|
|
1922
|
+
forces .set (force .assign (this ._force .getValue ()) .multiply (timeByMass), i * 4);
|
|
1923
|
+
forces [i * 4 + 3] = 0;
|
|
1924
|
+
|
|
1925
|
+
return true;
|
|
1926
|
+
}
|
|
1927
|
+
else
|
|
1928
|
+
{
|
|
1929
|
+
return false;
|
|
1930
|
+
}
|
|
1931
|
+
};
|
|
1932
|
+
})(),
|
|
1230
1933
|
});
|
|
1231
1934
|
|
|
1232
1935
|
return ForcePhysicsModel;
|
|
@@ -1308,28 +2011,24 @@ function (Vector3,
|
|
|
1308
2011
|
// left: We do not have to test for left.
|
|
1309
2012
|
];
|
|
1310
2013
|
|
|
2014
|
+
const
|
|
2015
|
+
NODE = 0,
|
|
2016
|
+
TRIANGLE = 1;
|
|
2017
|
+
|
|
1311
2018
|
function SortComparator (vertices, axis)
|
|
1312
2019
|
{
|
|
1313
|
-
function compare (a, b)
|
|
2020
|
+
return function compare (a, b)
|
|
1314
2021
|
{
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
axis = compare .axis;
|
|
1318
|
-
|
|
1319
|
-
return Math .min (vertices [a + axis], vertices [a + 4 + axis], vertices [a + 8 + axis]) <
|
|
1320
|
-
Math .min (vertices [b + axis], vertices [b + 4 + axis], vertices [b + 8 + axis]);
|
|
2022
|
+
return Math .min (vertices [a + axis], vertices [a + 4 + axis], vertices [a + 8 + axis]) <
|
|
2023
|
+
Math .min (vertices [b + axis], vertices [b + 4 + axis], vertices [b + 8 + axis]);
|
|
1321
2024
|
}
|
|
1322
|
-
|
|
1323
|
-
compare .vertices = vertices;
|
|
1324
|
-
compare .axis = axis;
|
|
1325
|
-
|
|
1326
|
-
return compare;
|
|
1327
2025
|
}
|
|
1328
2026
|
|
|
1329
2027
|
function Triangle (tree, triangle)
|
|
1330
2028
|
{
|
|
1331
2029
|
this .vertices = tree .vertices;
|
|
1332
2030
|
this .normals = tree .normals;
|
|
2031
|
+
this .triangle = triangle;
|
|
1333
2032
|
this .i4 = triangle * 12;
|
|
1334
2033
|
this .i3 = triangle * 9;
|
|
1335
2034
|
}
|
|
@@ -1379,6 +2078,14 @@ function (Vector3,
|
|
|
1379
2078
|
}
|
|
1380
2079
|
}
|
|
1381
2080
|
},
|
|
2081
|
+
toArray: function (array)
|
|
2082
|
+
{
|
|
2083
|
+
const index = array .length / 4;
|
|
2084
|
+
|
|
2085
|
+
array .push (TRIANGLE, this .triangle * 3, 0, 0);
|
|
2086
|
+
|
|
2087
|
+
return index;
|
|
2088
|
+
},
|
|
1382
2089
|
};
|
|
1383
2090
|
|
|
1384
2091
|
function Node (tree, triangles, first, size)
|
|
@@ -1537,15 +2244,30 @@ function (Vector3,
|
|
|
1537
2244
|
return 0;
|
|
1538
2245
|
}
|
|
1539
2246
|
},
|
|
2247
|
+
toArray: function (array)
|
|
2248
|
+
{
|
|
2249
|
+
const
|
|
2250
|
+
left = this .left .toArray (array),
|
|
2251
|
+
right = this .right .toArray (array),
|
|
2252
|
+
min = this .min,
|
|
2253
|
+
max = this .max,
|
|
2254
|
+
index = array .length / 4;
|
|
2255
|
+
|
|
2256
|
+
array .push (NODE, left, right, 0,
|
|
2257
|
+
min .x, min .y, min .z, 0,
|
|
2258
|
+
max .x, max .y, max .z, 0);
|
|
2259
|
+
|
|
2260
|
+
return index;
|
|
2261
|
+
},
|
|
1540
2262
|
};
|
|
1541
2263
|
|
|
1542
2264
|
function BVH (vertices, normals)
|
|
1543
2265
|
{
|
|
2266
|
+
const numTriangles = vertices .length / 12;
|
|
2267
|
+
|
|
1544
2268
|
this .vertices = vertices;
|
|
1545
2269
|
this .normals = normals;
|
|
1546
2270
|
|
|
1547
|
-
const numTriangles = vertices .length / 12;
|
|
1548
|
-
|
|
1549
2271
|
switch (numTriangles)
|
|
1550
2272
|
{
|
|
1551
2273
|
case 0:
|
|
@@ -1566,8 +2288,7 @@ function (Vector3,
|
|
|
1566
2288
|
triangles .push (i);
|
|
1567
2289
|
|
|
1568
2290
|
this .sorter = new QuickSort (triangles, SortComparator (vertices, 0));
|
|
1569
|
-
|
|
1570
|
-
this .root = new Node (this, triangles, 0, numTriangles);
|
|
2291
|
+
this .root = new Node (this, triangles, 0, numTriangles);
|
|
1571
2292
|
break;
|
|
1572
2293
|
}
|
|
1573
2294
|
}
|
|
@@ -1576,7 +2297,6 @@ function (Vector3,
|
|
|
1576
2297
|
BVH .prototype =
|
|
1577
2298
|
{
|
|
1578
2299
|
constructor: BVH,
|
|
1579
|
-
|
|
1580
2300
|
intersectsLine: function (line, intersections, intersectionNormals)
|
|
1581
2301
|
{
|
|
1582
2302
|
intersections .size = 0;
|
|
@@ -1589,6 +2309,17 @@ function (Vector3,
|
|
|
1589
2309
|
|
|
1590
2310
|
return 0;
|
|
1591
2311
|
},
|
|
2312
|
+
toArray: function (array)
|
|
2313
|
+
{
|
|
2314
|
+
if (this .root)
|
|
2315
|
+
{
|
|
2316
|
+
const root = this .root .toArray (array);
|
|
2317
|
+
|
|
2318
|
+
array .push (root, 0, 0, 0);
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
return array;
|
|
2322
|
+
},
|
|
1592
2323
|
};
|
|
1593
2324
|
|
|
1594
2325
|
return BVH;
|
|
@@ -1648,69 +2379,70 @@ define ('x_ite/Components/ParticleSystems/ParticleSystem',[
|
|
|
1648
2379
|
"x_ite/Base/X3DFieldDefinition",
|
|
1649
2380
|
"x_ite/Base/FieldDefinitionArray",
|
|
1650
2381
|
"x_ite/Components/Shape/X3DShapeNode",
|
|
2382
|
+
"x_ite/Browser/ParticleSystems/GeometryTypes",
|
|
2383
|
+
"x_ite/Rendering/VertexArray",
|
|
1651
2384
|
"x_ite/Rendering/TraverseType",
|
|
1652
2385
|
"x_ite/Base/X3DConstants",
|
|
1653
2386
|
"x_ite/Base/X3DCast",
|
|
1654
2387
|
"x_ite/Browser/Shape/AlphaMode",
|
|
1655
2388
|
"standard/Math/Numbers/Vector3",
|
|
1656
|
-
"standard/Math/Numbers/Vector4",
|
|
1657
2389
|
"standard/Math/Numbers/Matrix4",
|
|
1658
2390
|
"standard/Math/Numbers/Matrix3",
|
|
1659
|
-
"standard/Math/Algorithms/QuickSort",
|
|
1660
|
-
"standard/Math/Algorithm",
|
|
1661
2391
|
"standard/Math/Utility/BVH",
|
|
1662
2392
|
],
|
|
1663
2393
|
function (Fields,
|
|
1664
2394
|
X3DFieldDefinition,
|
|
1665
2395
|
FieldDefinitionArray,
|
|
1666
2396
|
X3DShapeNode,
|
|
2397
|
+
GeometryTypes,
|
|
2398
|
+
VertexArray,
|
|
1667
2399
|
TraverseType,
|
|
1668
2400
|
X3DConstants,
|
|
1669
2401
|
X3DCast,
|
|
1670
2402
|
AlphaMode,
|
|
1671
2403
|
Vector3,
|
|
1672
|
-
Vector4,
|
|
1673
2404
|
Matrix4,
|
|
1674
2405
|
Matrix3,
|
|
1675
|
-
QuickSort,
|
|
1676
|
-
Algorithm,
|
|
1677
2406
|
BVH)
|
|
1678
2407
|
{
|
|
1679
2408
|
"use strict";
|
|
1680
2409
|
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
const
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
2410
|
+
const PointGeometry = new Float32Array ([0, 0, 0, 1]);
|
|
2411
|
+
|
|
2412
|
+
const LineGeometry = new Float32Array ([
|
|
2413
|
+
// TexCoords
|
|
2414
|
+
0, 0, 0, 1,
|
|
2415
|
+
1, 0, 0, 1,
|
|
2416
|
+
// Vertices
|
|
2417
|
+
0, 0, -0.5, 1,
|
|
2418
|
+
0, 0, 0.5, 1,
|
|
2419
|
+
]);
|
|
2420
|
+
|
|
2421
|
+
// p4 ------ p3
|
|
2422
|
+
// | / |
|
|
2423
|
+
// | / |
|
|
2424
|
+
// | / |
|
|
2425
|
+
// | / |
|
|
2426
|
+
// p1 ------ p2
|
|
2427
|
+
|
|
2428
|
+
const QuadGeometry = new Float32Array ([
|
|
2429
|
+
// TexCoords
|
|
2430
|
+
0, 0, 0, 1,
|
|
2431
|
+
1, 0, 0, 1,
|
|
2432
|
+
1, 1, 0, 1,
|
|
2433
|
+
0, 0, 0, 1,
|
|
2434
|
+
1, 1, 0, 1,
|
|
2435
|
+
0, 1, 0, 1,
|
|
2436
|
+
// Normal
|
|
2437
|
+
0, 0, 1,
|
|
2438
|
+
// Vertices
|
|
2439
|
+
-0.5, -0.5, 0, 1,
|
|
2440
|
+
0.5, -0.5, 0, 1,
|
|
2441
|
+
0.5, 0.5, 0, 1,
|
|
2442
|
+
-0.5, -0.5, 0, 1,
|
|
2443
|
+
0.5, 0.5, 0, 1,
|
|
2444
|
+
-0.5, 0.5, 0, 1,
|
|
2445
|
+
]);
|
|
1714
2446
|
|
|
1715
2447
|
function ParticleSystem (executionContext)
|
|
1716
2448
|
{
|
|
@@ -1720,39 +2452,25 @@ function (Fields,
|
|
|
1720
2452
|
|
|
1721
2453
|
this ._particleSize .setUnit ("length");
|
|
1722
2454
|
|
|
1723
|
-
this .createParticles = true;
|
|
1724
|
-
this .particles = [ ];
|
|
1725
|
-
this .velocities = [ ];
|
|
1726
|
-
this .speeds = [ ];
|
|
1727
|
-
this .turbulences = [ ];
|
|
1728
|
-
this .geometryType = POINT;
|
|
1729
2455
|
this .maxParticles = 0;
|
|
1730
2456
|
this .numParticles = 0;
|
|
1731
|
-
this .particleLifetime = 0;
|
|
1732
|
-
this .lifetimeVariation = 0;
|
|
1733
|
-
this .emitterNode = null;
|
|
1734
2457
|
this .forcePhysicsModelNodes = [ ];
|
|
2458
|
+
this .forces = new Float32Array (4);
|
|
1735
2459
|
this .boundedPhysicsModelNodes = [ ];
|
|
1736
2460
|
this .boundedNormals = [ ];
|
|
1737
2461
|
this .boundedVertices = [ ];
|
|
1738
|
-
this .
|
|
2462
|
+
this .colorRamp = new Float32Array ();
|
|
2463
|
+
this .texCoordRamp = new Float32Array ();
|
|
2464
|
+
this .geometryContext = { };
|
|
1739
2465
|
this .creationTime = 0;
|
|
1740
2466
|
this .pauseTime = 0;
|
|
1741
2467
|
this .deltaTime = 0;
|
|
1742
|
-
this .
|
|
1743
|
-
this .
|
|
1744
|
-
this .
|
|
1745
|
-
this .
|
|
1746
|
-
this .
|
|
1747
|
-
this .
|
|
1748
|
-
this .texCoordRamp = [ ];
|
|
1749
|
-
this .texCoordAnim = false;
|
|
1750
|
-
this .vertexCount = 0;
|
|
1751
|
-
this .shaderNode = null;
|
|
1752
|
-
this .rotation = new Matrix3 ();
|
|
1753
|
-
this .particleSorter = new QuickSort (this .particles, compareDistance);
|
|
1754
|
-
this .sortParticles = false;
|
|
1755
|
-
this .geometryContext = { };
|
|
2468
|
+
this .particleStride = Float32Array .BYTES_PER_ELEMENT * 7 * 4; // 7 x vec4
|
|
2469
|
+
this .particleOffsets = Array .from ({length: 7}, (_, i) => Float32Array .BYTES_PER_ELEMENT * 4 * i); // i x vec4
|
|
2470
|
+
this .particleOffset = this .particleOffsets [0];
|
|
2471
|
+
this .colorOffset = this .particleOffsets [1];
|
|
2472
|
+
this .matrixOffset = this .particleOffsets [3];
|
|
2473
|
+
this .texCoordOffset = 0;
|
|
1756
2474
|
}
|
|
1757
2475
|
|
|
1758
2476
|
ParticleSystem .prototype = Object .assign (Object .create (X3DShapeNode .prototype),
|
|
@@ -1802,6 +2520,9 @@ function (Fields,
|
|
|
1802
2520
|
browser = this .getBrowser (),
|
|
1803
2521
|
gl = browser .getContext ();
|
|
1804
2522
|
|
|
2523
|
+
if (browser .getContext () .getVersion () < 2)
|
|
2524
|
+
return;
|
|
2525
|
+
|
|
1805
2526
|
this .isLive () .addInterest ("set_live__", this);
|
|
1806
2527
|
|
|
1807
2528
|
browser .getBrowserOptions () ._Shading .addInterest ("set_shader__", this);
|
|
@@ -1809,6 +2530,7 @@ function (Fields,
|
|
|
1809
2530
|
this ._enabled .addInterest ("set_enabled__", this);
|
|
1810
2531
|
this ._createParticles .addInterest ("set_createParticles__", this);
|
|
1811
2532
|
this ._geometryType .addInterest ("set_geometryType__", this);
|
|
2533
|
+
this ._geometryType .addInterest ("set_texCoord__", this);
|
|
1812
2534
|
this ._maxParticles .addInterest ("set_enabled__", this);
|
|
1813
2535
|
this ._particleLifetime .addInterest ("set_particleLifetime__", this);
|
|
1814
2536
|
this ._lifetimeVariation .addInterest ("set_lifetimeVariation__", this);
|
|
@@ -1819,38 +2541,42 @@ function (Fields,
|
|
|
1819
2541
|
this ._texCoordKey .addInterest ("set_texCoord__", this);
|
|
1820
2542
|
this ._texCoordRamp .addInterest ("set_texCoordRamp__", this);
|
|
1821
2543
|
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
this .
|
|
1825
|
-
this .
|
|
1826
|
-
|
|
1827
|
-
this .
|
|
1828
|
-
this .
|
|
1829
|
-
this .
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
this .
|
|
1837
|
-
this .
|
|
1838
|
-
this .
|
|
1839
|
-
this .
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
this .
|
|
2544
|
+
// Create particles stuff.
|
|
2545
|
+
|
|
2546
|
+
this .inputParticles = this .createBuffer ();
|
|
2547
|
+
this .outputParticles = this .createBuffer ();
|
|
2548
|
+
|
|
2549
|
+
this .inputParticles . emitterArrayObject = new VertexArray ();
|
|
2550
|
+
this .inputParticles . vertexArrayObject = new VertexArray ();
|
|
2551
|
+
this .inputParticles .shadowArrayObject = new VertexArray ();
|
|
2552
|
+
this .outputParticles .emitterArrayObject = new VertexArray ();
|
|
2553
|
+
this .outputParticles .vertexArrayObject = new VertexArray ();
|
|
2554
|
+
this .outputParticles .shadowArrayObject = new VertexArray ();
|
|
2555
|
+
|
|
2556
|
+
// Create forces stuff.
|
|
2557
|
+
|
|
2558
|
+
this .forcesTexture = this .createTexture ();
|
|
2559
|
+
this .boundedTexture = this .createTexture ();
|
|
2560
|
+
this .colorRampTexture = this .createTexture ();
|
|
2561
|
+
this .texCoordRampTexture = this .createTexture ();
|
|
2562
|
+
|
|
2563
|
+
// Create GL stuff.
|
|
2564
|
+
|
|
2565
|
+
this .geometryBuffer = this .createBuffer ();
|
|
2566
|
+
this .texCoordBuffers = new Array (browser .getMaxTextures ()) .fill (this .geometryBuffer);
|
|
1844
2567
|
|
|
1845
2568
|
// Geometry context
|
|
1846
2569
|
|
|
1847
|
-
this .geometryContext .fogCoords
|
|
2570
|
+
this .geometryContext .fogCoords = false;
|
|
1848
2571
|
this .geometryContext .textureCoordinateNode = browser .getDefaultTextureCoordinate ();
|
|
1849
2572
|
this .geometryContext .textureCoordinateMapping = new Map ();
|
|
1850
2573
|
|
|
1851
|
-
//
|
|
2574
|
+
// Init fields.
|
|
2575
|
+
// Call order is very important at startup.
|
|
2576
|
+
|
|
1852
2577
|
this .set_emitter__ ();
|
|
1853
2578
|
this .set_enabled__ ();
|
|
2579
|
+
this .set_geometryType__ ();
|
|
1854
2580
|
this .set_createParticles__ ();
|
|
1855
2581
|
this .set_particleLifetime__ ();
|
|
1856
2582
|
this .set_lifetimeVariation__ ();
|
|
@@ -1874,7 +2600,7 @@ function (Fields,
|
|
|
1874
2600
|
{
|
|
1875
2601
|
switch (this .geometryType)
|
|
1876
2602
|
{
|
|
1877
|
-
case POINT:
|
|
2603
|
+
case GeometryTypes .POINT:
|
|
1878
2604
|
{
|
|
1879
2605
|
this .setTransparent (true);
|
|
1880
2606
|
break;
|
|
@@ -1883,7 +2609,7 @@ function (Fields,
|
|
|
1883
2609
|
{
|
|
1884
2610
|
this .setTransparent (this .getAppearance () .getTransparent () ||
|
|
1885
2611
|
(this .colorRampNode && this .colorRampNode .getTransparent ()) ||
|
|
1886
|
-
(this .geometryType === GEOMETRY && this .geometryNode && this .geometryNode .getTransparent ()));
|
|
2612
|
+
(this .geometryType === GeometryTypes .GEOMETRY && this .geometryNode && this .geometryNode .getTransparent ()));
|
|
1887
2613
|
break;
|
|
1888
2614
|
}
|
|
1889
2615
|
}
|
|
@@ -1923,7 +2649,7 @@ function (Fields,
|
|
|
1923
2649
|
{
|
|
1924
2650
|
if (this ._enabled .getValue () && this ._maxParticles .getValue ())
|
|
1925
2651
|
{
|
|
1926
|
-
if (!
|
|
2652
|
+
if (!this ._isActive .getValue ())
|
|
1927
2653
|
{
|
|
1928
2654
|
if (this .isLive () .getValue ())
|
|
1929
2655
|
{
|
|
@@ -1935,6 +2661,8 @@ function (Fields,
|
|
|
1935
2661
|
this .pauseTime = performance .now () / 1000;
|
|
1936
2662
|
|
|
1937
2663
|
this ._isActive = true;
|
|
2664
|
+
|
|
2665
|
+
delete this .traverse;
|
|
1938
2666
|
}
|
|
1939
2667
|
}
|
|
1940
2668
|
else
|
|
@@ -1949,6 +2677,7 @@ function (Fields,
|
|
|
1949
2677
|
this ._isActive = false;
|
|
1950
2678
|
|
|
1951
2679
|
this .numParticles = 0;
|
|
2680
|
+
this .traverse = Function .prototype;
|
|
1952
2681
|
}
|
|
1953
2682
|
}
|
|
1954
2683
|
|
|
@@ -1960,161 +2689,86 @@ function (Fields,
|
|
|
1960
2689
|
},
|
|
1961
2690
|
set_geometryType__: function ()
|
|
1962
2691
|
{
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
// geometryType
|
|
2692
|
+
const
|
|
2693
|
+
browser = this .getBrowser (),
|
|
2694
|
+
gl = browser .getContext ();
|
|
1968
2695
|
|
|
1969
|
-
|
|
2696
|
+
// Set geometryType.
|
|
1970
2697
|
|
|
1971
|
-
|
|
1972
|
-
this .
|
|
2698
|
+
this .geometryType = GeometryTypes .hasOwnProperty (this ._geometryType .getValue ())
|
|
2699
|
+
? GeometryTypes [this ._geometryType .getValue ()]
|
|
2700
|
+
: GeometryTypes .QUAD;
|
|
1973
2701
|
|
|
1974
|
-
// Create buffers
|
|
2702
|
+
// Create buffers.
|
|
1975
2703
|
|
|
1976
2704
|
switch (this .geometryType)
|
|
1977
2705
|
{
|
|
1978
|
-
case POINT:
|
|
2706
|
+
case GeometryTypes .POINT:
|
|
1979
2707
|
{
|
|
1980
|
-
this .
|
|
1981
|
-
this .positionArray = new Float32Array (3 * maxParticles);
|
|
1982
|
-
this .elapsedTimeArray = new Float32Array (maxParticles);
|
|
1983
|
-
this .lifeArray = new Float32Array (maxParticles);
|
|
1984
|
-
this .colorArray = new Float32Array (4 * maxParticles);
|
|
1985
|
-
this .texCoordArray = new Float32Array ();
|
|
1986
|
-
this .normalArray = new Float32Array ();
|
|
1987
|
-
this .vertexArray = new Float32Array (4 * maxParticles);
|
|
1988
|
-
|
|
1989
|
-
for (var i = 0, a = this .idArray, l = a .length; i < l; ++ i)
|
|
1990
|
-
a [i] = i;
|
|
1991
|
-
|
|
1992
|
-
this .colorArray .fill (1);
|
|
1993
|
-
this .vertexArray .fill (1);
|
|
2708
|
+
this .geometryContext .geometryType = 0;
|
|
1994
2709
|
|
|
1995
|
-
this .testWireframe = false;
|
|
1996
|
-
this .primitiveMode = gl .POINTS;
|
|
1997
2710
|
this .texCoordCount = 0;
|
|
1998
2711
|
this .vertexCount = 1;
|
|
2712
|
+
this .hasNormals = false;
|
|
2713
|
+
this .testWireframe = false;
|
|
2714
|
+
this .primitiveMode = gl .POINTS;
|
|
2715
|
+
|
|
2716
|
+
this .verticesOffset = 0;
|
|
2717
|
+
|
|
2718
|
+
gl .bindBuffer (gl .ARRAY_BUFFER, this .geometryBuffer);
|
|
2719
|
+
gl .bufferData (gl .ARRAY_BUFFER, PointGeometry, gl .DYNAMIC_DRAW);
|
|
1999
2720
|
|
|
2000
|
-
this .geometryContext .geometryType = 0;
|
|
2001
2721
|
break;
|
|
2002
2722
|
}
|
|
2003
|
-
case LINE:
|
|
2723
|
+
case GeometryTypes .LINE:
|
|
2004
2724
|
{
|
|
2005
|
-
this .
|
|
2006
|
-
this .positionArray = new Float32Array (2 * 3 * maxParticles);
|
|
2007
|
-
this .elapsedTimeArray = new Float32Array (2 * maxParticles);
|
|
2008
|
-
this .lifeArray = new Float32Array (2 * maxParticles);
|
|
2009
|
-
this .colorArray = new Float32Array (2 * 4 * maxParticles);
|
|
2010
|
-
this .texCoordArray = new Float32Array ();
|
|
2011
|
-
this .normalArray = new Float32Array ();
|
|
2012
|
-
this .vertexArray = new Float32Array (2 * 4 * maxParticles);
|
|
2013
|
-
|
|
2014
|
-
for (var i = 0, a = this .idArray, l = a .length; i < l; ++ i)
|
|
2015
|
-
a [i] = Math .floor (i / 2);
|
|
2016
|
-
|
|
2017
|
-
this .colorArray .fill (1);
|
|
2018
|
-
this .vertexArray .fill (1);
|
|
2725
|
+
this .geometryContext .geometryType = 1;
|
|
2019
2726
|
|
|
2020
|
-
this .testWireframe = false;
|
|
2021
|
-
this .primitiveMode = gl .LINES;
|
|
2022
2727
|
this .texCoordCount = 2;
|
|
2023
2728
|
this .vertexCount = 2;
|
|
2729
|
+
this .hasNormals = false;
|
|
2730
|
+
this .testWireframe = false;
|
|
2731
|
+
this .primitiveMode = gl .LINES;
|
|
2732
|
+
|
|
2733
|
+
this .texCoordsOffset = 0;
|
|
2734
|
+
this .verticesOffset = Float32Array .BYTES_PER_ELEMENT * 8;
|
|
2735
|
+
|
|
2736
|
+
gl .bindBuffer (gl .ARRAY_BUFFER, this .geometryBuffer);
|
|
2737
|
+
gl .bufferData (gl .ARRAY_BUFFER, LineGeometry, gl .DYNAMIC_DRAW);
|
|
2024
2738
|
|
|
2025
|
-
this .geometryContext .geometryType = 1;
|
|
2026
2739
|
break;
|
|
2027
2740
|
}
|
|
2028
|
-
case TRIANGLE:
|
|
2029
|
-
case QUAD:
|
|
2030
|
-
case SPRITE:
|
|
2741
|
+
case GeometryTypes .TRIANGLE:
|
|
2742
|
+
case GeometryTypes .QUAD:
|
|
2743
|
+
case GeometryTypes .SPRITE:
|
|
2031
2744
|
{
|
|
2032
|
-
this .
|
|
2033
|
-
this .positionArray = new Float32Array (6 * 3 * maxParticles);
|
|
2034
|
-
this .elapsedTimeArray = new Float32Array (6 * maxParticles);
|
|
2035
|
-
this .lifeArray = new Float32Array (6 * maxParticles);
|
|
2036
|
-
this .colorArray = new Float32Array (6 * 4 * maxParticles);
|
|
2037
|
-
this .texCoordArray = new Float32Array (6 * 4 * maxParticles);
|
|
2038
|
-
this .normalArray = new Float32Array (6 * 3 * maxParticles);
|
|
2039
|
-
this .vertexArray = new Float32Array (6 * 4 * maxParticles);
|
|
2040
|
-
|
|
2041
|
-
for (var i = 0, a = this .idArray, l = a .length; i < l; ++ i)
|
|
2042
|
-
a [i] = Math .floor (i / 6);
|
|
2043
|
-
|
|
2044
|
-
this .colorArray .fill (1);
|
|
2045
|
-
this .vertexArray .fill (1);
|
|
2046
|
-
|
|
2047
|
-
var
|
|
2048
|
-
texCoordArray = this .texCoordArray,
|
|
2049
|
-
normalArray = this .normalArray;
|
|
2050
|
-
|
|
2051
|
-
for (var i = 0, length = 6 * 3 * maxParticles; i < length; i += 3)
|
|
2052
|
-
{
|
|
2053
|
-
normalArray [i] = 0;
|
|
2054
|
-
normalArray [i + 1] = 0;
|
|
2055
|
-
normalArray [i + 2] = 1;
|
|
2056
|
-
}
|
|
2057
|
-
|
|
2058
|
-
gl .bindBuffer (gl .ARRAY_BUFFER, this .normalBuffer);
|
|
2059
|
-
gl .bufferData (gl .ARRAY_BUFFER, this .normalArray, gl .STATIC_DRAW);
|
|
2060
|
-
|
|
2061
|
-
for (var i = 0; i < maxParticles; ++ i)
|
|
2062
|
-
{
|
|
2063
|
-
var i24 = i * 24;
|
|
2064
|
-
|
|
2065
|
-
// p4 ------ p3
|
|
2066
|
-
// | / |
|
|
2067
|
-
// | / |
|
|
2068
|
-
// | / |
|
|
2069
|
-
// | / |
|
|
2070
|
-
// p1 ------ p2
|
|
2071
|
-
|
|
2072
|
-
// p1
|
|
2073
|
-
texCoordArray [i24] = texCoordArray [i24 + 12] = 0;
|
|
2074
|
-
texCoordArray [i24 + 1] = texCoordArray [i24 + 13] = 0;
|
|
2075
|
-
texCoordArray [i24 + 2] = texCoordArray [i24 + 14] = 0;
|
|
2076
|
-
texCoordArray [i24 + 3] = texCoordArray [i24 + 15] = 1;
|
|
2077
|
-
|
|
2078
|
-
// p2
|
|
2079
|
-
texCoordArray [i24 + 4] = 1;
|
|
2080
|
-
texCoordArray [i24 + 5] = 0;
|
|
2081
|
-
texCoordArray [i24 + 6] = 0;
|
|
2082
|
-
texCoordArray [i24 + 7] = 1;
|
|
2083
|
-
|
|
2084
|
-
// p3
|
|
2085
|
-
texCoordArray [i24 + 8] = texCoordArray [i24 + 16] = 1;
|
|
2086
|
-
texCoordArray [i24 + 9] = texCoordArray [i24 + 17] = 1;
|
|
2087
|
-
texCoordArray [i24 + 10] = texCoordArray [i24 + 18] = 0;
|
|
2088
|
-
texCoordArray [i24 + 11] = texCoordArray [i24 + 19] = 1;
|
|
2089
|
-
|
|
2090
|
-
// p4
|
|
2091
|
-
texCoordArray [i24 + 20] = 0;
|
|
2092
|
-
texCoordArray [i24 + 21] = 1;
|
|
2093
|
-
texCoordArray [i24 + 22] = 0;
|
|
2094
|
-
texCoordArray [i24 + 23] = 1;
|
|
2095
|
-
}
|
|
2096
|
-
|
|
2097
|
-
gl .bindBuffer (gl .ARRAY_BUFFER, this .texCoordBuffers [0]);
|
|
2098
|
-
gl .bufferData (gl .ARRAY_BUFFER, this .texCoordArray, gl .STATIC_DRAW);
|
|
2745
|
+
this .geometryContext .geometryType = 2;
|
|
2099
2746
|
|
|
2100
|
-
this .testWireframe = true;
|
|
2101
|
-
this .primitiveMode = gl .TRIANGLES;
|
|
2102
2747
|
this .texCoordCount = 4;
|
|
2103
2748
|
this .vertexCount = 6;
|
|
2749
|
+
this .hasNormals = true;
|
|
2750
|
+
this .testWireframe = true;
|
|
2751
|
+
this .primitiveMode = gl .TRIANGLES;
|
|
2752
|
+
|
|
2753
|
+
this .texCoordsOffset = 0;
|
|
2754
|
+
this .normalOffset = Float32Array .BYTES_PER_ELEMENT * 24;
|
|
2755
|
+
this .verticesOffset = Float32Array .BYTES_PER_ELEMENT * 27;
|
|
2756
|
+
|
|
2757
|
+
gl .bindBuffer (gl .ARRAY_BUFFER, this .geometryBuffer);
|
|
2758
|
+
gl .bufferData (gl .ARRAY_BUFFER, QuadGeometry, gl .DYNAMIC_DRAW);
|
|
2104
2759
|
|
|
2105
|
-
this .geometryContext .geometryType = 2;
|
|
2106
2760
|
break;
|
|
2107
2761
|
}
|
|
2108
|
-
case GEOMETRY:
|
|
2762
|
+
case GeometryTypes .GEOMETRY:
|
|
2109
2763
|
{
|
|
2110
2764
|
this .texCoordCount = 0;
|
|
2111
2765
|
this .vertexCount = 0;
|
|
2766
|
+
|
|
2112
2767
|
break;
|
|
2113
2768
|
}
|
|
2114
2769
|
}
|
|
2115
2770
|
|
|
2116
|
-
|
|
2117
|
-
gl .bufferData (gl .ARRAY_BUFFER, this .idArray, gl .STATIC_DRAW);
|
|
2771
|
+
this .updateVertexArrays ();
|
|
2118
2772
|
|
|
2119
2773
|
this .set_shader__ ();
|
|
2120
2774
|
this .set_transparent__ ();
|
|
@@ -2123,20 +2777,17 @@ function (Fields,
|
|
|
2123
2777
|
{
|
|
2124
2778
|
switch (this .geometryType)
|
|
2125
2779
|
{
|
|
2126
|
-
case POINT:
|
|
2780
|
+
case GeometryTypes .POINT:
|
|
2127
2781
|
{
|
|
2128
2782
|
this .shaderNode = this .getBrowser () .getPointShader ();
|
|
2129
2783
|
break;
|
|
2130
2784
|
}
|
|
2131
|
-
case LINE:
|
|
2785
|
+
case GeometryTypes .LINE:
|
|
2132
2786
|
{
|
|
2133
2787
|
this .shaderNode = this .getBrowser () .getLineShader ();
|
|
2134
2788
|
break;
|
|
2135
2789
|
}
|
|
2136
|
-
|
|
2137
|
-
case QUAD:
|
|
2138
|
-
case SPRITE:
|
|
2139
|
-
case GEOMETRY:
|
|
2790
|
+
default:
|
|
2140
2791
|
{
|
|
2141
2792
|
this .shaderNode = null;
|
|
2142
2793
|
break;
|
|
@@ -2145,37 +2796,18 @@ function (Fields,
|
|
|
2145
2796
|
},
|
|
2146
2797
|
set_maxParticles__: function ()
|
|
2147
2798
|
{
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
maxParticles
|
|
2151
|
-
|
|
2152
|
-
for (var i = this .numParticles, length = Math .min (particles .length, maxParticles); i < length; ++ i)
|
|
2153
|
-
{
|
|
2154
|
-
particles [i] .life = 1;
|
|
2155
|
-
particles [i] .lifetime = -1;
|
|
2156
|
-
}
|
|
2157
|
-
|
|
2158
|
-
for (var i = particles .length, length = maxParticles; i < length; ++ i)
|
|
2159
|
-
{
|
|
2160
|
-
particles [i] = {
|
|
2161
|
-
id: i,
|
|
2162
|
-
life: 1,
|
|
2163
|
-
lifetime: -1,
|
|
2164
|
-
elapsedTime: 0,
|
|
2165
|
-
position: new Vector3 (0, 0, 0),
|
|
2166
|
-
velocity: new Vector3 (0, 0, 0),
|
|
2167
|
-
color: new Vector4 (1, 1, 1, 1),
|
|
2168
|
-
distance: 0,
|
|
2169
|
-
};
|
|
2170
|
-
}
|
|
2799
|
+
const
|
|
2800
|
+
lastNumParticles = this .numParticles,
|
|
2801
|
+
maxParticles = Math .max (0, this ._maxParticles .getValue ());
|
|
2171
2802
|
|
|
2172
2803
|
this .maxParticles = maxParticles;
|
|
2173
|
-
this .numParticles = Math .min (
|
|
2804
|
+
this .numParticles = Math .min (lastNumParticles, maxParticles);
|
|
2174
2805
|
|
|
2175
|
-
if (!
|
|
2806
|
+
if (!this .emitterNode .isExplosive ())
|
|
2176
2807
|
this .creationTime = performance .now () / 1000;
|
|
2177
2808
|
|
|
2178
|
-
this .
|
|
2809
|
+
this .resizeBuffers (lastNumParticles);
|
|
2810
|
+
this .updateVertexArrays ();
|
|
2179
2811
|
},
|
|
2180
2812
|
set_particleLifetime__: function ()
|
|
2181
2813
|
{
|
|
@@ -2189,33 +2821,33 @@ function (Fields,
|
|
|
2189
2821
|
{
|
|
2190
2822
|
this .emitterNode = X3DCast (X3DConstants .X3DParticleEmitterNode, this ._emitter);
|
|
2191
2823
|
|
|
2192
|
-
if (!
|
|
2824
|
+
if (!this .emitterNode)
|
|
2193
2825
|
this .emitterNode = this .getBrowser () .getDefaultEmitter ();
|
|
2194
2826
|
|
|
2195
2827
|
this .createParticles = this ._createParticles .getValue ();
|
|
2196
2828
|
},
|
|
2197
2829
|
set_physics__: function ()
|
|
2198
2830
|
{
|
|
2199
|
-
|
|
2831
|
+
const
|
|
2200
2832
|
physics = this ._physics .getValue (),
|
|
2201
2833
|
forcePhysicsModelNodes = this .forcePhysicsModelNodes,
|
|
2202
2834
|
boundedPhysicsModelNodes = this .boundedPhysicsModelNodes;
|
|
2203
2835
|
|
|
2204
|
-
for (
|
|
2836
|
+
for (let i = 0, length = boundedPhysicsModelNodes .length; i < length; ++ i)
|
|
2205
2837
|
boundedPhysicsModelNodes [i] .removeInterest ("set_boundedPhysics__", this);
|
|
2206
2838
|
|
|
2207
2839
|
forcePhysicsModelNodes .length = 0;
|
|
2208
2840
|
boundedPhysicsModelNodes .length = 0;
|
|
2209
2841
|
|
|
2210
|
-
for (
|
|
2842
|
+
for (let i = 0, length = physics .length; i < length; ++ i)
|
|
2211
2843
|
{
|
|
2212
2844
|
try
|
|
2213
2845
|
{
|
|
2214
|
-
|
|
2846
|
+
const
|
|
2215
2847
|
innerNode = physics [i] .getValue () .getInnerNode (),
|
|
2216
2848
|
type = innerNode .getType ();
|
|
2217
2849
|
|
|
2218
|
-
for (
|
|
2850
|
+
for (let t = type .length - 1; t >= 0; -- t)
|
|
2219
2851
|
{
|
|
2220
2852
|
switch (type [t])
|
|
2221
2853
|
{
|
|
@@ -2246,7 +2878,8 @@ function (Fields,
|
|
|
2246
2878
|
},
|
|
2247
2879
|
set_boundedPhysics__: function ()
|
|
2248
2880
|
{
|
|
2249
|
-
|
|
2881
|
+
const
|
|
2882
|
+
gl = this .getBrowser () .getContext (),
|
|
2250
2883
|
boundedPhysicsModelNodes = this .boundedPhysicsModelNodes,
|
|
2251
2884
|
boundedNormals = this .boundedNormals,
|
|
2252
2885
|
boundedVertices = this .boundedVertices;
|
|
@@ -2254,13 +2887,43 @@ function (Fields,
|
|
|
2254
2887
|
boundedNormals .length = 0;
|
|
2255
2888
|
boundedVertices .length = 0;
|
|
2256
2889
|
|
|
2257
|
-
for (
|
|
2890
|
+
for (let i = 0, length = boundedPhysicsModelNodes .length; i < length; ++ i)
|
|
2258
2891
|
{
|
|
2259
2892
|
boundedPhysicsModelNodes [i] .addGeometry (boundedNormals, boundedVertices);
|
|
2260
2893
|
}
|
|
2261
2894
|
|
|
2262
|
-
|
|
2263
|
-
|
|
2895
|
+
// Texture
|
|
2896
|
+
|
|
2897
|
+
const
|
|
2898
|
+
boundedHierarchy = new BVH (boundedVertices, boundedNormals) .toArray ([ ]),
|
|
2899
|
+
numBoundedVertices = boundedVertices .length / 4,
|
|
2900
|
+
numBoundedNormals = boundedNormals .length / 3,
|
|
2901
|
+
boundedHierarchyLength = boundedHierarchy .length / 4,
|
|
2902
|
+
boundedArraySize = Math .ceil (Math .sqrt (numBoundedVertices + numBoundedNormals + boundedHierarchyLength)),
|
|
2903
|
+
boundedArray = new Float32Array (boundedArraySize * boundedArraySize * 4);
|
|
2904
|
+
|
|
2905
|
+
this .boundedVerticesIndex = 0;
|
|
2906
|
+
this .boundedNormalsIndex = numBoundedVertices;
|
|
2907
|
+
this .boundedHierarchyIndex = this .boundedNormalsIndex + numBoundedNormals;
|
|
2908
|
+
this .boundedHierarchyRoot = this .boundedHierarchyIndex + boundedHierarchyLength - 1;
|
|
2909
|
+
|
|
2910
|
+
boundedArray .set (boundedVertices);
|
|
2911
|
+
|
|
2912
|
+
for (let s = this .boundedNormalsIndex * 4, n = 0, l = boundedNormals .length; n < l; s += 4, n += 3)
|
|
2913
|
+
{
|
|
2914
|
+
boundedArray [s + 0] = boundedNormals [n + 0];
|
|
2915
|
+
boundedArray [s + 1] = boundedNormals [n + 1];
|
|
2916
|
+
boundedArray [s + 2] = boundedNormals [n + 2];
|
|
2917
|
+
}
|
|
2918
|
+
|
|
2919
|
+
boundedArray .set (boundedHierarchy, this .boundedHierarchyIndex * 4);
|
|
2920
|
+
|
|
2921
|
+
if (boundedArraySize)
|
|
2922
|
+
{
|
|
2923
|
+
gl .bindTexture (gl .TEXTURE_2D, this .boundedTexture);
|
|
2924
|
+
gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, boundedArraySize, boundedArraySize, 0, gl .RGBA, gl .FLOAT, boundedArray);
|
|
2925
|
+
}
|
|
2926
|
+
},
|
|
2264
2927
|
set_colorRamp__: function ()
|
|
2265
2928
|
{
|
|
2266
2929
|
if (this .colorRampNode)
|
|
@@ -2276,25 +2939,35 @@ function (Fields,
|
|
|
2276
2939
|
},
|
|
2277
2940
|
set_color__: function ()
|
|
2278
2941
|
{
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2942
|
+
const
|
|
2943
|
+
gl = this .getBrowser () .getContext (),
|
|
2944
|
+
colorKey = this ._colorKey,
|
|
2945
|
+
numColors = colorKey .length,
|
|
2946
|
+
textureSize = Math .ceil (Math .sqrt (numColors * 2));
|
|
2283
2947
|
|
|
2284
|
-
|
|
2285
|
-
colorKeys [i] = colorKey [i];
|
|
2948
|
+
let colorRamp = this .colorRamp;
|
|
2286
2949
|
|
|
2287
|
-
|
|
2950
|
+
if (textureSize * textureSize * 4 > colorRamp .length)
|
|
2951
|
+
colorRamp = this .colorRamp = new Float32Array (textureSize * textureSize * 4);
|
|
2952
|
+
|
|
2953
|
+
for (let i = 0; i < numColors; ++ i)
|
|
2954
|
+
colorRamp [i * 4] = colorKey [i];
|
|
2288
2955
|
|
|
2289
2956
|
if (this .colorRampNode)
|
|
2290
|
-
this .colorRampNode .
|
|
2957
|
+
colorRamp .set (this .colorRampNode .addColors ([ ], numColors) .slice (0, numColors * 4), numColors * 4);
|
|
2958
|
+
else
|
|
2959
|
+
colorRamp .fill (1, numColors * 4);
|
|
2291
2960
|
|
|
2292
|
-
|
|
2293
|
-
|
|
2961
|
+
if (textureSize)
|
|
2962
|
+
{
|
|
2963
|
+
gl .bindTexture (gl .TEXTURE_2D, this .colorRampTexture);
|
|
2964
|
+
gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, textureSize, textureSize, 0, gl .RGBA, gl .FLOAT, colorRamp);
|
|
2965
|
+
}
|
|
2294
2966
|
|
|
2295
|
-
|
|
2967
|
+
this .numColors = numColors;
|
|
2968
|
+
this .geometryContext .colorMaterial = !! (numColors && this .colorRampNode);
|
|
2296
2969
|
|
|
2297
|
-
this .
|
|
2970
|
+
this .updateVertexArrays ();
|
|
2298
2971
|
},
|
|
2299
2972
|
set_texCoordRamp__: function ()
|
|
2300
2973
|
{
|
|
@@ -2310,48 +2983,117 @@ function (Fields,
|
|
|
2310
2983
|
},
|
|
2311
2984
|
set_texCoord__: function ()
|
|
2312
2985
|
{
|
|
2313
|
-
|
|
2986
|
+
const
|
|
2987
|
+
gl = this .getBrowser () .getContext (),
|
|
2314
2988
|
texCoordKey = this ._texCoordKey,
|
|
2315
|
-
|
|
2316
|
-
|
|
2989
|
+
numTexCoords = texCoordKey .length,
|
|
2990
|
+
textureSize = Math .ceil (Math .sqrt (numTexCoords + numTexCoords * this .texCoordCount));
|
|
2991
|
+
|
|
2992
|
+
let texCoordRamp = this .texCoordRamp;
|
|
2317
2993
|
|
|
2318
|
-
|
|
2319
|
-
|
|
2994
|
+
if (textureSize * textureSize * 4 > texCoordRamp .length)
|
|
2995
|
+
texCoordRamp = this .texCoordRamp = new Float32Array (textureSize * textureSize * 4);
|
|
2996
|
+
else
|
|
2997
|
+
texCoordRamp .fill (0);
|
|
2320
2998
|
|
|
2321
|
-
|
|
2999
|
+
for (let i = 0; i < numTexCoords; ++ i)
|
|
3000
|
+
texCoordRamp [i * 4] = texCoordKey [i];
|
|
2322
3001
|
|
|
2323
3002
|
if (this .texCoordRampNode)
|
|
2324
|
-
this .texCoordRampNode .getTexCoord (
|
|
3003
|
+
texCoordRamp .set (this .texCoordRampNode .getTexCoord ([ ]) .slice (0, numTexCoords * this .texCoordCount * 4), numTexCoords * 4);
|
|
2325
3004
|
|
|
2326
|
-
|
|
2327
|
-
|
|
3005
|
+
if (textureSize)
|
|
3006
|
+
{
|
|
3007
|
+
gl .bindTexture (gl .TEXTURE_2D, this .texCoordRampTexture);
|
|
3008
|
+
gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, textureSize, textureSize, 0, gl .RGBA, gl .FLOAT, texCoordRamp);
|
|
3009
|
+
}
|
|
2328
3010
|
|
|
2329
|
-
|
|
3011
|
+
this .numTexCoords = this .texCoordRampNode ? numTexCoords : 0;
|
|
2330
3012
|
|
|
2331
|
-
this .
|
|
3013
|
+
this .updateVertexArrays ();
|
|
2332
3014
|
},
|
|
2333
|
-
|
|
3015
|
+
updateVertexArrays: function ()
|
|
3016
|
+
{
|
|
3017
|
+
this .inputParticles .vertexArrayObject .update ();
|
|
3018
|
+
this .inputParticles .shadowArrayObject .update ();
|
|
3019
|
+
this .inputParticles .emitterArrayObject .update ();
|
|
3020
|
+
this .outputParticles .vertexArrayObject .update ();
|
|
3021
|
+
this .outputParticles .shadowArrayObject .update ();
|
|
3022
|
+
this .outputParticles .emitterArrayObject .update ();
|
|
3023
|
+
},
|
|
3024
|
+
createTexture: function ()
|
|
3025
|
+
{
|
|
3026
|
+
const
|
|
3027
|
+
gl = this .getBrowser () .getContext (),
|
|
3028
|
+
texture = gl .createTexture ();
|
|
3029
|
+
|
|
3030
|
+
gl .bindTexture (gl .TEXTURE_2D, texture);
|
|
3031
|
+
|
|
3032
|
+
gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_WRAP_S, gl .CLAMP_TO_EDGE);
|
|
3033
|
+
gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_WRAP_T, gl .CLAMP_TO_EDGE);
|
|
3034
|
+
gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_MAG_FILTER, gl .NEAREST);
|
|
3035
|
+
gl .texParameteri (gl .TEXTURE_2D, gl .TEXTURE_MIN_FILTER, gl .NEAREST);
|
|
3036
|
+
|
|
3037
|
+
gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, 1, 1, 0, gl .RGBA, gl .FLOAT, new Float32Array (4));
|
|
3038
|
+
|
|
3039
|
+
return texture;
|
|
3040
|
+
},
|
|
3041
|
+
createBuffer: function ()
|
|
3042
|
+
{
|
|
3043
|
+
const
|
|
3044
|
+
gl = this .getBrowser () .getContext (),
|
|
3045
|
+
buffer = gl .createBuffer ();
|
|
3046
|
+
|
|
3047
|
+
gl .bindBuffer (gl .ARRAY_BUFFER, buffer);
|
|
3048
|
+
gl .bufferData (gl .ARRAY_BUFFER, new Uint32Array (), gl .DYNAMIC_DRAW);
|
|
3049
|
+
|
|
3050
|
+
return buffer;
|
|
3051
|
+
},
|
|
3052
|
+
resizeBuffers: function (lastNumParticles)
|
|
2334
3053
|
{
|
|
2335
|
-
|
|
3054
|
+
const
|
|
3055
|
+
gl = this .getBrowser () .getContext (),
|
|
3056
|
+
maxParticles = this .maxParticles,
|
|
3057
|
+
particleStride = this .particleStride,
|
|
3058
|
+
outputParticles = Object .assign (gl .createBuffer (), this .outputParticles),
|
|
3059
|
+
data = new Uint8Array (maxParticles * particleStride);
|
|
3060
|
+
|
|
3061
|
+
// Resize input buffer.
|
|
3062
|
+
|
|
3063
|
+
gl .bindBuffer (gl .ARRAY_BUFFER, this .inputParticles);
|
|
3064
|
+
gl .bufferData (gl .ARRAY_BUFFER, data, gl .DYNAMIC_DRAW);
|
|
3065
|
+
|
|
3066
|
+
// Resize output buffer.
|
|
3067
|
+
|
|
3068
|
+
gl .bindBuffer (gl .COPY_READ_BUFFER, this .outputParticles);
|
|
3069
|
+
gl .bindBuffer (gl .ARRAY_BUFFER, outputParticles);
|
|
3070
|
+
gl .bufferData (gl .ARRAY_BUFFER, data, gl .DYNAMIC_DRAW);
|
|
3071
|
+
gl .copyBufferSubData (gl .COPY_READ_BUFFER, gl .ARRAY_BUFFER, 0, 0, Math .min (maxParticles * particleStride, lastNumParticles * particleStride));
|
|
3072
|
+
gl .deleteBuffer (this .outputParticles);
|
|
3073
|
+
|
|
3074
|
+
this .outputParticles = outputParticles;
|
|
2336
3075
|
},
|
|
2337
3076
|
animateParticles: function ()
|
|
2338
3077
|
{
|
|
2339
|
-
|
|
3078
|
+
const
|
|
3079
|
+
browser = this .getBrowser (),
|
|
3080
|
+
gl = browser .getContext (),
|
|
3081
|
+
emitterNode = this .emitterNode;
|
|
2340
3082
|
|
|
2341
3083
|
// Determine delta time
|
|
2342
3084
|
|
|
2343
|
-
|
|
2344
|
-
DELAY = 15, // Delay in frames when dt
|
|
3085
|
+
const
|
|
3086
|
+
DELAY = 15, // Delay in frames when dt fully applies.
|
|
2345
3087
|
dt = 1 / Math .max (10, this .getBrowser () .getCurrentFrameRate ());
|
|
2346
3088
|
|
|
2347
|
-
//
|
|
2348
|
-
|
|
3089
|
+
// let deltaTime is only for the emitter, this.deltaTime is for the forces.
|
|
3090
|
+
let deltaTime = this .deltaTime = ((DELAY - 1) * this .deltaTime + dt) / DELAY; // Moving average about DELAY frames.
|
|
2349
3091
|
|
|
2350
3092
|
// Determine numParticles
|
|
2351
3093
|
|
|
2352
3094
|
if (emitterNode .isExplosive ())
|
|
2353
3095
|
{
|
|
2354
|
-
|
|
3096
|
+
const
|
|
2355
3097
|
now = performance .now () / 1000,
|
|
2356
3098
|
particleLifetime = this .particleLifetime + this .particleLifetime * this .lifetimeVariation;
|
|
2357
3099
|
|
|
@@ -2370,7 +3112,7 @@ function (Fields,
|
|
|
2370
3112
|
{
|
|
2371
3113
|
if (this .numParticles < this .maxParticles)
|
|
2372
3114
|
{
|
|
2373
|
-
|
|
3115
|
+
const
|
|
2374
3116
|
now = performance .now () / 1000,
|
|
2375
3117
|
newParticles = Math .max (0, Math .floor ((now - this .creationTime) * this .maxParticles / this .particleLifetime));
|
|
2376
3118
|
|
|
@@ -2385,548 +3127,98 @@ function (Fields,
|
|
|
2385
3127
|
|
|
2386
3128
|
if (emitterNode .getMass ())
|
|
2387
3129
|
{
|
|
2388
|
-
|
|
2389
|
-
forcePhysicsModelNodes = this .forcePhysicsModelNodes,
|
|
2390
|
-
velocities = this .velocities,
|
|
2391
|
-
speeds = this .speeds,
|
|
2392
|
-
turbulences = this .turbulences,
|
|
2393
|
-
deltaMass = this .deltaTime / emitterNode .getMass ();
|
|
3130
|
+
const forcePhysicsModelNodes = this .forcePhysicsModelNodes;
|
|
2394
3131
|
|
|
2395
|
-
|
|
3132
|
+
let
|
|
3133
|
+
numForces = forcePhysicsModelNodes .length,
|
|
3134
|
+
forces = this .forces,
|
|
3135
|
+
timeByMass = deltaTime / emitterNode .getMass ();
|
|
2396
3136
|
|
|
2397
|
-
|
|
2398
|
-
velocities [i] = new Vector3 (0, 0, 0);
|
|
3137
|
+
// Collect forces in velocities and collect turbulences.
|
|
2399
3138
|
|
|
2400
|
-
|
|
2401
|
-
|
|
3139
|
+
if (numForces * 4 > forces .length)
|
|
3140
|
+
forces = this .forces = new Float32Array (numForces * 4);
|
|
2402
3141
|
|
|
2403
|
-
|
|
3142
|
+
let disabledForces = 0;
|
|
2404
3143
|
|
|
2405
|
-
for (
|
|
3144
|
+
for (let i = 0; i < numForces; ++ i)
|
|
2406
3145
|
{
|
|
2407
|
-
|
|
2408
|
-
speeds [i] = velocities [i] .abs ();
|
|
3146
|
+
disabledForces += !forcePhysicsModelNodes [i] .addForce (i - disabledForces, emitterNode, timeByMass, forces);
|
|
2409
3147
|
}
|
|
2410
3148
|
|
|
2411
|
-
this .numForces =
|
|
2412
|
-
}
|
|
2413
|
-
else
|
|
2414
|
-
{
|
|
2415
|
-
this .numForces = 0;
|
|
2416
|
-
}
|
|
2417
|
-
|
|
2418
|
-
// Determine particle position, velocity and colors
|
|
2419
|
-
|
|
2420
|
-
emitterNode .animate (this, deltaTime);
|
|
2421
|
-
|
|
2422
|
-
this .updateGeometry (null);
|
|
2423
|
-
|
|
2424
|
-
this .getBrowser () .addBrowserEvent ();
|
|
2425
|
-
},
|
|
2426
|
-
updateGeometry: function (modelViewMatrix)
|
|
2427
|
-
{
|
|
2428
|
-
switch (this .geometryType)
|
|
2429
|
-
{
|
|
2430
|
-
case POINT:
|
|
2431
|
-
if (! modelViewMatrix)
|
|
2432
|
-
this .updatePoint ();
|
|
2433
|
-
break;
|
|
2434
|
-
case LINE:
|
|
2435
|
-
if (! modelViewMatrix)
|
|
2436
|
-
this .updateLine ();
|
|
2437
|
-
break;
|
|
2438
|
-
case TRIANGLE:
|
|
2439
|
-
case QUAD:
|
|
2440
|
-
case SPRITE:
|
|
2441
|
-
this .updateQuad (modelViewMatrix);
|
|
2442
|
-
break;
|
|
2443
|
-
case GEOMETRY:
|
|
2444
|
-
break;
|
|
2445
|
-
}
|
|
2446
|
-
},
|
|
2447
|
-
updatePoint: function ()
|
|
2448
|
-
{
|
|
2449
|
-
var
|
|
2450
|
-
gl = this .getBrowser () .getContext (),
|
|
2451
|
-
particles = this .particles,
|
|
2452
|
-
numParticles = this .numParticles,
|
|
2453
|
-
positionArray = this .positionArray,
|
|
2454
|
-
elapsedTimeArray = this .elapsedTimeArray,
|
|
2455
|
-
lifeArray = this .lifeArray,
|
|
2456
|
-
colorArray = this .colorArray,
|
|
2457
|
-
vertexArray = this .vertexArray;
|
|
2458
|
-
|
|
2459
|
-
// Colors
|
|
3149
|
+
this .numForces = numForces -= disabledForces;
|
|
2460
3150
|
|
|
2461
|
-
|
|
2462
|
-
{
|
|
2463
|
-
for (var i = 0; i < numParticles; ++ i)
|
|
3151
|
+
if (numForces)
|
|
2464
3152
|
{
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
i4 = i * 4;
|
|
2468
|
-
|
|
2469
|
-
colorArray [i4] = color .x;
|
|
2470
|
-
colorArray [i4 + 1] = color .y;
|
|
2471
|
-
colorArray [i4 + 2] = color .z;
|
|
2472
|
-
colorArray [i4 + 3] = color .w;
|
|
3153
|
+
gl .bindTexture (gl .TEXTURE_2D, this .forcesTexture);
|
|
3154
|
+
gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, numForces, 1, 0, gl .RGBA, gl .FLOAT, forces);
|
|
2473
3155
|
}
|
|
2474
|
-
|
|
2475
|
-
gl .bindBuffer (gl .ARRAY_BUFFER, this .colorBuffer);
|
|
2476
|
-
gl .bufferData (gl .ARRAY_BUFFER, this .colorArray, gl .STATIC_DRAW);
|
|
2477
3156
|
}
|
|
2478
|
-
|
|
2479
|
-
// Vertices
|
|
2480
|
-
|
|
2481
|
-
for (var i = 0; i < numParticles; ++ i)
|
|
3157
|
+
else
|
|
2482
3158
|
{
|
|
2483
|
-
|
|
2484
|
-
position = particles [i] .position,
|
|
2485
|
-
elapsedTime = particles [i] .elapsedTime / particles [i] .lifetime,
|
|
2486
|
-
i3 = i * 3,
|
|
2487
|
-
i4 = i * 4;
|
|
2488
|
-
|
|
2489
|
-
positionArray [i3] = position .x;
|
|
2490
|
-
positionArray [i3 + 1] = position .y;
|
|
2491
|
-
positionArray [i3 + 2] = position .z;
|
|
2492
|
-
|
|
2493
|
-
elapsedTimeArray [i] = elapsedTime;
|
|
2494
|
-
lifeArray [i] = particles [i] .life;
|
|
2495
|
-
|
|
2496
|
-
vertexArray [i4] = position .x;
|
|
2497
|
-
vertexArray [i4 + 1] = position .y;
|
|
2498
|
-
vertexArray [i4 + 2] = position .z;
|
|
3159
|
+
this .numForces = 0;
|
|
2499
3160
|
}
|
|
2500
3161
|
|
|
2501
|
-
|
|
2502
|
-
gl .bufferData (gl .ARRAY_BUFFER, this .positionArray, gl .STATIC_DRAW);
|
|
2503
|
-
gl .bindBuffer (gl .ARRAY_BUFFER, this .elapsedTimeBuffer);
|
|
2504
|
-
gl .bufferData (gl .ARRAY_BUFFER, this .elapsedTimeArray, gl .STATIC_DRAW);
|
|
2505
|
-
gl .bindBuffer (gl .ARRAY_BUFFER, this .lifeBuffer);
|
|
2506
|
-
gl .bufferData (gl .ARRAY_BUFFER, this .lifeArray, gl .STATIC_DRAW);
|
|
2507
|
-
gl .bindBuffer (gl .ARRAY_BUFFER, this .vertexBuffer);
|
|
2508
|
-
gl .bufferData (gl .ARRAY_BUFFER, this .vertexArray, gl .STATIC_DRAW);
|
|
2509
|
-
},
|
|
2510
|
-
updateLine: function ()
|
|
2511
|
-
{
|
|
2512
|
-
var
|
|
2513
|
-
gl = this .getBrowser () .getContext (),
|
|
2514
|
-
particles = this .particles,
|
|
2515
|
-
numParticles = this .numParticles,
|
|
2516
|
-
positionArray = this .positionArray,
|
|
2517
|
-
elapsedTimeArray = this .elapsedTimeArray,
|
|
2518
|
-
lifeArray = this .lifeArray,
|
|
2519
|
-
colorArray = this .colorArray,
|
|
2520
|
-
vertexArray = this .vertexArray,
|
|
2521
|
-
sy1_2 = this ._particleSize .y / 2;
|
|
2522
|
-
|
|
2523
|
-
// Colors
|
|
2524
|
-
|
|
2525
|
-
if (this .geometryContext .colorMaterial)
|
|
2526
|
-
{
|
|
2527
|
-
for (var i = 0; i < numParticles; ++ i)
|
|
2528
|
-
{
|
|
2529
|
-
var
|
|
2530
|
-
color = particles [i] .color,
|
|
2531
|
-
i8 = i * 8;
|
|
2532
|
-
|
|
2533
|
-
colorArray [i8] = color .x;
|
|
2534
|
-
colorArray [i8 + 1] = color .y;
|
|
2535
|
-
colorArray [i8 + 2] = color .z;
|
|
2536
|
-
colorArray [i8 + 3] = color .w;
|
|
2537
|
-
|
|
2538
|
-
colorArray [i8 + 4] = color .x;
|
|
2539
|
-
colorArray [i8 + 5] = color .y;
|
|
2540
|
-
colorArray [i8 + 6] = color .z;
|
|
2541
|
-
colorArray [i8 + 7] = color .w;
|
|
2542
|
-
}
|
|
3162
|
+
// Swap buffers.
|
|
2543
3163
|
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
3164
|
+
const inputParticles = this .outputParticles;
|
|
3165
|
+
this .outputParticles = this .inputParticles;
|
|
3166
|
+
this .inputParticles = inputParticles;
|
|
2547
3167
|
|
|
2548
|
-
//
|
|
3168
|
+
// Determine particle position, velocity and colors.
|
|
2549
3169
|
|
|
2550
|
-
|
|
2551
|
-
{
|
|
2552
|
-
var
|
|
2553
|
-
particle = particles [i],
|
|
2554
|
-
position = particle .position,
|
|
2555
|
-
elapsedTime = particles [i] .elapsedTime / particles [i] .lifetime,
|
|
2556
|
-
life = particles [i] .life,
|
|
2557
|
-
x = position .x,
|
|
2558
|
-
y = position .y,
|
|
2559
|
-
z = position .z,
|
|
2560
|
-
i2 = i * 2,
|
|
2561
|
-
i6 = i * 6,
|
|
2562
|
-
i8 = i * 8;
|
|
2563
|
-
|
|
2564
|
-
positionArray [i6] = x;
|
|
2565
|
-
positionArray [i6 + 1] = y;
|
|
2566
|
-
positionArray [i6 + 2] = z;
|
|
2567
|
-
positionArray [i6 + 3] = x;
|
|
2568
|
-
positionArray [i6 + 4] = y;
|
|
2569
|
-
positionArray [i6 + 5] = z;
|
|
2570
|
-
|
|
2571
|
-
elapsedTimeArray [i2] = elapsedTime;
|
|
2572
|
-
elapsedTimeArray [i2 + 1] = elapsedTime;
|
|
2573
|
-
|
|
2574
|
-
lifeArray [i2] = life;
|
|
2575
|
-
lifeArray [i2 + 1] = life;
|
|
2576
|
-
|
|
2577
|
-
// Length of line / 2.
|
|
2578
|
-
normal .assign (particle .velocity) .normalize () .multiply (sy1_2);
|
|
2579
|
-
|
|
2580
|
-
vertexArray [i8] = x - normal .x;
|
|
2581
|
-
vertexArray [i8 + 1] = y - normal .y;
|
|
2582
|
-
vertexArray [i8 + 2] = z - normal .z;
|
|
2583
|
-
|
|
2584
|
-
vertexArray [i8 + 4] = x + normal .x;
|
|
2585
|
-
vertexArray [i8 + 5] = y + normal .y;
|
|
2586
|
-
vertexArray [i8 + 6] = z + normal .z;
|
|
2587
|
-
}
|
|
3170
|
+
emitterNode .animate (this, deltaTime);
|
|
2588
3171
|
|
|
2589
|
-
|
|
2590
|
-
gl .bufferData (gl .ARRAY_BUFFER, this .positionArray, gl .STATIC_DRAW);
|
|
2591
|
-
gl .bindBuffer (gl .ARRAY_BUFFER, this .elapsedTimeBuffer);
|
|
2592
|
-
gl .bufferData (gl .ARRAY_BUFFER, this .elapsedTimeArray, gl .STATIC_DRAW);
|
|
2593
|
-
gl .bindBuffer (gl .ARRAY_BUFFER, this .lifeBuffer);
|
|
2594
|
-
gl .bufferData (gl .ARRAY_BUFFER, this .lifeArray, gl .STATIC_DRAW);
|
|
2595
|
-
gl .bindBuffer (gl .ARRAY_BUFFER, this .vertexBuffer);
|
|
2596
|
-
gl .bufferData (gl .ARRAY_BUFFER, this .vertexArray, gl .STATIC_DRAW);
|
|
3172
|
+
browser .addBrowserEvent ();
|
|
2597
3173
|
},
|
|
2598
|
-
|
|
3174
|
+
updateSprite: (function ()
|
|
2599
3175
|
{
|
|
2600
|
-
|
|
2601
|
-
{
|
|
2602
|
-
var
|
|
2603
|
-
gl = this .getBrowser () .getContext (),
|
|
2604
|
-
particles = this .particles,
|
|
2605
|
-
maxParticles = this .maxParticles,
|
|
2606
|
-
numParticles = this .numParticles,
|
|
2607
|
-
positionArray = this .positionArray,
|
|
2608
|
-
elapsedTimeArray = this .elapsedTimeArray,
|
|
2609
|
-
lifeArray = this .lifeArray,
|
|
2610
|
-
colorArray = this .colorArray,
|
|
2611
|
-
texCoordArray = this .texCoordArray,
|
|
2612
|
-
normalArray = this .normalArray,
|
|
2613
|
-
vertexArray = this .vertexArray,
|
|
2614
|
-
sx1_2 = this ._particleSize .x / 2,
|
|
2615
|
-
sy1_2 = this ._particleSize .y / 2;
|
|
2616
|
-
|
|
2617
|
-
// Sort particles
|
|
2618
|
-
|
|
2619
|
-
// if (this .sortParticles) // always false
|
|
2620
|
-
// {
|
|
2621
|
-
// for (var i = 0; i < numParticles; ++ i)
|
|
2622
|
-
// {
|
|
2623
|
-
// var particle = particles [i];
|
|
2624
|
-
// particle .distance = modelViewMatrix .getDepth (particle .position);
|
|
2625
|
-
// }
|
|
2626
|
-
//
|
|
2627
|
-
// // Expensisive function!!!
|
|
2628
|
-
// this .particleSorter .sort (0, numParticles);
|
|
2629
|
-
// }
|
|
2630
|
-
|
|
2631
|
-
// Colors
|
|
2632
|
-
|
|
2633
|
-
if (! modelViewMatrix) // if called from animateParticles
|
|
2634
|
-
{
|
|
2635
|
-
if (this .geometryContext .colorMaterial)
|
|
2636
|
-
{
|
|
2637
|
-
for (var i = 0; i < maxParticles; ++ i)
|
|
2638
|
-
{
|
|
2639
|
-
var
|
|
2640
|
-
color = particles [i] .color,
|
|
2641
|
-
i24 = i * 24;
|
|
2642
|
-
|
|
2643
|
-
// p4 ------ p3
|
|
2644
|
-
// | / |
|
|
2645
|
-
// | / |
|
|
2646
|
-
// | / |
|
|
2647
|
-
// | / |
|
|
2648
|
-
// p1 ------ p2
|
|
2649
|
-
|
|
2650
|
-
// p1, p2, p3; p1, p3, p4
|
|
2651
|
-
colorArray [i24] = colorArray [i24 + 4] = colorArray [i24 + 8] = colorArray [i24 + 12] = colorArray [i24 + 16] = colorArray [i24 + 20] = color .x;
|
|
2652
|
-
colorArray [i24 + 1] = colorArray [i24 + 5] = colorArray [i24 + 9] = colorArray [i24 + 13] = colorArray [i24 + 17] = colorArray [i24 + 21] = color .y;
|
|
2653
|
-
colorArray [i24 + 2] = colorArray [i24 + 6] = colorArray [i24 + 10] = colorArray [i24 + 14] = colorArray [i24 + 18] = colorArray [i24 + 22] = color .z;
|
|
2654
|
-
colorArray [i24 + 3] = colorArray [i24 + 7] = colorArray [i24 + 11] = colorArray [i24 + 15] = colorArray [i24 + 19] = colorArray [i24 + 23] = color .w;
|
|
2655
|
-
}
|
|
2656
|
-
|
|
2657
|
-
gl .bindBuffer (gl .ARRAY_BUFFER, this .colorBuffer);
|
|
2658
|
-
gl .bufferData (gl .ARRAY_BUFFER, this .colorArray, gl .STATIC_DRAW);
|
|
2659
|
-
}
|
|
3176
|
+
const data = new Float32Array (QuadGeometry);
|
|
2660
3177
|
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
index0 = 0;
|
|
2670
|
-
|
|
2671
|
-
for (var i = 0; i < maxParticles; ++ i)
|
|
2672
|
-
{
|
|
2673
|
-
// Determine index0.
|
|
2674
|
-
|
|
2675
|
-
var
|
|
2676
|
-
particle = particles [i],
|
|
2677
|
-
fraction = particle .elapsedTime / particle .lifetime;
|
|
2678
|
-
|
|
2679
|
-
if (length == 1 || fraction <= texCoordKeys [0])
|
|
2680
|
-
{
|
|
2681
|
-
index0 = 0;
|
|
2682
|
-
}
|
|
2683
|
-
else if (fraction >= texCoordKeys .at (-1))
|
|
2684
|
-
{
|
|
2685
|
-
index0 = length - 2;
|
|
2686
|
-
}
|
|
2687
|
-
else
|
|
2688
|
-
{
|
|
2689
|
-
var index = Algorithm .upperBound (texCoordKeys, 0, length, fraction, Algorithm .less);
|
|
3178
|
+
const quad = [
|
|
3179
|
+
new Vector3 (-0.5, -0.5, 0),
|
|
3180
|
+
new Vector3 ( 0.5, -0.5, 0),
|
|
3181
|
+
new Vector3 ( 0.5, 0.5, 0),
|
|
3182
|
+
new Vector3 (-0.5, -0.5, 0),
|
|
3183
|
+
new Vector3 ( 0.5, 0.5, 0),
|
|
3184
|
+
new Vector3 (-0.5, 0.5, 0),
|
|
3185
|
+
];
|
|
2690
3186
|
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
index0 = 0;
|
|
2695
|
-
}
|
|
3187
|
+
const
|
|
3188
|
+
vertex = new Vector3 (0, 0, 0),
|
|
3189
|
+
size = new Vector3 (0, 0, 0);
|
|
2696
3190
|
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
var
|
|
2702
|
-
texCoord1 = texCoordRamp [index0],
|
|
2703
|
-
texCoord2 = texCoordRamp [index0 + 1],
|
|
2704
|
-
texCoord3 = texCoordRamp [index0 + 2],
|
|
2705
|
-
texCoord4 = texCoordRamp [index0 + 3],
|
|
2706
|
-
i24 = i * 24;
|
|
2707
|
-
|
|
2708
|
-
// p4 ------ p3
|
|
2709
|
-
// | / |
|
|
2710
|
-
// | / |
|
|
2711
|
-
// | / |
|
|
2712
|
-
// | / |
|
|
2713
|
-
// p1 ------ p2
|
|
2714
|
-
|
|
2715
|
-
// p1
|
|
2716
|
-
texCoordArray [i24] = texCoordArray [i24 + 12] = texCoord1 .x;
|
|
2717
|
-
texCoordArray [i24 + 1] = texCoordArray [i24 + 13] = texCoord1 .y;
|
|
2718
|
-
texCoordArray [i24 + 2] = texCoordArray [i24 + 14] = texCoord1 .z;
|
|
2719
|
-
texCoordArray [i24 + 3] = texCoordArray [i24 + 15] = texCoord1 .w;
|
|
2720
|
-
|
|
2721
|
-
// p2
|
|
2722
|
-
texCoordArray [i24 + 4] = texCoord2 .x;
|
|
2723
|
-
texCoordArray [i24 + 5] = texCoord2 .y;
|
|
2724
|
-
texCoordArray [i24 + 6] = texCoord2 .z;
|
|
2725
|
-
texCoordArray [i24 + 7] = texCoord2 .w;
|
|
2726
|
-
|
|
2727
|
-
// p3
|
|
2728
|
-
texCoordArray [i24 + 8] = texCoordArray [i24 + 16] = texCoord3 .x;
|
|
2729
|
-
texCoordArray [i24 + 9] = texCoordArray [i24 + 17] = texCoord3 .y;
|
|
2730
|
-
texCoordArray [i24 + 10] = texCoordArray [i24 + 18] = texCoord3 .z;
|
|
2731
|
-
texCoordArray [i24 + 11] = texCoordArray [i24 + 19] = texCoord3 .w;
|
|
2732
|
-
|
|
2733
|
-
// p4
|
|
2734
|
-
texCoordArray [i24 + 20] = texCoord4 .x;
|
|
2735
|
-
texCoordArray [i24 + 21] = texCoord4 .y;
|
|
2736
|
-
texCoordArray [i24 + 22] = texCoord4 .z;
|
|
2737
|
-
texCoordArray [i24 + 23] = texCoord4 .w;
|
|
2738
|
-
}
|
|
3191
|
+
return function (gl, rotation)
|
|
3192
|
+
{
|
|
3193
|
+
// Normal
|
|
2739
3194
|
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
}
|
|
2743
|
-
}
|
|
3195
|
+
for (let i = 0; i < 3; ++ i)
|
|
3196
|
+
data [24 + i] = rotation [i + 6];
|
|
2744
3197
|
|
|
2745
3198
|
// Vertices
|
|
2746
3199
|
|
|
2747
|
-
|
|
2748
|
-
{
|
|
2749
|
-
if (modelViewMatrix) // if called from depth or draw
|
|
2750
|
-
{
|
|
2751
|
-
// Normals
|
|
2752
|
-
|
|
2753
|
-
var rotation = this .getScreenAlignedRotation (modelViewMatrix);
|
|
2754
|
-
|
|
2755
|
-
normal
|
|
2756
|
-
.set (rotation [0], rotation [1], rotation [2])
|
|
2757
|
-
.cross (vector .set (rotation [3], rotation [4], rotation [5]))
|
|
2758
|
-
.normalize ();
|
|
2759
|
-
|
|
2760
|
-
var
|
|
2761
|
-
nx = normal .x,
|
|
2762
|
-
ny = normal .y,
|
|
2763
|
-
nz = normal .z;
|
|
2764
|
-
|
|
2765
|
-
for (var i = 0, length = 6 * 3 * maxParticles; i < length; i += 3)
|
|
2766
|
-
{
|
|
2767
|
-
normalArray [i] = nx;
|
|
2768
|
-
normalArray [i + 1] = ny;
|
|
2769
|
-
normalArray [i + 2] = nz;
|
|
2770
|
-
}
|
|
2771
|
-
|
|
2772
|
-
gl .bindBuffer (gl .ARRAY_BUFFER, this .normalBuffer);
|
|
2773
|
-
gl .bufferData (gl .ARRAY_BUFFER, this .normalArray, gl .STATIC_DRAW);
|
|
2774
|
-
|
|
2775
|
-
// Vertices
|
|
2776
|
-
|
|
2777
|
-
s1 .set (-sx1_2, -sy1_2, 0);
|
|
2778
|
-
s2 .set ( sx1_2, -sy1_2, 0);
|
|
2779
|
-
s3 .set ( sx1_2, sy1_2, 0);
|
|
2780
|
-
s4 .set (-sx1_2, sy1_2, 0);
|
|
2781
|
-
|
|
2782
|
-
rotation .multVecMatrix (s1);
|
|
2783
|
-
rotation .multVecMatrix (s2);
|
|
2784
|
-
rotation .multVecMatrix (s3);
|
|
2785
|
-
rotation .multVecMatrix (s4);
|
|
2786
|
-
|
|
2787
|
-
for (var i = 0; i < numParticles; ++ i)
|
|
2788
|
-
{
|
|
2789
|
-
var
|
|
2790
|
-
position = particles [i] .position,
|
|
2791
|
-
elapsedTime = particles [i] .elapsedTime / particles [i] .lifetime,
|
|
2792
|
-
x = position .x,
|
|
2793
|
-
y = position .y,
|
|
2794
|
-
z = position .z,
|
|
2795
|
-
i6 = i * 6,
|
|
2796
|
-
i18 = i * 18,
|
|
2797
|
-
i24 = i * 24;
|
|
2798
|
-
|
|
2799
|
-
// p4 ------ p3
|
|
2800
|
-
// | / |
|
|
2801
|
-
// | / |
|
|
2802
|
-
// | / |
|
|
2803
|
-
// | / |
|
|
2804
|
-
// p1 ------ p2
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
positionArray [i18] = positionArray [i18 + 3] = positionArray [i18 + 6] = positionArray [i18 + 9] = positionArray [i18 + 12] = positionArray [i18 + 15] = x;
|
|
2808
|
-
positionArray [i18 + 1] = positionArray [i18 + 4] = positionArray [i18 + 7] = positionArray [i18 + 10] = positionArray [i18 + 13] = positionArray [i18 + 16] = y;
|
|
2809
|
-
positionArray [i18 + 2] = positionArray [i18 + 5] = positionArray [i18 + 8] = positionArray [i18 + 11] = positionArray [i18 + 14] = positionArray [i18 + 17] = z;
|
|
2810
|
-
|
|
2811
|
-
elapsedTimeArray [i6] = elapsedTimeArray [i6 + 1] = elapsedTimeArray [i6 + 2] = elapsedTimeArray [i6 + 3] = elapsedTimeArray [i6 + 4] = elapsedTimeArray [i6 + 5] = elapsedTime;
|
|
2812
|
-
lifeArray [i6] = lifeArray [i6 + 1] = lifeArray [i6 + 2] = lifeArray [i6 + 3] = lifeArray [i6 + 4] = lifeArray [i6 + 5] = particles [i] .life;
|
|
2813
|
-
|
|
2814
|
-
// p1
|
|
2815
|
-
vertexArray [i24] = vertexArray [i24 + 12] = x + s1 .x;
|
|
2816
|
-
vertexArray [i24 + 1] = vertexArray [i24 + 13] = y + s1 .y;
|
|
2817
|
-
vertexArray [i24 + 2] = vertexArray [i24 + 14] = z + s1 .z;
|
|
2818
|
-
|
|
2819
|
-
// p2
|
|
2820
|
-
vertexArray [i24 + 4] = x + s2 .x;
|
|
2821
|
-
vertexArray [i24 + 5] = y + s2 .y;
|
|
2822
|
-
vertexArray [i24 + 6] = z + s2 .z;
|
|
2823
|
-
|
|
2824
|
-
// p3
|
|
2825
|
-
vertexArray [i24 + 8] = vertexArray [i24 + 16] = x + s3 .x;
|
|
2826
|
-
vertexArray [i24 + 9] = vertexArray [i24 + 17] = y + s3 .y;
|
|
2827
|
-
vertexArray [i24 + 10] = vertexArray [i24 + 18] = z + s3 .z;
|
|
2828
|
-
|
|
2829
|
-
// p4
|
|
2830
|
-
vertexArray [i24 + 20] = x + s4 .x;
|
|
2831
|
-
vertexArray [i24 + 21] = y + s4 .y;
|
|
2832
|
-
vertexArray [i24 + 22] = z + s4 .z;
|
|
2833
|
-
}
|
|
3200
|
+
size .set (this ._particleSize .x, this ._particleSize .y, 1);
|
|
2834
3201
|
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
gl .bindBuffer (gl .ARRAY_BUFFER, this .elapsedTimeBuffer);
|
|
2838
|
-
gl .bufferData (gl .ARRAY_BUFFER, this .elapsedTimeArray, gl .STATIC_DRAW);
|
|
2839
|
-
gl .bindBuffer (gl .ARRAY_BUFFER, this .lifeBuffer);
|
|
2840
|
-
gl .bufferData (gl .ARRAY_BUFFER, this .lifeArray, gl .STATIC_DRAW);
|
|
2841
|
-
gl .bindBuffer (gl .ARRAY_BUFFER, this .vertexBuffer);
|
|
2842
|
-
gl .bufferData (gl .ARRAY_BUFFER, this .vertexArray, gl .STATIC_DRAW);
|
|
2843
|
-
}
|
|
2844
|
-
}
|
|
2845
|
-
else
|
|
2846
|
-
{
|
|
2847
|
-
if (! modelViewMatrix) // if called from animateParticles
|
|
2848
|
-
{
|
|
2849
|
-
for (var i = 0; i < numParticles; ++ i)
|
|
2850
|
-
{
|
|
2851
|
-
var
|
|
2852
|
-
position = particles [i] .position,
|
|
2853
|
-
elapsedTime = particles [i] .elapsedTime / particles [i] .lifetime,
|
|
2854
|
-
x = position .x,
|
|
2855
|
-
y = position .y,
|
|
2856
|
-
z = position .z,
|
|
2857
|
-
i6 = i * 6,
|
|
2858
|
-
i18 = i * 18,
|
|
2859
|
-
i24 = i * 24;
|
|
2860
|
-
|
|
2861
|
-
// p4 ------ p3
|
|
2862
|
-
// | / |
|
|
2863
|
-
// | / |
|
|
2864
|
-
// | / |
|
|
2865
|
-
// | / |
|
|
2866
|
-
// p1 ------ p2
|
|
2867
|
-
|
|
2868
|
-
positionArray [i18] = positionArray [i18 + 3] = positionArray [i18 + 6] = positionArray [i18 + 9] = positionArray [i18 + 12] = positionArray [i18 + 15] = x;
|
|
2869
|
-
positionArray [i18 + 1] = positionArray [i18 + 4] = positionArray [i18 + 7] = positionArray [i18 + 10] = positionArray [i18 + 13] = positionArray [i18 + 16] = y;
|
|
2870
|
-
positionArray [i18 + 2] = positionArray [i18 + 5] = positionArray [i18 + 8] = positionArray [i18 + 11] = positionArray [i18 + 14] = positionArray [i18 + 17] = z;
|
|
2871
|
-
|
|
2872
|
-
elapsedTimeArray [i6] = elapsedTimeArray [i6 + 1] = elapsedTimeArray [i6 + 2] = elapsedTimeArray [i6 + 3] = elapsedTimeArray [i6 + 4] = elapsedTimeArray [i6 + 5] = elapsedTime;
|
|
2873
|
-
lifeArray [i6] = lifeArray [i6 + 1] = lifeArray [i6 + 2] = lifeArray [i6 + 3] = lifeArray [i6 + 4] = lifeArray [i6 + 5] = particles [i] .life;
|
|
2874
|
-
|
|
2875
|
-
// p1
|
|
2876
|
-
vertexArray [i24] = vertexArray [i24 + 12] = x - sx1_2;
|
|
2877
|
-
vertexArray [i24 + 1] = vertexArray [i24 + 13] = y - sy1_2;
|
|
2878
|
-
vertexArray [i24 + 2] = vertexArray [i24 + 14] = z;
|
|
2879
|
-
|
|
2880
|
-
// p2
|
|
2881
|
-
vertexArray [i24 + 4] = x + sx1_2;
|
|
2882
|
-
vertexArray [i24 + 5] = y - sy1_2;
|
|
2883
|
-
vertexArray [i24 + 6] = z;
|
|
2884
|
-
|
|
2885
|
-
// p3
|
|
2886
|
-
vertexArray [i24 + 8] = vertexArray [i24 + 16] = x + sx1_2;
|
|
2887
|
-
vertexArray [i24 + 9] = vertexArray [i24 + 17] = y + sy1_2;
|
|
2888
|
-
vertexArray [i24 + 10] = vertexArray [i24 + 18] = z;
|
|
2889
|
-
|
|
2890
|
-
// p4
|
|
2891
|
-
vertexArray [i24 + 20] = x - sx1_2;
|
|
2892
|
-
vertexArray [i24 + 21] = y + sy1_2;
|
|
2893
|
-
vertexArray [i24 + 22] = z;
|
|
2894
|
-
}
|
|
3202
|
+
for (let i = 0; i < 6; ++ i)
|
|
3203
|
+
data .set (rotation .multVecMatrix (vertex .assign (quad [i]) .multVec (size)), 27 + i * 4);
|
|
2895
3204
|
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
gl .bindBuffer (gl .ARRAY_BUFFER, this .vertexBuffer);
|
|
2903
|
-
gl .bufferData (gl .ARRAY_BUFFER, this .vertexArray, gl .STATIC_DRAW);
|
|
2904
|
-
}
|
|
2905
|
-
}
|
|
2906
|
-
}
|
|
2907
|
-
catch (error)
|
|
2908
|
-
{
|
|
2909
|
-
console .error (error);
|
|
2910
|
-
}
|
|
2911
|
-
},
|
|
3205
|
+
gl .bindBuffer (gl .ARRAY_BUFFER, this .geometryBuffer);
|
|
3206
|
+
gl .bufferData (gl .ARRAY_BUFFER, data, gl .DYNAMIC_DRAW);
|
|
3207
|
+
};
|
|
3208
|
+
})(),
|
|
3209
|
+
intersectsBox: function (box, clipPlanes)
|
|
3210
|
+
{ },
|
|
2912
3211
|
traverse: function (type, renderObject)
|
|
2913
3212
|
{
|
|
2914
|
-
if (
|
|
3213
|
+
if (this .numParticles === 0)
|
|
2915
3214
|
return;
|
|
2916
3215
|
|
|
2917
3216
|
switch (type)
|
|
2918
3217
|
{
|
|
2919
3218
|
case TraverseType .POINTER:
|
|
2920
|
-
{
|
|
2921
|
-
break;
|
|
2922
|
-
}
|
|
2923
3219
|
case TraverseType .PICKING:
|
|
2924
|
-
{
|
|
2925
|
-
break;
|
|
2926
|
-
}
|
|
2927
3220
|
case TraverseType .COLLISION:
|
|
2928
3221
|
{
|
|
2929
|
-
// TODO: to be implemented.
|
|
2930
3222
|
break;
|
|
2931
3223
|
}
|
|
2932
3224
|
case TraverseType .SHADOW:
|
|
@@ -2945,7 +3237,7 @@ function (Fields,
|
|
|
2945
3237
|
}
|
|
2946
3238
|
}
|
|
2947
3239
|
|
|
2948
|
-
if (this .geometryType === GEOMETRY)
|
|
3240
|
+
if (this .geometryType === GeometryTypes .GEOMETRY)
|
|
2949
3241
|
{
|
|
2950
3242
|
if (this .getGeometry ())
|
|
2951
3243
|
this .getGeometry () .traverse (type, renderObject); // Currently used for ScreenText.
|
|
@@ -2953,64 +3245,75 @@ function (Fields,
|
|
|
2953
3245
|
},
|
|
2954
3246
|
depth: function (gl, context, shaderNode)
|
|
2955
3247
|
{
|
|
2956
|
-
// Update geometry if SPRITE.
|
|
2957
|
-
|
|
2958
|
-
this .updateGeometry (context .modelViewMatrix);
|
|
2959
|
-
|
|
2960
3248
|
// Display geometry.
|
|
2961
3249
|
|
|
2962
|
-
|
|
3250
|
+
switch (this .geometryType)
|
|
2963
3251
|
{
|
|
2964
|
-
|
|
3252
|
+
case GeometryTypes .GEOMETRY:
|
|
3253
|
+
{
|
|
3254
|
+
const geometryNode = this .getGeometry ();
|
|
2965
3255
|
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
}
|
|
2969
|
-
else
|
|
2970
|
-
{
|
|
2971
|
-
if (this .numParticles <= 0)
|
|
2972
|
-
return;
|
|
3256
|
+
if (geometryNode)
|
|
3257
|
+
geometryNode .displayParticlesDepth (gl, context, shaderNode, this);
|
|
2973
3258
|
|
|
2974
|
-
|
|
3259
|
+
break;
|
|
3260
|
+
}
|
|
3261
|
+
case GeometryTypes .SPRITE:
|
|
3262
|
+
{
|
|
3263
|
+
this .updateSprite (gl, this .getScreenAlignedRotation (context .modelViewMatrix));
|
|
3264
|
+
// [fall trough]
|
|
3265
|
+
}
|
|
3266
|
+
default:
|
|
2975
3267
|
{
|
|
2976
|
-
|
|
3268
|
+
const outputParticles = this .outputParticles;
|
|
3269
|
+
|
|
3270
|
+
if (outputParticles .shadowArrayObject .enable (gl, shaderNode))
|
|
3271
|
+
{
|
|
3272
|
+
const particleStride = this .particleStride;
|
|
2977
3273
|
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
shaderNode .enableVertexAttribute (gl, this .vertexBuffer);
|
|
3274
|
+
shaderNode .enableParticleAttribute (gl, outputParticles, particleStride, this .particleOffset, 1);
|
|
3275
|
+
shaderNode .enableParticleMatrixAttribute (gl, outputParticles, particleStride, this .matrixOffset, 1);
|
|
3276
|
+
shaderNode .enableVertexAttribute (gl, this .geometryBuffer, 0, this .verticesOffset);
|
|
3277
|
+
}
|
|
2983
3278
|
|
|
2984
|
-
gl .
|
|
3279
|
+
gl .drawArraysInstanced (this .primitiveMode, 0, this .vertexCount, this .numParticles);
|
|
2985
3280
|
|
|
2986
|
-
|
|
2987
|
-
shaderNode .disableFloatAttrib (gl, "x3d_ParticlePosition");
|
|
2988
|
-
shaderNode .disableFloatAttrib (gl, "x3d_ParticleElapsedTime");
|
|
2989
|
-
shaderNode .disableFloatAttrib (gl, "x3d_ParticleLife");
|
|
3281
|
+
break;
|
|
2990
3282
|
}
|
|
2991
3283
|
}
|
|
2992
3284
|
},
|
|
2993
3285
|
display: function (gl, context)
|
|
2994
3286
|
{
|
|
2995
|
-
|
|
2996
|
-
{
|
|
2997
|
-
if (this .numParticles <= 0)
|
|
2998
|
-
return;
|
|
2999
|
-
|
|
3000
|
-
// Update geometry if SPRITE.
|
|
3001
|
-
|
|
3002
|
-
this .updateGeometry (context .modelViewMatrix);
|
|
3003
|
-
|
|
3004
|
-
// Display geometry.
|
|
3287
|
+
// Display geometry.
|
|
3005
3288
|
|
|
3006
|
-
|
|
3289
|
+
switch (this .geometryType)
|
|
3290
|
+
{
|
|
3291
|
+
case GeometryTypes .GEOMETRY:
|
|
3007
3292
|
{
|
|
3008
3293
|
const geometryNode = this .getGeometry ();
|
|
3009
3294
|
|
|
3010
3295
|
if (geometryNode)
|
|
3011
|
-
geometryNode .displayParticles (gl, context, this
|
|
3296
|
+
geometryNode .displayParticles (gl, context, this);
|
|
3297
|
+
|
|
3298
|
+
break;
|
|
3012
3299
|
}
|
|
3013
|
-
|
|
3300
|
+
case GeometryTypes .SPRITE:
|
|
3301
|
+
{
|
|
3302
|
+
this .updateSprite (gl, this .getScreenAlignedRotation (context .modelViewMatrix));
|
|
3303
|
+
// [fall trough]
|
|
3304
|
+
}
|
|
3305
|
+
case GeometryTypes .QUAD:
|
|
3306
|
+
case GeometryTypes .TRIANGLE:
|
|
3307
|
+
{
|
|
3308
|
+
const positiveScale = Matrix4 .prototype .determinant3 .call (context .modelViewMatrix) > 0;
|
|
3309
|
+
|
|
3310
|
+
gl .frontFace (positiveScale ? gl .CCW : gl .CW);
|
|
3311
|
+
gl .enable (gl .CULL_FACE);
|
|
3312
|
+
gl .cullFace (gl .BACK);
|
|
3313
|
+
|
|
3314
|
+
// [fall trough]
|
|
3315
|
+
}
|
|
3316
|
+
default:
|
|
3014
3317
|
{
|
|
3015
3318
|
const
|
|
3016
3319
|
appearanceNode = this .getAppearance (),
|
|
@@ -3018,7 +3321,7 @@ function (Fields,
|
|
|
3018
3321
|
|
|
3019
3322
|
// Setup shader.
|
|
3020
3323
|
|
|
3021
|
-
if (shaderNode .
|
|
3324
|
+
if (shaderNode .isValid ())
|
|
3022
3325
|
{
|
|
3023
3326
|
context .geometryContext = this .geometryContext;
|
|
3024
3327
|
|
|
@@ -3030,85 +3333,98 @@ function (Fields,
|
|
|
3030
3333
|
shaderNode .enable (gl);
|
|
3031
3334
|
shaderNode .setLocalUniforms (gl, context);
|
|
3032
3335
|
|
|
3336
|
+
if (this .numTexCoords)
|
|
3337
|
+
{
|
|
3338
|
+
const textureUnit = context .browser .getTexture2DUnit ();
|
|
3339
|
+
|
|
3340
|
+
gl .activeTexture (gl .TEXTURE0 + textureUnit);
|
|
3341
|
+
gl .bindTexture (gl .TEXTURE_2D, this .texCoordRampTexture);
|
|
3342
|
+
gl .uniform1i (shaderNode .x3d_TexCoordRamp, textureUnit);
|
|
3343
|
+
}
|
|
3344
|
+
|
|
3033
3345
|
// Setup vertex attributes.
|
|
3034
3346
|
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3347
|
+
const outputParticles = this .outputParticles;
|
|
3348
|
+
|
|
3349
|
+
if (outputParticles .vertexArrayObject .enable (gl, shaderNode))
|
|
3350
|
+
{
|
|
3351
|
+
const particleStride = this .particleStride;
|
|
3352
|
+
|
|
3353
|
+
shaderNode .enableParticleAttribute (gl, outputParticles, particleStride, this .particleOffset, 1);
|
|
3354
|
+
shaderNode .enableParticleMatrixAttribute (gl, outputParticles, particleStride, this .matrixOffset, 1);
|
|
3039
3355
|
|
|
3040
|
-
|
|
3041
|
-
|
|
3356
|
+
if (this .geometryContext .colorMaterial)
|
|
3357
|
+
{
|
|
3358
|
+
shaderNode .enableColorAttribute (gl, outputParticles, particleStride, this .colorOffset);
|
|
3359
|
+
shaderNode .colorAttributeDivisor (gl, 1);
|
|
3360
|
+
}
|
|
3042
3361
|
|
|
3043
|
-
|
|
3044
|
-
|
|
3362
|
+
if (this .texCoordCount)
|
|
3363
|
+
shaderNode .enableTexCoordAttribute (gl, this .texCoordBuffers, 0, this .texCoordOffset);
|
|
3045
3364
|
|
|
3046
|
-
|
|
3047
|
-
|
|
3365
|
+
if (this .hasNormals)
|
|
3366
|
+
{
|
|
3367
|
+
shaderNode .enableNormalAttribute (gl, this .geometryBuffer, 0, this .normalOffset);
|
|
3368
|
+
shaderNode .normalAttributeDivisor (gl, this .maxParticles);
|
|
3369
|
+
}
|
|
3048
3370
|
|
|
3049
|
-
|
|
3371
|
+
shaderNode .enableVertexAttribute (gl, this .geometryBuffer, 0, this .verticesOffset);
|
|
3372
|
+
}
|
|
3050
3373
|
|
|
3051
3374
|
if (shaderNode .wireframe && this .testWireframe)
|
|
3052
3375
|
{
|
|
3053
3376
|
// Wireframes are always solid so only one drawing call is needed.
|
|
3054
3377
|
|
|
3055
|
-
for (
|
|
3378
|
+
for (let i = 0, length = this .numParticles * this .vertexCount; i < length; i += 3)
|
|
3056
3379
|
gl .drawArrays (shaderNode .primitiveMode, i, 3);
|
|
3057
3380
|
}
|
|
3058
3381
|
else
|
|
3059
3382
|
{
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
gl .frontFace (positiveScale ? gl .CCW : gl .CW);
|
|
3063
|
-
gl .enable (gl .CULL_FACE);
|
|
3064
|
-
gl .cullFace (gl .BACK);
|
|
3065
|
-
|
|
3066
|
-
gl .drawArrays (this .primitiveMode, 0, this .numParticles * this .vertexCount);
|
|
3383
|
+
gl .drawArraysInstanced (this .primitiveMode, 0, this .vertexCount, this .numParticles);
|
|
3067
3384
|
}
|
|
3068
3385
|
|
|
3069
|
-
shaderNode .disableFloatAttrib (gl, "x3d_ParticleId");
|
|
3070
|
-
shaderNode .disableFloatAttrib (gl, "x3d_ParticlePosition");
|
|
3071
|
-
shaderNode .disableFloatAttrib (gl, "x3d_ParticleElapsedTime");
|
|
3072
|
-
shaderNode .disableFloatAttrib (gl, "x3d_ParticleLife");
|
|
3073
|
-
|
|
3074
|
-
shaderNode .disableColorAttribute (gl);
|
|
3075
|
-
shaderNode .disableTexCoordAttribute (gl);
|
|
3076
|
-
shaderNode .disableNormalAttribute (gl);
|
|
3077
|
-
|
|
3078
3386
|
if (blendModeNode)
|
|
3079
3387
|
blendModeNode .disable (gl);
|
|
3080
3388
|
|
|
3081
|
-
context .geometryContext
|
|
3389
|
+
delete context .geometryContext;
|
|
3082
3390
|
}
|
|
3391
|
+
|
|
3392
|
+
break;
|
|
3083
3393
|
}
|
|
3084
3394
|
}
|
|
3085
|
-
catch (error)
|
|
3086
|
-
{
|
|
3087
|
-
// Catch error from setLocalUniforms.
|
|
3088
|
-
console .error (error);
|
|
3089
|
-
}
|
|
3090
3395
|
},
|
|
3091
|
-
getScreenAlignedRotation: function (
|
|
3396
|
+
getScreenAlignedRotation: (function ()
|
|
3092
3397
|
{
|
|
3093
|
-
|
|
3398
|
+
const
|
|
3399
|
+
invModelViewMatrix = new Matrix4 (),
|
|
3400
|
+
billboardToScreen = new Vector3 (0, 0, 0),
|
|
3401
|
+
viewerYAxis = new Vector3 (0, 0, 0),
|
|
3402
|
+
y = new Vector3 (0, 0, 0),
|
|
3403
|
+
rotation = new Matrix3 (9);
|
|
3404
|
+
|
|
3405
|
+
return function (modelViewMatrix)
|
|
3406
|
+
{
|
|
3407
|
+
invModelViewMatrix .assign (modelViewMatrix) .inverse ();
|
|
3408
|
+
invModelViewMatrix .multDirMatrix (billboardToScreen .assign (Vector3 .zAxis));
|
|
3409
|
+
invModelViewMatrix .multDirMatrix (viewerYAxis .assign (Vector3 .yAxis));
|
|
3094
3410
|
|
|
3095
|
-
|
|
3096
|
-
|
|
3411
|
+
const x = viewerYAxis .cross (billboardToScreen);
|
|
3412
|
+
y .assign (billboardToScreen) .cross (x);
|
|
3413
|
+
const z = billboardToScreen;
|
|
3097
3414
|
|
|
3098
|
-
|
|
3099
|
-
y .assign (billboardToScreen) .cross (x);
|
|
3100
|
-
var z = billboardToScreen;
|
|
3415
|
+
// Compose rotation matrix.
|
|
3101
3416
|
|
|
3102
|
-
|
|
3417
|
+
x .normalize ();
|
|
3418
|
+
y .normalize ();
|
|
3419
|
+
z .normalize ();
|
|
3103
3420
|
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3421
|
+
rotation .set (x .x, x .y, x .z,
|
|
3422
|
+
y .x, y .y, y .z,
|
|
3423
|
+
z .x, z .y, z .z);
|
|
3107
3424
|
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
},
|
|
3425
|
+
return rotation;
|
|
3426
|
+
};
|
|
3427
|
+
})(),
|
|
3112
3428
|
});
|
|
3113
3429
|
|
|
3114
3430
|
return ParticleSystem;
|
|
@@ -3171,7 +3487,6 @@ define ('x_ite/Components/ParticleSystems/PolylineEmitter',[
|
|
|
3171
3487
|
"x_ite/Components/Rendering/IndexedLineSet",
|
|
3172
3488
|
"x_ite/Base/X3DConstants",
|
|
3173
3489
|
"standard/Math/Numbers/Vector3",
|
|
3174
|
-
"standard/Math/Algorithm",
|
|
3175
3490
|
],
|
|
3176
3491
|
function (Fields,
|
|
3177
3492
|
X3DFieldDefinition,
|
|
@@ -3179,8 +3494,7 @@ function (Fields,
|
|
|
3179
3494
|
X3DParticleEmitterNode,
|
|
3180
3495
|
IndexedLineSet,
|
|
3181
3496
|
X3DConstants,
|
|
3182
|
-
Vector3
|
|
3183
|
-
Algorithm)
|
|
3497
|
+
Vector3)
|
|
3184
3498
|
{
|
|
3185
3499
|
"use strict";
|
|
3186
3500
|
|
|
@@ -3190,28 +3504,69 @@ function (Fields,
|
|
|
3190
3504
|
|
|
3191
3505
|
this .addType (X3DConstants .PolylineEmitter);
|
|
3192
3506
|
|
|
3193
|
-
this .
|
|
3194
|
-
this .
|
|
3195
|
-
|
|
3507
|
+
this .polylinesNode = new IndexedLineSet (executionContext);
|
|
3508
|
+
this .polylinesArray = new Float32Array ();
|
|
3509
|
+
|
|
3510
|
+
this .addSampler ("polylines");
|
|
3511
|
+
|
|
3512
|
+
this .addUniform ("direction", "uniform vec3 direction;");
|
|
3513
|
+
this .addUniform ("verticesIndex", "uniform int verticesIndex;");
|
|
3514
|
+
this .addUniform ("polylines", "uniform sampler2D polylines;");
|
|
3515
|
+
|
|
3516
|
+
this .addFunction (/* glsl */ `vec3 getRandomVelocity ()
|
|
3517
|
+
{
|
|
3518
|
+
if (direction == vec3 (0.0))
|
|
3519
|
+
return getRandomSphericalVelocity ();
|
|
3520
|
+
|
|
3521
|
+
else
|
|
3522
|
+
return direction * getRandomSpeed ();
|
|
3523
|
+
}`);
|
|
3524
|
+
|
|
3525
|
+
this .addFunction (/* glsl */ `vec4 getRandomPosition ()
|
|
3526
|
+
{
|
|
3527
|
+
if (verticesIndex < 0)
|
|
3528
|
+
{
|
|
3529
|
+
return vec4 (NaN);
|
|
3530
|
+
}
|
|
3531
|
+
else
|
|
3532
|
+
{
|
|
3533
|
+
// Determine index0, index1 and weight.
|
|
3196
3534
|
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3535
|
+
float lastLengthSoFar = texelFetch (polylines, verticesIndex - 1, 0) .x;
|
|
3536
|
+
float fraction = random () * lastLengthSoFar;
|
|
3537
|
+
|
|
3538
|
+
int index0 = 0;
|
|
3539
|
+
int index1 = 0;
|
|
3540
|
+
float weight = 0.0;
|
|
3541
|
+
|
|
3542
|
+
interpolate (polylines, verticesIndex, fraction, index0, index1, weight);
|
|
3543
|
+
|
|
3544
|
+
// Interpolate and return position.
|
|
3545
|
+
|
|
3546
|
+
index0 *= 2;
|
|
3547
|
+
index1 = index0 + 1;
|
|
3548
|
+
|
|
3549
|
+
vec4 vertex0 = texelFetch (polylines, verticesIndex + index0, 0);
|
|
3550
|
+
vec4 vertex1 = texelFetch (polylines, verticesIndex + index1, 0);
|
|
3551
|
+
|
|
3552
|
+
return mix (vertex0, vertex1, weight);
|
|
3553
|
+
}
|
|
3554
|
+
}`);
|
|
3201
3555
|
}
|
|
3202
3556
|
|
|
3203
3557
|
PolylineEmitter .prototype = Object .assign (Object .create (X3DParticleEmitterNode .prototype),
|
|
3204
3558
|
{
|
|
3205
3559
|
constructor: PolylineEmitter,
|
|
3206
3560
|
[Symbol .for ("X_ITE.X3DBaseNode.fieldDefinitions")]: new FieldDefinitionArray ([
|
|
3207
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
3208
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
3209
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
3210
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
3211
|
-
new X3DFieldDefinition (X3DConstants .
|
|
3212
|
-
new X3DFieldDefinition (X3DConstants .
|
|
3213
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
3214
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
3561
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "metadata", new Fields .SFNode ()),
|
|
3562
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "on", new Fields .SFBool (true)),
|
|
3563
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "direction", new Fields .SFVec3f (0, 1, 0)),
|
|
3564
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "speed", new Fields .SFFloat ()),
|
|
3565
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "variation", new Fields .SFFloat (0.25)),
|
|
3566
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "mass", new Fields .SFFloat ()),
|
|
3567
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "surfaceArea", new Fields .SFFloat ()),
|
|
3568
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "coordIndex", new Fields .MFInt32 (-1)),
|
|
3569
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "coord", new Fields .SFNode ()),
|
|
3215
3570
|
]),
|
|
3216
3571
|
getTypeName: function ()
|
|
3217
3572
|
{
|
|
@@ -3229,148 +3584,93 @@ function (Fields,
|
|
|
3229
3584
|
{
|
|
3230
3585
|
X3DParticleEmitterNode .prototype .initialize .call (this);
|
|
3231
3586
|
|
|
3587
|
+
const browser = this .getBrowser ();
|
|
3588
|
+
|
|
3589
|
+
if (browser .getContext () .getVersion () < 2)
|
|
3590
|
+
return;
|
|
3591
|
+
|
|
3592
|
+
// Create GL stuff.
|
|
3593
|
+
|
|
3594
|
+
this .polylinesTexture = this .createTexture ();
|
|
3595
|
+
|
|
3596
|
+
// Initialize fields.
|
|
3597
|
+
|
|
3232
3598
|
this ._direction .addInterest ("set_direction__", this);
|
|
3233
3599
|
|
|
3234
|
-
this ._coordIndex .addFieldInterest (this .
|
|
3235
|
-
this ._coord .addFieldInterest (this .
|
|
3600
|
+
this ._coordIndex .addFieldInterest (this .polylinesNode ._coordIndex);
|
|
3601
|
+
this ._coord .addFieldInterest (this .polylinesNode ._coord);
|
|
3236
3602
|
|
|
3237
|
-
this .
|
|
3238
|
-
this .
|
|
3603
|
+
this .polylinesNode ._coordIndex = this ._coordIndex;
|
|
3604
|
+
this .polylinesNode ._coord = this ._coord;
|
|
3239
3605
|
|
|
3240
|
-
this .
|
|
3241
|
-
this .
|
|
3242
|
-
this .
|
|
3606
|
+
this .polylinesNode ._rebuild .addInterest ("set_polyline", this);
|
|
3607
|
+
this .polylinesNode .setPrivate (true);
|
|
3608
|
+
this .polylinesNode .setup ();
|
|
3243
3609
|
|
|
3244
3610
|
this .set_direction__ ();
|
|
3245
3611
|
this .set_polyline ();
|
|
3246
3612
|
},
|
|
3247
|
-
set_direction__: function ()
|
|
3613
|
+
set_direction__: (function ()
|
|
3248
3614
|
{
|
|
3249
|
-
|
|
3615
|
+
const direction = new Vector3 (0, 0, 0);
|
|
3250
3616
|
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3617
|
+
return function ()
|
|
3618
|
+
{
|
|
3619
|
+
direction .assign (this ._direction .getValue ()) .normalize ();
|
|
3620
|
+
|
|
3621
|
+
this .setUniform ("uniform3f", "direction", direction .x, direction .y, direction .z);
|
|
3622
|
+
};
|
|
3623
|
+
})(),
|
|
3256
3624
|
set_polyline: (function ()
|
|
3257
3625
|
{
|
|
3258
|
-
|
|
3626
|
+
const
|
|
3259
3627
|
vertex1 = new Vector3 (0, 0, 0),
|
|
3260
3628
|
vertex2 = new Vector3 (0, 0, 0);
|
|
3261
3629
|
|
|
3262
3630
|
return function ()
|
|
3263
3631
|
{
|
|
3264
|
-
|
|
3632
|
+
const
|
|
3633
|
+
gl = this .getBrowser () .getContext (),
|
|
3634
|
+
vertices = this .polylinesNode .getVertices () .getValue (),
|
|
3635
|
+
numVertices = vertices .length / 4,
|
|
3636
|
+
numLengthSoFar = numVertices / 2 + 1,
|
|
3637
|
+
polylineArraySize = Math .ceil (Math .sqrt (numLengthSoFar + numVertices));
|
|
3265
3638
|
|
|
3266
|
-
|
|
3267
|
-
{
|
|
3268
|
-
delete this .getRandomPosition;
|
|
3639
|
+
const verticesIndex = numLengthSoFar;
|
|
3269
3640
|
|
|
3270
|
-
|
|
3271
|
-
lengthSoFar = 0,
|
|
3272
|
-
lengthSoFarArray = this .lengthSoFarArray;
|
|
3641
|
+
let polylinesArray = this .polylinesArray;
|
|
3273
3642
|
|
|
3274
|
-
|
|
3643
|
+
if (polylinesArray .length < polylineArraySize * polylineArraySize * 4)
|
|
3644
|
+
polylinesArray = this .polylinesArray = new Float32Array (polylineArraySize * polylineArraySize * 4);
|
|
3275
3645
|
|
|
3276
|
-
|
|
3277
|
-
{
|
|
3278
|
-
vertex1 .set (vertices [i], vertices [i + 1], vertices [i + 2]);
|
|
3279
|
-
vertex2 .set (vertices [i + 4], vertices [i + 5], vertices [i + 6]);
|
|
3646
|
+
let lengthSoFar = 0;
|
|
3280
3647
|
|
|
3281
|
-
|
|
3282
|
-
lengthSoFarArray .push (lengthSoFar);
|
|
3283
|
-
}
|
|
3284
|
-
}
|
|
3285
|
-
else
|
|
3648
|
+
for (let i = 0, length = vertices .length; i < length; i += 8)
|
|
3286
3649
|
{
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
};
|
|
3290
|
-
})(),
|
|
3291
|
-
getRandomPosition: function (position)
|
|
3292
|
-
{
|
|
3293
|
-
// Determine index0 and weight.
|
|
3294
|
-
|
|
3295
|
-
var
|
|
3296
|
-
lengthSoFarArray = this .lengthSoFarArray,
|
|
3297
|
-
length = lengthSoFarArray .length,
|
|
3298
|
-
fraction = Math .random () * lengthSoFarArray .at (-1),
|
|
3299
|
-
index0 = 0,
|
|
3300
|
-
index1 = 0,
|
|
3301
|
-
weight = 0;
|
|
3650
|
+
vertex1 .set (vertices [i], vertices [i + 1], vertices [i + 2]);
|
|
3651
|
+
vertex2 .set (vertices [i + 4], vertices [i + 5], vertices [i + 6]);
|
|
3302
3652
|
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
index0 = 0;
|
|
3306
|
-
weight = 0;
|
|
3307
|
-
}
|
|
3308
|
-
else if (fraction >= lengthSoFarArray .at (-1))
|
|
3309
|
-
{
|
|
3310
|
-
index0 = length - 2;
|
|
3311
|
-
weight = 1;
|
|
3312
|
-
}
|
|
3313
|
-
else
|
|
3314
|
-
{
|
|
3315
|
-
var index = Algorithm .upperBound (lengthSoFarArray, 0, length, fraction, Algorithm .less);
|
|
3653
|
+
polylinesArray [i / 2 + 4] = lengthSoFar += vertex2 .subtract (vertex1) .abs ();
|
|
3654
|
+
}
|
|
3316
3655
|
|
|
3317
|
-
|
|
3318
|
-
{
|
|
3319
|
-
index1 = index;
|
|
3320
|
-
index0 = index - 1;
|
|
3656
|
+
polylinesArray .set (vertices, verticesIndex * 4);
|
|
3321
3657
|
|
|
3322
|
-
|
|
3323
|
-
key0 = lengthSoFarArray [index0],
|
|
3324
|
-
key1 = lengthSoFarArray [index1];
|
|
3658
|
+
this .setUniform ("uniform1i", "verticesIndex", numVertices ? verticesIndex : -1);
|
|
3325
3659
|
|
|
3326
|
-
|
|
3327
|
-
}
|
|
3328
|
-
else
|
|
3660
|
+
if (polylineArraySize)
|
|
3329
3661
|
{
|
|
3330
|
-
|
|
3331
|
-
|
|
3662
|
+
gl .bindTexture (gl .TEXTURE_2D, this .polylinesTexture);
|
|
3663
|
+
gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, polylineArraySize, polylineArraySize, 0, gl .RGBA, gl .FLOAT, polylinesArray);
|
|
3332
3664
|
}
|
|
3333
|
-
}
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
index0 *= 8;
|
|
3338
|
-
index1 = index0 + 4;
|
|
3339
|
-
|
|
3340
|
-
var
|
|
3341
|
-
vertices = this .vertices,
|
|
3342
|
-
x1 = vertices [index0],
|
|
3343
|
-
y1 = vertices [index0 + 1],
|
|
3344
|
-
z1 = vertices [index0 + 2],
|
|
3345
|
-
x2 = vertices [index1],
|
|
3346
|
-
y2 = vertices [index1 + 1],
|
|
3347
|
-
z2 = vertices [index1 + 2];
|
|
3348
|
-
|
|
3349
|
-
position .x = x1 + weight * (x2 - x1);
|
|
3350
|
-
position .y = y1 + weight * (y2 - y1);
|
|
3351
|
-
position .z = z1 + weight * (z2 - z1);
|
|
3352
|
-
|
|
3353
|
-
return position;
|
|
3354
|
-
},
|
|
3355
|
-
getRandomVelocity: function (velocity)
|
|
3665
|
+
};
|
|
3666
|
+
})(),
|
|
3667
|
+
activateTextures: function (gl, program)
|
|
3356
3668
|
{
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
velocity .x = direction .x * speed;
|
|
3362
|
-
velocity .y = direction .y * speed;
|
|
3363
|
-
velocity .z = direction .z * speed;
|
|
3364
|
-
|
|
3365
|
-
return velocity;
|
|
3366
|
-
},
|
|
3669
|
+
gl .activeTexture (gl .TEXTURE0 + program .polylinesTextureUnit);
|
|
3670
|
+
gl .bindTexture (gl .TEXTURE_2D, this .polylinesTexture);
|
|
3671
|
+
},
|
|
3367
3672
|
});
|
|
3368
3673
|
|
|
3369
|
-
function getPosition (position)
|
|
3370
|
-
{
|
|
3371
|
-
return position .set (0, 0, 0);
|
|
3372
|
-
}
|
|
3373
|
-
|
|
3374
3674
|
return PolylineEmitter;
|
|
3375
3675
|
});
|
|
3376
3676
|
|
|
@@ -3432,7 +3732,6 @@ define ('x_ite/Components/ParticleSystems/SurfaceEmitter',[
|
|
|
3432
3732
|
"x_ite/Base/X3DCast",
|
|
3433
3733
|
"standard/Math/Geometry/Triangle3",
|
|
3434
3734
|
"standard/Math/Numbers/Vector3",
|
|
3435
|
-
"standard/Math/Algorithm",
|
|
3436
3735
|
],
|
|
3437
3736
|
function (Fields,
|
|
3438
3737
|
X3DFieldDefinition,
|
|
@@ -3441,8 +3740,7 @@ function (Fields,
|
|
|
3441
3740
|
X3DConstants,
|
|
3442
3741
|
X3DCast,
|
|
3443
3742
|
Triangle3,
|
|
3444
|
-
Vector3
|
|
3445
|
-
Algorithm)
|
|
3743
|
+
Vector3)
|
|
3446
3744
|
{
|
|
3447
3745
|
"use strict";
|
|
3448
3746
|
|
|
@@ -3452,25 +3750,52 @@ function (Fields,
|
|
|
3452
3750
|
|
|
3453
3751
|
this .addType (X3DConstants .SurfaceEmitter);
|
|
3454
3752
|
|
|
3455
|
-
this .
|
|
3456
|
-
this .
|
|
3457
|
-
|
|
3753
|
+
this .surfaceNode = null;
|
|
3754
|
+
this .surfaceArray = new Float32Array ();
|
|
3755
|
+
|
|
3756
|
+
this .addSampler ("surface");
|
|
3757
|
+
|
|
3758
|
+
this .addUniform ("solid", "uniform bool solid;");
|
|
3759
|
+
this .addUniform ("verticesIndex", "uniform int verticesIndex;");
|
|
3760
|
+
this .addUniform ("normalsIndex", "uniform int normalsIndex;");
|
|
3761
|
+
this .addUniform ("surface", "uniform sampler2D surface;");
|
|
3458
3762
|
|
|
3459
|
-
this .
|
|
3460
|
-
|
|
3461
|
-
|
|
3763
|
+
this .addFunction (/* glsl */ `vec4 position; vec3 getRandomVelocity ()
|
|
3764
|
+
{
|
|
3765
|
+
if (verticesIndex < 0)
|
|
3766
|
+
{
|
|
3767
|
+
return vec3 (0.0);
|
|
3768
|
+
}
|
|
3769
|
+
else
|
|
3770
|
+
{
|
|
3771
|
+
vec3 normal;
|
|
3772
|
+
|
|
3773
|
+
getRandomPointOnSurface (surface, verticesIndex, normalsIndex, position, normal);
|
|
3774
|
+
|
|
3775
|
+
if (solid == false && random () > 0.5)
|
|
3776
|
+
normal = -normal;
|
|
3777
|
+
|
|
3778
|
+
return normal * getRandomSpeed ();
|
|
3779
|
+
}
|
|
3780
|
+
}`);
|
|
3781
|
+
|
|
3782
|
+
this .addFunction (/* glsl */ `vec4 getRandomPosition ()
|
|
3783
|
+
{
|
|
3784
|
+
return verticesIndex < 0 ? vec4 (NaN) : position;
|
|
3785
|
+
}`);
|
|
3462
3786
|
}
|
|
3463
3787
|
|
|
3464
3788
|
SurfaceEmitter .prototype = Object .assign (Object .create (X3DParticleEmitterNode .prototype),
|
|
3465
3789
|
{
|
|
3466
3790
|
constructor: SurfaceEmitter,
|
|
3467
3791
|
[Symbol .for ("X_ITE.X3DBaseNode.fieldDefinitions")]: new FieldDefinitionArray ([
|
|
3468
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
3469
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
3470
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
3471
|
-
new X3DFieldDefinition (X3DConstants .
|
|
3472
|
-
new X3DFieldDefinition (X3DConstants .
|
|
3473
|
-
new X3DFieldDefinition (X3DConstants .
|
|
3792
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "metadata", new Fields .SFNode ()),
|
|
3793
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "on", new Fields .SFBool (true)),
|
|
3794
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "speed", new Fields .SFFloat ()),
|
|
3795
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "variation", new Fields .SFFloat (0.25)),
|
|
3796
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "mass", new Fields .SFFloat ()),
|
|
3797
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "surfaceArea", new Fields .SFFloat ()),
|
|
3798
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "surface", new Fields .SFNode ()),
|
|
3474
3799
|
]),
|
|
3475
3800
|
getTypeName: function ()
|
|
3476
3801
|
{
|
|
@@ -3488,6 +3813,17 @@ function (Fields,
|
|
|
3488
3813
|
{
|
|
3489
3814
|
X3DParticleEmitterNode .prototype .initialize .call (this);
|
|
3490
3815
|
|
|
3816
|
+
const browser = this .getBrowser ();
|
|
3817
|
+
|
|
3818
|
+
if (browser .getContext () .getVersion () < 2)
|
|
3819
|
+
return;
|
|
3820
|
+
|
|
3821
|
+
// Create GL stuff.
|
|
3822
|
+
|
|
3823
|
+
this .surfaceTexture = this .createTexture ();
|
|
3824
|
+
|
|
3825
|
+
// Initialize fields.
|
|
3826
|
+
|
|
3491
3827
|
this ._surface .addInterest ("set_surface__", this);
|
|
3492
3828
|
|
|
3493
3829
|
this .set_surface__ ();
|
|
@@ -3495,142 +3831,99 @@ function (Fields,
|
|
|
3495
3831
|
set_surface__: function ()
|
|
3496
3832
|
{
|
|
3497
3833
|
if (this .surfaceNode)
|
|
3834
|
+
{
|
|
3835
|
+
this .surfaceNode ._solid .removeInterest ("set_solid__", this);
|
|
3498
3836
|
this .surfaceNode ._rebuild .removeInterest ("set_geometry__", this);
|
|
3837
|
+
}
|
|
3499
3838
|
|
|
3500
3839
|
this .surfaceNode = X3DCast (X3DConstants .X3DGeometryNode, this ._surface);
|
|
3501
3840
|
|
|
3502
3841
|
if (this .surfaceNode)
|
|
3842
|
+
{
|
|
3843
|
+
this .surfaceNode ._solid .addInterest ("set_solid__", this);
|
|
3503
3844
|
this .surfaceNode ._rebuild .addInterest ("set_geometry__", this);
|
|
3845
|
+
}
|
|
3504
3846
|
|
|
3847
|
+
this .set_solid__ ();
|
|
3505
3848
|
this .set_geometry__ ();
|
|
3506
3849
|
},
|
|
3850
|
+
set_solid__: function ()
|
|
3851
|
+
{
|
|
3852
|
+
if (this .surfaceNode)
|
|
3853
|
+
this .setUniform ("uniform1i", "solid", this .surfaceNode ._solid .getValue ());
|
|
3854
|
+
},
|
|
3507
3855
|
set_geometry__: (function ()
|
|
3508
3856
|
{
|
|
3509
|
-
|
|
3857
|
+
const
|
|
3510
3858
|
vertex1 = new Vector3 (0, 0, 0),
|
|
3511
3859
|
vertex2 = new Vector3 (0, 0, 0),
|
|
3512
3860
|
vertex3 = new Vector3 (0, 0, 0);
|
|
3513
3861
|
|
|
3514
3862
|
return function ()
|
|
3515
3863
|
{
|
|
3864
|
+
const gl = this .getBrowser () .getContext ();
|
|
3865
|
+
|
|
3516
3866
|
if (this .surfaceNode)
|
|
3517
3867
|
{
|
|
3518
|
-
|
|
3519
|
-
|
|
3868
|
+
const
|
|
3869
|
+
vertices = this .surfaceNode .getVertices () .getValue (),
|
|
3870
|
+
normals = this .surfaceNode .getNormals () .getValue (),
|
|
3871
|
+
numVertices = vertices .length / 4,
|
|
3872
|
+
numAreaSoFar = numVertices / 3 + 1,
|
|
3873
|
+
surfaceArraySize = Math .ceil (Math .sqrt (numAreaSoFar + numVertices + numVertices));
|
|
3874
|
+
|
|
3875
|
+
const
|
|
3876
|
+
verticesIndex = numAreaSoFar,
|
|
3877
|
+
normalsIndex = verticesIndex + numVertices;
|
|
3520
3878
|
|
|
3521
|
-
|
|
3522
|
-
areaSoFar = 0,
|
|
3523
|
-
areaSoFarArray = this .areaSoFarArray,
|
|
3524
|
-
vertices = this .surfaceNode .getVertices () .getValue ();
|
|
3879
|
+
let surfaceArray = this .surfaceArray;
|
|
3525
3880
|
|
|
3526
|
-
|
|
3527
|
-
|
|
3881
|
+
if (surfaceArray .length < surfaceArraySize * surfaceArraySize * 4)
|
|
3882
|
+
surfaceArray = this .surfaceArray = new Float32Array (surfaceArraySize * surfaceArraySize * 4);
|
|
3528
3883
|
|
|
3529
|
-
|
|
3884
|
+
let areaSoFar = 0;
|
|
3530
3885
|
|
|
3531
|
-
for (
|
|
3886
|
+
for (let i = 0, length = vertices .length; i < length; i += 12)
|
|
3532
3887
|
{
|
|
3533
3888
|
vertex1 .set (vertices [i], vertices [i + 1], vertices [i + 2]);
|
|
3534
3889
|
vertex2 .set (vertices [i + 4], vertices [i + 5], vertices [i + 6]);
|
|
3535
3890
|
vertex3 .set (vertices [i + 8], vertices [i + 9], vertices [i + 10]);
|
|
3536
3891
|
|
|
3537
|
-
areaSoFar += Triangle3 .area (vertex1, vertex2, vertex3);
|
|
3538
|
-
areaSoFarArray .push (areaSoFar);
|
|
3892
|
+
surfaceArray [i / 3 + 4] = areaSoFar += Triangle3 .area (vertex1, vertex2, vertex3);
|
|
3539
3893
|
}
|
|
3540
|
-
}
|
|
3541
|
-
else
|
|
3542
|
-
{
|
|
3543
|
-
this .getRandomPosition = getPosition;
|
|
3544
|
-
this .getRandomVelocity = this .getSphericalRandomVelocity;
|
|
3545
|
-
}
|
|
3546
|
-
};
|
|
3547
|
-
})(),
|
|
3548
|
-
getRandomPosition: function (position)
|
|
3549
|
-
{
|
|
3550
|
-
// Determine index0.
|
|
3551
3894
|
|
|
3552
|
-
|
|
3553
|
-
areaSoFarArray = this .areaSoFarArray,
|
|
3554
|
-
length = areaSoFarArray .length,
|
|
3555
|
-
fraction = Math .random () * areaSoFarArray .at (-1),
|
|
3556
|
-
index0 = 0;
|
|
3895
|
+
surfaceArray .set (vertices, verticesIndex * 4);
|
|
3557
3896
|
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
index0 = length - 2;
|
|
3565
|
-
}
|
|
3566
|
-
else
|
|
3567
|
-
{
|
|
3568
|
-
var index = Algorithm .upperBound (areaSoFarArray, 0, length, fraction, Algorithm .less);
|
|
3897
|
+
for (let s = normalsIndex * 4, n = 0, l = normals .length; n < l; s += 4, n += 3)
|
|
3898
|
+
{
|
|
3899
|
+
surfaceArray [s + 0] = normals [n + 0];
|
|
3900
|
+
surfaceArray [s + 1] = normals [n + 1];
|
|
3901
|
+
surfaceArray [s + 2] = normals [n + 2];
|
|
3902
|
+
}
|
|
3569
3903
|
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3904
|
+
this .setUniform ("uniform1i", "verticesIndex", numVertices ? verticesIndex : -1);
|
|
3905
|
+
this .setUniform ("uniform1i", "normalsIndex", numVertices ? normalsIndex : -1);
|
|
3906
|
+
|
|
3907
|
+
if (surfaceArraySize)
|
|
3908
|
+
{
|
|
3909
|
+
gl .bindTexture (gl .TEXTURE_2D, this .surfaceTexture);
|
|
3910
|
+
gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, surfaceArraySize, surfaceArraySize, 0, gl .RGBA, gl .FLOAT, surfaceArray);
|
|
3911
|
+
}
|
|
3573
3912
|
}
|
|
3574
3913
|
else
|
|
3575
3914
|
{
|
|
3576
|
-
|
|
3915
|
+
this .setUniform ("uniform1i", "verticesIndex", -1);
|
|
3916
|
+
this .setUniform ("uniform1i", "normalsIndex", -1);
|
|
3577
3917
|
}
|
|
3578
|
-
}
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
var
|
|
3583
|
-
u = Math .random (),
|
|
3584
|
-
v = Math .random ();
|
|
3585
|
-
|
|
3586
|
-
if (u + v > 1)
|
|
3587
|
-
{
|
|
3588
|
-
u = 1 - u;
|
|
3589
|
-
v = 1 - v;
|
|
3590
|
-
}
|
|
3591
|
-
|
|
3592
|
-
var t = 1 - u - v;
|
|
3593
|
-
|
|
3594
|
-
// Interpolate and set position.
|
|
3595
|
-
|
|
3596
|
-
var
|
|
3597
|
-
i = index0 * 12,
|
|
3598
|
-
vertices = this .vertices;
|
|
3599
|
-
|
|
3600
|
-
position .x = u * vertices [i] + v * vertices [i + 4] + t * vertices [i + 8];
|
|
3601
|
-
position .y = u * vertices [i + 1] + v * vertices [i + 5] + t * vertices [i + 9];
|
|
3602
|
-
position .z = u * vertices [i + 2] + v * vertices [i + 6] + t * vertices [i + 10];
|
|
3603
|
-
|
|
3604
|
-
var
|
|
3605
|
-
i = index0 * 9,
|
|
3606
|
-
normals = this .normals,
|
|
3607
|
-
direction = this .direction;
|
|
3608
|
-
|
|
3609
|
-
direction .x = u * normals [i] + v * normals [i + 3] + t * normals [i + 6];
|
|
3610
|
-
direction .y = u * normals [i + 1] + v * normals [i + 4] + t * normals [i + 7];
|
|
3611
|
-
direction .z = u * normals [i + 2] + v * normals [i + 5] + t * normals [i + 8];
|
|
3612
|
-
|
|
3613
|
-
return position;
|
|
3614
|
-
},
|
|
3615
|
-
getRandomVelocity: function (velocity)
|
|
3918
|
+
};
|
|
3919
|
+
})(),
|
|
3920
|
+
activateTextures: function (gl, program)
|
|
3616
3921
|
{
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
velocity .x = direction .x * speed;
|
|
3622
|
-
velocity .y = direction .y * speed;
|
|
3623
|
-
velocity .z = direction .z * speed;
|
|
3624
|
-
|
|
3625
|
-
return velocity;
|
|
3626
|
-
},
|
|
3922
|
+
gl .activeTexture (gl .TEXTURE0 + program .surfaceTextureUnit);
|
|
3923
|
+
gl .bindTexture (gl .TEXTURE_2D, this .surfaceTexture);
|
|
3924
|
+
},
|
|
3627
3925
|
});
|
|
3628
3926
|
|
|
3629
|
-
function getPosition (position)
|
|
3630
|
-
{
|
|
3631
|
-
return position .set (0, 0, 0);
|
|
3632
|
-
}
|
|
3633
|
-
|
|
3634
3927
|
return SurfaceEmitter;
|
|
3635
3928
|
});
|
|
3636
3929
|
|
|
@@ -3691,13 +3984,8 @@ define ('x_ite/Components/ParticleSystems/VolumeEmitter',[
|
|
|
3691
3984
|
"x_ite/Components/Geometry3D/IndexedFaceSet",
|
|
3692
3985
|
"x_ite/Base/X3DConstants",
|
|
3693
3986
|
"standard/Math/Numbers/Vector3",
|
|
3694
|
-
"standard/Math/Numbers/Rotation4",
|
|
3695
|
-
"standard/Math/Geometry/Line3",
|
|
3696
|
-
"standard/Math/Geometry/Plane3",
|
|
3697
3987
|
"standard/Math/Geometry/Triangle3",
|
|
3698
|
-
"standard/Math/Algorithm",
|
|
3699
3988
|
"standard/Math/Utility/BVH",
|
|
3700
|
-
"standard/Math/Algorithms/QuickSort",
|
|
3701
3989
|
],
|
|
3702
3990
|
function (Fields,
|
|
3703
3991
|
X3DFieldDefinition,
|
|
@@ -3706,13 +3994,8 @@ function (Fields,
|
|
|
3706
3994
|
IndexedFaceSet,
|
|
3707
3995
|
X3DConstants,
|
|
3708
3996
|
Vector3,
|
|
3709
|
-
Rotation4,
|
|
3710
|
-
Line3,
|
|
3711
|
-
Plane3,
|
|
3712
3997
|
Triangle3,
|
|
3713
|
-
|
|
3714
|
-
BVH,
|
|
3715
|
-
QuickSort)
|
|
3998
|
+
BVH)
|
|
3716
3999
|
{
|
|
3717
4000
|
"use strict";
|
|
3718
4001
|
|
|
@@ -3722,28 +4005,87 @@ function (Fields,
|
|
|
3722
4005
|
|
|
3723
4006
|
this .addType (X3DConstants .VolumeEmitter);
|
|
3724
4007
|
|
|
3725
|
-
this .
|
|
3726
|
-
this .
|
|
3727
|
-
|
|
4008
|
+
this .volumeNode = new IndexedFaceSet (executionContext);
|
|
4009
|
+
this .volumeArray = new Float32Array ();
|
|
4010
|
+
|
|
4011
|
+
this .addSampler ("volume");
|
|
4012
|
+
|
|
4013
|
+
this .addUniform ("direction", "uniform vec3 direction;");
|
|
4014
|
+
this .addUniform ("verticesIndex", "uniform int verticesIndex;");
|
|
4015
|
+
this .addUniform ("normalsIndex", "uniform int normalsIndex;");
|
|
4016
|
+
this .addUniform ("hierarchyIndex", "uniform int hierarchyIndex;");
|
|
4017
|
+
this .addUniform ("hierarchyRoot", "uniform int hierarchyRoot;");
|
|
4018
|
+
this .addUniform ("volume", "uniform sampler2D volume;");
|
|
4019
|
+
|
|
4020
|
+
this .addFunction (/* glsl */ `vec3 getRandomVelocity ()
|
|
4021
|
+
{
|
|
4022
|
+
if (hierarchyRoot < 0)
|
|
4023
|
+
{
|
|
4024
|
+
return vec3 (0.0);
|
|
4025
|
+
}
|
|
4026
|
+
else
|
|
4027
|
+
{
|
|
4028
|
+
if (direction == vec3 (0.0))
|
|
4029
|
+
return getRandomSphericalVelocity ();
|
|
4030
|
+
|
|
4031
|
+
else
|
|
4032
|
+
return direction * getRandomSpeed ();
|
|
4033
|
+
}
|
|
4034
|
+
}`);
|
|
4035
|
+
|
|
4036
|
+
this .addFunction (/* glsl */ `vec4 getRandomPosition ()
|
|
4037
|
+
{
|
|
4038
|
+
if (hierarchyRoot < 0)
|
|
4039
|
+
{
|
|
4040
|
+
return vec4 (NaN);
|
|
4041
|
+
}
|
|
4042
|
+
else
|
|
4043
|
+
{
|
|
4044
|
+
vec4 point;
|
|
4045
|
+
vec3 normal;
|
|
4046
|
+
|
|
4047
|
+
getRandomPointOnSurface (volume, verticesIndex, normalsIndex, point, normal);
|
|
4048
|
+
|
|
4049
|
+
Line3 line = Line3 (point .xyz, getRandomSurfaceNormal (normal));
|
|
4050
|
+
|
|
4051
|
+
vec4 points [ARRAY_SIZE];
|
|
4052
|
+
|
|
4053
|
+
int numIntersections = getIntersections (volume, verticesIndex, hierarchyIndex, hierarchyRoot, line, points);
|
|
4054
|
+
|
|
4055
|
+
numIntersections -= numIntersections % 2; // We need an even count of intersections.
|
|
3728
4056
|
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
4057
|
+
switch (numIntersections)
|
|
4058
|
+
{
|
|
4059
|
+
case 0:
|
|
4060
|
+
return vec4 (0.0);
|
|
4061
|
+
case 2:
|
|
4062
|
+
break;
|
|
4063
|
+
default:
|
|
4064
|
+
sort (points, numIntersections, plane3 (line .point, line .direction));
|
|
4065
|
+
break;
|
|
4066
|
+
}
|
|
4067
|
+
|
|
4068
|
+
int index = int (fract (random ()) * float (numIntersections / 2)) * 2; // Select random intersection.
|
|
4069
|
+
|
|
4070
|
+
return mix (points [index], points [index + 1], random ());
|
|
4071
|
+
}
|
|
4072
|
+
}`);
|
|
3732
4073
|
}
|
|
3733
4074
|
|
|
3734
4075
|
VolumeEmitter .prototype = Object .assign (Object .create (X3DParticleEmitterNode .prototype),
|
|
3735
4076
|
{
|
|
3736
4077
|
constructor: VolumeEmitter,
|
|
3737
4078
|
[Symbol .for ("X_ITE.X3DBaseNode.fieldDefinitions")]: new FieldDefinitionArray ([
|
|
3738
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
3739
|
-
new X3DFieldDefinition (X3DConstants .
|
|
3740
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
3741
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
3742
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
3743
|
-
new X3DFieldDefinition (X3DConstants .
|
|
3744
|
-
new X3DFieldDefinition (X3DConstants .
|
|
3745
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
3746
|
-
new X3DFieldDefinition (X3DConstants .inputOutput,
|
|
4079
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "metadata", new Fields .SFNode ()),
|
|
4080
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "on", new Fields .SFBool (true)),
|
|
4081
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "internal", new Fields .SFBool (true)),
|
|
4082
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "direction", new Fields .SFVec3f (0, 1, 0)),
|
|
4083
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "speed", new Fields .SFFloat ()),
|
|
4084
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "variation", new Fields .SFFloat (0.25)),
|
|
4085
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "mass", new Fields .SFFloat ()),
|
|
4086
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "surfaceArea", new Fields .SFFloat ()),
|
|
4087
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "coordIndex", new Fields .MFInt32 (-1)),
|
|
4088
|
+
new X3DFieldDefinition (X3DConstants .inputOutput, "coord", new Fields .SFNode ()),
|
|
3747
4089
|
]),
|
|
3748
4090
|
getTypeName: function ()
|
|
3749
4091
|
{
|
|
@@ -3761,6 +4103,17 @@ function (Fields,
|
|
|
3761
4103
|
{
|
|
3762
4104
|
X3DParticleEmitterNode .prototype .initialize .call (this);
|
|
3763
4105
|
|
|
4106
|
+
const browser = this .getBrowser ();
|
|
4107
|
+
|
|
4108
|
+
if (browser .getContext () .getVersion () < 2)
|
|
4109
|
+
return;
|
|
4110
|
+
|
|
4111
|
+
// Create GL stuff.
|
|
4112
|
+
|
|
4113
|
+
this .volumeTexture = this .createTexture ();
|
|
4114
|
+
|
|
4115
|
+
// Initialize fields.
|
|
4116
|
+
|
|
3764
4117
|
this ._direction .addInterest ("set_direction__", this);
|
|
3765
4118
|
|
|
3766
4119
|
this ._coordIndex .addFieldInterest (this .volumeNode ._coordIndex);
|
|
@@ -3778,184 +4131,86 @@ function (Fields,
|
|
|
3778
4131
|
this .set_direction__ ();
|
|
3779
4132
|
this .set_geometry__ ();
|
|
3780
4133
|
},
|
|
3781
|
-
set_direction__: function ()
|
|
4134
|
+
set_direction__: (function ()
|
|
3782
4135
|
{
|
|
3783
|
-
|
|
4136
|
+
const direction = new Vector3 (0, 0, 0);
|
|
3784
4137
|
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
4138
|
+
return function ()
|
|
4139
|
+
{
|
|
4140
|
+
direction .assign (this ._direction .getValue ()) .normalize ();
|
|
4141
|
+
|
|
4142
|
+
this .setUniform ("uniform3f", "direction", direction .x, direction .y, direction .z);
|
|
4143
|
+
};
|
|
4144
|
+
})(),
|
|
3790
4145
|
set_geometry__: (function ()
|
|
3791
4146
|
{
|
|
3792
|
-
|
|
4147
|
+
const
|
|
3793
4148
|
vertex1 = new Vector3 (0, 0, 0),
|
|
3794
4149
|
vertex2 = new Vector3 (0, 0, 0),
|
|
3795
4150
|
vertex3 = new Vector3 (0, 0, 0);
|
|
3796
4151
|
|
|
3797
4152
|
return function ()
|
|
3798
4153
|
{
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
normals
|
|
3803
|
-
|
|
4154
|
+
const
|
|
4155
|
+
gl = this .getBrowser () .getContext (),
|
|
4156
|
+
vertices = this .volumeNode .getVertices () .getValue (),
|
|
4157
|
+
normals = this .volumeNode .getNormals () .getValue (),
|
|
4158
|
+
hierarchy = new BVH (vertices, normals) .toArray ([ ]),
|
|
4159
|
+
numVertices = vertices .length / 4,
|
|
4160
|
+
numNormals = normals .length / 3,
|
|
4161
|
+
numAreaSoFar = numVertices / 3 + 1,
|
|
4162
|
+
hierarchyLength = hierarchy .length / 4,
|
|
4163
|
+
volumeArraySize = Math .ceil (Math .sqrt (numAreaSoFar + numVertices + numVertices + hierarchyLength));
|
|
3804
4164
|
|
|
3805
|
-
|
|
3806
|
-
|
|
4165
|
+
const
|
|
4166
|
+
verticesIndex = numAreaSoFar,
|
|
4167
|
+
normalsIndex = verticesIndex + numVertices,
|
|
4168
|
+
hierarchyIndex = normalsIndex + numNormals;
|
|
4169
|
+
|
|
4170
|
+
let volumeArray = this .volumeArray;
|
|
3807
4171
|
|
|
3808
|
-
|
|
4172
|
+
if (volumeArray .length < volumeArraySize * volumeArraySize * 4)
|
|
4173
|
+
volumeArray = this .volumeArray = new Float32Array (volumeArraySize * volumeArraySize * 4);
|
|
3809
4174
|
|
|
3810
|
-
|
|
4175
|
+
let areaSoFar = 0;
|
|
4176
|
+
|
|
4177
|
+
for (let i = 0, length = vertices .length; i < length; i += 12)
|
|
3811
4178
|
{
|
|
3812
4179
|
vertex1 .set (vertices [i], vertices [i + 1], vertices [i + 2]);
|
|
3813
4180
|
vertex2 .set (vertices [i + 4], vertices [i + 5], vertices [i + 6]);
|
|
3814
4181
|
vertex3 .set (vertices [i + 8], vertices [i + 9], vertices [i + 10]);
|
|
3815
4182
|
|
|
3816
|
-
areaSoFar += Triangle3 .area (vertex1, vertex2, vertex3);
|
|
3817
|
-
areaSoFarArray .push (areaSoFar);
|
|
3818
|
-
}
|
|
3819
|
-
|
|
3820
|
-
this .bvh = new BVH (vertices, normals);
|
|
3821
|
-
};
|
|
3822
|
-
})(),
|
|
3823
|
-
getRandomPosition: (function ()
|
|
3824
|
-
{
|
|
3825
|
-
var
|
|
3826
|
-
point = new Vector3 (0, 0, 0),
|
|
3827
|
-
normal = new Vector3 (0, 0, 0),
|
|
3828
|
-
rotation = new Rotation4 (0, 0, 1, 0),
|
|
3829
|
-
line = new Line3 (Vector3 .Zero, Vector3 .zAxis),
|
|
3830
|
-
plane = new Plane3 (Vector3 .Zero, Vector3 .zAxis),
|
|
3831
|
-
intersections = [ ],
|
|
3832
|
-
sorter = new QuickSort (intersections, PlaneCompare);
|
|
3833
|
-
|
|
3834
|
-
function PlaneCompare (a, b)
|
|
3835
|
-
{
|
|
3836
|
-
return plane .getDistanceToPoint (a) < plane .getDistanceToPoint (b);
|
|
3837
|
-
}
|
|
3838
|
-
|
|
3839
|
-
return function (position)
|
|
3840
|
-
{
|
|
3841
|
-
// Get random point on surface
|
|
3842
|
-
|
|
3843
|
-
// Determine index0.
|
|
3844
|
-
|
|
3845
|
-
var
|
|
3846
|
-
areaSoFarArray = this .areaSoFarArray,
|
|
3847
|
-
length = areaSoFarArray .length,
|
|
3848
|
-
fraction = Math .random () * areaSoFarArray .at (-1),
|
|
3849
|
-
index0 = 0;
|
|
3850
|
-
|
|
3851
|
-
if (length == 1 || fraction <= areaSoFarArray [0])
|
|
3852
|
-
{
|
|
3853
|
-
index0 = 0;
|
|
3854
|
-
}
|
|
3855
|
-
else if (fraction >= areaSoFarArray .at (-1))
|
|
3856
|
-
{
|
|
3857
|
-
index0 = length - 2;
|
|
3858
|
-
}
|
|
3859
|
-
else
|
|
3860
|
-
{
|
|
3861
|
-
var index = Algorithm .upperBound (areaSoFarArray, 0, length, fraction, Algorithm .less);
|
|
3862
|
-
|
|
3863
|
-
if (index < length)
|
|
3864
|
-
{
|
|
3865
|
-
index0 = index - 1;
|
|
3866
|
-
}
|
|
3867
|
-
else
|
|
3868
|
-
{
|
|
3869
|
-
index0 = 0;
|
|
3870
|
-
}
|
|
4183
|
+
volumeArray [i / 3 + 4] = areaSoFar += Triangle3 .area (vertex1, vertex2, vertex3);
|
|
3871
4184
|
}
|
|
3872
4185
|
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
var
|
|
3876
|
-
u = Math .random (),
|
|
3877
|
-
v = Math .random ();
|
|
4186
|
+
volumeArray .set (vertices, verticesIndex * 4);
|
|
3878
4187
|
|
|
3879
|
-
|
|
4188
|
+
for (let s = normalsIndex * 4, n = 0, l = normals .length; n < l; s += 4, n += 3)
|
|
3880
4189
|
{
|
|
3881
|
-
|
|
3882
|
-
|
|
4190
|
+
volumeArray [s + 0] = normals [n + 0];
|
|
4191
|
+
volumeArray [s + 1] = normals [n + 1];
|
|
4192
|
+
volumeArray [s + 2] = normals [n + 2];
|
|
3883
4193
|
}
|
|
3884
4194
|
|
|
3885
|
-
|
|
4195
|
+
volumeArray .set (hierarchy, hierarchyIndex * 4);
|
|
3886
4196
|
|
|
3887
|
-
|
|
4197
|
+
this .setUniform ("uniform1i", "verticesIndex", verticesIndex);
|
|
4198
|
+
this .setUniform ("uniform1i", "normalsIndex", normalsIndex);
|
|
4199
|
+
this .setUniform ("uniform1i", "hierarchyIndex", hierarchyIndex);
|
|
4200
|
+
this .setUniform ("uniform1i", "hierarchyRoot", hierarchyIndex + hierarchyLength - 1);
|
|
3888
4201
|
|
|
3889
|
-
|
|
3890
|
-
i = index0 * 12,
|
|
3891
|
-
vertices = this .vertices;
|
|
3892
|
-
|
|
3893
|
-
point .x = u * vertices [i] + v * vertices [i + 4] + t * vertices [i + 8];
|
|
3894
|
-
point .y = u * vertices [i + 1] + v * vertices [i + 5] + t * vertices [i + 9];
|
|
3895
|
-
point .z = u * vertices [i + 2] + v * vertices [i + 6] + t * vertices [i + 10];
|
|
3896
|
-
|
|
3897
|
-
var
|
|
3898
|
-
i = index0 * 9,
|
|
3899
|
-
normals = this .normals;
|
|
3900
|
-
|
|
3901
|
-
normal .x = u * normals [i] + v * normals [i + 3] + t * normals [i + 6];
|
|
3902
|
-
normal .y = u * normals [i + 1] + v * normals [i + 4] + t * normals [i + 7];
|
|
3903
|
-
normal .z = u * normals [i + 2] + v * normals [i + 5] + t * normals [i + 8];
|
|
3904
|
-
|
|
3905
|
-
rotation .setFromToVec (Vector3 .zAxis, normal);
|
|
3906
|
-
rotation .multVecRot (this .getRandomSurfaceNormal (normal));
|
|
3907
|
-
|
|
3908
|
-
// Setup random line throu volume for intersection text
|
|
3909
|
-
// and a plane corresponding to the line for intersection sorting.
|
|
3910
|
-
|
|
3911
|
-
line .set (point, normal);
|
|
3912
|
-
plane .set (point, normal);
|
|
3913
|
-
|
|
3914
|
-
// Find random point in volume.
|
|
3915
|
-
|
|
3916
|
-
var numIntersections = this .bvh .intersectsLine (line, intersections);
|
|
3917
|
-
|
|
3918
|
-
numIntersections -= numIntersections % 2; // We need an even count of intersections.
|
|
3919
|
-
|
|
3920
|
-
if (numIntersections)
|
|
4202
|
+
if (volumeArraySize)
|
|
3921
4203
|
{
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
sorter .sort (0, numIntersections);
|
|
3925
|
-
|
|
3926
|
-
// Select random intersection pair.
|
|
3927
|
-
|
|
3928
|
-
var
|
|
3929
|
-
index = Math .round (this .getRandomValue (0, numIntersections / 2 - 1)) * 2,
|
|
3930
|
-
point0 = intersections [index],
|
|
3931
|
-
point1 = intersections [index + 1],
|
|
3932
|
-
t = Math .random ();
|
|
3933
|
-
|
|
3934
|
-
// lerp
|
|
3935
|
-
position .x = point0 .x + (point1 .x - point0 .x) * t;
|
|
3936
|
-
position .y = point0 .y + (point1 .y - point0 .y) * t;
|
|
3937
|
-
position .z = point0 .z + (point1 .z - point0 .z) * t;
|
|
3938
|
-
|
|
3939
|
-
return position;
|
|
4204
|
+
gl .bindTexture (gl .TEXTURE_2D, this .volumeTexture);
|
|
4205
|
+
gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA32F, volumeArraySize, volumeArraySize, 0, gl .RGBA, gl .FLOAT, volumeArray);
|
|
3940
4206
|
}
|
|
3941
|
-
|
|
3942
|
-
// Discard point.
|
|
3943
|
-
|
|
3944
|
-
return position .set (Number .POSITIVE_INFINITY, Number .POSITIVE_INFINITY, Number .POSITIVE_INFINITY);
|
|
3945
4207
|
};
|
|
3946
4208
|
})(),
|
|
3947
|
-
|
|
4209
|
+
activateTextures: function (gl, program)
|
|
3948
4210
|
{
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
velocity .x = direction .x * speed;
|
|
3954
|
-
velocity .y = direction .y * speed;
|
|
3955
|
-
velocity .z = direction .z * speed;
|
|
3956
|
-
|
|
3957
|
-
return velocity;
|
|
3958
|
-
},
|
|
4211
|
+
gl .activeTexture (gl .TEXTURE0 + program .volumeTextureUnit);
|
|
4212
|
+
gl .bindTexture (gl .TEXTURE_2D, this .volumeTexture);
|
|
4213
|
+
},
|
|
3959
4214
|
});
|
|
3960
4215
|
|
|
3961
4216
|
return VolumeEmitter;
|
|
@@ -4063,7 +4318,7 @@ function (Fields,
|
|
|
4063
4318
|
},
|
|
4064
4319
|
getRandomSpeed: function (emitterNode)
|
|
4065
4320
|
{
|
|
4066
|
-
|
|
4321
|
+
const
|
|
4067
4322
|
speed = Math .max (0, this ._speed .getValue ()),
|
|
4068
4323
|
variation = speed * Math .max (0, this ._gustiness .getValue ());
|
|
4069
4324
|
|
|
@@ -4071,27 +4326,32 @@ function (Fields,
|
|
|
4071
4326
|
},
|
|
4072
4327
|
addForce: (function ()
|
|
4073
4328
|
{
|
|
4074
|
-
|
|
4329
|
+
const force = new Vector3 (0, 0, 0);
|
|
4075
4330
|
|
|
4076
|
-
return function (i, emitterNode,
|
|
4331
|
+
return function (i, emitterNode, timeByMass, forces)
|
|
4077
4332
|
{
|
|
4078
|
-
var surfaceArea = emitterNode ._surfaceArea .getValue ()
|
|
4079
|
-
|
|
4080
4333
|
if (this ._enabled .getValue ())
|
|
4081
4334
|
{
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4335
|
+
const
|
|
4336
|
+
surfaceArea = emitterNode ._surfaceArea .getValue (),
|
|
4337
|
+
speed = this .getRandomSpeed (emitterNode),
|
|
4338
|
+
pressure = Math .pow (10, 2 * Math .log (speed)) * 0.64615;
|
|
4085
4339
|
|
|
4086
4340
|
if (this ._direction .getValue () .equals (Vector3 .Zero))
|
|
4087
4341
|
emitterNode .getRandomNormal (force);
|
|
4088
4342
|
else
|
|
4089
4343
|
force .assign (this ._direction .getValue ()) .normalize ();
|
|
4090
4344
|
|
|
4091
|
-
forces
|
|
4092
|
-
|
|
4345
|
+
forces .set (force .multiply (surfaceArea * pressure * timeByMass), i * 4);
|
|
4346
|
+
forces [i * 4 + 3] = Math .PI * Algorithm .clamp (this ._turbulence .getValue (), 0, 1);
|
|
4347
|
+
|
|
4348
|
+
return true;
|
|
4093
4349
|
}
|
|
4094
|
-
|
|
4350
|
+
else
|
|
4351
|
+
{
|
|
4352
|
+
return false;
|
|
4353
|
+
}
|
|
4354
|
+
}
|
|
4095
4355
|
})(),
|
|
4096
4356
|
});
|
|
4097
4357
|
|
|
@@ -4199,7 +4459,7 @@ function (Components,
|
|
|
4199
4459
|
X3DParticleEmitterNode: X3DParticleEmitterNode,
|
|
4200
4460
|
X3DParticlePhysicsModelNode: X3DParticlePhysicsModelNode,
|
|
4201
4461
|
},
|
|
4202
|
-
|
|
4462
|
+
context: X3DParticleSystemsContext,
|
|
4203
4463
|
});
|
|
4204
4464
|
});
|
|
4205
4465
|
|