Saturday, April 12, 2014

The Attached are Attached

After the Manatee's Ride, I hoped that all of the attachment issues were fixed. Unfortunately, that's not the case. Another, more complicated attachment situation presents itself when Guybrush is arriving at Pegnose Pete's house. In this scene, Guybrush puts down the raft pole. Here, the pole is attached to Guybrush, who is in turn connected to the raft. When the pole is detached, the detached location doesn't match the retail version, resulting in the scene below:
How did the Pole get up there?
So, what's the problem in ResidualVM? A series of scripts generating scenarios indicated that the current code for detaching actors was incorrect. Reversing the procedure that was worked out in the Manatee's Ride resulted in the correct detached position for actors connected to another actor.

Great, now the above situation worked correctly right? Nope. It turns out that the situation is more complex when you've got a situation like the scene from the Mysts O' Time with three actors attached. We'll start by checking the values when everything is attached after Guybrush gets on the raft in the first setup of the scene "mot":
swampraft Retail ResidualVM
getpos (-0.109778, -0.12, -0.437341) (-0.109778, -0.12, -0.437341)
getworldpos (-0.109778, -0.12, -0.437341) (-0.109778, -0.12, -0.437341)
getrot (0,733,0) (0,13,0)
guybrush Retail ResidualVM
getpos (0.4, 0.25, 0.4) (0.4, 0.25, 0.4)
getworldpos (0.359951, 0.13, -0.137574) (0.36995, 0.13, -0.137573)
getrot (0,0.252186,0) (0,0,0)
mot.pole Retail ResidualVM
getpos (-0.0222, 0.0287, 0.147) (-0.0222, 0.0287, 0.147)
getworldpos (0.513002, 1.36408, 0.350046) (0.510769, 1.36408, 0.350696)
getrot (-13.8, -87.5, 0) (-13.8, -87.5, 0)

While there are some differences, these results match up pretty well. Let's detach the pole from guybrush and check the coordinates again:

mot.pole Retail ResidualVM
getpos (0.513002, 1.36408, 0.350046) (0.411437, 0.2787, 0.548226)
getworldpos (0.513002, 1.36408, 0.350046) (0.411437, 0.2787, 0.548226)
getrot (129.963, -25.8091, 0.0515321)(-13.8, -87.5, 0)

There's a quick fix for the world position, using the result from getworldpos gives us our new coordinates. This makes sense as we don't want to move when detached, so the world coordinates should become the new position. The rotation is more problematic, how did we get there? The resulting rotation seems to be the result of converting from providing the actor's pose in the local reference basis to the world reference basis.

Interestingly, detaching all three actors, then re-attaching them results in an incorrect placement of the pole object, indicating that there's probably some bugs in the original implementation. This appears to have been worked around by constantly setting the position and rotation in the game scripts.

To figure out exactly what was going on, I tested attaching three actors in different poses and recorded the final attached values. Then, I detached the third actor and recorded those values as well. The result of this experiment is recorded in this spreadsheet. Of interest, I found that the position of the actor does not change the resulting orientation, so the only values recorded are the rotation angles retrieved with the :getrot() method. In the next blog post, we'll interpret these values and figure out how EMI actually calculated the attached and detached position angle.

No comments:

Post a Comment