Bläddra i källkod

Worker-Collision optimizations

To make it run smoother (with IE in mind).
This reduces the number of Vector3.Dot calls and the creation of planes.
For in loop was also optimized (as it is constantly called).
Raanan Weber 10 år sedan
förälder
incheckning
562b3796f7

+ 27 - 27
Babylon/Collisions/babylon.collisionWorker.js

@@ -47,8 +47,12 @@ var BABYLON;
             this.collider._initialize(position, velocity, closeDistance);
             this.collider._initialize(position, velocity, closeDistance);
             // Check all meshes
             // Check all meshes
             var meshes = this._collisionCache.getMeshes();
             var meshes = this._collisionCache.getMeshes();
-            for (var uniqueId in meshes) {
-                if (meshes.hasOwnProperty(uniqueId) && parseInt(uniqueId) != excludedMeshUniqueId) {
+            var keys = Object.keys(meshes);
+            var len = keys.length;
+            var uniqueId;
+            for (var i = 0; i < len; ++i) {
+                uniqueId = keys[i];
+                if (parseInt(uniqueId) != excludedMeshUniqueId) {
                     var mesh = meshes[uniqueId];
                     var mesh = meshes[uniqueId];
                     if (mesh.checkCollisions)
                     if (mesh.checkCollisions)
                         this.checkCollision(mesh);
                         this.checkCollision(mesh);
@@ -107,33 +111,29 @@ var BABYLON;
                 // Bounding test
                 // Bounding test
                 if (len > 1 && !this.checkSubmeshCollision(subMesh))
                 if (len > 1 && !this.checkSubmeshCollision(subMesh))
                     continue;
                     continue;
-                //Unneeded
-                //subMesh['getMesh'] = function () {
-                //    return mesh.uniqueId;
-                //}
                 this.collideForSubMesh(subMesh, transformMatrix, meshGeometry);
                 this.collideForSubMesh(subMesh, transformMatrix, meshGeometry);
             }
             }
         };
         };
         CollideWorker.prototype.collideForSubMesh = function (subMesh, transformMatrix, meshGeometry) {
         CollideWorker.prototype.collideForSubMesh = function (subMesh, transformMatrix, meshGeometry) {
             var positionsArray = [];
             var positionsArray = [];
-            for (var i = 0; i < meshGeometry.positions.length; i = i + 3) {
+            for (var i = 0, len = meshGeometry.positions.length; i < len; i = i + 3) {
                 var p = BABYLON.Vector3.FromArray([meshGeometry.positions[i], meshGeometry.positions[i + 1], meshGeometry.positions[i + 2]]);
                 var p = BABYLON.Vector3.FromArray([meshGeometry.positions[i], meshGeometry.positions[i + 1], meshGeometry.positions[i + 2]]);
                 positionsArray.push(p);
                 positionsArray.push(p);
             }
             }
-            subMesh['_lastColliderTransformMatrix'] = transformMatrix.clone();
-            //The following two arrays should be initialized CORRECTLY to save some calculation time.
-            subMesh['_lastColliderWorldVertices'] = [];
-            subMesh['_trianglePlanes'] = [];
-            var start = subMesh.verticesStart;
-            var end = (subMesh.verticesStart + subMesh.verticesCount);
-            for (var i = start; i < end; i++) {
-                subMesh['_lastColliderWorldVertices'].push(BABYLON.Vector3.TransformCoordinates(positionsArray[i], transformMatrix));
+            if (!subMesh['_lastColliderWorldVertices'] || !subMesh['_lastColliderTransformMatrix'].equals(transformMatrix)) {
+                subMesh['_lastColliderTransformMatrix'] = transformMatrix.clone();
+                //The following two arrays should be initialized CORRECTLY to save some calculation time.
+                subMesh['_lastColliderWorldVertices'] = [];
+                subMesh['_trianglePlanes'] = [];
+                var start = subMesh.verticesStart;
+                var end = (subMesh.verticesStart + subMesh.verticesCount);
+                for (var i = start; i < end; i++) {
+                    subMesh['_lastColliderWorldVertices'].push(BABYLON.Vector3.TransformCoordinates(positionsArray[i], transformMatrix));
+                }
             }
             }
-            //}
             // Collide
             // Collide
-            this.collider._collide(subMesh['_trianglePlanes'] = [], subMesh['_lastColliderWorldVertices'], meshGeometry.indices, subMesh.indexStart, subMesh.indexStart + subMesh.indexCount, subMesh.verticesStart, subMesh.hasMaterial);
+            this.collider._collide(subMesh['_trianglePlanes'], subMesh['_lastColliderWorldVertices'], meshGeometry.indices, subMesh.indexStart, subMesh.indexStart + subMesh.indexCount, subMesh.verticesStart, subMesh.hasMaterial);
         };
         };
