ID:2069331
 
Resolved
The splitting of a matrix into its component operations (scale and skew, rotation, and translation) during interpolation was done incorrectly for some matrices.
BYOND Version:509
Operating System:Windows 10 Home 64-bit
Web Browser:Firefox 45.0
Applies to:Dream Daemon & Dream Seeker
Status: Resolved (510.1339)

This issue has been resolved.
Descriptive Problem Summary:
The animation portion of an animate() either uses right-multiplication while the final step of the animation uses left-multiplication, or vice-versa. This results in the final state of the animation "jumping" to the wrong final transformation, because the transformations of the final state are being applied in the opposite order of the rest of the animation.

See here for a demo project showing this.

Numbered Steps to Reproduce Problem:
See the code snippet below.

Code Snippet (if applicable) to Reproduce Problem:
These two will demonstrate the opposite behavior going on.
TurnScale()
if(TestObject)
del TestObject

TestObject = new(locate(5,5,1))

var/matrix/m = new

m.Turn(45)
m.Scale(2,3)

animate(TestObject, transform = m, time = 25)

ScaleTurn()
if(TestObject)
del TestObject

TestObject = new(locate(5,5,1))

var/matrix/m = new

m.Scale(2,3)
m.Turn(45)

animate(TestObject, transform = m, time = 25)


Expected Results:
The final state of the animation matches up with the rest of the animation.

Actual Results:
The opposite transformation is being applied after the animation. That is (up to transpose), (T1·...·Tn)·v is being applied for the animation, while Tn·...·T1)·v is being applied for the final state (for at least some of T1, ..., Tn).

Does the problem occur:
Every time? Or how often? Every time.
In other games? Presumably in any game using non-commutative transformations.
In other user accounts? Yes.
On other computers? Yes.

When does the problem NOT occur?
When using a single transform or transformations that commute.

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked? (Visit http://www.byond.com/download/build to download old versions for testing.)

Older versions of 510, at least.

Workarounds:
Manually apply the opposite transformation can work, e.g.,
TestObject = new(locate(5,5,1))

var/matrix/m = new

m.Scale(2,3)
m.Turn(45)

animate(TestObject, transform = m, time = 25)

// Opposite transformation.
m = new
m.Turn(45)
m.Scale(3,2)

TestObject.transform = m

It can be kind of jumpy, though, depending on the exact details of what you're doing.
Lummox JR resolved issue with message:
The splitting of a matrix into its component operations (scale and skew, rotation, and translation) during interpolation was done incorrectly for some matrices.