-
Notifications
You must be signed in to change notification settings - Fork 406
Scratchpads
See also: Scratchpad API reference
Any object creation inside a world's "step" phase is costly -- especially if it's inside additional loops. Vectors, especially, are most likely to end up in critical calculations but creating temporary vectors every iteration causes significant slow-downs for the engine. To solve this, when temporary vector
s, or transforms
are needed, they can be requested from the scratchpad
service and then released to be recycled in later calculations.
NOTE: Remember to always call .done()
when the computation is complete, otherwise the scratchpad will throw an error.
To create a scratchpad instance, simply call Physics.scratchpad()
. This scratchpad instance can be used to obtain recycled vector
s, or transforms
. They will likely be non-zero, and will need to be set to the appropriate values.
Typically the usage will look something like this:
function myAlgorithm( args ){
var scratch = Physics.scratchpad() // obtain a new scratchpad instance
,tempV = scratch.vector().set( 2, 4 )
;
// do some computation with tempV...
// important final step: release the scratchpad for reuse and return result
// passing result to `.done` is just a semantic trick
return scratch.done( result );
}
It is also possible to wrap a function using Physics.scratchpad()
to create a function that will be passed a scratchpad instance as its first parameter, and automatically call .done()
for you. Do this like so:
var myAlgorithm = Physics.scratchpad(function( scratch, args ){
var tempV = scratch.vector().set( 2, 4 );
// do some computation with tempV...
// no need to call .done since this function is wrapped
return result;
});
// call it normally
myAlgorithm( args );
The source code for the .getPolygonArea()
method demonstrates an example of the usage of scratchpads.
Physics.geometry.getPolygonArea = function getPolygonArea( hull ){
var scratch = Physics.scratchpad()
,prev = scratch.vector()
,next = scratch.vector()
,ret = 0
,l = hull.length
;
if ( l < 3 ){
// it must be a point or a line
// area = 0
scratch.done();
return 0;
}
prev.clone( hull[ l - 1 ] );
for ( var i = 0; i < l; ++i ){
next.clone( hull[ i ] );
ret += prev.cross( next );
prev.swap( next );
}
scratch.done();
return ret / 2;
};
If you create an object you would like to reuse with scratchpads, you can register it with the scratchpad service. Example:
var myObject = function(){
this.foo = 'bar';
};
Physics.scratchpad.register('myObject', myObject);
// use it!
var scratch = Physics.scratchpad();
var instance = scratch.myObject();
scratch.done();