Explorar el Código

Merge pull request #6893 from BabylonJSGuide/master

Point Cloud Particle System
David Catuhe hace 5 años
padre
commit
0b0bc17631

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

@@ -6,6 +6,7 @@
 - WIP: WebGPU support (NEED DOC OR SAMPLES) ([Sebavan](https://github.com/sebavan/))
 - .basis texture file format support [Doc](https://doc.babylonjs.com/resources/multi-platform_compressed_textures#basis-file-format) ([TrevorDev](https://github.com/TrevorDev))
 - WIP: Recast navigation mesh and crowd of moving agents [Demo](https://www.babylonjs-playground.com/#AJTRIL) ([CedricGuillemet](https://github.com/CedricGuillemet))
+- Added Point Cloud Particle System ([JohnK](https://github.com/BabylonJSGuide/))
 - Classes decoupling ending up with smaller bundle sizes [Blog](https://medium.com/@babylonjs/size-matters-e0e94dad01a7) ([Deltakosh](https://github.com/deltakosh/))
 - Babylon.js controls [Doc](https://doc.babylonjs.com/features/controls) ([Sebavan](https://github.com/sebavan/) / [Deltakosh](https://github.com/deltakosh/))
 - WebXR updates:

+ 244 - 0
src/Particles/cloudPoint.ts

@@ -0,0 +1,244 @@
+import { Nullable } from "../types";
+import { Color4, Vector2, Vector3, TmpVectors, Matrix, Quaternion } from "../Maths/math";
+import { Mesh } from "../Meshes/mesh";
+import { BoundingInfo } from "../Culling/boundingInfo";
+import { PointsCloudSystem } from "./pointsCloudSystem";
+/**
+ * Represents one particle of a points cloud system.
+ */
+export class CloudPoint {
+    /**
+     * particle global index
+     */
+    public idx: number = 0;
+    /**
+     * The color of the particle
+     */
+    public color: Nullable<Color4> = new Color4(1.0, 1.0, 1.0, 1.0);
+    /**
+     * The world space position of the particle.
+     */
+    public position: Vector3 = Vector3.Zero();
+    /**
+     * The world space rotation of the particle. (Not use if rotationQuaternion is set)
+     */
+    public rotation: Vector3 = Vector3.Zero();
+    /**
+     * The world space rotation quaternion of the particle.
+     */
+    public rotationQuaternion: Nullable<Quaternion>;
+    /**
+     * The uv of the particle.
+     */
+    public uv: Nullable<Vector2> = new Vector2(0.0, 0.0);
+    /**
+     * The current speed of the particle.
+     */
+    public velocity: Vector3 = Vector3.Zero();
+    /**
+     * The pivot point in the particle local space.
+     */
+    public pivot: Vector3 = Vector3.Zero();
+    /**
+     * Must the particle be translated from its pivot point in its local space ?
+     * In this case, the pivot point is set at the origin of the particle local space and the particle is translated.
+     * Default : false
+     */
+    public translateFromPivot: boolean = false;
+    /**
+     * Index of this particle in the global "positions" array (Internal use)
+     * @hidden
+     */
+    public _pos: number = 0;
+    /**
+     * @hidden Index of this particle in the global "indices" array (Internal use)
+     */
+    public _ind: number = 0;
+    /**
+     * Group this particle belongs to
+     */
+    public _group: PointsGroup;
+    /**
+     * Group id of this particle
+     */
+    public groupId: number = 0;
+    /**
+     * Index of the particle in its group id (Internal use)
+     */
+    public idxInGroup: number = 0;
+    /**
+     * @hidden Particle BoundingInfo object (Internal use)
+     */
+    public _boundingInfo: BoundingInfo;
+    /**
+     * @hidden Reference to the PCS that the particle belongs to (Internal use)
+     */
+    public _pcs: PointsCloudSystem;
+    /**
+     * @hidden Still set as invisible in order to skip useless computations (Internal use)
+     */
+    public _stillInvisible: boolean = false;
+    /**
+     * @hidden Last computed particle rotation matrix
+     */
+    public _rotationMatrix: number[] = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0];
+    /**
+     * Parent particle Id, if any.
+     * Default null.
+     */
+    public parentId: Nullable<number> = null;
+    /**
+     * @hidden Internal global position in the PCS.
+     */
+    public _globalPosition: Vector3 = Vector3.Zero();
+
+    /**
+     * Creates a Point Cloud object.
+     * Don't create particles manually, use instead the PCS internal tools like _addParticle()
+     * @param particleIndex (integer) is the particle index in the PCS pool. It's also the particle identifier.
+     * @param group (PointsGroup) is the group the particle belongs to
+     * @param groupId (integer) is the group identifier in the PCS.
+     * @param idxInGroup (integer) is the index of the particle in the current point group (ex: the 10th point of addPoints(30))
+     * @param pcs defines the PCS it is associated to
+     */
+    constructor(particleIndex: number, group: PointsGroup, groupId: number, idxInGroup: number, pcs: PointsCloudSystem) {
+        this.idx = particleIndex;
+        this._group = group;
+        this.groupId = groupId;
+        this.idxInGroup = idxInGroup;
+        this._pcs = pcs;
+    }
+
+    /**
+     * get point size
+     */
+    public get size(): Vector3 {
+        return this.size;
+    }
+
+    /**
+     * Set point size
+     */
+    public set size(scale: Vector3) {
+        this.size = scale;
+    }
+
+    /**
+     * Legacy support, changed quaternion to rotationQuaternion
+     */
+    public get quaternion(): Nullable<Quaternion> {
+        return this.rotationQuaternion;
+    }
+
+    /**
+     * Legacy support, changed quaternion to rotationQuaternion
+     */
+    public set quaternion(q: Nullable<Quaternion>) {
+        this.rotationQuaternion = q;
+    }
+
+    /**
+     * Returns a boolean. True if the particle intersects another particle or another mesh, else false.
+     * The intersection is computed on the particle bounding sphere and Axis Aligned Bounding Box (AABB)
+     * @param target is the object (point or mesh) what the intersection is computed against.
+     * @returns true if it intersects
+     */
+    public intersectsMesh(target: Mesh | CloudPoint): boolean {
+        if (!(target instanceof CloudPoint) || !target._boundingInfo) {
+            return false;
+        }
+        const radius = this._pcs._size;
+        let maxX: number = 0;
+        let minX: number = 0;
+        let maxY: number = 0;
+        let minY: number = 0;
+        let maxZ: number = 0;
+        let minZ: number = 0;
+        if (target instanceof CloudPoint) {
+            maxX = target.position.x + radius;
+            minX = target.position.x - radius;
+            maxY = target.position.y + radius;
+            minY = target.position.y - radius;
+            maxZ = target.position.z + radius;
+            minZ = target.position.z - radius;
+        }
+
+        if (target._boundingInfo) {
+            maxX = target._boundingInfo.maximum.x;
+            minX = target._boundingInfo.minimum.x;
+            maxY = target._boundingInfo.maximum.y;
+            minY = target._boundingInfo.minimum.y;
+            maxZ = target._boundingInfo.maximum.z;
+            minZ = target._boundingInfo.minimum.z;
+        }
+        const x = this.position.x;
+        const y = this.position.y;
+        const z = this.position.z;
+        return (minX <= x + radius || maxX >= x - radius) && (minY <= y + radius || maxY >= y - radius) && (minZ <= z + radius || maxZ >= z - radius);
+    }
+
+    /**
+     * get the rotation matrix of the particle
+     * @hidden
+     */
+    public getRotationMatrix(m: Matrix) {
+        let quaternion: Quaternion;
+        if (this.rotationQuaternion) {
+            quaternion = this.rotationQuaternion;
+        }
+        else {
+            quaternion = TmpVectors.Quaternion[0];
+            const rotation = this.rotation;
+            Quaternion.RotationYawPitchRollToRef(rotation.y, rotation.x, rotation.z, quaternion);
+        }
+
+        quaternion.toRotationMatrix(m);
+    }
+}
+
+/**
+ * Represents a group of points in a points cloud system
+ *  * PCS internal tool, don't use it manually.
+ */
+export class PointsGroup {
+    /**
+     * The group id
+     * @hidden
+     */
+    public groupID: number;
+    /**
+     * image data for group (internal use)
+     * @hidden
+     */
+    public _groupImageData: Nullable<ArrayBufferView>;
+    /**
+     * Image Width (internal use)
+     * @hidden
+     */
+    public _groupImgWidth: number;
+    /**
+     * Image Height (internal use)
+     * @hidden
+     */
+    public _groupImgHeight: number;
+    /**
+     * Custom position function (internal use)
+     * @hidden
+     */
+    public _positionFunction: Nullable<(particle: CloudPoint, i?: number, s?: number) => void>;
+    /**
+     * density per facet for surface points
+     * @hidden
+     */
+    public _groupDensity: number[];
+
+    /**
+     * Creates a points group object. This is an internal reference to produce particles for the PCS.
+     * PCS internal tool, don't use it manually.
+     * @hidden
+     */
+    constructor(id: number, posFunction: Nullable<(particle: CloudPoint, i?: number, s?: number) => void>) {
+        this.groupID = id;
+        this._positionFunction = posFunction;
+    }
+}

+ 2 - 0
src/Particles/index.ts

@@ -9,4 +9,6 @@ export * from "./particleSystemComponent";
 export * from "./particleSystemSet";
 export * from "./solidParticle";
 export * from "./solidParticleSystem";
+export * from "./cloudPoint";
+export * from "./pointsCloudSystem";
 export * from "./subEmitter";

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1049 - 0
src/Particles/pointsCloudSystem.ts