浏览代码

linter + doc + fixes + refactor

Jérôme Bousquié 5 年之前
父节点
当前提交
4b12112008
共有 3 个文件被更改,包括 143 次插入34 次删除
  1. 1 0
      dist/preview release/what's new.md
  2. 26 2
      src/Particles/solidParticle.ts
  3. 116 32
      src/Particles/solidParticleSystem.ts

+ 1 - 0
dist/preview release/what's new.md

@@ -142,6 +142,7 @@
 
 - Added the feature `expandable` to the Solid Particle System ([jerome](https://github.com/jbousquie/))
 - Added the feature `removeParticles()` to the Solid Particle System ([jerome](https://github.com/jbousquie/))
+- Added the feature "storable particles" and `insertParticlesFromArray()` to the Solid Particle System ([jerome](https://github.com/jbousquie/))
 
 ### Navigation Mesh
 

+ 26 - 2
src/Particles/solidParticle.ts

@@ -131,7 +131,7 @@ export class SolidParticle {
     /**
      * Creates a Solid Particle object.
      * Don't create particles manually, use instead the Solid Particle System internal tools like _addParticle()
-     * @param particleIndex (integer) is the particle index in the Solid Particle System pool. 
+     * @param particleIndex (integer) is the particle index in the Solid Particle System pool.
      * @param particleId (integer) is the particle identifier. Unless some particles are removed from the SPS, it's the same value than the particle idx.
      * @param positionIndex (integer) is the starting index of the particle vertices in the SPS "positions" array.
      * @param indiceIndex (integer) is the starting index of the particle indices in the SPS "indices" array.
@@ -155,7 +155,31 @@ export class SolidParticle {
             this._boundingInfo = new BoundingInfo(modelBoundingInfo.minimum, modelBoundingInfo.maximum);
         }
     }
-
+    /**
+     * Copies the particle property values into the existing target : position, rotation, scaling, uvs, colors, pivot, parent, visibility, alive
+     * @param target the particle target
+     * @returns the current particle
+     */
+    public copyToRef(target: SolidParticle): SolidParticle {
+        target.position.copyFrom(this.position);
+        target.rotation.copyFrom(this.rotation);
+        if (this.rotationQuaternion) {
+            target.rotationQuaternion!.copyFrom(this.rotationQuaternion!);
+        }
+        target.scaling.copyFrom(this.scaling);
+        if (this.color) {
+            target.color!.copyFrom(this.color!);
+        }
+        target.uvs.copyFrom(this.uvs);
+        target.velocity.copyFrom(this.velocity);
+        target.pivot.copyFrom(this.pivot);
+        target.translateFromPivot = this.translateFromPivot;
+        target.alive = this.alive;
+        target.isVisible = this.isVisible;
+        target.parentId = this.parentId;
+        target.cullingStrategy = this.cullingStrategy;
+        return this;
+    }
     /**
      * Legacy support, changed scale to scaling
      */

+ 116 - 32
src/Particles/solidParticleSystem.ts

@@ -228,7 +228,7 @@ export class SolidParticleSystem implements IDisposable {
      * @param options {facetNb} (optional integer, default 1) is the number of mesh facets per particle, this parameter is overriden by the parameter `number` if any
      * {delta} (optional integer, default 0) is the random extra number of facets per particle , each particle will have between `facetNb` and `facetNb + delta` facets
      * {number} (optional positive integer) is the wanted number of particles : each particle is built with `mesh_total_facets / number` facets
-     * {storage} (optional existing array) is an array where the particles will be stored for a further use instead of being inserted in the SPS.  
+     * {storage} (optional existing array) is an array where the particles will be stored for a further use instead of being inserted in the SPS.
      * @returns the current SPS
      */
     public digest(mesh: Mesh, options?: { facetNb?: number; number?: number; delta?: number; storage?: [] }): SolidParticleSystem {
@@ -344,7 +344,10 @@ export class SolidParticleSystem implements IDisposable {
         return this;
     }
 
-    // unrotate the fixed normals in case the mesh was built with pre-rotated particles, ex : use of positionFunction in addShape()
+    /**
+     * Unrotate the fixed normals in case the mesh was built with pre-rotated particles, ex : use of positionFunction in addShape()
+     * @hidden
+     */
     private _unrotateFixedNormals() {
         var index = 0;
         var idx = 0;
@@ -376,7 +379,10 @@ export class SolidParticleSystem implements IDisposable {
         }
     }
 
-    //reset copy
+    /**
+     * Resets the temporary working copy particle
+     * @hidden
+     */
     private _resetCopy() {
         const copy = this._copy;
         copy.position.setAll(0);
@@ -388,7 +394,24 @@ export class SolidParticleSystem implements IDisposable {
         copy.translateFromPivot = false;
     }
 
-    // _meshBuilder : inserts the shape model in the global SPS mesh
+    /**
+     * Inserts the shape model geometry in the global SPS mesh by updating the positions, indices, normals, colors, uvs arrays
+     * @param p the current index in the positions array to be updated
+     * @param shape a Vector3 array, the shape geometry
+     * @param positions the positions array to be updated
+     * @param meshInd the shape indices array
+     * @param indices the indices array to be updated
+     * @param meshUV the shape uv array
+     * @param uvs the uv array to be updated
+     * @param meshCol the shape color array
+     * @param colors the color array to be updated
+     * @param meshNor the shape normals array
+     * @param normals the normals array to be updated
+     * @param idx the particle index
+     * @param idxInShape the particle index in its shape
+     * @param options the addShape() method  passed options
+     * @hidden
+     */
     private _meshBuilder(p: number, shape: Vector3[], positions: number[], meshInd: IndicesArray, indices: number[], meshUV: number[] | Float32Array, uvs: number[], meshCol: number[] | Float32Array, colors: number[], meshNor: number[] | Float32Array, normals: number[], idx: number, idxInShape: number, options: any): SolidParticle {
         var i;
         var u = 0;
@@ -425,7 +448,7 @@ export class SolidParticleSystem implements IDisposable {
         else {
             pivotBackTranslation.copyFrom(scaledPivot);
         }
-        
+
         for (i = 0; i < shape.length; i++) {
             tmpVertex.copyFrom(shape[i]);
             if (options && options.vertexFunction) {
@@ -436,7 +459,7 @@ export class SolidParticleSystem implements IDisposable {
             Vector3.TransformCoordinatesToRef(tmpVertex, rotMatrix, tmpRotated);
             tmpRotated.addInPlace(pivotBackTranslation).addInPlace(copy.position);
             positions.push(tmpRotated.x, tmpRotated.y, tmpRotated.z);
-            
+
             if (meshUV) {
                 const copyUvs = copy.uvs;
                 uvs.push((copyUvs.z - copyUvs.x) * meshUV[u] + copyUvs.x, (copyUvs.w - copyUvs.y) * meshUV[u + 1] + copyUvs.y);
@@ -461,7 +484,7 @@ export class SolidParticleSystem implements IDisposable {
             }
             colors.push(this._color.r, this._color.g, this._color.b, this._color.a);
             c += 4;
-    
+
             if (!this.recomputeNormals && meshNor) {
                 tmpVertex.x = meshNor[n];
                 tmpVertex.y = meshNor[n + 1];
@@ -470,7 +493,6 @@ export class SolidParticleSystem implements IDisposable {
                 normals.push(tmpVertex.x, tmpVertex.y, tmpVertex.z);
                 n += 3;
             }
-
         }
 
         for (i = 0; i < meshInd.length; i++) {
@@ -495,7 +517,12 @@ export class SolidParticleSystem implements IDisposable {
         return copy;
     }
 
-    // returns a shape array from positions array
+    /**
+     * Returns a shape Vector3 array from positions float array
+     * @param positions float array
+     * @returns a vector3 array
+     * @hidden
+     */
     private _posToShape(positions: number[] | Float32Array): Vector3[] {
         var shape = [];
         for (var i = 0; i < positions.length; i += 3) {
@@ -504,7 +531,12 @@ export class SolidParticleSystem implements IDisposable {
         return shape;
     }
 
-    // returns a shapeUV array from a Vector4 uvs
+    /**
+     * Returns a shapeUV array from a float uvs (array deep copy)
+     * @param uvs as a float array
+     * @returns a shapeUV array
+     * @hidden
+     */
     private _uvsToShapeUV(uvs: number[] | Float32Array): number[] {
         var shapeUV = [];
         if (uvs) {
@@ -515,7 +547,19 @@ export class SolidParticleSystem implements IDisposable {
         return shapeUV;
     }
 
-    // adds a new particle object in the particles array
+    /**
+     * Adds a new particle object in the particles array
+     * @param idx particle index in particles array
+     * @param id particle id
+     * @param idxpos positionIndex : the starting index of the particle vertices in the SPS "positions" array
+     * @param idxind indiceIndex : he starting index of the particle indices in the SPS "indices" array
+     * @param model particle ModelShape object
+     * @param shapeId model shape identifier
+     * @param idxInShape index of the particle in the current model
+     * @param bInfo model bounding info object
+     * @param storage target storage array, if any
+     * @hidden
+     */
     private _addParticle(idx: number, id: number, idxpos: number, idxind: number, model: ModelShape, shapeId: number, idxInShape: number, bInfo: Nullable<BoundingInfo> = null, storage: Nullable<[]> = null): SolidParticle {
         var sp = new SolidParticle(idx, id, idxpos, idxind, model, shapeId, idxInShape, this, bInfo);
         var target = (storage) ? storage : this.particles;
@@ -530,7 +574,7 @@ export class SolidParticleSystem implements IDisposable {
      * @param nb (positive integer) the number of particles to be created from this model
      * @param options {positionFunction} is an optional javascript function to called for each particle on SPS creation.
      * {vertexFunction} is an optional javascript function to called for each vertex of each particle on SPS creation
-     * {storage} (optional existing array) is an array where the particles will be stored for a further use instead of being inserted in the SPS.  
+     * {storage} (optional existing array) is an array where the particles will be stored for a further use instead of being inserted in the SPS.
      * @returns the number of shapes in the system
      */
     public addShape(mesh: Mesh, nb: number, options?: { positionFunction?: any; vertexFunction?: any; storage?: [] }): number {
@@ -543,6 +587,7 @@ export class SolidParticleSystem implements IDisposable {
         var indices = Array.from(meshInd);
         var shapeNormals = Array.from(meshNor);
         var shapeColors = (meshCol) ? Array.from(meshCol) : [];
+        var storage = (options && options.storage) ? options.storage : null;
         var bbInfo: Nullable<BoundingInfo> = null;
         if (this._particlesIntersect) {
             bbInfo = mesh.getBoundingInfo();
@@ -559,14 +604,17 @@ export class SolidParticleSystem implements IDisposable {
         // particles
         var idx = this.nbParticles;
         for (var i = 0; i < nb; i++) {
-            this._insertNewParticle(idx, i, modelShape, shape, meshInd, meshCol, meshUV, meshNor, bbInfo, options);
-        } 
+            this._insertNewParticle(idx, i, modelShape, shape, meshInd, meshUV, meshCol, meshNor, bbInfo, storage, options);
+        }
         this._shapeCounter++;
         this._isNotBuilt = true;        // buildMesh() call is now expected for setParticles() to work
         return this._shapeCounter - 1;
     }
 
-    // rebuilds a particle back to its just built status : if needed, recomputes the custom positions and vertices
+    /**
+     * Rebuilds a particle back to its just built status : if needed, recomputes the custom positions and vertices
+     * @hidden
+     */
     private _rebuildParticle(particle: SolidParticle, reset: boolean = false): void {
         this._resetCopy();
         const copy = this._copy;
@@ -627,6 +675,7 @@ export class SolidParticleSystem implements IDisposable {
         this.mesh.updateVerticesData(VertexBuffer.PositionKind, this._positions32, false, false);
         return this;
     }
+
     /** Removes the particles from the start-th to the end-th included from an expandable SPS (required).
      *  Returns an array with the removed particles.
      *  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.
@@ -659,6 +708,9 @@ export class SolidParticleSystem implements IDisposable {
         this._normals.length = 0;
         this._index = 0;
         this._idxOfId.length = 0;
+        if (this._depthSort) {
+            this.depthSortedParticles.length = 0;
+        }
         const particlesLength = particles.length;
         for (var p = 0; p < particlesLength; p++) {
             var particle = particles[p];
@@ -677,16 +729,16 @@ export class SolidParticleSystem implements IDisposable {
         this._isNotBuilt = true;        // buildMesh() is now expected for setParticles() to work
         return removed;
     }
+
     /**
-     * Inserts some pre-created particles in the solid particle system so that they can be managed by setParticles().  
-     * @param solidParticleArray an array populated with Solid Particles object
-     * Returns the SPS.
+     * Inserts some pre-created particles in the solid particle system so that they can be managed by setParticles().
+     * @param solidParticleArray an array populated with Solid Particles objects
+     * @returns the SPS
      */
     public insertParticlesFromArray(solidParticleArray: SolidParticle[]): SolidParticleSystem {
         if (!this._expandable) {
             return this;
         }
-
         var idxInShape = 0;
         var  currentShapeId = solidParticleArray[0].shapeId;
         const nb = solidParticleArray.length;
@@ -699,27 +751,43 @@ export class SolidParticleSystem implements IDisposable {
             var meshCol = model._shapeColors;
             var meshNor = model._normals;
             var bbInfo = sp._boundingInfo;
-            this._insertNewParticle(this.nbParticles, idxInShape, sp._model, shape, meshInd, meshCol, meshUV, meshNor, bbInfo, null);
+            var particle = this._insertNewParticle(this.nbParticles, idxInShape, sp._model, shape, meshInd, meshUV, meshCol, meshNor, bbInfo, null, null);
+            sp.copyToRef(particle!);
             idxInShape++;
             if (currentShapeId != sp.shapeId) {
                 currentShapeId = sp.shapeId;
                 idxInShape = 0;
             }
-        } 
+        }
         this._isNotBuilt = true;        // buildMesh() call is now expected for setParticles() to work
         return this;
     }
 
-    // Calls _meshBuilder() to increase the SPS mesh geometry step by step
-    // calls _addParticle() to populate the particle array
-    // factorized code from addShape() and insertParticlesFromArray()
-    private _insertNewParticle(idx: number, i: number, modelShape: ModelShape, shape: Vector3[], meshInd: IndicesArray, meshUV: number[] | Float32Array, meshCol: number[] | Float32Array, meshNor: number[] | Float32Array, bbInfo: Nullable<BoundingInfo>, options: any): void {
+    /**
+     * Creates a new particle and modifies the SPS mesh geometry :
+     * - calls _meshBuilder() to increase the SPS mesh geometry step by step
+     * - calls _addParticle() to populate the particle array
+     * factorized code from addShape() and insertParticlesFromArray()
+     * @param idx particle index in the particles array
+     * @param i particle index in its shape
+     * @param modelShape particle ModelShape object
+     * @param shape shape vertex array
+     * @param meshInd shape indices array
+     * @param meshUV shape uv array
+     * @param meshCol shape color array
+     * @param meshNor shape normals array
+     * @param bbInfo shape bounding info
+     * @param storage target particle storage
+     * @options addShape() passed options
+     * @hidden
+     */
+    private _insertNewParticle(idx: number, i: number, modelShape: ModelShape, shape: Vector3[], meshInd: IndicesArray, meshUV: number[] | Float32Array, meshCol: number[] | Float32Array, meshNor: number[] | Float32Array, bbInfo: Nullable<BoundingInfo>, storage: Nullable<[]> , options: any): Nullable<SolidParticle> {
         var currentPos = this._positions.length;
         var currentInd = this._indices.length;
         var currentCopy = this._meshBuilder(this._index, shape, this._positions, meshInd, this._indices, meshUV, this._uvs, meshCol, this._colors, meshNor, this._normals, idx, i, options);
-        var storage = (options && options.storage) ? options.storage : null;
+        var sp: Nullable<SolidParticle> = null;
         if (this._updatable) {
-            var sp = this._addParticle(this.nbParticles, this._lastParticleId, currentPos, currentInd, modelShape, this._shapeCounter, i, bbInfo, storage);
+            sp = this._addParticle(this.nbParticles, this._lastParticleId, currentPos, currentInd, modelShape, this._shapeCounter, i, bbInfo, storage);
             sp.position.copyFrom(currentCopy.position);
             sp.rotation.copyFrom(currentCopy.rotation);
             if (currentCopy.rotationQuaternion && sp.rotationQuaternion) {
@@ -730,12 +798,16 @@ export class SolidParticleSystem implements IDisposable {
             }
             sp.scaling.copyFrom(currentCopy.scaling);
             sp.uvs.copyFrom(currentCopy.uvs);
+            if (this.expandable) {
+                this._idxOfId[sp.id] = sp.idx;
+            }
         }
         if (!storage) {
             this._index += shape.length;
             this.nbParticles++;
             this._lastParticleId++;
         }
+        return sp;
     }
 
     /**
@@ -1144,10 +1216,11 @@ export class SolidParticleSystem implements IDisposable {
         (<any>this._colors32) = null;
         (<any>this.pickedParticles) = null;
     }
+
     /**
      * Returns a SolidParticle object from its identifier : particle.id
      * @param id (integer) the particle Id
-     * returns null of not found in the SPS.
+     * @returns the searched particle or null if not found in the SPS.
      */
     public getParticleById(id: number): Nullable<SolidParticle> {
         const p = this.particles[id];
@@ -1170,20 +1243,23 @@ export class SolidParticleSystem implements IDisposable {
         }
         return null;
     }
+
     /**
      * Returns a new array populated with the particles having the passed shapeId.
-     * @param shapeId (integer)
+     * @param shapeId (integer) the shape identifier
+     * @returns a new solid particle array
      */
     public getParticlesByShapeId(shapeId: number): SolidParticle[] {
         var ref: SolidParticle[] = [];
         this.getParticlesByShapeIdToRef(shapeId, ref);
         return ref;
     }
+
     /**
      * Populates the passed array "ref" with the particles having the passed shapeId.
-     * Returns the SPS.
-     * @param shapeId 
-     * @param ref 
+     * @param shapeId the shape identifier
+     * @returns the SPS
+     * @param ref
      */
     public getParticlesByShapeIdToRef(shapeId: number, ref: SolidParticle[]): SolidParticleSystem {
         ref.length = 0;
@@ -1195,6 +1271,7 @@ export class SolidParticleSystem implements IDisposable {
         }
         return this;
     }
+
     /**
      * Visibilty helper : Recomputes the visible size according to the mesh bounding box
      * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#sps-visibility
@@ -1263,6 +1340,7 @@ export class SolidParticleSystem implements IDisposable {
     public set computeParticleRotation(val: boolean) {
         this._computeParticleRotation = val;
     }
+
     /**
      * Tells to `setParticles()` to compute the particle colors or not.
      * Default value : true. The SPS is faster when it's set to false.
@@ -1306,6 +1384,7 @@ export class SolidParticleSystem implements IDisposable {
     public get computeParticleRotation(): boolean {
         return this._computeParticleRotation;
     }
+
     /**
      * Gets if `setParticles()` computes the particle colors or not.
      * Default value : true. The SPS is faster when it's set to false.
@@ -1314,6 +1393,7 @@ export class SolidParticleSystem implements IDisposable {
     public get computeParticleColor(): boolean {
         return this._computeParticleColor;
     }
+
     /**
      * Gets if `setParticles()` computes the particle textures or not.
      * Default value : true. The SPS is faster when it's set to false.
@@ -1322,6 +1402,7 @@ export class SolidParticleSystem implements IDisposable {
     public get computeParticleTexture(): boolean {
         return this._computeParticleTexture;
     }
+
     /**
      * Gets if `setParticles()` calls the vertex function for each vertex of each particle, or not.
      * Default value : false. The SPS is faster when it's set to false.
@@ -1330,12 +1411,14 @@ export class SolidParticleSystem implements IDisposable {
     public get computeParticleVertex(): boolean {
         return this._computeParticleVertex;
     }
+
     /**
      * Gets if `setParticles()` computes or not the mesh bounding box when computing the particle positions.
      */
     public get computeBoundingBox(): boolean {
         return this._computeBoundingBox;
     }
+
     /**
      * Gets if `setParticles()` sorts or not the distance between each particle and the camera.
      * Skipped when `enableDepthSort` is set to `false` (default) at construction time.
@@ -1344,6 +1427,7 @@ export class SolidParticleSystem implements IDisposable {
     public get depthSortParticles(): boolean {
         return this._depthSortParticles;
     }
+
     /**
      * Gets if the SPS is created as expandable at construction time.
      * Default : `false`