DisplayObject.worldToLocal should include himself when get world matrix
I'm not sure if you want to do it this way, but this give you the coords in parent space:
127 ss2d.DisplayObject.prototype.worldToLocal = function(point) 128 { 129 var worldMatrix = this.getWorldTransformationMatrix(); 130 var invWorldMatrix = worldMatrix.invert(); 131 var transformedPoint = invWorldMatrix.transformPoint(point); 132 return transformedPoint; 133 };
, but I think it would be more useful if the transformation of the object is included, that I'm expecting when converting from world space to local
ss2d.DisplayObject.prototype.worldToLocal = function(pointf)
{
var targetMatrix = new ss2d.Matrix3();
var worldMatrix = this.getWorldTransformationMatrix(targetMatrix, null, true);
var invWorldMatrix = worldMatrix.invert();
var transformedPoint = invWorldMatrix.transformPoint(point);
return transformedPoint;
};
worldToLocal returns a point transformed to the same coordinate space as the object, if you include the object what you are returning is that object's children coordinate space, I understand that this could be useful if the object is rotated cause with the current implementation you can only do AABB hit test, but, if you add the object to a container and transform the container with the rotation only, you can test even rotated object. The other solution would be instead of including the entire object transformation, get a rotation matrix only and include it in the worldToLocal, we can try if that variation work as expected.
You are right, I want to work in children space of that object, though I considered that is the object space. I'm creating a scrollable grid class and I want to show only visible cells, so I need to convert coords to that space.
I think that maybe it's worth to add an optional argument to the worldToLocal to achieve this behaviour.
Here is the code of my scrollable grid component:
Number.prototype.clamp = function(min, max) {
return Math.min(Math.max(this, min), max);
};
var Grid = function () {
this.mSize = 1024;
ss2d.Quad.call(this, 0, 0, this.mSize, this.mSize, "#7774e7");
this.mCols = 64;
this.mRows = 64;
this.mCellWidth = this.mWidth / this.mCols;
this.mCellHeight = this.mHeight / this.mRows;
this.mGap = 32;
this.mPickable = new ss2d.Pickable(this);
}
goog.inherits(Grid, ss2d.Quad);
Grid.prototype.tick = function(dt) {
this.mPickable.tick(dt);
}
Grid.prototype.render = function (renderSupport) {
var ctx = renderSupport.mContext;
var cx = 0;
var cy = 0;
var cw = ctx.canvas.width;
var ch = ctx.canvas.height;
cx += this.mGap;
cy += this.mGap;
cw -= 4*this.mGap;
ch -= 2*this.mGap;
var start = new ss2d.Point();
var end = new ss2d.Point();
var matrix = new ss2d.Matrix3();
this.getWorldTransformationMatrix(matrix, null, true);
matrix.invert();
matrix.transformPoint( new ss2d.Point(cx,cy), start );
matrix.transformPoint( new ss2d.Point(cx+cw,cy+ch), end );
// start = this.worldToLocal( new ss2d.Point(cx,cy));
// end = this.worldToLocal( new ss2d.Point(cx+cw,cy+ch));
renderSupport.pushTransform(this);
ctx = renderSupport.mContext;
ctx.beginPath();
ctx.moveTo(start.mX,start.mY);
ctx.lineTo(start.mX, end.mY);
ctx.lineTo(end.mX, end.mY);
ctx.lineTo(end.mX, start.mY);
ctx.lineTo(start.mX, start.mY);
ctx.clip();
ctx.fillStyle = this.mColor.getHexString();
ctx.fillRect(0, 0, this.mWidth, this.mHeight);
ctx.strokeStyle = "#ffff30";
start.mX = Math.floor(start.mX / this.mCellWidth) * this.mCellWidth;
end.mX = Math.ceil(end.mX / this.mCellWidth) * this.mCellWidth;
start.mY = Math.floor(start.mY / this.mCellHeight) * this.mCellHeight;
end.mY = Math.ceil(end.mY / this.mCellHeight) * this.mCellHeight;
start.mX = start.mX.clamp(0, this.mWidth);
end.mX = end.mX.clamp(0, this.mWidth);
start.mY = start.mY.clamp(0, this.mHeight);
end.mY = end.mY.clamp(0, this.mHeight);
for (var x = start.mX; x<=end.mX; x+=this.mCellWidth) {
ctx.moveTo(x,0);
ctx.lineTo(x, this.mHeight);
}
for (var y = start.mY; y<=end.mY; y+=this.mCellHeight) {
ctx.moveTo(0,y);
ctx.lineTo(this.mWidth, y);
}
ctx.stroke();
renderSupport.popTransform();
}
var view = new ss2d.View('mainCanvas');
view.mBackgroundFillStyle = "#000000";
var grid = new Grid();
view.mMainScene.addObject(grid);
view.startLoop();