diff --git a/src/material/ContactMaterial.js b/src/material/ContactMaterial.js index e1d955ff..cc2159ba 100644 --- a/src/material/ContactMaterial.js +++ b/src/material/ContactMaterial.js @@ -116,3 +116,20 @@ function ContactMaterial(materialA, materialB, options){ } ContactMaterial.idCounter = 0; + +/** + * Returns unique hash that was generated based on material id's. Usage: World.contactMaterials[hash]. + * @private + * @method getHash + */ +ContactMaterial.prototype.getHash = function(){ + return ContactMaterial.createHash(this.materialA, this.materialB); +}; + +ContactMaterial.createHash = function(materialA, materialB){ + if (materialA.id <= materialB.id) { + return materialA.id + '-' + materialB.id; + } else { + return materialB.id + '-' + materialA.id; + } +}; diff --git a/src/world/World.js b/src/world/World.js index 4260c1cb..c64be326 100644 --- a/src/world/World.js +++ b/src/world/World.js @@ -174,11 +174,11 @@ function World(options){ this.solveConstraints = true; /** - * The ContactMaterials added to the World. + * Hash object containing ContactMaterials added to the World. * @property contactMaterials - * @type {Array} + * @type {Object} */ - this.contactMaterials = []; + this.contactMaterials = {}; /** * World time. @@ -400,7 +400,7 @@ World.prototype.addConstraint = function(constraint){ * @param {ContactMaterial} contactMaterial */ World.prototype.addContactMaterial = function(contactMaterial){ - this.contactMaterials.push(contactMaterial); + this.contactMaterials[contactMaterial.getHash()] = contactMaterial; }; /** @@ -410,7 +410,7 @@ World.prototype.addContactMaterial = function(contactMaterial){ * @param {ContactMaterial} cm */ World.prototype.removeContactMaterial = function(cm){ - arrayRemove(this.contactMaterials, cm); + delete this.contactMaterials[cm.getHash()]; }; /** @@ -419,17 +419,9 @@ World.prototype.removeContactMaterial = function(cm){ * @param {Material} materialA * @param {Material} materialB * @return {ContactMaterial} The matching ContactMaterial, or false on fail. - * @todo Use faster hash map to lookup from material id's */ World.prototype.getContactMaterial = function(materialA,materialB){ - var cmats = this.contactMaterials; - for(var i=0, N=cmats.length; i!==N; i++){ - var cm = cmats[i]; - if((cm.materialA === materialA && cm.materialB === materialB) || (cm.materialA === materialB && cm.materialB === materialA)){ - return cm; - } - } - return false; + return this.contactMaterials[ContactMaterial.createHash(materialA, materialB)] || false; }; /** @@ -1166,9 +1158,8 @@ World.prototype.clear = function(){ // Remove all contact materials var cms = this.contactMaterials; - i = cms.length; - while(i--){ - this.removeContactMaterial(cms[i]); + for (var hash in cms) { + delete cms[hash]; } }; @@ -1234,8 +1225,8 @@ World.prototype.setGlobalStiffness = function(stiffness){ // Set for all contact materials var contactMaterials = this.contactMaterials; - for(var i=0; i !== contactMaterials.length; i++){ - var c = contactMaterials[i]; + for(var hash in contactMaterials){ + var c = contactMaterials[hash]; c.stiffness = c.frictionStiffness = stiffness; } @@ -1253,8 +1244,9 @@ World.prototype.setGlobalRelaxation = function(relaxation){ setGlobalEquationParams(this, { relaxation: relaxation }); // Set for all contact materials - for(var i=0; i !== this.contactMaterials.length; i++){ - var c = this.contactMaterials[i]; + var contactMaterials = this.contactMaterials; + for(var hash in contactMaterials){ + var c = contactMaterials[hash]; c.relaxation = c.frictionRelaxation = relaxation; } diff --git a/test/world/World.js b/test/world/World.js index 643211d6..4a5ed710 100644 --- a/test/world/World.js +++ b/test/world/World.js @@ -140,7 +140,7 @@ exports.clear = function(test){ test.deepEqual(world.bodies, []); test.deepEqual(world.springs, []); test.deepEqual(world.constraints, []); - test.deepEqual(world.contactMaterials, []); + test.deepEqual(world.contactMaterials, {}); test.done(); };