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