|
@@ -9,6 +9,7 @@ module BABYLON {
|
|
|
public name: string;
|
|
|
public mesh: Mesh;
|
|
|
public vars: any = {};
|
|
|
+ public pickedParticles: {idx: number; faceId: number}[];
|
|
|
|
|
|
// private members
|
|
|
private _scene: Scene;
|
|
@@ -18,11 +19,13 @@ module BABYLON {
|
|
|
private _colors: number[] = new Array<number>();
|
|
|
private _uvs: number[] = new Array<number>();
|
|
|
private _positions32: Float32Array;
|
|
|
- private _normals32: Float32Array;
|
|
|
+ private _normals32: Float32Array; // updated normals for the VBO
|
|
|
+ private _fixedNormal32: Float32Array; // initial normal references
|
|
|
private _colors32: Float32Array;
|
|
|
private _uvs32: Float32Array;
|
|
|
private _index: number = 0; // indices index
|
|
|
private _updatable: boolean = true;
|
|
|
+ private _pickable: boolean = false;
|
|
|
private _shapeCounter: number = 0;
|
|
|
private _copy: SolidParticle = new SolidParticle(null, null, null, null, null);
|
|
|
private _shape: Vector3[];
|
|
@@ -46,6 +49,7 @@ module BABYLON {
|
|
|
private _rotated: Vector3 = Vector3.Zero();
|
|
|
private _quaternion: Quaternion = new Quaternion();
|
|
|
private _vertex: Vector3 = Vector3.Zero();
|
|
|
+ private _normal: Vector3 = Vector3.Zero();
|
|
|
private _yaw: number = 0.0;
|
|
|
private _pitch: number = 0.0;
|
|
|
private _roll: number = 0.0;
|
|
@@ -61,15 +65,19 @@ module BABYLON {
|
|
|
private _w: number = 0.0;
|
|
|
|
|
|
|
|
|
- constructor(name: string, scene: Scene, options?: { updatable?: boolean }) {
|
|
|
+ constructor(name: string, scene: Scene, options?: { updatable?: boolean, pickable? :boolean }) {
|
|
|
this.name = name;
|
|
|
this._scene = scene;
|
|
|
this._camera = scene.activeCamera;
|
|
|
+ this._pickable = options ? options.pickable : false;
|
|
|
if (options && options.updatable) {
|
|
|
this._updatable = options.updatable;
|
|
|
} else {
|
|
|
this._updatable = true;
|
|
|
}
|
|
|
+ if (this._pickable) {
|
|
|
+ this.pickedParticles = [];
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// build the SPS mesh : returns the mesh
|
|
@@ -84,6 +92,7 @@ module BABYLON {
|
|
|
this._colors32 = new Float32Array(this._colors);
|
|
|
VertexData.ComputeNormals(this._positions32, this._indices, this._normals);
|
|
|
this._normals32 = new Float32Array(this._normals);
|
|
|
+ this._fixedNormal32 = new Float32Array(this._normals);
|
|
|
var vertexData = new VertexData();
|
|
|
vertexData.set(this._positions32, VertexBuffer.PositionKind);
|
|
|
vertexData.indices = this._indices;
|
|
@@ -106,6 +115,7 @@ module BABYLON {
|
|
|
|
|
|
if (!this._updatable) {
|
|
|
this.particles.length = 0;
|
|
|
+ this.mesh.isPickable = true;
|
|
|
}
|
|
|
|
|
|
return mesh;
|
|
@@ -191,9 +201,17 @@ module BABYLON {
|
|
|
c += 4;
|
|
|
|
|
|
}
|
|
|
+
|
|
|
for (i = 0; i < meshInd.length; i++) {
|
|
|
indices.push(p + meshInd[i]);
|
|
|
}
|
|
|
+
|
|
|
+ if (this._pickable) {
|
|
|
+ var nbfaces = meshInd.length / 3;
|
|
|
+ for (i = 0; i < nbfaces; i++) {
|
|
|
+ this.pickedParticles.push({idx: idx, faceId: i});
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// returns a shape array from positions array
|
|
@@ -216,12 +234,12 @@ module BABYLON {
|
|
|
}
|
|
|
|
|
|
// adds a new particle object in the particles array
|
|
|
- private _addParticle(p: number, idxpos: number, model: ModelShape, shapeId: number, idxInShape: number): void {
|
|
|
- this.particles.push(new SolidParticle(p, idxpos, model, shapeId, idxInShape));
|
|
|
+ private _addParticle(idx: number, idxpos: number, model: ModelShape, shapeId: number, idxInShape: number): void {
|
|
|
+ this.particles.push(new SolidParticle(idx, idxpos, model, shapeId, idxInShape));
|
|
|
}
|
|
|
|
|
|
// add solid particles from a shape model in the particles array
|
|
|
- public addShape(mesh: Mesh, nb: number, options?: { positionFunction?: any, vertexFunction?: any }): number {
|
|
|
+ public addShape(mesh: Mesh, nb: number, options?: { positionFunction?: any; vertexFunction?: any }): number {
|
|
|
var meshPos = mesh.getVerticesData(VertexBuffer.PositionKind);
|
|
|
var meshInd = mesh.getIndices();
|
|
|
var meshUV = mesh.getVerticesData(VertexBuffer.UVKind);
|
|
@@ -236,12 +254,14 @@ module BABYLON {
|
|
|
var modelShape = new ModelShape(this._shapeCounter, shape, shapeUV, posfunc, vtxfunc);
|
|
|
|
|
|
// particles
|
|
|
+ var idx = this.nbParticles;
|
|
|
for (var i = 0; i < nb; i++) {
|
|
|
- this._meshBuilder(this._index, shape, this._positions, meshInd, this._indices, meshUV, this._uvs, meshCol, this._colors, this.nbParticles + i, i, options);
|
|
|
+ this._meshBuilder(this._index, shape, this._positions, meshInd, this._indices, meshUV, this._uvs, meshCol, this._colors, idx, i, options);
|
|
|
if (this._updatable) {
|
|
|
- this._addParticle(this.nbParticles + i, this._positions.length, modelShape, this._shapeCounter, i);
|
|
|
+ this._addParticle(idx, this._positions.length, modelShape, this._shapeCounter, i);
|
|
|
}
|
|
|
this._index += shape.length;
|
|
|
+ idx++;
|
|
|
}
|
|
|
this.nbParticles += nb;
|
|
|
this._shapeCounter++;
|
|
@@ -311,6 +331,10 @@ module BABYLON {
|
|
|
|
|
|
// sets all the particles : updates the VBO
|
|
|
public setParticles(start: number = 0, end: number = this.nbParticles - 1, update: boolean = true): void {
|
|
|
+ if (!this._updatable) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
// custom beforeUpdate
|
|
|
this.beforeUpdateParticles(start, end, update);
|
|
|
|
|
@@ -396,11 +420,12 @@ module BABYLON {
|
|
|
if (this._computeParticleVertex) {
|
|
|
this.updateParticleVertex(this._particle, this._vertex, pt);
|
|
|
}
|
|
|
+
|
|
|
+ // positions
|
|
|
this._vertex.x *= this._particle.scale.x;
|
|
|
this._vertex.y *= this._particle.scale.y;
|
|
|
this._vertex.z *= this._particle.scale.z;
|
|
|
|
|
|
- //Vector3.TransformCoordinatesToRef(this._vertex, this._rotMatrix, this._rotated);
|
|
|
this._w = (this._vertex.x * this._rotMatrix.m[3]) + (this._vertex.y * this._rotMatrix.m[7]) + (this._vertex.z * this._rotMatrix.m[11]) + this._rotMatrix.m[15];
|
|
|
this._rotated.x = ( (this._vertex.x * this._rotMatrix.m[0]) + (this._vertex.y * this._rotMatrix.m[4]) + (this._vertex.z * this._rotMatrix.m[8]) + this._rotMatrix.m[12] ) / this._w;
|
|
|
this._rotated.y = ( (this._vertex.x * this._rotMatrix.m[1]) + (this._vertex.y * this._rotMatrix.m[5]) + (this._vertex.z * this._rotMatrix.m[9]) + this._rotMatrix.m[13] ) / this._w;
|
|
@@ -410,6 +435,22 @@ module BABYLON {
|
|
|
this._positions32[idx + 1] = 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;
|
|
|
this._positions32[idx + 2] = 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;
|
|
|
|
|
|
+ // normals : if the particles can't be morphed then just rotate the normals
|
|
|
+ if (!this._computeParticleVertex) {
|
|
|
+ this._normal.x = this._fixedNormal32[idx];
|
|
|
+ this._normal.y = this._fixedNormal32[idx + 1];
|
|
|
+ this._normal.z = this._fixedNormal32[idx + 2];
|
|
|
+
|
|
|
+ this._w = (this._normal.x * this._rotMatrix.m[3]) + (this._normal.y * this._rotMatrix.m[7]) + (this._normal.z * this._rotMatrix.m[11]) + this._rotMatrix.m[15];
|
|
|
+ this._rotated.x = ( (this._normal.x * this._rotMatrix.m[0]) + (this._normal.y * this._rotMatrix.m[4]) + (this._normal.z * this._rotMatrix.m[8]) + this._rotMatrix.m[12] ) / this._w;
|
|
|
+ this._rotated.y = ( (this._normal.x * this._rotMatrix.m[1]) + (this._normal.y * this._rotMatrix.m[5]) + (this._normal.z * this._rotMatrix.m[9]) + this._rotMatrix.m[13] ) / this._w;
|
|
|
+ this._rotated.z = ( (this._normal.x * this._rotMatrix.m[2]) + (this._normal.y * this._rotMatrix.m[6]) + (this._normal.z * this._rotMatrix.m[10]) + this._rotMatrix.m[14] ) / this._w;
|
|
|
+
|
|
|
+ this._normals32[idx] = this._cam_axisX.x * this._rotated.x + this._cam_axisY.x * this._rotated.y + this._cam_axisZ.x * this._rotated.z;
|
|
|
+ this._normals32[idx + 1] = this._cam_axisX.y * this._rotated.x + this._cam_axisY.y * this._rotated.y + this._cam_axisZ.y * this._rotated.z;
|
|
|
+ this._normals32[idx + 2] = this._cam_axisX.z * this._rotated.x + this._cam_axisY.z * this._rotated.y + this._cam_axisZ.z * this._rotated.z;
|
|
|
+ }
|
|
|
+
|
|
|
if (this._computeParticleColor) {
|
|
|
this._colors32[colidx] = this._particle.color.r;
|
|
|
this._colors32[colidx + 1] = this._particle.color.g;
|
|
@@ -436,7 +477,13 @@ module BABYLON {
|
|
|
}
|
|
|
this.mesh.updateVerticesData(VertexBuffer.PositionKind, this._positions32, false, false);
|
|
|
if (!this.mesh.areNormalsFrozen) {
|
|
|
- VertexData.ComputeNormals(this._positions32, this._indices, this._normals32);
|
|
|
+ if (this._computeParticleVertex) {
|
|
|
+ // recompute the normals only if the particles can be morphed, update then the normal reference array
|
|
|
+ VertexData.ComputeNormals(this._positions32, this._indices, this._normals32);
|
|
|
+ for (var i = 0; i < this._normals32.length; i++) {
|
|
|
+ this._fixedNormal32[i] = this._normals32[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
this.mesh.updateVerticesData(VertexBuffer.NormalKind, this._normals32, false, false);
|
|
|
}
|
|
|
}
|
|
@@ -490,8 +537,10 @@ module BABYLON {
|
|
|
this._colors = null;
|
|
|
this._positions32 = null;
|
|
|
this._normals32 = null;
|
|
|
+ this._fixedNormal32 = null;
|
|
|
this._uvs32 = null;
|
|
|
this._colors32 = null;
|
|
|
+ this.pickedParticles = null;
|
|
|
}
|
|
|
|
|
|
// Optimizer setters
|