Explorar el Código

Add bSphereOnly parameter + fix intersect/visibility

jbousquie hace 8 años
padre
commit
fd4f0289a5

+ 6 - 1
src/Particles/babylon.solidParticle.ts

@@ -17,6 +17,7 @@ module BABYLON {
         public idxInShape: number = 0;                  // index of the particle in its shape id
         public _modelBoundingInfo: BoundingInfo;        // reference to the shape model BoundingInfo object
         public _boundingInfo: BoundingInfo;             // particle BoundingInfo
+        public _sps: SolidParticleSystem;               // reference to the SPS what the particle belongs to
 
         /**
          * Creates a Solid Particle object.
@@ -28,12 +29,13 @@ module BABYLON {
          * `idxInShape` (integer) is the index of the particle in the current model (ex: the 10th box of addShape(box, 30))
          * `modelBoundingInfo` is the reference to the model BoundingInfo used for intersection computations.
          */
-        constructor(particleIndex: number, positionIndex: number, model: ModelShape, shapeId: number, idxInShape: number, modelBoundingInfo?: BoundingInfo) {
+        constructor(particleIndex: number, positionIndex: number, model: ModelShape, shapeId: number, idxInShape: number, sps: SolidParticleSystem, modelBoundingInfo?: BoundingInfo) {
             this.idx = particleIndex;
             this._pos = positionIndex;
             this._model = model;
             this.shapeId = shapeId;
             this.idxInShape = idxInShape;
+            this._sps = sps;
             if (modelBoundingInfo) {
                 this._modelBoundingInfo = modelBoundingInfo;
                 this._boundingInfo = new BoundingInfo(modelBoundingInfo.minimum, modelBoundingInfo.maximum);
@@ -71,6 +73,9 @@ module BABYLON {
             if (!this._boundingInfo || !target._boundingInfo) {
                 return false;
             }
+            if (this._sps._bSphereOnly) {
+                return BoundingSphere.Intersects(this._boundingInfo.boundingSphere, target._boundingInfo.boundingSphere);
+            }
             return this._boundingInfo.intersects(target._boundingInfo, false);
         }
     }

+ 21 - 34
src/Particles/babylon.solidParticleSystem.ts

@@ -67,7 +67,7 @@
         private _isVisibilityBoxLocked = false;
         private _alwaysVisible: boolean = false;
         private _shapeCounter: number = 0;
-        private _copy: SolidParticle = new SolidParticle(null, null, null, null, null);
+        private _copy: SolidParticle = new SolidParticle(null, null, null, null, null, null);
         private _shape: Vector3[];
         private _shapeUV: number[];
         private _color: Color4 = new Color4(0, 0, 0, 0);
@@ -111,6 +111,7 @@
         private _minBbox: Vector3 = Tmp.Vector3[4];
         private _maxBbox: Vector3 = Tmp.Vector3[5];
         private _particlesIntersect: boolean = false;
+        public _bSphereOnly: boolean = false;
 
         /**
         * Creates a SPS (Solid Particle System) object.
@@ -120,12 +121,13 @@
         * `isPickable` (default false) : if the solid particles must be pickable.  
         * `particleIntersection` (default false) : if the solid particle intersections must be computed
         */
-        constructor(name: string, scene: Scene, options?: { updatable?: boolean; isPickable?: boolean; particleIntersection?: boolean }) {
+        constructor(name: string, scene: Scene, options?: { updatable?: boolean; isPickable?: boolean; particleIntersection?: boolean; boundingSphereOnly?: boolean }) {
             this.name = name;
             this._scene = scene;
             this._camera = <TargetCamera>scene.activeCamera;
             this._pickable = options ? options.isPickable : false;
             this._particlesIntersect = options ? options.particleIntersection : false;
+            this._bSphereOnly= options ? options.boundingSphereOnly : false;
             if (options && options.updatable) {
                 this._updatable = options.updatable;
             } else {
@@ -404,7 +406,7 @@
 
         // adds a new particle object in the particles array
         private _addParticle(idx: number, idxpos: number, model: ModelShape, shapeId: number, idxInShape: number, bInfo?: BoundingInfo): void {
-            this.particles.push(new SolidParticle(idx, idxpos, model, shapeId, idxInShape, bInfo));
+            this.particles.push(new SolidParticle(idx, idxpos, model, shapeId, idxInShape, this, bInfo));
         }
 
         /**
@@ -704,11 +706,10 @@
                 if (this._particlesIntersect) {
                     var bInfo = this._particle._boundingInfo;
                     var bBox = bInfo.boundingBox;
-                    var bSphere = bInfo.boundingSphere;
-                    
-                    // place, scale and rotate the particle bbox within the SPS local system
-                    for (var b = 0; b < bBox.vectors.length; b++) {
-                        if (this._particle.isVisible) {
+                    var bSphere = bInfo.boundingSphere;                   
+                    if (!this._bSphereOnly) {
+                        // place, scale and rotate the particle bbox within the SPS local system, then update it
+                        for (var b = 0; b < bBox.vectors.length; b++) {
                             this._vertex.x = this._particle._modelBoundingInfo.boundingBox.vectors[b].x * this._particle.scaling.x;
                             this._vertex.y = this._particle._modelBoundingInfo.boundingBox.vectors[b].y * this._particle.scaling.y;
                             this._vertex.z = this._particle._modelBoundingInfo.boundingBox.vectors[b].z * this._particle.scaling.z;
@@ -720,33 +721,19 @@
                             bBox.vectors[b].y = this._particle.position.y + this._cam_axisX.y * this._rotated.x + this._cam_axisY.y * this._rotated.y + this._cam_axisZ.y * this._rotated.z;
                             bBox.vectors[b].z = this._particle.position.z + this._cam_axisX.z * this._rotated.x + this._cam_axisY.z * this._rotated.y + this._cam_axisZ.z * this._rotated.z;
                         }
-                        else {
-                            bBox.vectors[b].x = this._camera.position.x;
-                            bBox.vectors[b].y = this._camera.position.y;
-                            bBox.vectors[b].z = this._camera.position.z;
-                        }
-                    }
-                    // place and scale the particle bouding sphere in the SPS local system
-                    if (this._particle.isVisible) {
-                        this._minBbox.x = this._particle._modelBoundingInfo.minimum.x * this._particle.scaling.x;
-                        this._minBbox.y = this._particle._modelBoundingInfo.minimum.y * this._particle.scaling.y;
-                        this._minBbox.z = this._particle._modelBoundingInfo.minimum.z * this._particle.scaling.z;
-                        this._maxBbox.x = this._particle._modelBoundingInfo.maximum.x * this._particle.scaling.x;
-                        this._maxBbox.y = this._particle._modelBoundingInfo.maximum.y * this._particle.scaling.y;
-                        this._maxBbox.z = this._particle._modelBoundingInfo.maximum.z * this._particle.scaling.z;
-                        bSphere.center.x = this._particle.position.x + (this._minBbox.x + this._maxBbox.x) * 0.5;
-                        bSphere.center.y = this._particle.position.y + (this._minBbox.y + this._maxBbox.y) * 0.5;
-                        bSphere.center.z = this._particle.position.z + (this._minBbox.z + this._maxBbox.z) * 0.5;
-                        bSphere.radius = Vector3.Distance(this._minimum, this._maximum) * 0.5;
-                    } else {
-                        bSphere.center.x = this._camera.position.x;
-                        bSphere.center.y = this._camera.position.x;
-                        bSphere.center.z = this._camera.position.x;
-                        bSphere.radius = 0.0;                       
+                        bBox._update(this.mesh._worldMatrix);
                     }
-
-                    // then update the bbox and the bsphere into the world system
-                    bBox._update(this.mesh._worldMatrix);
+                    // place and scale the particle bouding sphere in the SPS local system, then update it
+                    this._minBbox.x = this._particle._modelBoundingInfo.minimum.x * this._particle.scaling.x;
+                    this._minBbox.y = this._particle._modelBoundingInfo.minimum.y * this._particle.scaling.y;
+                    this._minBbox.z = this._particle._modelBoundingInfo.minimum.z * this._particle.scaling.z;
+                    this._maxBbox.x = this._particle._modelBoundingInfo.maximum.x * this._particle.scaling.x;
+                    this._maxBbox.y = this._particle._modelBoundingInfo.maximum.y * this._particle.scaling.y;
+                    this._maxBbox.z = this._particle._modelBoundingInfo.maximum.z * this._particle.scaling.z;
+                    bSphere.center.x = this._particle.position.x + (this._minBbox.x + this._maxBbox.x) * 0.5;
+                    bSphere.center.y = this._particle.position.y + (this._minBbox.y + this._maxBbox.y) * 0.5;
+                    bSphere.center.z = this._particle.position.z + (this._minBbox.z + this._maxBbox.z) * 0.5;
+                    bSphere.radius = 0.5 * Math.sqrt((this._maxBbox.x - this._minBbox.x) * (this._maxBbox.x - this._minBbox.x) + (this._maxBbox.y - this._minBbox.y) * (this._maxBbox.y - this._minBbox.y) + (this._maxBbox.z - this._minBbox.z) * (this._maxBbox.z - this._minBbox.z));
                     bSphere._update(this.mesh._worldMatrix);
                 }