luatabletop-simulator

Translate coordinates relative to obj1 to be relative to obj2


I have an object (obj1) that creates a button.

self.createButton({ position={ 15.7, 0.1, -1.8 }, ...})

That position, of course, is relative to obj1.

obj1 is a bag, and the button it creates is on the game board, far away from the bag (as you can tell by the magnitude of the X component). This isn't appropriate, and it means the bag can't be moved. I want to have the game board create the button instead.

How do I determine the coordinates to provide when calling createButton from within the game board (obj2)?


Solution

  • I worked out that one can translate the relative position to an absolute position using the following:

    local rel_pos = Vector(15.7, 0.1, -1.8)
    local abs_pos = Vector(-v[1], v[2], v[3])
    abs_pos:scale( obj1.getScale() )
    abs_pos:rotateOver('z', obj1.getRotation()['z'] )  -- The order is important
    abs_pos:rotateOver('x', obj1.getRotation()['x'] )
    abs_pos:rotateOver('y', obj1.getRotation()['y'] )
    abs_pos:add( obj1.getPosition() )
    

    Reversing the process using obj2 will get the vector to use in obj2.


    But why is the X component negated? I thought I was missing something until I discovered positionToWorld, a function meant to do exactly what the above attempts. It turns out I still needed to negate the X component.

    local rel_pos = Vector(15.7, 0.1, -1.8)
    local abs_pos = obj1.positionToWorld(Vector(-v[1], v[2], v[3]))
    

    I can only conclude that that createButton has a bug that requires one to negate the X component of the position it is provided.


    The following is the complete solution:

    local v = Vector(15.7, 0.1, -1.8)
    v:setAt(1, -v[1])             -- Bug-compensated loc rel to obj1 -> Loc rel to obj1
    v = obj1.positionToWorld(v)   -- Loc rel to obj1 -> Absolute loc
    v = obj2.positionToLocal(v)   -- Absolute loc -> Loc rel to obj2
    v:setAt(1, -v[1])             -- Loc rel to obj2 -> Bug-compensated loc rel to obj2
    print(logString(v))
    

    The final result was replacing

    -- In obj1 (the bag)
    self.createButton({ position={ 15.7, 0.1, -1.8 }, ... })
    

    with

    -- In obj2 (the game board)
    self.createButton({ position={ -7.745875, 13.7634, -1.006971 }, ... })