-        //TODO - this! :-)
         CollideWorker.prototype.checkSubmeshCollision = function (subMesh) {
         CollideWorker.prototype.checkSubmeshCollision = function (subMesh) {
             return this.collider._canDoCollision(BABYLON.Vector3.FromArray(subMesh.sphereCenter), subMesh.sphereRadius, BABYLON.Vector3.FromArray(subMesh.boxMinimum), BABYLON.Vector3.FromArray(subMesh.boxMaximum));
             return this.collider._canDoCollision(BABYLON.Vector3.FromArray(subMesh.sphereCenter), subMesh.sphereRadius, BABYLON.Vector3.FromArray(subMesh.boxMinimum), BABYLON.Vector3.FromArray(subMesh.boxMaximum));
         };
         };
@@ -146,8 +146,8 @@ var BABYLON;
         CollisionDetectorTransferable.prototype.onInit = function (payload) {
         CollisionDetectorTransferable.prototype.onInit = function (payload) {
             this._collisionCache = new CollisionCache();
             this._collisionCache = new CollisionCache();
             var reply = {
             var reply = {
-                error: 0 /* SUCCESS */,
-                taskType: 0 /* INIT */
+                error: BABYLON.WorkerReplyType.SUCCESS,
+                taskType: BABYLON.WorkerTaskType.INIT
             };
             };
             postMessage(reply, undefined);
             postMessage(reply, undefined);
         };
         };
@@ -163,8 +163,8 @@ var BABYLON;
                 }
                 }
             }
             }
             var replay = {
             var replay = {
-                error: 0 /* SUCCESS */,
-                taskType: 1 /* UPDATE */
+                error: BABYLON.WorkerReplyType.SUCCESS,
+                taskType: BABYLON.WorkerTaskType.UPDATE
             };
             };
             postMessage(replay, undefined);
             postMessage(replay, undefined);
         };
         };
@@ -181,8 +181,8 @@ var BABYLON;
                 newPosition: finalPosition.asArray()
                 newPosition: finalPosition.asArray()
             };
             };
             var reply = {
             var reply = {
-                error: 0 /* SUCCESS */,
-                taskType: 2 /* COLLIDE */,
+                error: BABYLON.WorkerReplyType.SUCCESS,
+                taskType: BABYLON.WorkerTaskType.COLLIDE,
                 payload: replyPayload
                 payload: replyPayload
             };
             };
             postMessage(reply, undefined);
             postMessage(reply, undefined);
