175d8b347c9af0618d48ebfb2029dce4bdc8626d69da6a23539547f5cb9b947d.json 232 KB

1
  1. {"ast":null,"code":"import { Vector3, Matrix, TmpVectors, Quaternion } from \"../Maths/math.vector.js\";\nimport { Color4 } from \"../Maths/math.color.js\";\nimport { VertexBuffer } from \"../Buffers/buffer.js\";\nimport { VertexData } from \"../Meshes/mesh.vertexData.js\";\nimport { Mesh } from \"../Meshes/mesh.js\";\nimport { CreateDisc } from \"../Meshes/Builders/discBuilder.js\";\nimport { EngineStore } from \"../Engines/engineStore.js\";\nimport { DepthSortedParticle, SolidParticle, ModelShape, SolidParticleVertex } from \"./solidParticle.js\";\nimport { BoundingInfo } from \"../Culling/boundingInfo.js\";\nimport { Axis } from \"../Maths/math.axis.js\";\nimport { SubMesh } from \"../Meshes/subMesh.js\";\nimport { StandardMaterial } from \"../Materials/standardMaterial.js\";\nimport { MultiMaterial } from \"../Materials/multiMaterial.js\";\n/**\n * The SPS is a single updatable mesh. The solid particles are simply separate parts or faces of this big mesh.\n *As it is just a mesh, the SPS has all the same properties than any other BJS mesh : not more, not less. It can be scaled, rotated, translated, enlighted, textured, moved, etc.\n\n * The SPS is also a particle system. It provides some methods to manage the particles.\n * However it is behavior agnostic. This means it has no emitter, no particle physics, no particle recycler. You have to implement your own behavior.\n *\n * Full documentation here : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_intro\n */\nexport class SolidParticleSystem {\n /**\n * Creates a SPS (Solid Particle System) object.\n * @param name (String) is the SPS name, this will be the underlying mesh name.\n * @param scene (Scene) is the scene in which the SPS is added.\n * @param options defines the options of the sps e.g.\n * * updatable (optional boolean, default true) : if the SPS must be updatable or immutable.\n * * isPickable (optional boolean, default false) : if the solid particles must be pickable.\n * * enableDepthSort (optional boolean, default false) : if the solid particles must be sorted in the geometry according to their distance to the camera.\n * * useModelMaterial (optional boolean, default false) : if the model materials must be used to create the SPS multimaterial. This enables the multimaterial supports of the SPS.\n * * enableMultiMaterial (optional boolean, default false) : if the solid particles can be given different materials.\n * * expandable (optional boolean, default false) : if particles can still be added after the initial SPS mesh creation.\n * * particleIntersection (optional boolean, default false) : if the solid particle intersections must be computed.\n * * boundingSphereOnly (optional boolean, default false) : if the particle intersection must be computed only with the bounding sphere (no bounding box computation, so faster).\n * * bSphereRadiusFactor (optional float, default 1.0) : a number to multiply the bounding sphere radius by in order to reduce it for instance.\n * * computeBoundingBox (optional boolean, default false): if the bounding box of the entire SPS will be computed (for occlusion detection, for example). If it is false, the bounding box will be the bounding box of the first particle.\n * * autoFixFaceOrientation (optional boolean, default false): if the particle face orientations will be flipped for transformations that change orientation (scale (-1, 1, 1), for example)\n * @param options.updatable\n * @param options.isPickable\n * @param options.enableDepthSort\n * @param options.particleIntersection\n * @param options.boundingSphereOnly\n * @param options.bSphereRadiusFactor\n * @param options.expandable\n * @param options.useModelMaterial\n * @param options.enableMultiMaterial\n * @param options.computeBoundingBox\n * @param options.autoFixFaceOrientation\n * @example bSphereRadiusFactor = 1.0 / Math.sqrt(3.0) => the bounding sphere exactly matches a spherical mesh.\n */\n constructor(name, scene, options) {\n /**\n * The SPS array of Solid Particle objects. Just access each particle as with any classic array.\n * Example : var p = SPS.particles[i];\n */\n this.particles = new Array();\n /**\n * The SPS total number of particles. Read only. Use SPS.counter instead if you need to set your own value.\n */\n this.nbParticles = 0;\n /**\n * If the particles must ever face the camera (default false). Useful for planar particles.\n */\n this.billboard = false;\n /**\n * Recompute normals when adding a shape\n */\n this.recomputeNormals = false;\n /**\n * This a counter ofr your own usage. It's not set by any SPS functions.\n */\n this.counter = 0;\n /**\n * This empty object is intended to store some SPS specific or temporary values in order to lower the Garbage Collector activity.\n * Please read : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/optimize_sps#limit-garbage-collection\n */\n this.vars = {};\n /**\n * If the particle intersection must be computed only with the bounding sphere (no bounding box computation, so faster). (Internal use only)\n * @internal\n */\n this._bSphereOnly = false;\n /**\n * A number to multiply the bounding sphere radius by in order to reduce it for instance. (Internal use only)\n * @internal\n */\n this._bSphereRadiusFactor = 1.0;\n this._positions = new Array();\n this._indices = new Array();\n this._normals = new Array();\n this._colors = new Array();\n this._uvs = new Array();\n this._index = 0; // indices index\n this._updatable = true;\n this._pickable = false;\n this._isVisibilityBoxLocked = false;\n this._alwaysVisible = false;\n this._depthSort = false;\n this._expandable = false;\n this._shapeCounter = 0;\n this._copy = new SolidParticle(0, 0, 0, 0, null, 0, 0, this);\n this._color = new Color4(0, 0, 0, 0);\n this._computeParticleColor = true;\n this._computeParticleTexture = true;\n this._computeParticleRotation = true;\n this._computeParticleVertex = false;\n this._computeBoundingBox = false;\n this._autoFixFaceOrientation = false;\n this._depthSortParticles = true;\n this._mustUnrotateFixedNormals = false;\n this._particlesIntersect = false;\n this._needs32Bits = false;\n this._isNotBuilt = true;\n this._lastParticleId = 0;\n this._idxOfId = []; // array : key = particle.id / value = particle.idx\n this._multimaterialEnabled = false;\n this._useModelMaterial = false;\n this._depthSortFunction = (p1, p2) => p2.sqDistance - p1.sqDistance;\n this._materialSortFunction = (p1, p2) => p1.materialIndex - p2.materialIndex;\n this._autoUpdateSubMeshes = false;\n this._recomputeInvisibles = false;\n this.name = name;\n this._scene = scene || EngineStore.LastCreatedScene;\n this._camera = scene.activeCamera;\n this._pickable = options ? options.isPickable : false;\n this._depthSort = options ? options.enableDepthSort : false;\n this._multimaterialEnabled = options ? options.enableMultiMaterial : false;\n this._useModelMaterial = options ? options.useModelMaterial : false;\n this._multimaterialEnabled = this._useModelMaterial ? true : this._multimaterialEnabled;\n this._expandable = options ? options.expandable : false;\n this._particlesIntersect = options ? options.particleIntersection : false;\n this._bSphereOnly = options ? options.boundingSphereOnly : false;\n this._bSphereRadiusFactor = options && options.bSphereRadiusFactor ? options.bSphereRadiusFactor : 1.0;\n this._computeBoundingBox = options !== null && options !== void 0 && options.computeBoundingBox ? options.computeBoundingBox : false;\n this._autoFixFaceOrientation = options !== null && options !== void 0 && options.autoFixFaceOrientation ? options.autoFixFaceOrientation : false;\n if (options && options.updatable !== undefined) {\n this._updatable = options.updatable;\n } else {\n this._updatable = true;\n }\n if (this._pickable) {\n this.pickedBySubMesh = [[]];\n this.pickedParticles = this.pickedBySubMesh[0];\n }\n if (this._depthSort || this._multimaterialEnabled) {\n this.depthSortedParticles = [];\n }\n if (this._multimaterialEnabled) {\n this._multimaterial = new MultiMaterial(this.name + \"MultiMaterial\", this._scene);\n this._materials = [];\n this._materialIndexesById = {};\n }\n this._tmpVertex = new SolidParticleVertex();\n }\n /**\n * Builds the SPS underlying mesh. Returns a standard Mesh.\n * If no model shape was added to the SPS, the returned mesh is just a single triangular plane.\n * @returns the created mesh\n */\n buildMesh() {\n if (!this._isNotBuilt && this.mesh) {\n return this.mesh;\n }\n if (this.nbParticles === 0 && !this.mesh) {\n const triangle = CreateDisc(\"\", {\n radius: 1,\n tessellation: 3\n }, this._scene);\n this.addShape(triangle, 1);\n triangle.dispose();\n }\n this._indices32 = this._needs32Bits ? new Uint32Array(this._indices) : new Uint16Array(this._indices);\n this._positions32 = new Float32Array(this._positions);\n this._uvs32 = new Float32Array(this._uvs);\n this._colors32 = new Float32Array(this._colors);\n if (!this.mesh) {\n // in case it's already expanded\n const mesh = new Mesh(this.name, this._scene);\n this.mesh = mesh;\n }\n if (!this._updatable && this._multimaterialEnabled) {\n this._sortParticlesByMaterial(); // this may reorder the indices32\n }\n if (this.recomputeNormals) {\n VertexData.ComputeNormals(this._positions32, this._indices32, this._normals);\n }\n this._normals32 = new Float32Array(this._normals);\n this._fixedNormal32 = new Float32Array(this._normals);\n if (this._mustUnrotateFixedNormals) {\n // the particles could be created already rotated in the mesh with a positionFunction\n this._unrotateFixedNormals();\n }\n const vertexData = new VertexData();\n vertexData.indices = this._depthSort ? this._indices : this._indices32;\n vertexData.set(this._positions32, VertexBuffer.PositionKind);\n vertexData.set(this._normals32, VertexBuffer.NormalKind);\n if (this._uvs32.length > 0) {\n vertexData.set(this._uvs32, VertexBuffer.UVKind);\n }\n if (this._colors32.length > 0) {\n vertexData.set(this._colors32, VertexBuffer.ColorKind);\n }\n vertexData.applyToMesh(this.mesh, this._updatable);\n this.mesh.isPickable = this._pickable;\n if (this._pickable) {\n let faceId = 0;\n for (let p = 0; p < this.nbParticles; p++) {\n const part = this.particles[p];\n const lind = part._model._indicesLength;\n for (let i = 0; i < lind; i++) {\n const f = i % 3;\n if (f == 0) {\n const pickedData = {\n idx: part.idx,\n faceId: faceId\n };\n this.pickedParticles[faceId] = pickedData;\n faceId++;\n }\n }\n }\n }\n if (this._multimaterialEnabled) {\n this.setMultiMaterial(this._materials);\n }\n if (!this._expandable) {\n // free memory\n if (!this._depthSort && !this._multimaterialEnabled && !this._autoFixFaceOrientation) {\n this._indices = null;\n }\n this._positions = null;\n this._normals = null;\n this._uvs = null;\n this._colors = null;\n if (!this._updatable) {\n this.particles.length = 0;\n }\n }\n this._isNotBuilt = false;\n this.recomputeNormals = false;\n this._recomputeInvisibles = true;\n return this.mesh;\n }\n _getUVKind(mesh, uvKind) {\n if (uvKind === -1) {\n var _mesh$material, _mesh$material2;\n if ((_mesh$material = mesh.material) !== null && _mesh$material !== void 0 && _mesh$material.diffuseTexture) {\n uvKind = mesh.material.diffuseTexture.coordinatesIndex;\n } else if ((_mesh$material2 = mesh.material) !== null && _mesh$material2 !== void 0 && _mesh$material2.albedoTexture) {\n uvKind = mesh.material.albedoTexture.coordinatesIndex;\n }\n }\n return \"uv\" + (uvKind ? uvKind + 1 : \"\");\n }\n /**\n * Digests the mesh and generates as many solid particles in the system as wanted. Returns the SPS.\n * These particles will have the same geometry than the mesh parts and will be positioned at the same localisation than the mesh original places.\n * Thus the particles generated from `digest()` have their property `position` set yet.\n * @param mesh ( Mesh ) is the mesh to be digested\n * @param options {facetNb} (optional integer, default 1) is the number of mesh facets per particle, this parameter is overridden by the parameter `number` if any\n * {delta} (optional integer, default 0) is the random extra number of facets per particle , each particle will have between `facetNb` and `facetNb + delta` facets\n * {number} (optional positive integer) is the wanted number of particles : each particle is built with `mesh_total_facets / number` facets\n * {storage} (optional existing array) is an array where the particles will be stored for a further use instead of being inserted in the SPS.\n * {uvKind} (optional positive integer, default 0) is the kind of UV to read from. Use -1 to deduce it from the diffuse/albedo texture (if any) of the mesh material\n * @param options.facetNb\n * @param options.number\n * @param options.delta\n * @param options.storage\n * @param options.uvKind\n * @returns the current SPS\n */\n digest(mesh, options) {\n var _options$uvKind;\n let size = options && options.facetNb || 1;\n let number = options && options.number || 0;\n let delta = options && options.delta || 0;\n const meshPos = mesh.getVerticesData(VertexBuffer.PositionKind);\n const meshInd = mesh.getIndices();\n const meshUV = mesh.getVerticesData(this._getUVKind(mesh, (_options$uvKind = options === null || options === void 0 ? void 0 : options.uvKind) !== null && _options$uvKind !== void 0 ? _options$uvKind : 0));\n const meshCol = mesh.getVerticesData(VertexBuffer.ColorKind);\n const meshNor = mesh.getVerticesData(VertexBuffer.NormalKind);\n const storage = options && options.storage ? options.storage : null;\n let f = 0; // facet counter\n const totalFacets = meshInd.length / 3; // a facet is a triangle, so 3 indices\n // compute size from number\n if (number) {\n number = number > totalFacets ? totalFacets : number;\n size = Math.round(totalFacets / number);\n delta = 0;\n } else {\n size = size > totalFacets ? totalFacets : size;\n }\n const facetPos = []; // submesh positions\n const facetNor = [];\n const facetInd = []; // submesh indices\n const facetUV = []; // submesh UV\n const facetCol = []; // submesh colors\n const barycenter = Vector3.Zero();\n const sizeO = size;\n while (f < totalFacets) {\n size = sizeO + Math.floor((1 + delta) * Math.random());\n if (f > totalFacets - size) {\n size = totalFacets - f;\n }\n // reset temp arrays\n facetPos.length = 0;\n facetNor.length = 0;\n facetInd.length = 0;\n facetUV.length = 0;\n facetCol.length = 0;\n // iterate over \"size\" facets\n let fi = 0;\n for (let j = f * 3; j < (f + size) * 3; j++) {\n facetInd.push(fi);\n const i = meshInd[j];\n const i3 = i * 3;\n facetPos.push(meshPos[i3], meshPos[i3 + 1], meshPos[i3 + 2]);\n facetNor.push(meshNor[i3], meshNor[i3 + 1], meshNor[i3 + 2]);\n if (meshUV) {\n const i2 = i * 2;\n facetUV.push(meshUV[i2], meshUV[i2 + 1]);\n }\n if (meshCol) {\n const i4 = i * 4;\n facetCol.push(meshCol[i4], meshCol[i4 + 1], meshCol[i4 + 2], meshCol[i4 + 3]);\n }\n fi++;\n }\n // create a model shape for each single particle\n let idx = this.nbParticles;\n const shape = this._posToShape(facetPos);\n const shapeUV = this._uvsToShapeUV(facetUV);\n const shapeInd = facetInd.slice();\n const shapeCol = facetCol.slice();\n const shapeNor = facetNor.slice();\n // compute the barycenter of the shape\n barycenter.copyFromFloats(0, 0, 0);\n let v;\n for (v = 0; v < shape.length; v++) {\n barycenter.addInPlace(shape[v]);\n }\n barycenter.scaleInPlace(1 / shape.length);\n // shift the shape from its barycenter to the origin\n // and compute the BBox required for intersection.\n const minimum = new Vector3(Infinity, Infinity, Infinity);\n const maximum = new Vector3(-Infinity, -Infinity, -Infinity);\n for (v = 0; v < shape.length; v++) {\n shape[v].subtractInPlace(barycenter);\n minimum.minimizeInPlaceFromFloats(shape[v].x, shape[v].y, shape[v].z);\n maximum.maximizeInPlaceFromFloats(shape[v].x, shape[v].y, shape[v].z);\n }\n let bInfo;\n if (this._particlesIntersect) {\n bInfo = new BoundingInfo(minimum, maximum);\n }\n let material = null;\n if (this._useModelMaterial) {\n material = mesh.material ? mesh.material : this._setDefaultMaterial();\n }\n const modelShape = new ModelShape(this._shapeCounter, shape, shapeInd, shapeNor, shapeCol, shapeUV, null, null, material);\n // add the particle in the SPS\n const currentPos = this._positions.length;\n const currentInd = this._indices.length;\n this._meshBuilder(this._index, currentInd, shape, this._positions, shapeInd, this._indices, facetUV, this._uvs, shapeCol, this._colors, shapeNor, this._normals, idx, 0, null, modelShape);\n this._addParticle(idx, this._lastParticleId, currentPos, currentInd, modelShape, this._shapeCounter, 0, bInfo, storage);\n // initialize the particle position\n this.particles[this.nbParticles].position.addInPlace(barycenter);\n if (!storage) {\n this._index += shape.length;\n idx++;\n this.nbParticles++;\n this._lastParticleId++;\n }\n this._shapeCounter++;\n f += size;\n }\n this._isNotBuilt = true; // buildMesh() is now expected for setParticles() to work\n return this;\n }\n /**\n * Unrotate the fixed normals in case the mesh was built with pre-rotated particles, ex : use of positionFunction in addShape()\n * @internal\n */\n _unrotateFixedNormals() {\n let index = 0;\n let idx = 0;\n const tmpNormal = TmpVectors.Vector3[0];\n const quaternion = TmpVectors.Quaternion[0];\n const invertedRotMatrix = TmpVectors.Matrix[0];\n for (let p = 0; p < this.particles.length; p++) {\n const particle = this.particles[p];\n const shape = particle._model._shape;\n // computing the inverse of the rotation matrix from the quaternion\n // is equivalent to computing the matrix of the inverse quaternion, i.e of the conjugate quaternion\n if (particle.rotationQuaternion) {\n particle.rotationQuaternion.conjugateToRef(quaternion);\n } else {\n const rotation = particle.rotation;\n Quaternion.RotationYawPitchRollToRef(rotation.y, rotation.x, rotation.z, quaternion);\n quaternion.conjugateInPlace();\n }\n quaternion.toRotationMatrix(invertedRotMatrix);\n for (let pt = 0; pt < shape.length; pt++) {\n idx = index + pt * 3;\n Vector3.TransformNormalFromFloatsToRef(this._normals32[idx], this._normals32[idx + 1], this._normals32[idx + 2], invertedRotMatrix, tmpNormal);\n tmpNormal.toArray(this._fixedNormal32, idx);\n }\n index = idx + 3;\n }\n }\n /**\n * Resets the temporary working copy particle\n * @internal\n */\n _resetCopy() {\n const copy = this._copy;\n copy.position.setAll(0);\n copy.rotation.setAll(0);\n copy.rotationQuaternion = null;\n copy.scaling.setAll(1);\n copy.uvs.copyFromFloats(0.0, 0.0, 1.0, 1.0);\n copy.color = null;\n copy.translateFromPivot = false;\n copy.shapeId = 0;\n copy.materialIndex = null;\n }\n /**\n * Inserts the shape model geometry in the global SPS mesh by updating the positions, indices, normals, colors, uvs arrays\n * @param p the current index in the positions array to be updated\n * @param ind the current index in the indices array\n * @param shape a Vector3 array, the shape geometry\n * @param positions the positions array to be updated\n * @param meshInd the shape indices array\n * @param indices the indices array to be updated\n * @param meshUV the shape uv array\n * @param uvs the uv array to be updated\n * @param meshCol the shape color array\n * @param colors the color array to be updated\n * @param meshNor the shape normals array\n * @param normals the normals array to be updated\n * @param idx the particle index\n * @param idxInShape the particle index in its shape\n * @param options the addShape() method passed options\n * @param model\n * @model the particle model\n * @internal\n */\n _meshBuilder(p, ind, shape, positions, meshInd, indices, meshUV, uvs, meshCol, colors, meshNor, normals, idx, idxInShape, options, model) {\n let i;\n let u = 0;\n let c = 0;\n let n = 0;\n this._resetCopy();\n const copy = this._copy;\n const storeApart = options && options.storage ? true : false;\n copy.idx = idx;\n copy.idxInShape = idxInShape;\n copy.shapeId = model.shapeId;\n if (this._useModelMaterial) {\n const materialId = model._material.uniqueId;\n const materialIndexesById = this._materialIndexesById;\n if (!Object.prototype.hasOwnProperty.call(materialIndexesById, materialId)) {\n materialIndexesById[materialId] = this._materials.length;\n this._materials.push(model._material);\n }\n const matIdx = materialIndexesById[materialId];\n copy.materialIndex = matIdx;\n }\n if (options && options.positionFunction) {\n // call to custom positionFunction\n options.positionFunction(copy, idx, idxInShape);\n this._mustUnrotateFixedNormals = true;\n }\n // in case the particle geometry must NOT be inserted in the SPS mesh geometry\n if (storeApart) {\n return copy;\n }\n const rotMatrix = TmpVectors.Matrix[0];\n const tmpVertex = this._tmpVertex;\n const tmpVector = tmpVertex.position;\n const tmpColor = tmpVertex.color;\n const tmpUV = tmpVertex.uv;\n const tmpRotated = TmpVectors.Vector3[1];\n const pivotBackTranslation = TmpVectors.Vector3[2];\n const scaledPivot = TmpVectors.Vector3[3];\n Matrix.IdentityToRef(rotMatrix);\n copy.getRotationMatrix(rotMatrix);\n copy.pivot.multiplyToRef(copy.scaling, scaledPivot);\n if (copy.translateFromPivot) {\n pivotBackTranslation.setAll(0.0);\n } else {\n pivotBackTranslation.copyFrom(scaledPivot);\n }\n const someVertexFunction = options && options.vertexFunction;\n for (i = 0; i < shape.length; i++) {\n tmpVector.copyFrom(shape[i]);\n if (copy.color) {\n tmpColor.copyFrom(copy.color);\n }\n if (meshUV) {\n tmpUV.copyFromFloats(meshUV[u], meshUV[u + 1]);\n }\n if (someVertexFunction) {\n options.vertexFunction(copy, tmpVertex, i);\n }\n tmpVector.multiplyInPlace(copy.scaling).subtractInPlace(scaledPivot);\n Vector3.TransformCoordinatesToRef(tmpVector, rotMatrix, tmpRotated);\n tmpRotated.addInPlace(pivotBackTranslation).addInPlace(copy.position);\n positions.push(tmpRotated.x, tmpRotated.y, tmpRotated.z);\n if (meshUV) {\n const copyUvs = copy.uvs;\n uvs.push((copyUvs.z - copyUvs.x) * tmpUV.x + copyUvs.x, (copyUvs.w - copyUvs.y) * tmpUV.y + copyUvs.y);\n u += 2;\n }\n if (copy.color) {\n this._color.copyFrom(tmpColor);\n } else {\n const color = this._color;\n if (meshCol && meshCol[c] !== undefined) {\n color.r = meshCol[c];\n color.g = meshCol[c + 1];\n color.b = meshCol[c + 2];\n color.a = meshCol[c + 3];\n } else {\n color.r = 1.0;\n color.g = 1.0;\n color.b = 1.0;\n color.a = 1.0;\n }\n }\n colors.push(this._color.r, this._color.g, this._color.b, this._color.a);\n c += 4;\n if (!this.recomputeNormals && meshNor) {\n Vector3.TransformNormalFromFloatsToRef(meshNor[n], meshNor[n + 1], meshNor[n + 2], rotMatrix, tmpVector);\n normals.push(tmpVector.x, tmpVector.y, tmpVector.z);\n n += 3;\n }\n }\n for (i = 0; i < meshInd.length; i++) {\n const current_ind = p + meshInd[i];\n indices.push(current_ind);\n if (current_ind > 65535) {\n this._needs32Bits = true;\n }\n }\n if (this._depthSort || this._multimaterialEnabled) {\n const matIndex = copy.materialIndex !== null ? copy.materialIndex : 0;\n this.depthSortedParticles.push(new DepthSortedParticle(idx, ind, meshInd.length, matIndex));\n }\n return copy;\n }\n /**\n * Returns a shape Vector3 array from positions float array\n * @param positions float array\n * @returns a vector3 array\n * @internal\n */\n _posToShape(positions) {\n const shape = [];\n for (let i = 0; i < positions.length; i += 3) {\n shape.push(Vector3.FromArray(positions, i));\n }\n return shape;\n }\n /**\n * Returns a shapeUV array from a float uvs (array deep copy)\n * @param uvs as a float array\n * @returns a shapeUV array\n * @internal\n */\n _uvsToShapeUV(uvs) {\n const shapeUV = [];\n if (uvs) {\n for (let i = 0; i < uvs.length; i++) {\n shapeUV.push(uvs[i]);\n }\n }\n return shapeUV;\n }\n /**\n * Adds a new particle object in the particles array\n * @param idx particle index in particles array\n * @param id particle id\n * @param idxpos positionIndex : the starting index of the particle vertices in the SPS \"positions\" array\n * @param idxind indiceIndex : he starting index of the particle indices in the SPS \"indices\" array\n * @param model particle ModelShape object\n * @param shapeId model shape identifier\n * @param idxInShape index of the particle in the current model\n * @param bInfo model bounding info object\n * @param storage target storage array, if any\n * @internal\n */\n _addParticle(idx, id, idxpos, idxind, model, shapeId, idxInShape, bInfo = null, storage = null) {\n const sp = new SolidParticle(idx, id, idxpos, idxind, model, shapeId, idxInShape, this, bInfo);\n const target = storage ? storage : this.particles;\n target.push(sp);\n return sp;\n }\n /**\n * Adds some particles to the SPS from the model shape. Returns the shape id.\n * Please read the doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/immutable_sps\n * @param mesh is any Mesh object that will be used as a model for the solid particles. If the mesh does not have vertex normals, it will turn on the recomputeNormals attribute.\n * @param nb (positive integer) the number of particles to be created from this model\n * @param options {positionFunction} is an optional javascript function to called for each particle on SPS creation.\n * {vertexFunction} is an optional javascript function to called for each vertex of each particle on SPS creation\n * {storage} (optional existing array) is an array where the particles will be stored for a further use instead of being inserted in the SPS.\n * @param options.positionFunction\n * @param options.vertexFunction\n * @param options.storage\n * @returns the number of shapes in the system\n */\n addShape(mesh, nb, options) {\n const meshPos = mesh.getVerticesData(VertexBuffer.PositionKind);\n const meshInd = mesh.getIndices();\n const meshUV = mesh.getVerticesData(VertexBuffer.UVKind);\n const meshCol = mesh.getVerticesData(VertexBuffer.ColorKind);\n const meshNor = mesh.getVerticesData(VertexBuffer.NormalKind);\n this.recomputeNormals = meshNor ? false : true;\n const indices = Array.from(meshInd);\n const shapeNormals = meshNor ? Array.from(meshNor) : [];\n const shapeColors = meshCol ? Array.from(meshCol) : [];\n const storage = options && options.storage ? options.storage : null;\n let bbInfo = null;\n if (this._particlesIntersect) {\n bbInfo = mesh.getBoundingInfo();\n }\n const shape = this._posToShape(meshPos);\n const shapeUV = this._uvsToShapeUV(meshUV);\n const posfunc = options ? options.positionFunction : null;\n const vtxfunc = options ? options.vertexFunction : null;\n let material = null;\n if (this._useModelMaterial) {\n material = mesh.material ? mesh.material : this._setDefaultMaterial();\n }\n const modelShape = new ModelShape(this._shapeCounter, shape, indices, shapeNormals, shapeColors, shapeUV, posfunc, vtxfunc, material);\n // particles\n for (let i = 0; i < nb; i++) {\n this._insertNewParticle(this.nbParticles, i, modelShape, shape, meshInd, meshUV, meshCol, meshNor, bbInfo, storage, options);\n }\n this._shapeCounter++;\n this._isNotBuilt = true; // buildMesh() call is now expected for setParticles() to work\n return this._shapeCounter - 1;\n }\n /**\n * Rebuilds a particle back to its just built status : if needed, recomputes the custom positions and vertices\n * @internal\n */\n _rebuildParticle(particle, reset = false) {\n this._resetCopy();\n const copy = this._copy;\n if (particle._model._positionFunction) {\n // recall to stored custom positionFunction\n particle._model._positionFunction(copy, particle.idx, particle.idxInShape);\n }\n const rotMatrix = TmpVectors.Matrix[0];\n const tmpVertex = TmpVectors.Vector3[0];\n const tmpRotated = TmpVectors.Vector3[1];\n const pivotBackTranslation = TmpVectors.Vector3[2];\n const scaledPivot = TmpVectors.Vector3[3];\n copy.getRotationMatrix(rotMatrix);\n particle.pivot.multiplyToRef(particle.scaling, scaledPivot);\n if (copy.translateFromPivot) {\n pivotBackTranslation.copyFromFloats(0.0, 0.0, 0.0);\n } else {\n pivotBackTranslation.copyFrom(scaledPivot);\n }\n const shape = particle._model._shape;\n for (let pt = 0; pt < shape.length; pt++) {\n tmpVertex.copyFrom(shape[pt]);\n if (particle._model._vertexFunction) {\n particle._model._vertexFunction(copy, tmpVertex, pt); // recall to stored vertexFunction\n }\n tmpVertex.multiplyInPlace(copy.scaling).subtractInPlace(scaledPivot);\n Vector3.TransformCoordinatesToRef(tmpVertex, rotMatrix, tmpRotated);\n tmpRotated.addInPlace(pivotBackTranslation).addInPlace(copy.position).toArray(this._positions32, particle._pos + pt * 3);\n }\n if (reset) {\n particle.position.setAll(0.0);\n particle.rotation.setAll(0.0);\n particle.rotationQuaternion = null;\n particle.scaling.setAll(1.0);\n particle.uvs.setAll(0.0);\n particle.pivot.setAll(0.0);\n particle.translateFromPivot = false;\n particle.parentId = null;\n }\n }\n /**\n * Rebuilds the whole mesh and updates the VBO : custom positions and vertices are recomputed if needed.\n * @param reset boolean, default false : if the particles must be reset at position and rotation zero, scaling 1, color white, initial UVs and not parented.\n * @returns the SPS.\n */\n rebuildMesh(reset = false) {\n for (let p = 0; p < this.particles.length; p++) {\n this._rebuildParticle(this.particles[p], reset);\n }\n this.mesh.updateVerticesData(VertexBuffer.PositionKind, this._positions32, false, false);\n return this;\n }\n /** Removes the particles from the start-th to the end-th included from an expandable SPS (required).\n * Returns an array with the removed particles.\n * If the number of particles to remove is lower than zero or greater than the global remaining particle number, then an empty array is returned.\n * The SPS can't be empty so at least one particle needs to remain in place.\n * Under the hood, the VertexData array, so the VBO buffer, is recreated each call.\n * @param start index of the first particle to remove\n * @param end index of the last particle to remove (included)\n * @returns an array populated with the removed particles\n */\n removeParticles(start, end) {\n const nb = end - start + 1;\n if (!this._expandable || nb <= 0 || nb >= this.nbParticles || !this._updatable) {\n return [];\n }\n const particles = this.particles;\n const currentNb = this.nbParticles;\n if (end < currentNb - 1) {\n // update the particle indexes in the positions array in case they're remaining particles after the last removed\n const firstRemaining = end + 1;\n const shiftPos = particles[firstRemaining]._pos - particles[start]._pos;\n const shifInd = particles[firstRemaining]._ind - particles[start]._ind;\n for (let i = firstRemaining; i < currentNb; i++) {\n const part = particles[i];\n part._pos -= shiftPos;\n part._ind -= shifInd;\n }\n }\n const removed = particles.splice(start, nb);\n this._positions.length = 0;\n this._indices.length = 0;\n this._colors.length = 0;\n this._uvs.length = 0;\n this._normals.length = 0;\n this._index = 0;\n this._idxOfId.length = 0;\n if (this._depthSort || this._multimaterialEnabled) {\n this.depthSortedParticles = [];\n }\n let ind = 0;\n const particlesLength = particles.length;\n for (let p = 0; p < particlesLength; p++) {\n const particle = particles[p];\n const model = particle._model;\n const shape = model._shape;\n const modelIndices = model._indices;\n const modelNormals = model._normals;\n const modelColors = model._shapeColors;\n const modelUVs = model._shapeUV;\n particle.idx = p;\n this._idxOfId[particle.id] = p;\n this._meshBuilder(this._index, ind, shape, this._positions, modelIndices, this._indices, modelUVs, this._uvs, modelColors, this._colors, modelNormals, this._normals, particle.idx, particle.idxInShape, null, model);\n this._index += shape.length;\n ind += modelIndices.length;\n }\n this.nbParticles -= nb;\n this._isNotBuilt = true; // buildMesh() call is now expected for setParticles() to work\n return removed;\n }\n /**\n * Inserts some pre-created particles in the solid particle system so that they can be managed by setParticles().\n * @param solidParticleArray an array populated with Solid Particles objects\n * @returns the SPS\n */\n insertParticlesFromArray(solidParticleArray) {\n if (!this._expandable) {\n return this;\n }\n let idxInShape = 0;\n let currentShapeId = solidParticleArray[0].shapeId;\n const nb = solidParticleArray.length;\n for (let i = 0; i < nb; i++) {\n const sp = solidParticleArray[i];\n const model = sp._model;\n const shape = model._shape;\n const meshInd = model._indices;\n const meshUV = model._shapeUV;\n const meshCol = model._shapeColors;\n const meshNor = model._normals;\n const noNor = meshNor ? false : true;\n this.recomputeNormals = noNor || this.recomputeNormals;\n const bbInfo = sp.getBoundingInfo();\n const newPart = this._insertNewParticle(this.nbParticles, idxInShape, model, shape, meshInd, meshUV, meshCol, meshNor, bbInfo, null, null);\n sp.copyToRef(newPart);\n idxInShape++;\n if (currentShapeId != sp.shapeId) {\n currentShapeId = sp.shapeId;\n idxInShape = 0;\n }\n }\n this._isNotBuilt = true; // buildMesh() call is now expected for setParticles() to work\n return this;\n }\n /**\n * Creates a new particle and modifies the SPS mesh geometry :\n * - calls _meshBuilder() to increase the SPS mesh geometry step by step\n * - calls _addParticle() to populate the particle array\n * factorized code from addShape() and insertParticlesFromArray()\n * @param idx particle index in the particles array\n * @param i particle index in its shape\n * @param modelShape particle ModelShape object\n * @param shape shape vertex array\n * @param meshInd shape indices array\n * @param meshUV shape uv array\n * @param meshCol shape color array\n * @param meshNor shape normals array\n * @param bbInfo shape bounding info\n * @param storage target particle storage\n * @param options\n * @options addShape() passed options\n * @internal\n */\n _insertNewParticle(idx, i, modelShape, shape, meshInd, meshUV, meshCol, meshNor, bbInfo, storage, options) {\n const currentPos = this._positions.length;\n const currentInd = this._indices.length;\n const currentCopy = this._meshBuilder(this._index, currentInd, shape, this._positions, meshInd, this._indices, meshUV, this._uvs, meshCol, this._colors, meshNor, this._normals, idx, i, options, modelShape);\n let sp = null;\n if (this._updatable) {\n sp = this._addParticle(this.nbParticles, this._lastParticleId, currentPos, currentInd, modelShape, this._shapeCounter, i, bbInfo, storage);\n sp.position.copyFrom(currentCopy.position);\n sp.rotation.copyFrom(currentCopy.rotation);\n if (currentCopy.rotationQuaternion) {\n if (sp.rotationQuaternion) {\n sp.rotationQuaternion.copyFrom(currentCopy.rotationQuaternion);\n } else {\n sp.rotationQuaternion = currentCopy.rotationQuaternion.clone();\n }\n }\n if (currentCopy.color) {\n if (sp.color) {\n sp.color.copyFrom(currentCopy.color);\n } else {\n sp.color = currentCopy.color.clone();\n }\n }\n sp.scaling.copyFrom(currentCopy.scaling);\n sp.uvs.copyFrom(currentCopy.uvs);\n if (currentCopy.materialIndex !== null) {\n sp.materialIndex = currentCopy.materialIndex;\n }\n if (this.expandable) {\n this._idxOfId[sp.id] = sp.idx;\n }\n }\n if (!storage) {\n this._index += shape.length;\n this.nbParticles++;\n this._lastParticleId++;\n }\n return sp;\n }\n /**\n * Sets all the particles : this method actually really updates the mesh according to the particle positions, rotations, colors, textures, etc.\n * This method calls `updateParticle()` for each particle of the SPS.\n * For an animated SPS, it is usually called within the render loop.\n * This methods does nothing if called on a non updatable or not yet built SPS. Example : buildMesh() not called after having added or removed particles from an expandable SPS.\n * @param start The particle index in the particle array where to start to compute the particle property values _(default 0)_\n * @param end The particle index in the particle array where to stop to compute the particle property values _(default nbParticle - 1)_\n * @param update If the mesh must be finally updated on this call after all the particle computations _(default true)_\n * @returns the SPS.\n */\n setParticles(start = 0, end = this.nbParticles - 1, update = true) {\n if (!this._updatable || this._isNotBuilt) {\n return this;\n }\n // custom beforeUpdate\n this.beforeUpdateParticles(start, end, update);\n const rotMatrix = TmpVectors.Matrix[0];\n const invertedMatrix = TmpVectors.Matrix[1];\n const mesh = this.mesh;\n const colors32 = this._colors32;\n const positions32 = this._positions32;\n const normals32 = this._normals32;\n const uvs32 = this._uvs32;\n const indices32 = this._indices32;\n const indices = this._indices;\n const fixedNormal32 = this._fixedNormal32;\n const depthSortParticles = this._depthSort && this._depthSortParticles;\n const tempVectors = TmpVectors.Vector3;\n const camAxisX = tempVectors[5].copyFromFloats(1.0, 0.0, 0.0);\n const camAxisY = tempVectors[6].copyFromFloats(0.0, 1.0, 0.0);\n const camAxisZ = tempVectors[7].copyFromFloats(0.0, 0.0, 1.0);\n const minimum = tempVectors[8].setAll(Number.MAX_VALUE);\n const maximum = tempVectors[9].setAll(-Number.MAX_VALUE);\n const camInvertedPosition = tempVectors[10].setAll(0);\n const tmpVertex = this._tmpVertex;\n const tmpVector = tmpVertex.position;\n const tmpColor = tmpVertex.color;\n const tmpUV = tmpVertex.uv;\n // cases when the World Matrix is to be computed first\n if (this.billboard || this._depthSort) {\n this.mesh.computeWorldMatrix(true);\n this.mesh._worldMatrix.invertToRef(invertedMatrix);\n }\n // if the particles will always face the camera\n if (this.billboard) {\n // compute the camera position and un-rotate it by the current mesh rotation\n const tmpVector0 = tempVectors[0];\n this._camera.getDirectionToRef(Axis.Z, tmpVector0);\n Vector3.TransformNormalToRef(tmpVector0, invertedMatrix, camAxisZ);\n camAxisZ.normalize();\n // same for camera up vector extracted from the cam view matrix\n const view = this._camera.getViewMatrix(true);\n Vector3.TransformNormalFromFloatsToRef(view.m[1], view.m[5], view.m[9], invertedMatrix, camAxisY);\n Vector3.CrossToRef(camAxisY, camAxisZ, camAxisX);\n camAxisY.normalize();\n camAxisX.normalize();\n }\n // if depthSort, compute the camera global position in the mesh local system\n if (this._depthSort) {\n Vector3.TransformCoordinatesToRef(this._camera.globalPosition, invertedMatrix, camInvertedPosition); // then un-rotate the camera\n }\n Matrix.IdentityToRef(rotMatrix);\n let idx = 0; // current position index in the global array positions32\n let index = 0; // position start index in the global array positions32 of the current particle\n let colidx = 0; // current color index in the global array colors32\n let colorIndex = 0; // color start index in the global array colors32 of the current particle\n let uvidx = 0; // current uv index in the global array uvs32\n let uvIndex = 0; // uv start index in the global array uvs32 of the current particle\n let pt = 0; // current index in the particle model shape\n if (this.mesh.isFacetDataEnabled) {\n this._computeBoundingBox = true;\n }\n end = end >= this.nbParticles ? this.nbParticles - 1 : end;\n if (this._computeBoundingBox) {\n if (start != 0 || end != this.nbParticles - 1) {\n // only some particles are updated, then use the current existing BBox basis. Note : it can only increase.\n const boundingInfo = this.mesh.getBoundingInfo();\n if (boundingInfo) {\n minimum.copyFrom(boundingInfo.minimum);\n maximum.copyFrom(boundingInfo.maximum);\n }\n }\n }\n // particle loop\n index = this.particles[start]._pos;\n const vpos = index / 3 | 0;\n colorIndex = vpos * 4;\n uvIndex = vpos * 2;\n for (let p = start; p <= end; p++) {\n const particle = this.particles[p];\n // call to custom user function to update the particle properties\n this.updateParticle(particle);\n const shape = particle._model._shape;\n const shapeUV = particle._model._shapeUV;\n const particleRotationMatrix = particle._rotationMatrix;\n const particlePosition = particle.position;\n const particleRotation = particle.rotation;\n const particleScaling = particle.scaling;\n const particleGlobalPosition = particle._globalPosition;\n // camera-particle distance for depth sorting\n if (depthSortParticles) {\n const dsp = this.depthSortedParticles[p];\n dsp.idx = particle.idx;\n dsp.ind = particle._ind;\n dsp.indicesLength = particle._model._indicesLength;\n dsp.sqDistance = Vector3.DistanceSquared(particle.position, camInvertedPosition);\n }\n // skip the computations for inactive or already invisible particles\n if (!particle.alive || particle._stillInvisible && !particle.isVisible && !this._recomputeInvisibles) {\n // increment indexes for the next particle\n pt = shape.length;\n index += pt * 3;\n colorIndex += pt * 4;\n uvIndex += pt * 2;\n continue;\n }\n if (particle.isVisible) {\n particle._stillInvisible = false; // un-mark permanent invisibility\n const scaledPivot = tempVectors[12];\n particle.pivot.multiplyToRef(particleScaling, scaledPivot);\n // particle rotation matrix\n if (this.billboard) {\n particleRotation.x = 0.0;\n particleRotation.y = 0.0;\n }\n if (this._computeParticleRotation || this.billboard) {\n particle.getRotationMatrix(rotMatrix);\n }\n const particleHasParent = particle.parentId !== null;\n if (particleHasParent) {\n const parent = this.getParticleById(particle.parentId);\n if (parent) {\n const parentRotationMatrix = parent._rotationMatrix;\n const parentGlobalPosition = parent._globalPosition;\n const rotatedY = particlePosition.x * parentRotationMatrix[1] + particlePosition.y * parentRotationMatrix[4] + particlePosition.z * parentRotationMatrix[7];\n const rotatedX = particlePosition.x * parentRotationMatrix[0] + particlePosition.y * parentRotationMatrix[3] + particlePosition.z * parentRotationMatrix[6];\n const rotatedZ = particlePosition.x * parentRotationMatrix[2] + particlePosition.y * parentRotationMatrix[5] + particlePosition.z * parentRotationMatrix[8];\n particleGlobalPosition.x = parentGlobalPosition.x + rotatedX;\n particleGlobalPosition.y = parentGlobalPosition.y + rotatedY;\n particleGlobalPosition.z = parentGlobalPosition.z + rotatedZ;\n if (this._computeParticleRotation || this.billboard) {\n const rotMatrixValues = rotMatrix.m;\n particleRotationMatrix[0] = rotMatrixValues[0] * parentRotationMatrix[0] + rotMatrixValues[1] * parentRotationMatrix[3] + rotMatrixValues[2] * parentRotationMatrix[6];\n particleRotationMatrix[1] = rotMatrixValues[0] * parentRotationMatrix[1] + rotMatrixValues[1] * parentRotationMatrix[4] + rotMatrixValues[2] * parentRotationMatrix[7];\n particleRotationMatrix[2] = rotMatrixValues[0] * parentRotationMatrix[2] + rotMatrixValues[1] * parentRotationMatrix[5] + rotMatrixValues[2] * parentRotationMatrix[8];\n particleRotationMatrix[3] = rotMatrixValues[4] * parentRotationMatrix[0] + rotMatrixValues[5] * parentRotationMatrix[3] + rotMatrixValues[6] * parentRotationMatrix[6];\n particleRotationMatrix[4] = rotMatrixValues[4] * parentRotationMatrix[1] + rotMatrixValues[5] * parentRotationMatrix[4] + rotMatrixValues[6] * parentRotationMatrix[7];\n particleRotationMatrix[5] = rotMatrixValues[4] * parentRotationMatrix[2] + rotMatrixValues[5] * parentRotationMatrix[5] + rotMatrixValues[6] * parentRotationMatrix[8];\n particleRotationMatrix[6] = rotMatrixValues[8] * parentRotationMatrix[0] + rotMatrixValues[9] * parentRotationMatrix[3] + rotMatrixValues[10] * parentRotationMatrix[6];\n particleRotationMatrix[7] = rotMatrixValues[8] * parentRotationMatrix[1] + rotMatrixValues[9] * parentRotationMatrix[4] + rotMatrixValues[10] * parentRotationMatrix[7];\n particleRotationMatrix[8] = rotMatrixValues[8] * parentRotationMatrix[2] + rotMatrixValues[9] * parentRotationMatrix[5] + rotMatrixValues[10] * parentRotationMatrix[8];\n }\n } else {\n // in case the parent were removed at some moment\n particle.parentId = null;\n }\n } else {\n particleGlobalPosition.x = particlePosition.x;\n particleGlobalPosition.y = particlePosition.y;\n particleGlobalPosition.z = particlePosition.z;\n if (this._computeParticleRotation || this.billboard) {\n const rotMatrixValues = rotMatrix.m;\n particleRotationMatrix[0] = rotMatrixValues[0];\n particleRotationMatrix[1] = rotMatrixValues[1];\n particleRotationMatrix[2] = rotMatrixValues[2];\n particleRotationMatrix[3] = rotMatrixValues[4];\n particleRotationMatrix[4] = rotMatrixValues[5];\n particleRotationMatrix[5] = rotMatrixValues[6];\n particleRotationMatrix[6] = rotMatrixValues[8];\n particleRotationMatrix[7] = rotMatrixValues[9];\n particleRotationMatrix[8] = rotMatrixValues[10];\n }\n }\n const pivotBackTranslation = tempVectors[11];\n if (particle.translateFromPivot) {\n pivotBackTranslation.setAll(0.0);\n } else {\n pivotBackTranslation.copyFrom(scaledPivot);\n }\n // particle vertex loop\n for (pt = 0; pt < shape.length; pt++) {\n idx = index + pt * 3;\n colidx = colorIndex + pt * 4;\n uvidx = uvIndex + pt * 2;\n const iu = 2 * pt;\n const iv = iu + 1;\n tmpVector.copyFrom(shape[pt]);\n if (this._computeParticleColor && particle.color) {\n tmpColor.copyFrom(particle.color);\n }\n if (this._computeParticleTexture) {\n tmpUV.copyFromFloats(shapeUV[iu], shapeUV[iv]);\n }\n if (this._computeParticleVertex) {\n this.updateParticleVertex(particle, tmpVertex, pt);\n }\n // positions\n const vertexX = tmpVector.x * particleScaling.x - scaledPivot.x;\n const vertexY = tmpVector.y * particleScaling.y - scaledPivot.y;\n const vertexZ = tmpVector.z * particleScaling.z - scaledPivot.z;\n let rotatedX = vertexX * particleRotationMatrix[0] + vertexY * particleRotationMatrix[3] + vertexZ * particleRotationMatrix[6];\n let rotatedY = vertexX * particleRotationMatrix[1] + vertexY * particleRotationMatrix[4] + vertexZ * particleRotationMatrix[7];\n let rotatedZ = vertexX * particleRotationMatrix[2] + vertexY * particleRotationMatrix[5] + vertexZ * particleRotationMatrix[8];\n rotatedX += pivotBackTranslation.x;\n rotatedY += pivotBackTranslation.y;\n rotatedZ += pivotBackTranslation.z;\n const px = positions32[idx] = particleGlobalPosition.x + camAxisX.x * rotatedX + camAxisY.x * rotatedY + camAxisZ.x * rotatedZ;\n const py = positions32[idx + 1] = particleGlobalPosition.y + camAxisX.y * rotatedX + camAxisY.y * rotatedY + camAxisZ.y * rotatedZ;\n const pz = positions32[idx + 2] = particleGlobalPosition.z + camAxisX.z * rotatedX + camAxisY.z * rotatedY + camAxisZ.z * rotatedZ;\n if (this._computeBoundingBox) {\n minimum.minimizeInPlaceFromFloats(px, py, pz);\n maximum.maximizeInPlaceFromFloats(px, py, pz);\n }\n // normals : if the particles can't be morphed then just rotate the normals, what is much more faster than ComputeNormals()\n if (!this._computeParticleVertex) {\n const normalx = fixedNormal32[idx];\n const normaly = fixedNormal32[idx + 1];\n const normalz = fixedNormal32[idx + 2];\n const rotatedx = normalx * particleRotationMatrix[0] + normaly * particleRotationMatrix[3] + normalz * particleRotationMatrix[6];\n const rotatedy = normalx * particleRotationMatrix[1] + normaly * particleRotationMatrix[4] + normalz * particleRotationMatrix[7];\n const rotatedz = normalx * particleRotationMatrix[2] + normaly * particleRotationMatrix[5] + normalz * particleRotationMatrix[8];\n normals32[idx] = camAxisX.x * rotatedx + camAxisY.x * rotatedy + camAxisZ.x * rotatedz;\n normals32[idx + 1] = camAxisX.y * rotatedx + camAxisY.y * rotatedy + camAxisZ.y * rotatedz;\n normals32[idx + 2] = camAxisX.z * rotatedx + camAxisY.z * rotatedy + camAxisZ.z * rotatedz;\n }\n if (this._computeParticleColor && particle.color) {\n const colors32 = this._colors32;\n colors32[colidx] = tmpColor.r;\n colors32[colidx + 1] = tmpColor.g;\n colors32[colidx + 2] = tmpColor.b;\n colors32[colidx + 3] = tmpColor.a;\n }\n if (this._computeParticleTexture) {\n const uvs = particle.uvs;\n uvs32[uvidx] = tmpUV.x * (uvs.z - uvs.x) + uvs.x;\n uvs32[uvidx + 1] = tmpUV.y * (uvs.w - uvs.y) + uvs.y;\n }\n }\n }\n // particle just set invisible : scaled to zero and positioned at the origin\n else {\n particle._stillInvisible = true; // mark the particle as invisible\n for (pt = 0; pt < shape.length; pt++) {\n idx = index + pt * 3;\n colidx = colorIndex + pt * 4;\n uvidx = uvIndex + pt * 2;\n positions32[idx] = positions32[idx + 1] = positions32[idx + 2] = 0;\n normals32[idx] = normals32[idx + 1] = normals32[idx + 2] = 0;\n if (this._computeParticleColor && particle.color) {\n const color = particle.color;\n colors32[colidx] = color.r;\n colors32[colidx + 1] = color.g;\n colors32[colidx + 2] = color.b;\n colors32[colidx + 3] = color.a;\n }\n if (this._computeParticleTexture) {\n const uvs = particle.uvs;\n uvs32[uvidx] = shapeUV[pt * 2] * (uvs.z - uvs.x) + uvs.x;\n uvs32[uvidx + 1] = shapeUV[pt * 2 + 1] * (uvs.w - uvs.y) + uvs.y;\n }\n }\n }\n // if the particle intersections must be computed : update the bbInfo\n if (this._particlesIntersect) {\n const bInfo = particle.getBoundingInfo();\n const bBox = bInfo.boundingBox;\n const bSphere = bInfo.boundingSphere;\n const modelBoundingInfo = particle._modelBoundingInfo;\n if (!this._bSphereOnly) {\n // place, scale and rotate the particle bbox within the SPS local system, then update it\n const modelBoundingInfoVectors = modelBoundingInfo.boundingBox.vectors;\n const tempMin = tempVectors[1];\n const tempMax = tempVectors[2];\n tempMin.setAll(Number.MAX_VALUE);\n tempMax.setAll(-Number.MAX_VALUE);\n for (let b = 0; b < 8; b++) {\n const scaledX = modelBoundingInfoVectors[b].x * particleScaling.x;\n const scaledY = modelBoundingInfoVectors[b].y * particleScaling.y;\n const scaledZ = modelBoundingInfoVectors[b].z * particleScaling.z;\n const rotatedX = scaledX * particleRotationMatrix[0] + scaledY * particleRotationMatrix[3] + scaledZ * particleRotationMatrix[6];\n const rotatedY = scaledX * particleRotationMatrix[1] + scaledY * particleRotationMatrix[4] + scaledZ * particleRotationMatrix[7];\n const rotatedZ = scaledX * particleRotationMatrix[2] + scaledY * particleRotationMatrix[5] + scaledZ * particleRotationMatrix[8];\n const x = particlePosition.x + camAxisX.x * rotatedX + camAxisY.x * rotatedY + camAxisZ.x * rotatedZ;\n const y = particlePosition.y + camAxisX.y * rotatedX + camAxisY.y * rotatedY + camAxisZ.y * rotatedZ;\n const z = particlePosition.z + camAxisX.z * rotatedX + camAxisY.z * rotatedY + camAxisZ.z * rotatedZ;\n tempMin.minimizeInPlaceFromFloats(x, y, z);\n tempMax.maximizeInPlaceFromFloats(x, y, z);\n }\n bBox.reConstruct(tempMin, tempMax, mesh._worldMatrix);\n }\n // place and scale the particle bouding sphere in the SPS local system, then update it\n const minBbox = modelBoundingInfo.minimum.multiplyToRef(particleScaling, tempVectors[1]);\n const maxBbox = modelBoundingInfo.maximum.multiplyToRef(particleScaling, tempVectors[2]);\n const bSphereCenter = maxBbox.addToRef(minBbox, tempVectors[3]).scaleInPlace(0.5).addInPlace(particleGlobalPosition);\n const halfDiag = maxBbox.subtractToRef(minBbox, tempVectors[4]).scaleInPlace(0.5 * this._bSphereRadiusFactor);\n const bSphereMinBbox = bSphereCenter.subtractToRef(halfDiag, tempVectors[1]);\n const bSphereMaxBbox = bSphereCenter.addToRef(halfDiag, tempVectors[2]);\n bSphere.reConstruct(bSphereMinBbox, bSphereMaxBbox, mesh._worldMatrix);\n }\n // increment indexes for the next particle\n index = idx + 3;\n colorIndex = colidx + 4;\n uvIndex = uvidx + 2;\n }\n // if the VBO must be updated\n if (update) {\n if (this._computeParticleColor) {\n const vb = mesh.getVertexBuffer(VertexBuffer.ColorKind);\n if (vb && !mesh.isPickable) {\n vb.updateDirectly(colors32, 0);\n } else {\n mesh.updateVerticesData(VertexBuffer.ColorKind, colors32, false, false);\n }\n }\n if (this._computeParticleTexture) {\n const vb = mesh.getVertexBuffer(VertexBuffer.UVKind);\n if (vb && !mesh.isPickable) {\n vb.updateDirectly(uvs32, 0);\n } else {\n mesh.updateVerticesData(VertexBuffer.UVKind, uvs32, false, false);\n }\n }\n const vbp = mesh.getVertexBuffer(VertexBuffer.PositionKind);\n if (vbp && !mesh.isPickable) {\n vbp.updateDirectly(positions32, 0);\n } else {\n mesh.updateVerticesData(VertexBuffer.PositionKind, positions32, false, false);\n }\n if (!mesh.areNormalsFrozen || mesh.isFacetDataEnabled) {\n if (this._computeParticleVertex || mesh.isFacetDataEnabled) {\n // recompute the normals only if the particles can be morphed, update then also the normal reference array _fixedNormal32[]\n const params = mesh.isFacetDataEnabled ? mesh.getFacetDataParameters() : null;\n VertexData.ComputeNormals(positions32, indices32, normals32, params);\n for (let i = 0; i < normals32.length; i++) {\n fixedNormal32[i] = normals32[i];\n }\n }\n if (!mesh.areNormalsFrozen) {\n const vb = mesh.getVertexBuffer(VertexBuffer.NormalKind);\n if (vb && !mesh.isPickable) {\n vb.updateDirectly(normals32, 0);\n } else {\n mesh.updateVerticesData(VertexBuffer.NormalKind, normals32, false, false);\n }\n }\n }\n if (depthSortParticles) {\n const depthSortedParticles = this.depthSortedParticles;\n depthSortedParticles.sort(this._depthSortFunction);\n const dspl = depthSortedParticles.length;\n let sid = 0;\n let faceId = 0;\n for (let sorted = 0; sorted < dspl; sorted++) {\n const sortedParticle = depthSortedParticles[sorted];\n const lind = sortedParticle.indicesLength;\n const sind = sortedParticle.ind;\n for (let i = 0; i < lind; i++) {\n indices32[sid] = indices[sind + i];\n sid++;\n if (this._pickable) {\n const f = i % 3;\n if (f == 0) {\n const pickedData = this.pickedParticles[faceId];\n pickedData.idx = sortedParticle.idx;\n pickedData.faceId = faceId;\n faceId++;\n }\n }\n }\n }\n }\n if (this._autoFixFaceOrientation) {\n let particleInd = 0;\n for (let particleIdx = 0; particleIdx < this.particles.length; particleIdx++) {\n const particle = depthSortParticles ? this.particles[this.depthSortedParticles[particleIdx].idx] : this.particles[particleIdx];\n const flipFaces = particle.scale.x * particle.scale.y * particle.scale.z < 0;\n if (flipFaces) {\n for (let faceInd = 0; faceInd < particle._model._indicesLength; faceInd += 3) {\n const tmp = indices[particle._ind + faceInd];\n indices32[particleInd + faceInd] = indices[particle._ind + faceInd + 1];\n indices32[particleInd + faceInd + 1] = tmp;\n }\n }\n particleInd += particle._model._indicesLength;\n }\n }\n if (depthSortParticles || this._autoFixFaceOrientation) {\n mesh.updateIndices(indices32);\n }\n }\n if (this._computeBoundingBox) {\n if (mesh.hasBoundingInfo) {\n mesh.getBoundingInfo().reConstruct(minimum, maximum, mesh._worldMatrix);\n } else {\n mesh.buildBoundingInfo(minimum, maximum, mesh._worldMatrix);\n }\n }\n if (this._autoUpdateSubMeshes) {\n this.computeSubMeshes();\n }\n this._recomputeInvisibles = false;\n this.afterUpdateParticles(start, end, update);\n return this;\n }\n /**\n * Disposes the SPS.\n */\n dispose() {\n this.mesh.dispose();\n this.vars = null;\n // drop references to internal big arrays for the GC\n this._positions = null;\n this._indices = null;\n this._normals = null;\n this._uvs = null;\n this._colors = null;\n this._indices32 = null;\n this._positions32 = null;\n this._normals32 = null;\n this._fixedNormal32 = null;\n this._uvs32 = null;\n this._colors32 = null;\n this.pickedParticles = null;\n this.pickedBySubMesh = null;\n this._materials = null;\n this._materialIndexes = null;\n this._indicesByMaterial = null;\n this._idxOfId = null;\n }\n /** Returns an object {idx: number faceId: number} for the picked particle from the passed pickingInfo object.\n * idx is the particle index in the SPS\n * faceId is the picked face index counted within this particle.\n * Returns null if the pickInfo can't identify a picked particle.\n * @param pickingInfo (PickingInfo object)\n * @returns {idx: number, faceId: number} or null\n */\n pickedParticle(pickingInfo) {\n if (pickingInfo.hit) {\n const subMesh = pickingInfo.subMeshId;\n const faceId = pickingInfo.faceId - this.mesh.subMeshes[subMesh].indexStart / 3;\n const picked = this.pickedBySubMesh;\n if (picked[subMesh] && picked[subMesh][faceId]) {\n return picked[subMesh][faceId];\n }\n }\n return null;\n }\n /**\n * Returns a SolidParticle object from its identifier : particle.id\n * @param id (integer) the particle Id\n * @returns the searched particle or null if not found in the SPS.\n */\n getParticleById(id) {\n const p = this.particles[id];\n if (p && p.id == id) {\n return p;\n }\n const particles = this.particles;\n const idx = this._idxOfId[id];\n if (idx !== undefined) {\n return particles[idx];\n }\n let i = 0;\n const nb = this.nbParticles;\n while (i < nb) {\n const particle = particles[i];\n if (particle.id == id) {\n return particle;\n }\n i++;\n }\n return null;\n }\n /**\n * Returns a new array populated with the particles having the passed shapeId.\n * @param shapeId (integer) the shape identifier\n * @returns a new solid particle array\n */\n getParticlesByShapeId(shapeId) {\n const ref = [];\n this.getParticlesByShapeIdToRef(shapeId, ref);\n return ref;\n }\n /**\n * Populates the passed array \"ref\" with the particles having the passed shapeId.\n * @param shapeId the shape identifier\n * @param ref array to populate\n * @returns the SPS\n */\n getParticlesByShapeIdToRef(shapeId, ref) {\n ref.length = 0;\n for (let i = 0; i < this.nbParticles; i++) {\n const p = this.particles[i];\n if (p.shapeId == shapeId) {\n ref.push(p);\n }\n }\n return this;\n }\n /**\n * Computes the required SubMeshes according the materials assigned to the particles.\n * @returns the solid particle system.\n * Does nothing if called before the SPS mesh is built.\n */\n computeSubMeshes() {\n if (!this.mesh || !this._multimaterialEnabled) {\n return this;\n }\n const depthSortedParticles = this.depthSortedParticles;\n if (this.particles.length > 0) {\n for (let p = 0; p < this.particles.length; p++) {\n const part = this.particles[p];\n if (!part.materialIndex) {\n part.materialIndex = 0;\n }\n const sortedPart = depthSortedParticles[p];\n sortedPart.materialIndex = part.materialIndex;\n sortedPart.ind = part._ind;\n sortedPart.indicesLength = part._model._indicesLength;\n sortedPart.idx = part.idx;\n }\n }\n this._sortParticlesByMaterial();\n const indicesByMaterial = this._indicesByMaterial;\n const materialIndexes = this._materialIndexes;\n const mesh = this.mesh;\n mesh.subMeshes = [];\n const vcount = mesh.getTotalVertices();\n for (let m = 0; m < materialIndexes.length; m++) {\n const start = indicesByMaterial[m];\n const count = indicesByMaterial[m + 1] - start;\n const matIndex = materialIndexes[m];\n new SubMesh(matIndex, 0, vcount, start, count, mesh);\n }\n return this;\n }\n /**\n * Sorts the solid particles by material when MultiMaterial is enabled.\n * Updates the indices32 array.\n * Updates the indicesByMaterial array.\n * Updates the mesh indices array.\n * @returns the SPS\n * @internal\n */\n _sortParticlesByMaterial() {\n const indicesByMaterial = [0];\n this._indicesByMaterial = indicesByMaterial;\n const materialIndexes = [];\n this._materialIndexes = materialIndexes;\n const depthSortedParticles = this.depthSortedParticles;\n depthSortedParticles.sort(this._materialSortFunction);\n const length = depthSortedParticles.length;\n const indices32 = this._indices32;\n const indices = this._indices;\n let subMeshIndex = 0;\n let subMeshFaceId = 0;\n let sid = 0;\n let lastMatIndex = depthSortedParticles[0].materialIndex;\n materialIndexes.push(lastMatIndex);\n if (this._pickable) {\n this.pickedBySubMesh = [[]];\n this.pickedParticles = this.pickedBySubMesh[0];\n }\n for (let sorted = 0; sorted < length; sorted++) {\n const sortedPart = depthSortedParticles[sorted];\n const lind = sortedPart.indicesLength;\n const sind = sortedPart.ind;\n if (sortedPart.materialIndex !== lastMatIndex) {\n lastMatIndex = sortedPart.materialIndex;\n indicesByMaterial.push(sid);\n materialIndexes.push(lastMatIndex);\n if (this._pickable) {\n subMeshIndex++;\n this.pickedBySubMesh[subMeshIndex] = [];\n subMeshFaceId = 0;\n }\n }\n let faceId = 0;\n for (let i = 0; i < lind; i++) {\n indices32[sid] = indices[sind + i];\n if (this._pickable) {\n const f = i % 3;\n if (f == 0) {\n const pickedData = this.pickedBySubMesh[subMeshIndex][subMeshFaceId];\n if (pickedData) {\n pickedData.idx = sortedPart.idx;\n pickedData.faceId = faceId;\n } else {\n this.pickedBySubMesh[subMeshIndex][subMeshFaceId] = {\n idx: sortedPart.idx,\n faceId: faceId\n };\n }\n subMeshFaceId++;\n faceId++;\n }\n }\n sid++;\n }\n }\n indicesByMaterial.push(indices32.length); // add the last number to ease the indices start/count values for subMeshes creation\n if (this._updatable) {\n this.mesh.updateIndices(indices32);\n }\n return this;\n }\n /**\n * Sets the material indexes by id materialIndexesById[id] = materialIndex\n * @internal\n */\n _setMaterialIndexesById() {\n this._materialIndexesById = {};\n for (let i = 0; i < this._materials.length; i++) {\n const id = this._materials[i].uniqueId;\n this._materialIndexesById[id] = i;\n }\n }\n /**\n * Returns an array with unique values of Materials from the passed array\n * @param array the material array to be checked and filtered\n * @internal\n */\n _filterUniqueMaterialId(array) {\n const filtered = array.filter(function (value, index, self) {\n return self.indexOf(value) === index;\n });\n return filtered;\n }\n /**\n * Sets a new Standard Material as _defaultMaterial if not already set.\n * @internal\n */\n _setDefaultMaterial() {\n if (!this._defaultMaterial) {\n this._defaultMaterial = new StandardMaterial(this.name + \"DefaultMaterial\", this._scene);\n }\n return this._defaultMaterial;\n }\n /**\n * Visibility helper : Recomputes the visible size according to the mesh bounding box\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_visibility\n * @returns the SPS.\n */\n refreshVisibleSize() {\n if (!this._isVisibilityBoxLocked) {\n this.mesh.refreshBoundingInfo();\n }\n return this;\n }\n /**\n * Visibility helper : Sets the size of a visibility box, this sets the underlying mesh bounding box.\n * @param size the size (float) of the visibility box\n * note : this doesn't lock the SPS mesh bounding box.\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_visibility\n */\n setVisibilityBox(size) {\n const vis = size / 2;\n this.mesh.buildBoundingInfo(new Vector3(-vis, -vis, -vis), new Vector3(vis, vis, vis));\n }\n /**\n * Gets whether the SPS as always visible or not\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_visibility\n */\n get isAlwaysVisible() {\n return this._alwaysVisible;\n }\n /**\n * Sets the SPS as always visible or not\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_visibility\n */\n set isAlwaysVisible(val) {\n this._alwaysVisible = val;\n this.mesh.alwaysSelectAsActiveMesh = val;\n }\n /**\n * Sets the SPS visibility box as locked or not. This enables/disables the underlying mesh bounding box updates.\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_visibility\n */\n set isVisibilityBoxLocked(val) {\n this._isVisibilityBoxLocked = val;\n const boundingInfo = this.mesh.getBoundingInfo();\n boundingInfo.isLocked = val;\n }\n /**\n * Gets if the SPS visibility box as locked or not. This enables/disables the underlying mesh bounding box updates.\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_visibility\n */\n get isVisibilityBoxLocked() {\n return this._isVisibilityBoxLocked;\n }\n /**\n * Tells to `setParticles()` to compute the particle rotations or not.\n * Default value : true. The SPS is faster when it's set to false.\n * Note : the particle rotations aren't stored values, so setting `computeParticleRotation` to false will prevents the particle to rotate.\n */\n set computeParticleRotation(val) {\n this._computeParticleRotation = val;\n }\n /**\n * Tells to `setParticles()` to compute the particle colors or not.\n * Default value : true. The SPS is faster when it's set to false.\n * Note : the particle colors are stored values, so setting `computeParticleColor` to false will keep yet the last colors set.\n */\n set computeParticleColor(val) {\n this._computeParticleColor = val;\n }\n set computeParticleTexture(val) {\n this._computeParticleTexture = val;\n }\n /**\n * Tells to `setParticles()` to call the vertex function for each vertex of each particle, or not.\n * Default value : false. The SPS is faster when it's set to false.\n * Note : the particle custom vertex positions aren't stored values.\n */\n set computeParticleVertex(val) {\n this._computeParticleVertex = val;\n }\n /**\n * Tells to `setParticles()` to compute or not the mesh bounding box when computing the particle positions.\n */\n set computeBoundingBox(val) {\n this._computeBoundingBox = val;\n }\n /**\n * Tells to `setParticles()` to sort or not the distance between each particle and the camera.\n * Skipped when `enableDepthSort` is set to `false` (default) at construction time.\n * Default : `true`\n */\n set depthSortParticles(val) {\n this._depthSortParticles = val;\n }\n /**\n * Gets if `setParticles()` computes the particle rotations or not.\n * Default value : true. The SPS is faster when it's set to false.\n * Note : the particle rotations aren't stored values, so setting `computeParticleRotation` to false will prevents the particle to rotate.\n */\n get computeParticleRotation() {\n return this._computeParticleRotation;\n }\n /**\n * Gets if `setParticles()` computes the particle colors or not.\n * Default value : true. The SPS is faster when it's set to false.\n * Note : the particle colors are stored values, so setting `computeParticleColor` to false will keep yet the last colors set.\n */\n get computeParticleColor() {\n return this._computeParticleColor;\n }\n /**\n * Gets if `setParticles()` computes the particle textures or not.\n * Default value : true. The SPS is faster when it's set to false.\n * Note : the particle textures are stored values, so setting `computeParticleTexture` to false will keep yet the last colors set.\n */\n get computeParticleTexture() {\n return this._computeParticleTexture;\n }\n /**\n * Gets if `setParticles()` calls the vertex function for each vertex of each particle, or not.\n * Default value : false. The SPS is faster when it's set to false.\n * Note : the particle custom vertex positions aren't stored values.\n */\n get computeParticleVertex() {\n return this._computeParticleVertex;\n }\n /**\n * Gets if `setParticles()` computes or not the mesh bounding box when computing the particle positions.\n */\n get computeBoundingBox() {\n return this._computeBoundingBox;\n }\n /**\n * Gets if `setParticles()` sorts or not the distance between each particle and the camera.\n * Skipped when `enableDepthSort` is set to `false` (default) at construction time.\n * Default : `true`\n */\n get depthSortParticles() {\n return this._depthSortParticles;\n }\n /**\n * Gets if the SPS is created as expandable at construction time.\n * Default : `false`\n */\n get expandable() {\n return this._expandable;\n }\n /**\n * Gets if the SPS supports the Multi Materials\n */\n get multimaterialEnabled() {\n return this._multimaterialEnabled;\n }\n /**\n * Gets if the SPS uses the model materials for its own multimaterial.\n */\n get useModelMaterial() {\n return this._useModelMaterial;\n }\n /**\n * The SPS used material array.\n */\n get materials() {\n return this._materials;\n }\n /**\n * Sets the SPS MultiMaterial from the passed materials.\n * Note : the passed array is internally copied and not used then by reference.\n * @param materials an array of material objects. This array indexes are the materialIndex values of the particles.\n */\n setMultiMaterial(materials) {\n this._materials = this._filterUniqueMaterialId(materials);\n this._setMaterialIndexesById();\n if (this._multimaterial) {\n this._multimaterial.dispose();\n }\n this._multimaterial = new MultiMaterial(this.name + \"MultiMaterial\", this._scene);\n for (let m = 0; m < this._materials.length; m++) {\n this._multimaterial.subMaterials.push(this._materials[m]);\n }\n this.computeSubMeshes();\n this.mesh.material = this._multimaterial;\n }\n /**\n * The SPS computed multimaterial object\n */\n get multimaterial() {\n return this._multimaterial;\n }\n set multimaterial(mm) {\n this._multimaterial = mm;\n }\n /**\n * If the subMeshes must be updated on the next call to setParticles()\n */\n get autoUpdateSubMeshes() {\n return this._autoUpdateSubMeshes;\n }\n set autoUpdateSubMeshes(val) {\n this._autoUpdateSubMeshes = val;\n }\n // =======================================================================\n // Particle behavior logic\n // these following methods may be overwritten by the user to fit his needs\n /**\n * This function does nothing. It may be overwritten to set all the particle first values.\n * The SPS doesn't call this function, you may have to call it by your own.\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/manage_sps_particles\n */\n initParticles() {}\n /**\n * This function does nothing. It may be overwritten to recycle a particle.\n * The SPS doesn't call this function, you may have to call it by your own.\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/manage_sps_particles\n * @param particle The particle to recycle\n * @returns the recycled particle\n */\n recycleParticle(particle) {\n return particle;\n }\n /**\n * Updates a particle : this function should be overwritten by the user.\n * It is called on each particle by `setParticles()`. This is the place to code each particle behavior.\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/manage_sps_particles\n * @example : just set a particle position or velocity and recycle conditions\n * @param particle The particle to update\n * @returns the updated particle\n */\n updateParticle(particle) {\n return particle;\n }\n /**\n * Updates a vertex of a particle : it can be overwritten by the user.\n * This will be called on each vertex particle by `setParticles()` if `computeParticleVertex` is set to true only.\n * @param particle the current particle\n * @param vertex the current vertex of the current particle : a SolidParticleVertex object\n * @param pt the index of the current vertex in the particle shape\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_vertices\n * @example : just set a vertex particle position or color\n * @returns the sps\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n updateParticleVertex(particle, vertex, pt) {\n return this;\n }\n /**\n * This will be called before any other treatment by `setParticles()` and will be passed three parameters.\n * This does nothing and may be overwritten by the user.\n * @param start the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()\n * @param stop the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()\n * @param update the boolean update value actually passed to setParticles()\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n beforeUpdateParticles(start, stop, update) {}\n /**\n * This will be called by `setParticles()` after all the other treatments and just before the actual mesh update.\n * This will be passed three parameters.\n * This does nothing and may be overwritten by the user.\n * @param start the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()\n * @param stop the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()\n * @param update the boolean update value actually passed to setParticles()\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n afterUpdateParticles(start, stop, update) {}\n}","map":{"version":3,"names":["Vector3","Matrix","TmpVectors","Quaternion","Color4","VertexBuffer","VertexData","Mesh","CreateDisc","EngineStore","DepthSortedParticle","SolidParticle","ModelShape","SolidParticleVertex","BoundingInfo","Axis","SubMesh","StandardMaterial","MultiMaterial","SolidParticleSystem","constructor","name","scene","options","particles","Array","nbParticles","billboard","recomputeNormals","counter","vars","_bSphereOnly","_bSphereRadiusFactor","_positions","_indices","_normals","_colors","_uvs","_index","_updatable","_pickable","_isVisibilityBoxLocked","_alwaysVisible","_depthSort","_expandable","_shapeCounter","_copy","_color","_computeParticleColor","_computeParticleTexture","_computeParticleRotation","_computeParticleVertex","_computeBoundingBox","_autoFixFaceOrientation","_depthSortParticles","_mustUnrotateFixedNormals","_particlesIntersect","_needs32Bits","_isNotBuilt","_lastParticleId","_idxOfId","_multimaterialEnabled","_useModelMaterial","_depthSortFunction","p1","p2","sqDistance","_materialSortFunction","materialIndex","_autoUpdateSubMeshes","_recomputeInvisibles","_scene","LastCreatedScene","_camera","activeCamera","isPickable","enableDepthSort","enableMultiMaterial","useModelMaterial","expandable","particleIntersection","boundingSphereOnly","bSphereRadiusFactor","computeBoundingBox","autoFixFaceOrientation","updatable","undefined","pickedBySubMesh","pickedParticles","depthSortedParticles","_multimaterial","_materials","_materialIndexesById","_tmpVertex","buildMesh","mesh","triangle","radius","tessellation","addShape","dispose","_indices32","Uint32Array","Uint16Array","_positions32","Float32Array","_uvs32","_colors32","_sortParticlesByMaterial","ComputeNormals","_normals32","_fixedNormal32","_unrotateFixedNormals","vertexData","indices","set","PositionKind","NormalKind","length","UVKind","ColorKind","applyToMesh","faceId","p","part","lind","_model","_indicesLength","i","f","pickedData","idx","setMultiMaterial","_getUVKind","uvKind","_mesh$material","_mesh$material2","material","diffuseTexture","coordinatesIndex","albedoTexture","digest","_options$uvKind","size","facetNb","number","delta","meshPos","getVerticesData","meshInd","getIndices","meshUV","meshCol","meshNor","storage","totalFacets","Math","round","facetPos","facetNor","facetInd","facetUV","facetCol","barycenter","Zero","sizeO","floor","random","fi","j","push","i3","i2","i4","shape","_posToShape","shapeUV","_uvsToShapeUV","shapeInd","slice","shapeCol","shapeNor","copyFromFloats","v","addInPlace","scaleInPlace","minimum","Infinity","maximum","subtractInPlace","minimizeInPlaceFromFloats","x","y","z","maximizeInPlaceFromFloats","bInfo","_setDefaultMaterial","modelShape","currentPos","currentInd","_meshBuilder","_addParticle","position","index","tmpNormal","quaternion","invertedRotMatrix","particle","_shape","rotationQuaternion","conjugateToRef","rotation","RotationYawPitchRollToRef","conjugateInPlace","toRotationMatrix","pt","TransformNormalFromFloatsToRef","toArray","_resetCopy","copy","setAll","scaling","uvs","color","translateFromPivot","shapeId","ind","positions","colors","normals","idxInShape","model","u","c","n","storeApart","materialId","_material","uniqueId","materialIndexesById","Object","prototype","hasOwnProperty","call","matIdx","positionFunction","rotMatrix","tmpVertex","tmpVector","tmpColor","tmpUV","uv","tmpRotated","pivotBackTranslation","scaledPivot","IdentityToRef","getRotationMatrix","pivot","multiplyToRef","copyFrom","someVertexFunction","vertexFunction","multiplyInPlace","TransformCoordinatesToRef","copyUvs","w","r","g","b","a","current_ind","matIndex","FromArray","id","idxpos","idxind","sp","target","nb","from","shapeNormals","shapeColors","bbInfo","getBoundingInfo","posfunc","vtxfunc","_insertNewParticle","_rebuildParticle","reset","_positionFunction","_vertexFunction","_pos","parentId","rebuildMesh","updateVerticesData","removeParticles","start","end","currentNb","firstRemaining","shiftPos","shifInd","_ind","removed","splice","particlesLength","modelIndices","modelNormals","modelColors","_shapeColors","modelUVs","_shapeUV","insertParticlesFromArray","solidParticleArray","currentShapeId","noNor","newPart","copyToRef","currentCopy","clone","setParticles","update","beforeUpdateParticles","invertedMatrix","colors32","positions32","normals32","uvs32","indices32","fixedNormal32","depthSortParticles","tempVectors","camAxisX","camAxisY","camAxisZ","Number","MAX_VALUE","camInvertedPosition","computeWorldMatrix","_worldMatrix","invertToRef","tmpVector0","getDirectionToRef","Z","TransformNormalToRef","normalize","view","getViewMatrix","m","CrossToRef","globalPosition","colidx","colorIndex","uvidx","uvIndex","isFacetDataEnabled","boundingInfo","vpos","updateParticle","particleRotationMatrix","_rotationMatrix","particlePosition","particleRotation","particleScaling","particleGlobalPosition","_globalPosition","dsp","indicesLength","DistanceSquared","alive","_stillInvisible","isVisible","particleHasParent","parent","getParticleById","parentRotationMatrix","parentGlobalPosition","rotatedY","rotatedX","rotatedZ","rotMatrixValues","iu","iv","updateParticleVertex","vertexX","vertexY","vertexZ","px","py","pz","normalx","normaly","normalz","rotatedx","rotatedy","rotatedz","bBox","boundingBox","bSphere","boundingSphere","modelBoundingInfo","_modelBoundingInfo","modelBoundingInfoVectors","vectors","tempMin","tempMax","scaledX","scaledY","scaledZ","reConstruct","minBbox","maxBbox","bSphereCenter","addToRef","halfDiag","subtractToRef","bSphereMinBbox","bSphereMaxBbox","vb","getVertexBuffer","updateDirectly","vbp","areNormalsFrozen","params","getFacetDataParameters","sort","dspl","sid","sorted","sortedParticle","sind","particleInd","particleIdx","flipFaces","scale","faceInd","tmp","updateIndices","hasBoundingInfo","buildBoundingInfo","computeSubMeshes","afterUpdateParticles","_materialIndexes","_indicesByMaterial","pickedParticle","pickingInfo","hit","subMesh","subMeshId","subMeshes","indexStart","picked","getParticlesByShapeId","ref","getParticlesByShapeIdToRef","sortedPart","indicesByMaterial","materialIndexes","vcount","getTotalVertices","count","subMeshIndex","subMeshFaceId","lastMatIndex","_setMaterialIndexesById","_filterUniqueMaterialId","array","filtered","filter","value","self","indexOf","_defaultMaterial","refreshVisibleSize","refreshBoundingInfo","setVisibilityBox","vis","isAlwaysVisible","val","alwaysSelectAsActiveMesh","isVisibilityBoxLocked","isLocked","computeParticleRotation","computeParticleColor","computeParticleTexture","computeParticleVertex","multimaterialEnabled","materials","subMaterials","multimaterial","mm","autoUpdateSubMeshes","initParticles","recycleParticle","vertex","stop"],"sources":["F:/workspace/202226701027/huinongbao-app/node_modules/@babylonjs/core/Particles/solidParticleSystem.js"],"sourcesContent":["import { Vector3, Matrix, TmpVectors, Quaternion } from \"../Maths/math.vector.js\";\nimport { Color4 } from \"../Maths/math.color.js\";\nimport { VertexBuffer } from \"../Buffers/buffer.js\";\nimport { VertexData } from \"../Meshes/mesh.vertexData.js\";\nimport { Mesh } from \"../Meshes/mesh.js\";\nimport { CreateDisc } from \"../Meshes/Builders/discBuilder.js\";\nimport { EngineStore } from \"../Engines/engineStore.js\";\nimport { DepthSortedParticle, SolidParticle, ModelShape, SolidParticleVertex } from \"./solidParticle.js\";\nimport { BoundingInfo } from \"../Culling/boundingInfo.js\";\nimport { Axis } from \"../Maths/math.axis.js\";\nimport { SubMesh } from \"../Meshes/subMesh.js\";\nimport { StandardMaterial } from \"../Materials/standardMaterial.js\";\nimport { MultiMaterial } from \"../Materials/multiMaterial.js\";\n/**\n * The SPS is a single updatable mesh. The solid particles are simply separate parts or faces of this big mesh.\n *As it is just a mesh, the SPS has all the same properties than any other BJS mesh : not more, not less. It can be scaled, rotated, translated, enlighted, textured, moved, etc.\n\n * The SPS is also a particle system. It provides some methods to manage the particles.\n * However it is behavior agnostic. This means it has no emitter, no particle physics, no particle recycler. You have to implement your own behavior.\n *\n * Full documentation here : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_intro\n */\nexport class SolidParticleSystem {\n /**\n * Creates a SPS (Solid Particle System) object.\n * @param name (String) is the SPS name, this will be the underlying mesh name.\n * @param scene (Scene) is the scene in which the SPS is added.\n * @param options defines the options of the sps e.g.\n * * updatable (optional boolean, default true) : if the SPS must be updatable or immutable.\n * * isPickable (optional boolean, default false) : if the solid particles must be pickable.\n * * enableDepthSort (optional boolean, default false) : if the solid particles must be sorted in the geometry according to their distance to the camera.\n * * useModelMaterial (optional boolean, default false) : if the model materials must be used to create the SPS multimaterial. This enables the multimaterial supports of the SPS.\n * * enableMultiMaterial (optional boolean, default false) : if the solid particles can be given different materials.\n * * expandable (optional boolean, default false) : if particles can still be added after the initial SPS mesh creation.\n * * particleIntersection (optional boolean, default false) : if the solid particle intersections must be computed.\n * * boundingSphereOnly (optional boolean, default false) : if the particle intersection must be computed only with the bounding sphere (no bounding box computation, so faster).\n * * bSphereRadiusFactor (optional float, default 1.0) : a number to multiply the bounding sphere radius by in order to reduce it for instance.\n * * computeBoundingBox (optional boolean, default false): if the bounding box of the entire SPS will be computed (for occlusion detection, for example). If it is false, the bounding box will be the bounding box of the first particle.\n * * autoFixFaceOrientation (optional boolean, default false): if the particle face orientations will be flipped for transformations that change orientation (scale (-1, 1, 1), for example)\n * @param options.updatable\n * @param options.isPickable\n * @param options.enableDepthSort\n * @param options.particleIntersection\n * @param options.boundingSphereOnly\n * @param options.bSphereRadiusFactor\n * @param options.expandable\n * @param options.useModelMaterial\n * @param options.enableMultiMaterial\n * @param options.computeBoundingBox\n * @param options.autoFixFaceOrientation\n * @example bSphereRadiusFactor = 1.0 / Math.sqrt(3.0) => the bounding sphere exactly matches a spherical mesh.\n */\n constructor(name, scene, options) {\n /**\n * The SPS array of Solid Particle objects. Just access each particle as with any classic array.\n * Example : var p = SPS.particles[i];\n */\n this.particles = new Array();\n /**\n * The SPS total number of particles. Read only. Use SPS.counter instead if you need to set your own value.\n */\n this.nbParticles = 0;\n /**\n * If the particles must ever face the camera (default false). Useful for planar particles.\n */\n this.billboard = false;\n /**\n * Recompute normals when adding a shape\n */\n this.recomputeNormals = false;\n /**\n * This a counter ofr your own usage. It's not set by any SPS functions.\n */\n this.counter = 0;\n /**\n * This empty object is intended to store some SPS specific or temporary values in order to lower the Garbage Collector activity.\n * Please read : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/optimize_sps#limit-garbage-collection\n */\n this.vars = {};\n /**\n * If the particle intersection must be computed only with the bounding sphere (no bounding box computation, so faster). (Internal use only)\n * @internal\n */\n this._bSphereOnly = false;\n /**\n * A number to multiply the bounding sphere radius by in order to reduce it for instance. (Internal use only)\n * @internal\n */\n this._bSphereRadiusFactor = 1.0;\n this._positions = new Array();\n this._indices = new Array();\n this._normals = new Array();\n this._colors = new Array();\n this._uvs = new Array();\n this._index = 0; // indices index\n this._updatable = true;\n this._pickable = false;\n this._isVisibilityBoxLocked = false;\n this._alwaysVisible = false;\n this._depthSort = false;\n this._expandable = false;\n this._shapeCounter = 0;\n this._copy = new SolidParticle(0, 0, 0, 0, null, 0, 0, this);\n this._color = new Color4(0, 0, 0, 0);\n this._computeParticleColor = true;\n this._computeParticleTexture = true;\n this._computeParticleRotation = true;\n this._computeParticleVertex = false;\n this._computeBoundingBox = false;\n this._autoFixFaceOrientation = false;\n this._depthSortParticles = true;\n this._mustUnrotateFixedNormals = false;\n this._particlesIntersect = false;\n this._needs32Bits = false;\n this._isNotBuilt = true;\n this._lastParticleId = 0;\n this._idxOfId = []; // array : key = particle.id / value = particle.idx\n this._multimaterialEnabled = false;\n this._useModelMaterial = false;\n this._depthSortFunction = (p1, p2) => p2.sqDistance - p1.sqDistance;\n this._materialSortFunction = (p1, p2) => p1.materialIndex - p2.materialIndex;\n this._autoUpdateSubMeshes = false;\n this._recomputeInvisibles = false;\n this.name = name;\n this._scene = scene || EngineStore.LastCreatedScene;\n this._camera = scene.activeCamera;\n this._pickable = options ? options.isPickable : false;\n this._depthSort = options ? options.enableDepthSort : false;\n this._multimaterialEnabled = options ? options.enableMultiMaterial : false;\n this._useModelMaterial = options ? options.useModelMaterial : false;\n this._multimaterialEnabled = this._useModelMaterial ? true : this._multimaterialEnabled;\n this._expandable = options ? options.expandable : false;\n this._particlesIntersect = options ? options.particleIntersection : false;\n this._bSphereOnly = options ? options.boundingSphereOnly : false;\n this._bSphereRadiusFactor = options && options.bSphereRadiusFactor ? options.bSphereRadiusFactor : 1.0;\n this._computeBoundingBox = options?.computeBoundingBox ? options.computeBoundingBox : false;\n this._autoFixFaceOrientation = options?.autoFixFaceOrientation ? options.autoFixFaceOrientation : false;\n if (options && options.updatable !== undefined) {\n this._updatable = options.updatable;\n }\n else {\n this._updatable = true;\n }\n if (this._pickable) {\n this.pickedBySubMesh = [[]];\n this.pickedParticles = this.pickedBySubMesh[0];\n }\n if (this._depthSort || this._multimaterialEnabled) {\n this.depthSortedParticles = [];\n }\n if (this._multimaterialEnabled) {\n this._multimaterial = new MultiMaterial(this.name + \"MultiMaterial\", this._scene);\n this._materials = [];\n this._materialIndexesById = {};\n }\n this._tmpVertex = new SolidParticleVertex();\n }\n /**\n * Builds the SPS underlying mesh. Returns a standard Mesh.\n * If no model shape was added to the SPS, the returned mesh is just a single triangular plane.\n * @returns the created mesh\n */\n buildMesh() {\n if (!this._isNotBuilt && this.mesh) {\n return this.mesh;\n }\n if (this.nbParticles === 0 && !this.mesh) {\n const triangle = CreateDisc(\"\", { radius: 1, tessellation: 3 }, this._scene);\n this.addShape(triangle, 1);\n triangle.dispose();\n }\n this._indices32 = this._needs32Bits ? new Uint32Array(this._indices) : new Uint16Array(this._indices);\n this._positions32 = new Float32Array(this._positions);\n this._uvs32 = new Float32Array(this._uvs);\n this._colors32 = new Float32Array(this._colors);\n if (!this.mesh) {\n // in case it's already expanded\n const mesh = new Mesh(this.name, this._scene);\n this.mesh = mesh;\n }\n if (!this._updatable && this._multimaterialEnabled) {\n this._sortParticlesByMaterial(); // this may reorder the indices32\n }\n if (this.recomputeNormals) {\n VertexData.ComputeNormals(this._positions32, this._indices32, this._normals);\n }\n this._normals32 = new Float32Array(this._normals);\n this._fixedNormal32 = new Float32Array(this._normals);\n if (this._mustUnrotateFixedNormals) {\n // the particles could be created already rotated in the mesh with a positionFunction\n this._unrotateFixedNormals();\n }\n const vertexData = new VertexData();\n vertexData.indices = this._depthSort ? this._indices : this._indices32;\n vertexData.set(this._positions32, VertexBuffer.PositionKind);\n vertexData.set(this._normals32, VertexBuffer.NormalKind);\n if (this._uvs32.length > 0) {\n vertexData.set(this._uvs32, VertexBuffer.UVKind);\n }\n if (this._colors32.length > 0) {\n vertexData.set(this._colors32, VertexBuffer.ColorKind);\n }\n vertexData.applyToMesh(this.mesh, this._updatable);\n this.mesh.isPickable = this._pickable;\n if (this._pickable) {\n let faceId = 0;\n for (let p = 0; p < this.nbParticles; p++) {\n const part = this.particles[p];\n const lind = part._model._indicesLength;\n for (let i = 0; i < lind; i++) {\n const f = i % 3;\n if (f == 0) {\n const pickedData = { idx: part.idx, faceId: faceId };\n this.pickedParticles[faceId] = pickedData;\n faceId++;\n }\n }\n }\n }\n if (this._multimaterialEnabled) {\n this.setMultiMaterial(this._materials);\n }\n if (!this._expandable) {\n // free memory\n if (!this._depthSort && !this._multimaterialEnabled && !this._autoFixFaceOrientation) {\n this._indices = null;\n }\n this._positions = null;\n this._normals = null;\n this._uvs = null;\n this._colors = null;\n if (!this._updatable) {\n this.particles.length = 0;\n }\n }\n this._isNotBuilt = false;\n this.recomputeNormals = false;\n this._recomputeInvisibles = true;\n return this.mesh;\n }\n _getUVKind(mesh, uvKind) {\n if (uvKind === -1) {\n if (mesh.material?.diffuseTexture) {\n uvKind = mesh.material.diffuseTexture.coordinatesIndex;\n }\n else if (mesh.material?.albedoTexture) {\n uvKind = mesh.material.albedoTexture.coordinatesIndex;\n }\n }\n return \"uv\" + (uvKind ? uvKind + 1 : \"\");\n }\n /**\n * Digests the mesh and generates as many solid particles in the system as wanted. Returns the SPS.\n * These particles will have the same geometry than the mesh parts and will be positioned at the same localisation than the mesh original places.\n * Thus the particles generated from `digest()` have their property `position` set yet.\n * @param mesh ( Mesh ) is the mesh to be digested\n * @param options {facetNb} (optional integer, default 1) is the number of mesh facets per particle, this parameter is overridden by the parameter `number` if any\n * {delta} (optional integer, default 0) is the random extra number of facets per particle , each particle will have between `facetNb` and `facetNb + delta` facets\n * {number} (optional positive integer) is the wanted number of particles : each particle is built with `mesh_total_facets / number` facets\n * {storage} (optional existing array) is an array where the particles will be stored for a further use instead of being inserted in the SPS.\n * {uvKind} (optional positive integer, default 0) is the kind of UV to read from. Use -1 to deduce it from the diffuse/albedo texture (if any) of the mesh material\n * @param options.facetNb\n * @param options.number\n * @param options.delta\n * @param options.storage\n * @param options.uvKind\n * @returns the current SPS\n */\n digest(mesh, options) {\n let size = (options && options.facetNb) || 1;\n let number = (options && options.number) || 0;\n let delta = (options && options.delta) || 0;\n const meshPos = mesh.getVerticesData(VertexBuffer.PositionKind);\n const meshInd = mesh.getIndices();\n const meshUV = mesh.getVerticesData(this._getUVKind(mesh, options?.uvKind ?? 0));\n const meshCol = mesh.getVerticesData(VertexBuffer.ColorKind);\n const meshNor = mesh.getVerticesData(VertexBuffer.NormalKind);\n const storage = options && options.storage ? options.storage : null;\n let f = 0; // facet counter\n const totalFacets = meshInd.length / 3; // a facet is a triangle, so 3 indices\n // compute size from number\n if (number) {\n number = number > totalFacets ? totalFacets : number;\n size = Math.round(totalFacets / number);\n delta = 0;\n }\n else {\n size = size > totalFacets ? totalFacets : size;\n }\n const facetPos = []; // submesh positions\n const facetNor = [];\n const facetInd = []; // submesh indices\n const facetUV = []; // submesh UV\n const facetCol = []; // submesh colors\n const barycenter = Vector3.Zero();\n const sizeO = size;\n while (f < totalFacets) {\n size = sizeO + Math.floor((1 + delta) * Math.random());\n if (f > totalFacets - size) {\n size = totalFacets - f;\n }\n // reset temp arrays\n facetPos.length = 0;\n facetNor.length = 0;\n facetInd.length = 0;\n facetUV.length = 0;\n facetCol.length = 0;\n // iterate over \"size\" facets\n let fi = 0;\n for (let j = f * 3; j < (f + size) * 3; j++) {\n facetInd.push(fi);\n const i = meshInd[j];\n const i3 = i * 3;\n facetPos.push(meshPos[i3], meshPos[i3 + 1], meshPos[i3 + 2]);\n facetNor.push(meshNor[i3], meshNor[i3 + 1], meshNor[i3 + 2]);\n if (meshUV) {\n const i2 = i * 2;\n facetUV.push(meshUV[i2], meshUV[i2 + 1]);\n }\n if (meshCol) {\n const i4 = i * 4;\n facetCol.push(meshCol[i4], meshCol[i4 + 1], meshCol[i4 + 2], meshCol[i4 + 3]);\n }\n fi++;\n }\n // create a model shape for each single particle\n let idx = this.nbParticles;\n const shape = this._posToShape(facetPos);\n const shapeUV = this._uvsToShapeUV(facetUV);\n const shapeInd = facetInd.slice();\n const shapeCol = facetCol.slice();\n const shapeNor = facetNor.slice();\n // compute the barycenter of the shape\n barycenter.copyFromFloats(0, 0, 0);\n let v;\n for (v = 0; v < shape.length; v++) {\n barycenter.addInPlace(shape[v]);\n }\n barycenter.scaleInPlace(1 / shape.length);\n // shift the shape from its barycenter to the origin\n // and compute the BBox required for intersection.\n const minimum = new Vector3(Infinity, Infinity, Infinity);\n const maximum = new Vector3(-Infinity, -Infinity, -Infinity);\n for (v = 0; v < shape.length; v++) {\n shape[v].subtractInPlace(barycenter);\n minimum.minimizeInPlaceFromFloats(shape[v].x, shape[v].y, shape[v].z);\n maximum.maximizeInPlaceFromFloats(shape[v].x, shape[v].y, shape[v].z);\n }\n let bInfo;\n if (this._particlesIntersect) {\n bInfo = new BoundingInfo(minimum, maximum);\n }\n let material = null;\n if (this._useModelMaterial) {\n material = mesh.material ? mesh.material : this._setDefaultMaterial();\n }\n const modelShape = new ModelShape(this._shapeCounter, shape, shapeInd, shapeNor, shapeCol, shapeUV, null, null, material);\n // add the particle in the SPS\n const currentPos = this._positions.length;\n const currentInd = this._indices.length;\n this._meshBuilder(this._index, currentInd, shape, this._positions, shapeInd, this._indices, facetUV, this._uvs, shapeCol, this._colors, shapeNor, this._normals, idx, 0, null, modelShape);\n this._addParticle(idx, this._lastParticleId, currentPos, currentInd, modelShape, this._shapeCounter, 0, bInfo, storage);\n // initialize the particle position\n this.particles[this.nbParticles].position.addInPlace(barycenter);\n if (!storage) {\n this._index += shape.length;\n idx++;\n this.nbParticles++;\n this._lastParticleId++;\n }\n this._shapeCounter++;\n f += size;\n }\n this._isNotBuilt = true; // buildMesh() is now expected for setParticles() to work\n return this;\n }\n /**\n * Unrotate the fixed normals in case the mesh was built with pre-rotated particles, ex : use of positionFunction in addShape()\n * @internal\n */\n _unrotateFixedNormals() {\n let index = 0;\n let idx = 0;\n const tmpNormal = TmpVectors.Vector3[0];\n const quaternion = TmpVectors.Quaternion[0];\n const invertedRotMatrix = TmpVectors.Matrix[0];\n for (let p = 0; p < this.particles.length; p++) {\n const particle = this.particles[p];\n const shape = particle._model._shape;\n // computing the inverse of the rotation matrix from the quaternion\n // is equivalent to computing the matrix of the inverse quaternion, i.e of the conjugate quaternion\n if (particle.rotationQuaternion) {\n particle.rotationQuaternion.conjugateToRef(quaternion);\n }\n else {\n const rotation = particle.rotation;\n Quaternion.RotationYawPitchRollToRef(rotation.y, rotation.x, rotation.z, quaternion);\n quaternion.conjugateInPlace();\n }\n quaternion.toRotationMatrix(invertedRotMatrix);\n for (let pt = 0; pt < shape.length; pt++) {\n idx = index + pt * 3;\n Vector3.TransformNormalFromFloatsToRef(this._normals32[idx], this._normals32[idx + 1], this._normals32[idx + 2], invertedRotMatrix, tmpNormal);\n tmpNormal.toArray(this._fixedNormal32, idx);\n }\n index = idx + 3;\n }\n }\n /**\n * Resets the temporary working copy particle\n * @internal\n */\n _resetCopy() {\n const copy = this._copy;\n copy.position.setAll(0);\n copy.rotation.setAll(0);\n copy.rotationQuaternion = null;\n copy.scaling.setAll(1);\n copy.uvs.copyFromFloats(0.0, 0.0, 1.0, 1.0);\n copy.color = null;\n copy.translateFromPivot = false;\n copy.shapeId = 0;\n copy.materialIndex = null;\n }\n /**\n * Inserts the shape model geometry in the global SPS mesh by updating the positions, indices, normals, colors, uvs arrays\n * @param p the current index in the positions array to be updated\n * @param ind the current index in the indices array\n * @param shape a Vector3 array, the shape geometry\n * @param positions the positions array to be updated\n * @param meshInd the shape indices array\n * @param indices the indices array to be updated\n * @param meshUV the shape uv array\n * @param uvs the uv array to be updated\n * @param meshCol the shape color array\n * @param colors the color array to be updated\n * @param meshNor the shape normals array\n * @param normals the normals array to be updated\n * @param idx the particle index\n * @param idxInShape the particle index in its shape\n * @param options the addShape() method passed options\n * @param model\n * @model the particle model\n * @internal\n */\n _meshBuilder(p, ind, shape, positions, meshInd, indices, meshUV, uvs, meshCol, colors, meshNor, normals, idx, idxInShape, options, model) {\n let i;\n let u = 0;\n let c = 0;\n let n = 0;\n this._resetCopy();\n const copy = this._copy;\n const storeApart = options && options.storage ? true : false;\n copy.idx = idx;\n copy.idxInShape = idxInShape;\n copy.shapeId = model.shapeId;\n if (this._useModelMaterial) {\n const materialId = model._material.uniqueId;\n const materialIndexesById = this._materialIndexesById;\n if (!Object.prototype.hasOwnProperty.call(materialIndexesById, materialId)) {\n materialIndexesById[materialId] = this._materials.length;\n this._materials.push(model._material);\n }\n const matIdx = materialIndexesById[materialId];\n copy.materialIndex = matIdx;\n }\n if (options && options.positionFunction) {\n // call to custom positionFunction\n options.positionFunction(copy, idx, idxInShape);\n this._mustUnrotateFixedNormals = true;\n }\n // in case the particle geometry must NOT be inserted in the SPS mesh geometry\n if (storeApart) {\n return copy;\n }\n const rotMatrix = TmpVectors.Matrix[0];\n const tmpVertex = this._tmpVertex;\n const tmpVector = tmpVertex.position;\n const tmpColor = tmpVertex.color;\n const tmpUV = tmpVertex.uv;\n const tmpRotated = TmpVectors.Vector3[1];\n const pivotBackTranslation = TmpVectors.Vector3[2];\n const scaledPivot = TmpVectors.Vector3[3];\n Matrix.IdentityToRef(rotMatrix);\n copy.getRotationMatrix(rotMatrix);\n copy.pivot.multiplyToRef(copy.scaling, scaledPivot);\n if (copy.translateFromPivot) {\n pivotBackTranslation.setAll(0.0);\n }\n else {\n pivotBackTranslation.copyFrom(scaledPivot);\n }\n const someVertexFunction = options && options.vertexFunction;\n for (i = 0; i < shape.length; i++) {\n tmpVector.copyFrom(shape[i]);\n if (copy.color) {\n tmpColor.copyFrom(copy.color);\n }\n if (meshUV) {\n tmpUV.copyFromFloats(meshUV[u], meshUV[u + 1]);\n }\n if (someVertexFunction) {\n options.vertexFunction(copy, tmpVertex, i);\n }\n tmpVector.multiplyInPlace(copy.scaling).subtractInPlace(scaledPivot);\n Vector3.TransformCoordinatesToRef(tmpVector, rotMatrix, tmpRotated);\n tmpRotated.addInPlace(pivotBackTranslation).addInPlace(copy.position);\n positions.push(tmpRotated.x, tmpRotated.y, tmpRotated.z);\n if (meshUV) {\n const copyUvs = copy.uvs;\n uvs.push((copyUvs.z - copyUvs.x) * tmpUV.x + copyUvs.x, (copyUvs.w - copyUvs.y) * tmpUV.y + copyUvs.y);\n u += 2;\n }\n if (copy.color) {\n this._color.copyFrom(tmpColor);\n }\n else {\n const color = this._color;\n if (meshCol && meshCol[c] !== undefined) {\n color.r = meshCol[c];\n color.g = meshCol[c + 1];\n color.b = meshCol[c + 2];\n color.a = meshCol[c + 3];\n }\n else {\n color.r = 1.0;\n color.g = 1.0;\n color.b = 1.0;\n color.a = 1.0;\n }\n }\n colors.push(this._color.r, this._color.g, this._color.b, this._color.a);\n c += 4;\n if (!this.recomputeNormals && meshNor) {\n Vector3.TransformNormalFromFloatsToRef(meshNor[n], meshNor[n + 1], meshNor[n + 2], rotMatrix, tmpVector);\n normals.push(tmpVector.x, tmpVector.y, tmpVector.z);\n n += 3;\n }\n }\n for (i = 0; i < meshInd.length; i++) {\n const current_ind = p + meshInd[i];\n indices.push(current_ind);\n if (current_ind > 65535) {\n this._needs32Bits = true;\n }\n }\n if (this._depthSort || this._multimaterialEnabled) {\n const matIndex = copy.materialIndex !== null ? copy.materialIndex : 0;\n this.depthSortedParticles.push(new DepthSortedParticle(idx, ind, meshInd.length, matIndex));\n }\n return copy;\n }\n /**\n * Returns a shape Vector3 array from positions float array\n * @param positions float array\n * @returns a vector3 array\n * @internal\n */\n _posToShape(positions) {\n const shape = [];\n for (let i = 0; i < positions.length; i += 3) {\n shape.push(Vector3.FromArray(positions, i));\n }\n return shape;\n }\n /**\n * Returns a shapeUV array from a float uvs (array deep copy)\n * @param uvs as a float array\n * @returns a shapeUV array\n * @internal\n */\n _uvsToShapeUV(uvs) {\n const shapeUV = [];\n if (uvs) {\n for (let i = 0; i < uvs.length; i++) {\n shapeUV.push(uvs[i]);\n }\n }\n return shapeUV;\n }\n /**\n * Adds a new particle object in the particles array\n * @param idx particle index in particles array\n * @param id particle id\n * @param idxpos positionIndex : the starting index of the particle vertices in the SPS \"positions\" array\n * @param idxind indiceIndex : he starting index of the particle indices in the SPS \"indices\" array\n * @param model particle ModelShape object\n * @param shapeId model shape identifier\n * @param idxInShape index of the particle in the current model\n * @param bInfo model bounding info object\n * @param storage target storage array, if any\n * @internal\n */\n _addParticle(idx, id, idxpos, idxind, model, shapeId, idxInShape, bInfo = null, storage = null) {\n const sp = new SolidParticle(idx, id, idxpos, idxind, model, shapeId, idxInShape, this, bInfo);\n const target = storage ? storage : this.particles;\n target.push(sp);\n return sp;\n }\n /**\n * Adds some particles to the SPS from the model shape. Returns the shape id.\n * Please read the doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/immutable_sps\n * @param mesh is any Mesh object that will be used as a model for the solid particles. If the mesh does not have vertex normals, it will turn on the recomputeNormals attribute.\n * @param nb (positive integer) the number of particles to be created from this model\n * @param options {positionFunction} is an optional javascript function to called for each particle on SPS creation.\n * {vertexFunction} is an optional javascript function to called for each vertex of each particle on SPS creation\n * {storage} (optional existing array) is an array where the particles will be stored for a further use instead of being inserted in the SPS.\n * @param options.positionFunction\n * @param options.vertexFunction\n * @param options.storage\n * @returns the number of shapes in the system\n */\n addShape(mesh, nb, options) {\n const meshPos = mesh.getVerticesData(VertexBuffer.PositionKind);\n const meshInd = mesh.getIndices();\n const meshUV = mesh.getVerticesData(VertexBuffer.UVKind);\n const meshCol = mesh.getVerticesData(VertexBuffer.ColorKind);\n const meshNor = mesh.getVerticesData(VertexBuffer.NormalKind);\n this.recomputeNormals = meshNor ? false : true;\n const indices = Array.from(meshInd);\n const shapeNormals = meshNor ? Array.from(meshNor) : [];\n const shapeColors = meshCol ? Array.from(meshCol) : [];\n const storage = options && options.storage ? options.storage : null;\n let bbInfo = null;\n if (this._particlesIntersect) {\n bbInfo = mesh.getBoundingInfo();\n }\n const shape = this._posToShape(meshPos);\n const shapeUV = this._uvsToShapeUV(meshUV);\n const posfunc = options ? options.positionFunction : null;\n const vtxfunc = options ? options.vertexFunction : null;\n let material = null;\n if (this._useModelMaterial) {\n material = mesh.material ? mesh.material : this._setDefaultMaterial();\n }\n const modelShape = new ModelShape(this._shapeCounter, shape, indices, shapeNormals, shapeColors, shapeUV, posfunc, vtxfunc, material);\n // particles\n for (let i = 0; i < nb; i++) {\n this._insertNewParticle(this.nbParticles, i, modelShape, shape, meshInd, meshUV, meshCol, meshNor, bbInfo, storage, options);\n }\n this._shapeCounter++;\n this._isNotBuilt = true; // buildMesh() call is now expected for setParticles() to work\n return this._shapeCounter - 1;\n }\n /**\n * Rebuilds a particle back to its just built status : if needed, recomputes the custom positions and vertices\n * @internal\n */\n _rebuildParticle(particle, reset = false) {\n this._resetCopy();\n const copy = this._copy;\n if (particle._model._positionFunction) {\n // recall to stored custom positionFunction\n particle._model._positionFunction(copy, particle.idx, particle.idxInShape);\n }\n const rotMatrix = TmpVectors.Matrix[0];\n const tmpVertex = TmpVectors.Vector3[0];\n const tmpRotated = TmpVectors.Vector3[1];\n const pivotBackTranslation = TmpVectors.Vector3[2];\n const scaledPivot = TmpVectors.Vector3[3];\n copy.getRotationMatrix(rotMatrix);\n particle.pivot.multiplyToRef(particle.scaling, scaledPivot);\n if (copy.translateFromPivot) {\n pivotBackTranslation.copyFromFloats(0.0, 0.0, 0.0);\n }\n else {\n pivotBackTranslation.copyFrom(scaledPivot);\n }\n const shape = particle._model._shape;\n for (let pt = 0; pt < shape.length; pt++) {\n tmpVertex.copyFrom(shape[pt]);\n if (particle._model._vertexFunction) {\n particle._model._vertexFunction(copy, tmpVertex, pt); // recall to stored vertexFunction\n }\n tmpVertex.multiplyInPlace(copy.scaling).subtractInPlace(scaledPivot);\n Vector3.TransformCoordinatesToRef(tmpVertex, rotMatrix, tmpRotated);\n tmpRotated\n .addInPlace(pivotBackTranslation)\n .addInPlace(copy.position)\n .toArray(this._positions32, particle._pos + pt * 3);\n }\n if (reset) {\n particle.position.setAll(0.0);\n particle.rotation.setAll(0.0);\n particle.rotationQuaternion = null;\n particle.scaling.setAll(1.0);\n particle.uvs.setAll(0.0);\n particle.pivot.setAll(0.0);\n particle.translateFromPivot = false;\n particle.parentId = null;\n }\n }\n /**\n * Rebuilds the whole mesh and updates the VBO : custom positions and vertices are recomputed if needed.\n * @param reset boolean, default false : if the particles must be reset at position and rotation zero, scaling 1, color white, initial UVs and not parented.\n * @returns the SPS.\n */\n rebuildMesh(reset = false) {\n for (let p = 0; p < this.particles.length; p++) {\n this._rebuildParticle(this.particles[p], reset);\n }\n this.mesh.updateVerticesData(VertexBuffer.PositionKind, this._positions32, false, false);\n return this;\n }\n /** Removes the particles from the start-th to the end-th included from an expandable SPS (required).\n * Returns an array with the removed particles.\n * If the number of particles to remove is lower than zero or greater than the global remaining particle number, then an empty array is returned.\n * The SPS can't be empty so at least one particle needs to remain in place.\n * Under the hood, the VertexData array, so the VBO buffer, is recreated each call.\n * @param start index of the first particle to remove\n * @param end index of the last particle to remove (included)\n * @returns an array populated with the removed particles\n */\n removeParticles(start, end) {\n const nb = end - start + 1;\n if (!this._expandable || nb <= 0 || nb >= this.nbParticles || !this._updatable) {\n return [];\n }\n const particles = this.particles;\n const currentNb = this.nbParticles;\n if (end < currentNb - 1) {\n // update the particle indexes in the positions array in case they're remaining particles after the last removed\n const firstRemaining = end + 1;\n const shiftPos = particles[firstRemaining]._pos - particles[start]._pos;\n const shifInd = particles[firstRemaining]._ind - particles[start]._ind;\n for (let i = firstRemaining; i < currentNb; i++) {\n const part = particles[i];\n part._pos -= shiftPos;\n part._ind -= shifInd;\n }\n }\n const removed = particles.splice(start, nb);\n this._positions.length = 0;\n this._indices.length = 0;\n this._colors.length = 0;\n this._uvs.length = 0;\n this._normals.length = 0;\n this._index = 0;\n this._idxOfId.length = 0;\n if (this._depthSort || this._multimaterialEnabled) {\n this.depthSortedParticles = [];\n }\n let ind = 0;\n const particlesLength = particles.length;\n for (let p = 0; p < particlesLength; p++) {\n const particle = particles[p];\n const model = particle._model;\n const shape = model._shape;\n const modelIndices = model._indices;\n const modelNormals = model._normals;\n const modelColors = model._shapeColors;\n const modelUVs = model._shapeUV;\n particle.idx = p;\n this._idxOfId[particle.id] = p;\n this._meshBuilder(this._index, ind, shape, this._positions, modelIndices, this._indices, modelUVs, this._uvs, modelColors, this._colors, modelNormals, this._normals, particle.idx, particle.idxInShape, null, model);\n this._index += shape.length;\n ind += modelIndices.length;\n }\n this.nbParticles -= nb;\n this._isNotBuilt = true; // buildMesh() call is now expected for setParticles() to work\n return removed;\n }\n /**\n * Inserts some pre-created particles in the solid particle system so that they can be managed by setParticles().\n * @param solidParticleArray an array populated with Solid Particles objects\n * @returns the SPS\n */\n insertParticlesFromArray(solidParticleArray) {\n if (!this._expandable) {\n return this;\n }\n let idxInShape = 0;\n let currentShapeId = solidParticleArray[0].shapeId;\n const nb = solidParticleArray.length;\n for (let i = 0; i < nb; i++) {\n const sp = solidParticleArray[i];\n const model = sp._model;\n const shape = model._shape;\n const meshInd = model._indices;\n const meshUV = model._shapeUV;\n const meshCol = model._shapeColors;\n const meshNor = model._normals;\n const noNor = meshNor ? false : true;\n this.recomputeNormals = noNor || this.recomputeNormals;\n const bbInfo = sp.getBoundingInfo();\n const newPart = this._insertNewParticle(this.nbParticles, idxInShape, model, shape, meshInd, meshUV, meshCol, meshNor, bbInfo, null, null);\n sp.copyToRef(newPart);\n idxInShape++;\n if (currentShapeId != sp.shapeId) {\n currentShapeId = sp.shapeId;\n idxInShape = 0;\n }\n }\n this._isNotBuilt = true; // buildMesh() call is now expected for setParticles() to work\n return this;\n }\n /**\n * Creates a new particle and modifies the SPS mesh geometry :\n * - calls _meshBuilder() to increase the SPS mesh geometry step by step\n * - calls _addParticle() to populate the particle array\n * factorized code from addShape() and insertParticlesFromArray()\n * @param idx particle index in the particles array\n * @param i particle index in its shape\n * @param modelShape particle ModelShape object\n * @param shape shape vertex array\n * @param meshInd shape indices array\n * @param meshUV shape uv array\n * @param meshCol shape color array\n * @param meshNor shape normals array\n * @param bbInfo shape bounding info\n * @param storage target particle storage\n * @param options\n * @options addShape() passed options\n * @internal\n */\n _insertNewParticle(idx, i, modelShape, shape, meshInd, meshUV, meshCol, meshNor, bbInfo, storage, options) {\n const currentPos = this._positions.length;\n const currentInd = this._indices.length;\n const currentCopy = this._meshBuilder(this._index, currentInd, shape, this._positions, meshInd, this._indices, meshUV, this._uvs, meshCol, this._colors, meshNor, this._normals, idx, i, options, modelShape);\n let sp = null;\n if (this._updatable) {\n sp = this._addParticle(this.nbParticles, this._lastParticleId, currentPos, currentInd, modelShape, this._shapeCounter, i, bbInfo, storage);\n sp.position.copyFrom(currentCopy.position);\n sp.rotation.copyFrom(currentCopy.rotation);\n if (currentCopy.rotationQuaternion) {\n if (sp.rotationQuaternion) {\n sp.rotationQuaternion.copyFrom(currentCopy.rotationQuaternion);\n }\n else {\n sp.rotationQuaternion = currentCopy.rotationQuaternion.clone();\n }\n }\n if (currentCopy.color) {\n if (sp.color) {\n sp.color.copyFrom(currentCopy.color);\n }\n else {\n sp.color = currentCopy.color.clone();\n }\n }\n sp.scaling.copyFrom(currentCopy.scaling);\n sp.uvs.copyFrom(currentCopy.uvs);\n if (currentCopy.materialIndex !== null) {\n sp.materialIndex = currentCopy.materialIndex;\n }\n if (this.expandable) {\n this._idxOfId[sp.id] = sp.idx;\n }\n }\n if (!storage) {\n this._index += shape.length;\n this.nbParticles++;\n this._lastParticleId++;\n }\n return sp;\n }\n /**\n * Sets all the particles : this method actually really updates the mesh according to the particle positions, rotations, colors, textures, etc.\n * This method calls `updateParticle()` for each particle of the SPS.\n * For an animated SPS, it is usually called within the render loop.\n * This methods does nothing if called on a non updatable or not yet built SPS. Example : buildMesh() not called after having added or removed particles from an expandable SPS.\n * @param start The particle index in the particle array where to start to compute the particle property values _(default 0)_\n * @param end The particle index in the particle array where to stop to compute the particle property values _(default nbParticle - 1)_\n * @param update If the mesh must be finally updated on this call after all the particle computations _(default true)_\n * @returns the SPS.\n */\n setParticles(start = 0, end = this.nbParticles - 1, update = true) {\n if (!this._updatable || this._isNotBuilt) {\n return this;\n }\n // custom beforeUpdate\n this.beforeUpdateParticles(start, end, update);\n const rotMatrix = TmpVectors.Matrix[0];\n const invertedMatrix = TmpVectors.Matrix[1];\n const mesh = this.mesh;\n const colors32 = this._colors32;\n const positions32 = this._positions32;\n const normals32 = this._normals32;\n const uvs32 = this._uvs32;\n const indices32 = this._indices32;\n const indices = this._indices;\n const fixedNormal32 = this._fixedNormal32;\n const depthSortParticles = this._depthSort && this._depthSortParticles;\n const tempVectors = TmpVectors.Vector3;\n const camAxisX = tempVectors[5].copyFromFloats(1.0, 0.0, 0.0);\n const camAxisY = tempVectors[6].copyFromFloats(0.0, 1.0, 0.0);\n const camAxisZ = tempVectors[7].copyFromFloats(0.0, 0.0, 1.0);\n const minimum = tempVectors[8].setAll(Number.MAX_VALUE);\n const maximum = tempVectors[9].setAll(-Number.MAX_VALUE);\n const camInvertedPosition = tempVectors[10].setAll(0);\n const tmpVertex = this._tmpVertex;\n const tmpVector = tmpVertex.position;\n const tmpColor = tmpVertex.color;\n const tmpUV = tmpVertex.uv;\n // cases when the World Matrix is to be computed first\n if (this.billboard || this._depthSort) {\n this.mesh.computeWorldMatrix(true);\n this.mesh._worldMatrix.invertToRef(invertedMatrix);\n }\n // if the particles will always face the camera\n if (this.billboard) {\n // compute the camera position and un-rotate it by the current mesh rotation\n const tmpVector0 = tempVectors[0];\n this._camera.getDirectionToRef(Axis.Z, tmpVector0);\n Vector3.TransformNormalToRef(tmpVector0, invertedMatrix, camAxisZ);\n camAxisZ.normalize();\n // same for camera up vector extracted from the cam view matrix\n const view = this._camera.getViewMatrix(true);\n Vector3.TransformNormalFromFloatsToRef(view.m[1], view.m[5], view.m[9], invertedMatrix, camAxisY);\n Vector3.CrossToRef(camAxisY, camAxisZ, camAxisX);\n camAxisY.normalize();\n camAxisX.normalize();\n }\n // if depthSort, compute the camera global position in the mesh local system\n if (this._depthSort) {\n Vector3.TransformCoordinatesToRef(this._camera.globalPosition, invertedMatrix, camInvertedPosition); // then un-rotate the camera\n }\n Matrix.IdentityToRef(rotMatrix);\n let idx = 0; // current position index in the global array positions32\n let index = 0; // position start index in the global array positions32 of the current particle\n let colidx = 0; // current color index in the global array colors32\n let colorIndex = 0; // color start index in the global array colors32 of the current particle\n let uvidx = 0; // current uv index in the global array uvs32\n let uvIndex = 0; // uv start index in the global array uvs32 of the current particle\n let pt = 0; // current index in the particle model shape\n if (this.mesh.isFacetDataEnabled) {\n this._computeBoundingBox = true;\n }\n end = end >= this.nbParticles ? this.nbParticles - 1 : end;\n if (this._computeBoundingBox) {\n if (start != 0 || end != this.nbParticles - 1) {\n // only some particles are updated, then use the current existing BBox basis. Note : it can only increase.\n const boundingInfo = this.mesh.getBoundingInfo();\n if (boundingInfo) {\n minimum.copyFrom(boundingInfo.minimum);\n maximum.copyFrom(boundingInfo.maximum);\n }\n }\n }\n // particle loop\n index = this.particles[start]._pos;\n const vpos = (index / 3) | 0;\n colorIndex = vpos * 4;\n uvIndex = vpos * 2;\n for (let p = start; p <= end; p++) {\n const particle = this.particles[p];\n // call to custom user function to update the particle properties\n this.updateParticle(particle);\n const shape = particle._model._shape;\n const shapeUV = particle._model._shapeUV;\n const particleRotationMatrix = particle._rotationMatrix;\n const particlePosition = particle.position;\n const particleRotation = particle.rotation;\n const particleScaling = particle.scaling;\n const particleGlobalPosition = particle._globalPosition;\n // camera-particle distance for depth sorting\n if (depthSortParticles) {\n const dsp = this.depthSortedParticles[p];\n dsp.idx = particle.idx;\n dsp.ind = particle._ind;\n dsp.indicesLength = particle._model._indicesLength;\n dsp.sqDistance = Vector3.DistanceSquared(particle.position, camInvertedPosition);\n }\n // skip the computations for inactive or already invisible particles\n if (!particle.alive || (particle._stillInvisible && !particle.isVisible && !this._recomputeInvisibles)) {\n // increment indexes for the next particle\n pt = shape.length;\n index += pt * 3;\n colorIndex += pt * 4;\n uvIndex += pt * 2;\n continue;\n }\n if (particle.isVisible) {\n particle._stillInvisible = false; // un-mark permanent invisibility\n const scaledPivot = tempVectors[12];\n particle.pivot.multiplyToRef(particleScaling, scaledPivot);\n // particle rotation matrix\n if (this.billboard) {\n particleRotation.x = 0.0;\n particleRotation.y = 0.0;\n }\n if (this._computeParticleRotation || this.billboard) {\n particle.getRotationMatrix(rotMatrix);\n }\n const particleHasParent = particle.parentId !== null;\n if (particleHasParent) {\n const parent = this.getParticleById(particle.parentId);\n if (parent) {\n const parentRotationMatrix = parent._rotationMatrix;\n const parentGlobalPosition = parent._globalPosition;\n const rotatedY = particlePosition.x * parentRotationMatrix[1] + particlePosition.y * parentRotationMatrix[4] + particlePosition.z * parentRotationMatrix[7];\n const rotatedX = particlePosition.x * parentRotationMatrix[0] + particlePosition.y * parentRotationMatrix[3] + particlePosition.z * parentRotationMatrix[6];\n const rotatedZ = particlePosition.x * parentRotationMatrix[2] + particlePosition.y * parentRotationMatrix[5] + particlePosition.z * parentRotationMatrix[8];\n particleGlobalPosition.x = parentGlobalPosition.x + rotatedX;\n particleGlobalPosition.y = parentGlobalPosition.y + rotatedY;\n particleGlobalPosition.z = parentGlobalPosition.z + rotatedZ;\n if (this._computeParticleRotation || this.billboard) {\n const rotMatrixValues = rotMatrix.m;\n particleRotationMatrix[0] =\n rotMatrixValues[0] * parentRotationMatrix[0] + rotMatrixValues[1] * parentRotationMatrix[3] + rotMatrixValues[2] * parentRotationMatrix[6];\n particleRotationMatrix[1] =\n rotMatrixValues[0] * parentRotationMatrix[1] + rotMatrixValues[1] * parentRotationMatrix[4] + rotMatrixValues[2] * parentRotationMatrix[7];\n particleRotationMatrix[2] =\n rotMatrixValues[0] * parentRotationMatrix[2] + rotMatrixValues[1] * parentRotationMatrix[5] + rotMatrixValues[2] * parentRotationMatrix[8];\n particleRotationMatrix[3] =\n rotMatrixValues[4] * parentRotationMatrix[0] + rotMatrixValues[5] * parentRotationMatrix[3] + rotMatrixValues[6] * parentRotationMatrix[6];\n particleRotationMatrix[4] =\n rotMatrixValues[4] * parentRotationMatrix[1] + rotMatrixValues[5] * parentRotationMatrix[4] + rotMatrixValues[6] * parentRotationMatrix[7];\n particleRotationMatrix[5] =\n rotMatrixValues[4] * parentRotationMatrix[2] + rotMatrixValues[5] * parentRotationMatrix[5] + rotMatrixValues[6] * parentRotationMatrix[8];\n particleRotationMatrix[6] =\n rotMatrixValues[8] * parentRotationMatrix[0] + rotMatrixValues[9] * parentRotationMatrix[3] + rotMatrixValues[10] * parentRotationMatrix[6];\n particleRotationMatrix[7] =\n rotMatrixValues[8] * parentRotationMatrix[1] + rotMatrixValues[9] * parentRotationMatrix[4] + rotMatrixValues[10] * parentRotationMatrix[7];\n particleRotationMatrix[8] =\n rotMatrixValues[8] * parentRotationMatrix[2] + rotMatrixValues[9] * parentRotationMatrix[5] + rotMatrixValues[10] * parentRotationMatrix[8];\n }\n }\n else {\n // in case the parent were removed at some moment\n particle.parentId = null;\n }\n }\n else {\n particleGlobalPosition.x = particlePosition.x;\n particleGlobalPosition.y = particlePosition.y;\n particleGlobalPosition.z = particlePosition.z;\n if (this._computeParticleRotation || this.billboard) {\n const rotMatrixValues = rotMatrix.m;\n particleRotationMatrix[0] = rotMatrixValues[0];\n particleRotationMatrix[1] = rotMatrixValues[1];\n particleRotationMatrix[2] = rotMatrixValues[2];\n particleRotationMatrix[3] = rotMatrixValues[4];\n particleRotationMatrix[4] = rotMatrixValues[5];\n particleRotationMatrix[5] = rotMatrixValues[6];\n particleRotationMatrix[6] = rotMatrixValues[8];\n particleRotationMatrix[7] = rotMatrixValues[9];\n particleRotationMatrix[8] = rotMatrixValues[10];\n }\n }\n const pivotBackTranslation = tempVectors[11];\n if (particle.translateFromPivot) {\n pivotBackTranslation.setAll(0.0);\n }\n else {\n pivotBackTranslation.copyFrom(scaledPivot);\n }\n // particle vertex loop\n for (pt = 0; pt < shape.length; pt++) {\n idx = index + pt * 3;\n colidx = colorIndex + pt * 4;\n uvidx = uvIndex + pt * 2;\n const iu = 2 * pt;\n const iv = iu + 1;\n tmpVector.copyFrom(shape[pt]);\n if (this._computeParticleColor && particle.color) {\n tmpColor.copyFrom(particle.color);\n }\n if (this._computeParticleTexture) {\n tmpUV.copyFromFloats(shapeUV[iu], shapeUV[iv]);\n }\n if (this._computeParticleVertex) {\n this.updateParticleVertex(particle, tmpVertex, pt);\n }\n // positions\n const vertexX = tmpVector.x * particleScaling.x - scaledPivot.x;\n const vertexY = tmpVector.y * particleScaling.y - scaledPivot.y;\n const vertexZ = tmpVector.z * particleScaling.z - scaledPivot.z;\n let rotatedX = vertexX * particleRotationMatrix[0] + vertexY * particleRotationMatrix[3] + vertexZ * particleRotationMatrix[6];\n let rotatedY = vertexX * particleRotationMatrix[1] + vertexY * particleRotationMatrix[4] + vertexZ * particleRotationMatrix[7];\n let rotatedZ = vertexX * particleRotationMatrix[2] + vertexY * particleRotationMatrix[5] + vertexZ * particleRotationMatrix[8];\n rotatedX += pivotBackTranslation.x;\n rotatedY += pivotBackTranslation.y;\n rotatedZ += pivotBackTranslation.z;\n const px = (positions32[idx] = particleGlobalPosition.x + camAxisX.x * rotatedX + camAxisY.x * rotatedY + camAxisZ.x * rotatedZ);\n const py = (positions32[idx + 1] = particleGlobalPosition.y + camAxisX.y * rotatedX + camAxisY.y * rotatedY + camAxisZ.y * rotatedZ);\n const pz = (positions32[idx + 2] = particleGlobalPosition.z + camAxisX.z * rotatedX + camAxisY.z * rotatedY + camAxisZ.z * rotatedZ);\n if (this._computeBoundingBox) {\n minimum.minimizeInPlaceFromFloats(px, py, pz);\n maximum.maximizeInPlaceFromFloats(px, py, pz);\n }\n // normals : if the particles can't be morphed then just rotate the normals, what is much more faster than ComputeNormals()\n if (!this._computeParticleVertex) {\n const normalx = fixedNormal32[idx];\n const normaly = fixedNormal32[idx + 1];\n const normalz = fixedNormal32[idx + 2];\n const rotatedx = normalx * particleRotationMatrix[0] + normaly * particleRotationMatrix[3] + normalz * particleRotationMatrix[6];\n const rotatedy = normalx * particleRotationMatrix[1] + normaly * particleRotationMatrix[4] + normalz * particleRotationMatrix[7];\n const rotatedz = normalx * particleRotationMatrix[2] + normaly * particleRotationMatrix[5] + normalz * particleRotationMatrix[8];\n normals32[idx] = camAxisX.x * rotatedx + camAxisY.x * rotatedy + camAxisZ.x * rotatedz;\n normals32[idx + 1] = camAxisX.y * rotatedx + camAxisY.y * rotatedy + camAxisZ.y * rotatedz;\n normals32[idx + 2] = camAxisX.z * rotatedx + camAxisY.z * rotatedy + camAxisZ.z * rotatedz;\n }\n if (this._computeParticleColor && particle.color) {\n const colors32 = this._colors32;\n colors32[colidx] = tmpColor.r;\n colors32[colidx + 1] = tmpColor.g;\n colors32[colidx + 2] = tmpColor.b;\n colors32[colidx + 3] = tmpColor.a;\n }\n if (this._computeParticleTexture) {\n const uvs = particle.uvs;\n uvs32[uvidx] = tmpUV.x * (uvs.z - uvs.x) + uvs.x;\n uvs32[uvidx + 1] = tmpUV.y * (uvs.w - uvs.y) + uvs.y;\n }\n }\n }\n // particle just set invisible : scaled to zero and positioned at the origin\n else {\n particle._stillInvisible = true; // mark the particle as invisible\n for (pt = 0; pt < shape.length; pt++) {\n idx = index + pt * 3;\n colidx = colorIndex + pt * 4;\n uvidx = uvIndex + pt * 2;\n positions32[idx] = positions32[idx + 1] = positions32[idx + 2] = 0;\n normals32[idx] = normals32[idx + 1] = normals32[idx + 2] = 0;\n if (this._computeParticleColor && particle.color) {\n const color = particle.color;\n colors32[colidx] = color.r;\n colors32[colidx + 1] = color.g;\n colors32[colidx + 2] = color.b;\n colors32[colidx + 3] = color.a;\n }\n if (this._computeParticleTexture) {\n const uvs = particle.uvs;\n uvs32[uvidx] = shapeUV[pt * 2] * (uvs.z - uvs.x) + uvs.x;\n uvs32[uvidx + 1] = shapeUV[pt * 2 + 1] * (uvs.w - uvs.y) + uvs.y;\n }\n }\n }\n // if the particle intersections must be computed : update the bbInfo\n if (this._particlesIntersect) {\n const bInfo = particle.getBoundingInfo();\n const bBox = bInfo.boundingBox;\n const bSphere = bInfo.boundingSphere;\n const modelBoundingInfo = particle._modelBoundingInfo;\n if (!this._bSphereOnly) {\n // place, scale and rotate the particle bbox within the SPS local system, then update it\n const modelBoundingInfoVectors = modelBoundingInfo.boundingBox.vectors;\n const tempMin = tempVectors[1];\n const tempMax = tempVectors[2];\n tempMin.setAll(Number.MAX_VALUE);\n tempMax.setAll(-Number.MAX_VALUE);\n for (let b = 0; b < 8; b++) {\n const scaledX = modelBoundingInfoVectors[b].x * particleScaling.x;\n const scaledY = modelBoundingInfoVectors[b].y * particleScaling.y;\n const scaledZ = modelBoundingInfoVectors[b].z * particleScaling.z;\n const rotatedX = scaledX * particleRotationMatrix[0] + scaledY * particleRotationMatrix[3] + scaledZ * particleRotationMatrix[6];\n const rotatedY = scaledX * particleRotationMatrix[1] + scaledY * particleRotationMatrix[4] + scaledZ * particleRotationMatrix[7];\n const rotatedZ = scaledX * particleRotationMatrix[2] + scaledY * particleRotationMatrix[5] + scaledZ * particleRotationMatrix[8];\n const x = particlePosition.x + camAxisX.x * rotatedX + camAxisY.x * rotatedY + camAxisZ.x * rotatedZ;\n const y = particlePosition.y + camAxisX.y * rotatedX + camAxisY.y * rotatedY + camAxisZ.y * rotatedZ;\n const z = particlePosition.z + camAxisX.z * rotatedX + camAxisY.z * rotatedY + camAxisZ.z * rotatedZ;\n tempMin.minimizeInPlaceFromFloats(x, y, z);\n tempMax.maximizeInPlaceFromFloats(x, y, z);\n }\n bBox.reConstruct(tempMin, tempMax, mesh._worldMatrix);\n }\n // place and scale the particle bouding sphere in the SPS local system, then update it\n const minBbox = modelBoundingInfo.minimum.multiplyToRef(particleScaling, tempVectors[1]);\n const maxBbox = modelBoundingInfo.maximum.multiplyToRef(particleScaling, tempVectors[2]);\n const bSphereCenter = maxBbox.addToRef(minBbox, tempVectors[3]).scaleInPlace(0.5).addInPlace(particleGlobalPosition);\n const halfDiag = maxBbox.subtractToRef(minBbox, tempVectors[4]).scaleInPlace(0.5 * this._bSphereRadiusFactor);\n const bSphereMinBbox = bSphereCenter.subtractToRef(halfDiag, tempVectors[1]);\n const bSphereMaxBbox = bSphereCenter.addToRef(halfDiag, tempVectors[2]);\n bSphere.reConstruct(bSphereMinBbox, bSphereMaxBbox, mesh._worldMatrix);\n }\n // increment indexes for the next particle\n index = idx + 3;\n colorIndex = colidx + 4;\n uvIndex = uvidx + 2;\n }\n // if the VBO must be updated\n if (update) {\n if (this._computeParticleColor) {\n const vb = mesh.getVertexBuffer(VertexBuffer.ColorKind);\n if (vb && !mesh.isPickable) {\n vb.updateDirectly(colors32, 0);\n }\n else {\n mesh.updateVerticesData(VertexBuffer.ColorKind, colors32, false, false);\n }\n }\n if (this._computeParticleTexture) {\n const vb = mesh.getVertexBuffer(VertexBuffer.UVKind);\n if (vb && !mesh.isPickable) {\n vb.updateDirectly(uvs32, 0);\n }\n else {\n mesh.updateVerticesData(VertexBuffer.UVKind, uvs32, false, false);\n }\n }\n const vbp = mesh.getVertexBuffer(VertexBuffer.PositionKind);\n if (vbp && !mesh.isPickable) {\n vbp.updateDirectly(positions32, 0);\n }\n else {\n mesh.updateVerticesData(VertexBuffer.PositionKind, positions32, false, false);\n }\n if (!mesh.areNormalsFrozen || mesh.isFacetDataEnabled) {\n if (this._computeParticleVertex || mesh.isFacetDataEnabled) {\n // recompute the normals only if the particles can be morphed, update then also the normal reference array _fixedNormal32[]\n const params = mesh.isFacetDataEnabled ? mesh.getFacetDataParameters() : null;\n VertexData.ComputeNormals(positions32, indices32, normals32, params);\n for (let i = 0; i < normals32.length; i++) {\n fixedNormal32[i] = normals32[i];\n }\n }\n if (!mesh.areNormalsFrozen) {\n const vb = mesh.getVertexBuffer(VertexBuffer.NormalKind);\n if (vb && !mesh.isPickable) {\n vb.updateDirectly(normals32, 0);\n }\n else {\n mesh.updateVerticesData(VertexBuffer.NormalKind, normals32, false, false);\n }\n }\n }\n if (depthSortParticles) {\n const depthSortedParticles = this.depthSortedParticles;\n depthSortedParticles.sort(this._depthSortFunction);\n const dspl = depthSortedParticles.length;\n let sid = 0;\n let faceId = 0;\n for (let sorted = 0; sorted < dspl; sorted++) {\n const sortedParticle = depthSortedParticles[sorted];\n const lind = sortedParticle.indicesLength;\n const sind = sortedParticle.ind;\n for (let i = 0; i < lind; i++) {\n indices32[sid] = indices[sind + i];\n sid++;\n if (this._pickable) {\n const f = i % 3;\n if (f == 0) {\n const pickedData = this.pickedParticles[faceId];\n pickedData.idx = sortedParticle.idx;\n pickedData.faceId = faceId;\n faceId++;\n }\n }\n }\n }\n }\n if (this._autoFixFaceOrientation) {\n let particleInd = 0;\n for (let particleIdx = 0; particleIdx < this.particles.length; particleIdx++) {\n const particle = depthSortParticles ? this.particles[this.depthSortedParticles[particleIdx].idx] : this.particles[particleIdx];\n const flipFaces = particle.scale.x * particle.scale.y * particle.scale.z < 0;\n if (flipFaces) {\n for (let faceInd = 0; faceInd < particle._model._indicesLength; faceInd += 3) {\n const tmp = indices[particle._ind + faceInd];\n indices32[particleInd + faceInd] = indices[particle._ind + faceInd + 1];\n indices32[particleInd + faceInd + 1] = tmp;\n }\n }\n particleInd += particle._model._indicesLength;\n }\n }\n if (depthSortParticles || this._autoFixFaceOrientation) {\n mesh.updateIndices(indices32);\n }\n }\n if (this._computeBoundingBox) {\n if (mesh.hasBoundingInfo) {\n mesh.getBoundingInfo().reConstruct(minimum, maximum, mesh._worldMatrix);\n }\n else {\n mesh.buildBoundingInfo(minimum, maximum, mesh._worldMatrix);\n }\n }\n if (this._autoUpdateSubMeshes) {\n this.computeSubMeshes();\n }\n this._recomputeInvisibles = false;\n this.afterUpdateParticles(start, end, update);\n return this;\n }\n /**\n * Disposes the SPS.\n */\n dispose() {\n this.mesh.dispose();\n this.vars = null;\n // drop references to internal big arrays for the GC\n this._positions = null;\n this._indices = null;\n this._normals = null;\n this._uvs = null;\n this._colors = null;\n this._indices32 = null;\n this._positions32 = null;\n this._normals32 = null;\n this._fixedNormal32 = null;\n this._uvs32 = null;\n this._colors32 = null;\n this.pickedParticles = null;\n this.pickedBySubMesh = null;\n this._materials = null;\n this._materialIndexes = null;\n this._indicesByMaterial = null;\n this._idxOfId = null;\n }\n /** Returns an object {idx: number faceId: number} for the picked particle from the passed pickingInfo object.\n * idx is the particle index in the SPS\n * faceId is the picked face index counted within this particle.\n * Returns null if the pickInfo can't identify a picked particle.\n * @param pickingInfo (PickingInfo object)\n * @returns {idx: number, faceId: number} or null\n */\n pickedParticle(pickingInfo) {\n if (pickingInfo.hit) {\n const subMesh = pickingInfo.subMeshId;\n const faceId = pickingInfo.faceId - this.mesh.subMeshes[subMesh].indexStart / 3;\n const picked = this.pickedBySubMesh;\n if (picked[subMesh] && picked[subMesh][faceId]) {\n return picked[subMesh][faceId];\n }\n }\n return null;\n }\n /**\n * Returns a SolidParticle object from its identifier : particle.id\n * @param id (integer) the particle Id\n * @returns the searched particle or null if not found in the SPS.\n */\n getParticleById(id) {\n const p = this.particles[id];\n if (p && p.id == id) {\n return p;\n }\n const particles = this.particles;\n const idx = this._idxOfId[id];\n if (idx !== undefined) {\n return particles[idx];\n }\n let i = 0;\n const nb = this.nbParticles;\n while (i < nb) {\n const particle = particles[i];\n if (particle.id == id) {\n return particle;\n }\n i++;\n }\n return null;\n }\n /**\n * Returns a new array populated with the particles having the passed shapeId.\n * @param shapeId (integer) the shape identifier\n * @returns a new solid particle array\n */\n getParticlesByShapeId(shapeId) {\n const ref = [];\n this.getParticlesByShapeIdToRef(shapeId, ref);\n return ref;\n }\n /**\n * Populates the passed array \"ref\" with the particles having the passed shapeId.\n * @param shapeId the shape identifier\n * @param ref array to populate\n * @returns the SPS\n */\n getParticlesByShapeIdToRef(shapeId, ref) {\n ref.length = 0;\n for (let i = 0; i < this.nbParticles; i++) {\n const p = this.particles[i];\n if (p.shapeId == shapeId) {\n ref.push(p);\n }\n }\n return this;\n }\n /**\n * Computes the required SubMeshes according the materials assigned to the particles.\n * @returns the solid particle system.\n * Does nothing if called before the SPS mesh is built.\n */\n computeSubMeshes() {\n if (!this.mesh || !this._multimaterialEnabled) {\n return this;\n }\n const depthSortedParticles = this.depthSortedParticles;\n if (this.particles.length > 0) {\n for (let p = 0; p < this.particles.length; p++) {\n const part = this.particles[p];\n if (!part.materialIndex) {\n part.materialIndex = 0;\n }\n const sortedPart = depthSortedParticles[p];\n sortedPart.materialIndex = part.materialIndex;\n sortedPart.ind = part._ind;\n sortedPart.indicesLength = part._model._indicesLength;\n sortedPart.idx = part.idx;\n }\n }\n this._sortParticlesByMaterial();\n const indicesByMaterial = this._indicesByMaterial;\n const materialIndexes = this._materialIndexes;\n const mesh = this.mesh;\n mesh.subMeshes = [];\n const vcount = mesh.getTotalVertices();\n for (let m = 0; m < materialIndexes.length; m++) {\n const start = indicesByMaterial[m];\n const count = indicesByMaterial[m + 1] - start;\n const matIndex = materialIndexes[m];\n new SubMesh(matIndex, 0, vcount, start, count, mesh);\n }\n return this;\n }\n /**\n * Sorts the solid particles by material when MultiMaterial is enabled.\n * Updates the indices32 array.\n * Updates the indicesByMaterial array.\n * Updates the mesh indices array.\n * @returns the SPS\n * @internal\n */\n _sortParticlesByMaterial() {\n const indicesByMaterial = [0];\n this._indicesByMaterial = indicesByMaterial;\n const materialIndexes = [];\n this._materialIndexes = materialIndexes;\n const depthSortedParticles = this.depthSortedParticles;\n depthSortedParticles.sort(this._materialSortFunction);\n const length = depthSortedParticles.length;\n const indices32 = this._indices32;\n const indices = this._indices;\n let subMeshIndex = 0;\n let subMeshFaceId = 0;\n let sid = 0;\n let lastMatIndex = depthSortedParticles[0].materialIndex;\n materialIndexes.push(lastMatIndex);\n if (this._pickable) {\n this.pickedBySubMesh = [[]];\n this.pickedParticles = this.pickedBySubMesh[0];\n }\n for (let sorted = 0; sorted < length; sorted++) {\n const sortedPart = depthSortedParticles[sorted];\n const lind = sortedPart.indicesLength;\n const sind = sortedPart.ind;\n if (sortedPart.materialIndex !== lastMatIndex) {\n lastMatIndex = sortedPart.materialIndex;\n indicesByMaterial.push(sid);\n materialIndexes.push(lastMatIndex);\n if (this._pickable) {\n subMeshIndex++;\n this.pickedBySubMesh[subMeshIndex] = [];\n subMeshFaceId = 0;\n }\n }\n let faceId = 0;\n for (let i = 0; i < lind; i++) {\n indices32[sid] = indices[sind + i];\n if (this._pickable) {\n const f = i % 3;\n if (f == 0) {\n const pickedData = this.pickedBySubMesh[subMeshIndex][subMeshFaceId];\n if (pickedData) {\n pickedData.idx = sortedPart.idx;\n pickedData.faceId = faceId;\n }\n else {\n this.pickedBySubMesh[subMeshIndex][subMeshFaceId] = { idx: sortedPart.idx, faceId: faceId };\n }\n subMeshFaceId++;\n faceId++;\n }\n }\n sid++;\n }\n }\n indicesByMaterial.push(indices32.length); // add the last number to ease the indices start/count values for subMeshes creation\n if (this._updatable) {\n this.mesh.updateIndices(indices32);\n }\n return this;\n }\n /**\n * Sets the material indexes by id materialIndexesById[id] = materialIndex\n * @internal\n */\n _setMaterialIndexesById() {\n this._materialIndexesById = {};\n for (let i = 0; i < this._materials.length; i++) {\n const id = this._materials[i].uniqueId;\n this._materialIndexesById[id] = i;\n }\n }\n /**\n * Returns an array with unique values of Materials from the passed array\n * @param array the material array to be checked and filtered\n * @internal\n */\n _filterUniqueMaterialId(array) {\n const filtered = array.filter(function (value, index, self) {\n return self.indexOf(value) === index;\n });\n return filtered;\n }\n /**\n * Sets a new Standard Material as _defaultMaterial if not already set.\n * @internal\n */\n _setDefaultMaterial() {\n if (!this._defaultMaterial) {\n this._defaultMaterial = new StandardMaterial(this.name + \"DefaultMaterial\", this._scene);\n }\n return this._defaultMaterial;\n }\n /**\n * Visibility helper : Recomputes the visible size according to the mesh bounding box\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_visibility\n * @returns the SPS.\n */\n refreshVisibleSize() {\n if (!this._isVisibilityBoxLocked) {\n this.mesh.refreshBoundingInfo();\n }\n return this;\n }\n /**\n * Visibility helper : Sets the size of a visibility box, this sets the underlying mesh bounding box.\n * @param size the size (float) of the visibility box\n * note : this doesn't lock the SPS mesh bounding box.\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_visibility\n */\n setVisibilityBox(size) {\n const vis = size / 2;\n this.mesh.buildBoundingInfo(new Vector3(-vis, -vis, -vis), new Vector3(vis, vis, vis));\n }\n /**\n * Gets whether the SPS as always visible or not\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_visibility\n */\n get isAlwaysVisible() {\n return this._alwaysVisible;\n }\n /**\n * Sets the SPS as always visible or not\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_visibility\n */\n set isAlwaysVisible(val) {\n this._alwaysVisible = val;\n this.mesh.alwaysSelectAsActiveMesh = val;\n }\n /**\n * Sets the SPS visibility box as locked or not. This enables/disables the underlying mesh bounding box updates.\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_visibility\n */\n set isVisibilityBoxLocked(val) {\n this._isVisibilityBoxLocked = val;\n const boundingInfo = this.mesh.getBoundingInfo();\n boundingInfo.isLocked = val;\n }\n /**\n * Gets if the SPS visibility box as locked or not. This enables/disables the underlying mesh bounding box updates.\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_visibility\n */\n get isVisibilityBoxLocked() {\n return this._isVisibilityBoxLocked;\n }\n /**\n * Tells to `setParticles()` to compute the particle rotations or not.\n * Default value : true. The SPS is faster when it's set to false.\n * Note : the particle rotations aren't stored values, so setting `computeParticleRotation` to false will prevents the particle to rotate.\n */\n set computeParticleRotation(val) {\n this._computeParticleRotation = val;\n }\n /**\n * Tells to `setParticles()` to compute the particle colors or not.\n * Default value : true. The SPS is faster when it's set to false.\n * Note : the particle colors are stored values, so setting `computeParticleColor` to false will keep yet the last colors set.\n */\n set computeParticleColor(val) {\n this._computeParticleColor = val;\n }\n set computeParticleTexture(val) {\n this._computeParticleTexture = val;\n }\n /**\n * Tells to `setParticles()` to call the vertex function for each vertex of each particle, or not.\n * Default value : false. The SPS is faster when it's set to false.\n * Note : the particle custom vertex positions aren't stored values.\n */\n set computeParticleVertex(val) {\n this._computeParticleVertex = val;\n }\n /**\n * Tells to `setParticles()` to compute or not the mesh bounding box when computing the particle positions.\n */\n set computeBoundingBox(val) {\n this._computeBoundingBox = val;\n }\n /**\n * Tells to `setParticles()` to sort or not the distance between each particle and the camera.\n * Skipped when `enableDepthSort` is set to `false` (default) at construction time.\n * Default : `true`\n */\n set depthSortParticles(val) {\n this._depthSortParticles = val;\n }\n /**\n * Gets if `setParticles()` computes the particle rotations or not.\n * Default value : true. The SPS is faster when it's set to false.\n * Note : the particle rotations aren't stored values, so setting `computeParticleRotation` to false will prevents the particle to rotate.\n */\n get computeParticleRotation() {\n return this._computeParticleRotation;\n }\n /**\n * Gets if `setParticles()` computes the particle colors or not.\n * Default value : true. The SPS is faster when it's set to false.\n * Note : the particle colors are stored values, so setting `computeParticleColor` to false will keep yet the last colors set.\n */\n get computeParticleColor() {\n return this._computeParticleColor;\n }\n /**\n * Gets if `setParticles()` computes the particle textures or not.\n * Default value : true. The SPS is faster when it's set to false.\n * Note : the particle textures are stored values, so setting `computeParticleTexture` to false will keep yet the last colors set.\n */\n get computeParticleTexture() {\n return this._computeParticleTexture;\n }\n /**\n * Gets if `setParticles()` calls the vertex function for each vertex of each particle, or not.\n * Default value : false. The SPS is faster when it's set to false.\n * Note : the particle custom vertex positions aren't stored values.\n */\n get computeParticleVertex() {\n return this._computeParticleVertex;\n }\n /**\n * Gets if `setParticles()` computes or not the mesh bounding box when computing the particle positions.\n */\n get computeBoundingBox() {\n return this._computeBoundingBox;\n }\n /**\n * Gets if `setParticles()` sorts or not the distance between each particle and the camera.\n * Skipped when `enableDepthSort` is set to `false` (default) at construction time.\n * Default : `true`\n */\n get depthSortParticles() {\n return this._depthSortParticles;\n }\n /**\n * Gets if the SPS is created as expandable at construction time.\n * Default : `false`\n */\n get expandable() {\n return this._expandable;\n }\n /**\n * Gets if the SPS supports the Multi Materials\n */\n get multimaterialEnabled() {\n return this._multimaterialEnabled;\n }\n /**\n * Gets if the SPS uses the model materials for its own multimaterial.\n */\n get useModelMaterial() {\n return this._useModelMaterial;\n }\n /**\n * The SPS used material array.\n */\n get materials() {\n return this._materials;\n }\n /**\n * Sets the SPS MultiMaterial from the passed materials.\n * Note : the passed array is internally copied and not used then by reference.\n * @param materials an array of material objects. This array indexes are the materialIndex values of the particles.\n */\n setMultiMaterial(materials) {\n this._materials = this._filterUniqueMaterialId(materials);\n this._setMaterialIndexesById();\n if (this._multimaterial) {\n this._multimaterial.dispose();\n }\n this._multimaterial = new MultiMaterial(this.name + \"MultiMaterial\", this._scene);\n for (let m = 0; m < this._materials.length; m++) {\n this._multimaterial.subMaterials.push(this._materials[m]);\n }\n this.computeSubMeshes();\n this.mesh.material = this._multimaterial;\n }\n /**\n * The SPS computed multimaterial object\n */\n get multimaterial() {\n return this._multimaterial;\n }\n set multimaterial(mm) {\n this._multimaterial = mm;\n }\n /**\n * If the subMeshes must be updated on the next call to setParticles()\n */\n get autoUpdateSubMeshes() {\n return this._autoUpdateSubMeshes;\n }\n set autoUpdateSubMeshes(val) {\n this._autoUpdateSubMeshes = val;\n }\n // =======================================================================\n // Particle behavior logic\n // these following methods may be overwritten by the user to fit his needs\n /**\n * This function does nothing. It may be overwritten to set all the particle first values.\n * The SPS doesn't call this function, you may have to call it by your own.\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/manage_sps_particles\n */\n initParticles() { }\n /**\n * This function does nothing. It may be overwritten to recycle a particle.\n * The SPS doesn't call this function, you may have to call it by your own.\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/manage_sps_particles\n * @param particle The particle to recycle\n * @returns the recycled particle\n */\n recycleParticle(particle) {\n return particle;\n }\n /**\n * Updates a particle : this function should be overwritten by the user.\n * It is called on each particle by `setParticles()`. This is the place to code each particle behavior.\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/manage_sps_particles\n * @example : just set a particle position or velocity and recycle conditions\n * @param particle The particle to update\n * @returns the updated particle\n */\n updateParticle(particle) {\n return particle;\n }\n /**\n * Updates a vertex of a particle : it can be overwritten by the user.\n * This will be called on each vertex particle by `setParticles()` if `computeParticleVertex` is set to true only.\n * @param particle the current particle\n * @param vertex the current vertex of the current particle : a SolidParticleVertex object\n * @param pt the index of the current vertex in the particle shape\n * doc : https://doc.babylonjs.com/features/featuresDeepDive/particles/solid_particle_system/sps_vertices\n * @example : just set a vertex particle position or color\n * @returns the sps\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n updateParticleVertex(particle, vertex, pt) {\n return this;\n }\n /**\n * This will be called before any other treatment by `setParticles()` and will be passed three parameters.\n * This does nothing and may be overwritten by the user.\n * @param start the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()\n * @param stop the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()\n * @param update the boolean update value actually passed to setParticles()\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n beforeUpdateParticles(start, stop, update) { }\n /**\n * This will be called by `setParticles()` after all the other treatments and just before the actual mesh update.\n * This will be passed three parameters.\n * This does nothing and may be overwritten by the user.\n * @param start the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()\n * @param stop the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()\n * @param update the boolean update value actually passed to setParticles()\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n afterUpdateParticles(start, stop, update) { }\n}\n"],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]}