123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- var WORLDMONGER = WORLDMONGER || {};
- (function () {
- WORLDMONGER.ElevationControl = function (ground) {
- this._ground = ground;
- this.radius = 5.0;
- this._invertDirection = 1.0;
- this.heightMin = 0;
- this.heightMax = 11.0;
-
- // Particle system
- var scene = ground.getScene();
- var particleSystem = new BABYLON.ParticleSystem("particles", 4000, scene);
- particleSystem.particleTexture = new BABYLON.Texture("Assets/Flare.png", scene);
- particleSystem.minAngularSpeed = -4.5;
- particleSystem.maxAngularSpeed = 4.5;
- particleSystem.minSize = 0.5;
- particleSystem.maxSize = 4.0;
- particleSystem.minLifeTime = 0.5;
- particleSystem.maxLifeTime = 2.0;
- particleSystem.minEmitPower = 0.5;
- particleSystem.maxEmitPower = 1.0;
- particleSystem.emitRate = 400;
- particleSystem.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE;
- particleSystem.minEmitBox = new BABYLON.Vector3(0, 0, 0);
- particleSystem.maxEmitBox = new BABYLON.Vector3(0, 0, 0);
- particleSystem.direction1 = new BABYLON.Vector3(0, 1, 0);
- particleSystem.direction2 = new BABYLON.Vector3(0, 1, 0);
- particleSystem.color1 = new BABYLON.Color4(0, 0, 1, 1);
- particleSystem.color2 = new BABYLON.Color4(1, 1, 1, 1);
- particleSystem.gravity = new BABYLON.Vector3(0, 5, 0);
- particleSystem.manualEmitCount = 0;
- particleSystem.emitter = new BABYLON.Vector3(0, 0, 0);
- particleSystem.start();
- this._particleSystem = particleSystem;
- };
- WORLDMONGER.ElevationControl.prototype.direction = 1;
- WORLDMONGER.ElevationControl.prototype.attachControl = function (canvas) {
- var currentPosition;
- var that = this;
- this._onBeforeRender = function () {
- if (!currentPosition) {
- return;
- }
- var pickInfo = that._ground.getScene().pick(currentPosition.x, currentPosition.y);
- if (!pickInfo.hit)
- return;
- if (pickInfo.pickedMesh != that._ground)
- return;
- that._particleSystem.emitter = pickInfo.pickedPoint.add(new BABYLON.Vector3(0, 3, 0));
- that._particleSystem.manualEmitCount += 400;
- that._elevateFaces(pickInfo, that.radius, 0.2);
- };
- this._onPointerDown = function (evt) {
- evt.preventDefault();
- currentPosition = {
- x: evt.clientX,
- y: evt.clientY
- };
- };
- this._onPointerUp = function (evt) {
- evt.preventDefault();
- currentPosition = null;
- };
- this._onPointerMove = function (evt) {
- evt.preventDefault();
- if (!currentPosition) {
- return;
- }
- that._invertDirection = evt.button == 2 ? -1 : 1;
- currentPosition = {
- x: evt.clientX,
- y: evt.clientY
- };
- };
- this._onLostFocus = function () {
- currentPosition = null;
- };
- canvas.addEventListener("pointerdown", this._onPointerDown, true);
- canvas.addEventListener("pointerup", this._onPointerUp, true);
- canvas.addEventListener("pointerout", this._onPointerUp, true);
- canvas.addEventListener("pointermove", this._onPointerMove, true);
- window.addEventListener("blur", this._onLostFocus, true);
- this._ground.getScene().registerBeforeRender(this._onBeforeRender);
- };
- WORLDMONGER.ElevationControl.prototype.detachControl = function (canvas) {
- canvas.removeEventListener("pointerdown", this._onPointerDown);
- canvas.removeEventListener("pointerup", this._onPointerUp);
- canvas.removeEventListener("pointerout", this._onPointerUp);
- canvas.removeEventListener("pointermove", this._onPointerMove);
- window.removeEventListener("blur", this._onLostFocus);
- this._ground.getScene().unregisterBeforeRender(this._onBeforeRender);
- };
- WORLDMONGER.ElevationControl.prototype._prepareDataModelForElevation = function () {
- if (this._facesOfVertices == null) {
- this._facesOfVertices = [];
- this._groundVertices = this._ground.getVertices();
- this._groundIndices = this._ground.getIndices();
- this._groundPositions = [];
- var index;
- for (index = 0; index < this._groundVertices.length; index += this._ground.getFloatVertexStrideSize()) {
- this._groundPositions.push(new BABYLON.Vector3(this._groundVertices[index], this._groundVertices[index + 1], this._groundVertices[index + 2]));
- }
- this._groundFacesNormals = [];
- for (index = 0; index < this._ground.getTotalIndices() / 3; index++) {
- this._computeFaceNormal(index);
- }
- this._getFacesOfVertices();
- }
- };
- WORLDMONGER.ElevationControl.prototype._getFaceVerticesIndex = function (faceID) {
- return {
- v1: this._groundIndices[faceID * 3],
- v2: this._groundIndices[faceID * 3 + 1],
- v3: this._groundIndices[faceID * 3 + 2]
- };
- };
- WORLDMONGER.ElevationControl.prototype._computeFaceNormal = function (face) {
- var faceInfo = this._getFaceVerticesIndex(face);
- var v1v2 = this._groundPositions[faceInfo.v1].subtract(this._groundPositions[faceInfo.v2]);
- var v3v2 = this._groundPositions[faceInfo.v3].subtract(this._groundPositions[faceInfo.v2]);
- this._groundFacesNormals[face] = BABYLON.Vector3.Normalize(BABYLON.Vector3.Cross(v1v2, v3v2));
- };
- WORLDMONGER.ElevationControl.prototype._getFacesOfVertices = function () {
- this._facesOfVertices = [];
- this._subdivisionsOfVertices = [];
- var index;
- for (index = 0; index < this._groundPositions.length; index++) {
- this._facesOfVertices[index] = [];
- this._subdivisionsOfVertices[index] = [];
- }
- for (index = 0; index < this._groundIndices.length; index++) {
- this._facesOfVertices[this._groundIndices[index]].push((index / 3) | 0);
- }
- for (var subIndex = 0; subIndex < this._ground.subMeshes.length; subIndex++) {
- var subMesh = this._ground.subMeshes[subIndex];
- for (index = subMesh.verticesStart; index < subMesh.verticesStart + subMesh.verticesCount; index++) {
- this._subdivisionsOfVertices[index].push(subMesh);
- }
- }
- };
- WORLDMONGER.ElevationControl.prototype._isBoxSphereIntersected = function(box, sphereCenter, sphereRadius) {
- var vector = BABYLON.Vector3.Clamp(sphereCenter, box.minimumWorld, box.maximumWorld);
- var num = BABYLON.Vector3.DistanceSquared(sphereCenter, vector);
- return (num <= (sphereRadius * sphereRadius));
- };
- WORLDMONGER.ElevationControl.prototype._elevateFaces = function (pickInfo, radius, height) {
- this._prepareDataModelForElevation();
- this._selectedVertices = [];
- // Impact zone
- var sphereCenter = pickInfo.pickedPoint;
- sphereCenter.y = 0;
- var index;
- // Determine list of vertices
- for (var subIndex = 0; subIndex < this._ground.subMeshes.length; subIndex++) {
- var subMesh = this._ground.subMeshes[subIndex];
- if (!this._isBoxSphereIntersected(subMesh.getBoundingInfo().boundingBox, sphereCenter, radius)) {
- continue;
- }
- for (index = subMesh.verticesStart; index < subMesh.verticesStart + subMesh.verticesCount; index++) {
- var position = this._groundPositions[index];
- sphereCenter.y = position.y;
- var distance = BABYLON.Vector3.Distance(position, sphereCenter);
- if (distance < radius) {
- this._selectedVertices[index] = distance;
- }
- }
- }
- // Elevate vertices
- var stride = this._ground.getFloatVertexStrideSize();
- for (var selectedVertice in this._selectedVertices) {
- var position = this._groundPositions[selectedVertice];
- var distance = this._selectedVertices[selectedVertice];
- var fullHeight = height * this.direction * this._invertDirection;
- if (distance < radius * 0.3) {
- position.y += fullHeight;
- } else {
- position.y += fullHeight * (1.0 - (distance - radius * 0.3) / (radius * 0.7));
- }
- if (position.y > this.heightMax)
- position.y = this.heightMax;
- else if (position.y < this.heightMin)
- position.y = this.heightMin;
- this._groundVertices[selectedVertice * stride + 1] = position.y;
- this._updateSubdivisions(selectedVertice);
- }
- // Normals
- this._reComputeNormals()
- // Update vertex buffer
- this._ground.updateVertices(this._groundVertices);
- };
- WORLDMONGER.ElevationControl.prototype._reComputeNormals = function () {
- var faces = [];
- var face;
- for (selectedVertice in this._selectedVertices) {
- var faceOfVertices = this._facesOfVertices[selectedVertice];
- for (var index = 0; index < faceOfVertices.length; index++) {
- faces[faceOfVertices[index]] = true;
- }
- }
- for (face in faces) {
- this._computeFaceNormal(face);
- }
- for (face in faces) {
- var faceInfo = this._getFaceVerticesIndex(face);
- this._computeNormal(faceInfo.v1);
- this._computeNormal(faceInfo.v2);
- this._computeNormal(faceInfo.v3);
- }
- };
- WORLDMONGER.ElevationControl.prototype._computeNormal = function (vertexIndex) {
- var faces = this._facesOfVertices[vertexIndex];
- var normal = BABYLON.Vector3.Zero();
- for (var index = 0; index < faces.length; index++) {
- normal = normal.add(this._groundFacesNormals[faces[index]]);
- }
- normal = BABYLON.Vector3.Normalize(normal.scale(1.0 / faces.length));
- var stride = this._ground.getFloatVertexStrideSize();
- this._groundVertices[vertexIndex * stride + 3] = normal.x;
- this._groundVertices[vertexIndex * stride + 4] = normal.y;
- this._groundVertices[vertexIndex * stride + 5] = normal.z;
- }
- WORLDMONGER.ElevationControl.prototype._updateSubdivisions = function (vertexIndex) {
- for (var index = 0; index < this._subdivisionsOfVertices[vertexIndex].length; index++) {
- var sub = this._subdivisionsOfVertices[vertexIndex][index];
- var boundingBox = sub.getBoundingInfo().boundingBox;
- var boundingSphere = sub.getBoundingInfo().boundingSphere;
- if (this._groundPositions[vertexIndex].y < boundingBox.minimum.y) {
- boundingSphere.radius += Math.abs(this._groundPositions[vertexIndex].y - boundingBox.minimum.y);
- boundingBox.minimum.y = this._groundPositions[vertexIndex].y;
- } else if (this._groundPositions[vertexIndex].y > boundingBox.maximum.y) {
- boundingBox.maximum.y = this._groundPositions[vertexIndex].y;
- }
- }
- var boundingBox = this._ground.getBoundingInfo().boundingBox;
- var boundingSphere = this._ground.getBoundingInfo().boundingSphere;
- if (this._groundPositions[vertexIndex].y < boundingBox.minimum.y) {
- boundingSphere.Radius += Math.abs(this._groundPositions[vertexIndex].y - boundingBox.minimum.y);
- boundingBox.minimum.y = this._groundPositions[vertexIndex].y;
- } else if (this._groundPositions[vertexIndex].y > boundingBox.maximum.y) {
- boundingBox.maximum.y = this._groundPositions[vertexIndex].y;
- }
- };
- })();
|