@@ -204,13 +204,13 @@ var BABYLON;
             var onNewMessage = function (event) {
             var onNewMessage = function (event) {
                 var message = event.data;
                 var message = event.data;
                 switch (message.taskType) {
                 switch (message.taskType) {
-                    case 0 /* INIT */:
+                    case BABYLON.WorkerTaskType.INIT:
                         collisionDetector.onInit(message.payload);
                         collisionDetector.onInit(message.payload);
                         break;
                         break;
-                    case 2 /* COLLIDE */:
+                    case BABYLON.WorkerTaskType.COLLIDE:
                         collisionDetector.onCollision(message.payload);
                         collisionDetector.onCollision(message.payload);
                         break;
                         break;
-                    case 1 /* UPDATE */:
+                    case BABYLON.WorkerTaskType.UPDATE:
                         collisionDetector.onUpdate(message.payload);
                         collisionDetector.onUpdate(message.payload);
                         break;
                         break;
                 }
                 }

+ 21 - 20
Babylon/Collisions/babylon.collisionWorker.ts

@@ -56,8 +56,13 @@ module BABYLON {
 
 
             // Check all meshes
             // Check all meshes
             var meshes = this._collisionCache.getMeshes();
             var meshes = this._collisionCache.getMeshes();
-            for (var uniqueId in meshes) {
-                if (meshes.hasOwnProperty(uniqueId) && parseInt(uniqueId) != excludedMeshUniqueId) {
+            var keys = Object.keys(meshes);
+            var len = keys.length;
+            var uniqueId;
+
+            for (var i = 0; i < len; ++i) {
+                uniqueId = keys[i];
+                if (parseInt(uniqueId) != excludedMeshUniqueId) {
                     var mesh: SerializedMesh = meshes[uniqueId];
                     var mesh: SerializedMesh = meshes[uniqueId];
                     if (mesh.checkCollisions)
                     if (mesh.checkCollisions)
                         this.checkCollision(mesh);
                         this.checkCollision(mesh);
@@ -131,36 +136,32 @@ module BABYLON {
                 if (len > 1 && !this.checkSubmeshCollision(subMesh))
                 if (len > 1 && !this.checkSubmeshCollision(subMesh))
                     continue;
                     continue;
 
 
-                //Unneeded
-                //subMesh['getMesh'] = function () {
-                //    return mesh.uniqueId;
-                //}
                 this.collideForSubMesh(subMesh, transformMatrix, meshGeometry);
                 this.collideForSubMesh(subMesh, transformMatrix, meshGeometry);
             }
             }
         }
         }
 
 
         private collideForSubMesh(subMesh: SerializedSubMesh, transformMatrix: BABYLON.Matrix, meshGeometry: SerializedGeometry): void {
         private collideForSubMesh(subMesh: SerializedSubMesh, transformMatrix: BABYLON.Matrix, meshGeometry: SerializedGeometry): void {
             var positionsArray = [];
             var positionsArray = [];
-            for (var i = 0; i < meshGeometry.positions.length; i = i + 3) {
+            for (var i = 0, len = meshGeometry.positions.length; i < len; i = i + 3) {
                 var p = BABYLON.Vector3.FromArray([meshGeometry.positions[i], meshGeometry.positions[i + 1], meshGeometry.positions[i + 2]]);
                 var p = BABYLON.Vector3.FromArray([meshGeometry.positions[i], meshGeometry.positions[i + 1], meshGeometry.positions[i + 2]]);
                 positionsArray.push(p);
                 positionsArray.push(p);
             }
             }
-            subMesh['_lastColliderTransformMatrix'] = transformMatrix.clone();
-            //The following two arrays should be initialized CORRECTLY to save some calculation time.
-            subMesh['_lastColliderWorldVertices'] = [];
-            subMesh['_trianglePlanes'] = [];
-            var start = subMesh.verticesStart;
-            var end = (subMesh.verticesStart + subMesh.verticesCount);
-            for (var i = start; i < end; i++) {
-                subMesh['_lastColliderWorldVertices'].push(BABYLON.Vector3.TransformCoordinates(positionsArray[i], transformMatrix));
-            }
-        
-            //}
+            if (!subMesh['_lastColliderWorldVertices'] || !subMesh['_lastColliderTransformMatrix'].equals(transformMatrix)) {
+                subMesh['_lastColliderTransformMatrix'] = transformMatrix.clone();
+                //The following two arrays should be initialized CORRECTLY to save some calculation time.
+                subMesh['_lastColliderWorldVertices'] = [];
+                subMesh['_trianglePlanes'] = [];
+                var start = subMesh.verticesStart;
+                var end = (subMesh.verticesStart + subMesh.verticesCount);
+                for (var i = start; i < end; i++) {
+                    subMesh['_lastColliderWorldVertices'].push(BABYLON.Vector3.TransformCoordinates(positionsArray[i], transformMatrix));
+                }
+            }        
+
             // Collide
             // Collide
-            this.collider._collide(subMesh['_trianglePlanes'] = [], subMesh['_lastColliderWorldVertices'], <any> meshGeometry.indices, subMesh.indexStart, subMesh.indexStart + subMesh.indexCount, subMesh.verticesStart, subMesh.hasMaterial);
+            this.collider._collide(subMesh['_trianglePlanes'], subMesh['_lastColliderWorldVertices'], <any> meshGeometry.indices, subMesh.indexStart, subMesh.indexStart + subMesh.indexCount, subMesh.verticesStart, subMesh.hasMaterial);
         }
         }
 
 
-        //TODO - this! :-)
         private checkSubmeshCollision(subMesh: SerializedSubMesh) : boolean {
         private checkSubmeshCollision(subMesh: SerializedSubMesh) : boolean {
             return this.collider._canDoCollision(BABYLON.Vector3.FromArray(subMesh.sphereCenter), subMesh.sphereRadius, BABYLON.Vector3.FromArray(subMesh.boxMinimum), BABYLON.Vector3.FromArray(subMesh.boxMaximum));
             return this.collider._canDoCollision(BABYLON.Vector3.FromArray(subMesh.sphereCenter), subMesh.sphereRadius, BABYLON.Vector3.FromArray(subMesh.boxMinimum), BABYLON.Vector3.FromArray(subMesh.boxMaximum));
         }
         }