ss2d icon indicating copy to clipboard operation
ss2d copied to clipboard

DisplayObject.worldToLocal should include himself when get world matrix

Open CharcoStudios opened this issue 11 years ago • 2 comments

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; };

CharcoStudios avatar Sep 30 '13 18:09 CharcoStudios

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.

galloscript avatar Sep 30 '13 20:09 galloscript

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();

CharcoStudios avatar Oct 01 '13 06:10 CharcoStudios