{"id":61,"date":"2014-04-01T17:12:23","date_gmt":"2014-04-01T17:12:23","guid":{"rendered":"https:\/\/blogs.scummvm.org\/josejx\/?p=61"},"modified":"2022-05-21T17:16:21","modified_gmt":"2022-05-21T17:16:21","slug":"that-menacing-mechanical-manatee","status":"publish","type":"post","link":"https:\/\/blogs.scummvm.org\/josejx\/2014\/04\/01\/that-menacing-mechanical-manatee\/","title":{"rendered":"That Menacing Mechanical Manatee"},"content":{"rendered":"<p><i>Continued from the <a href=\"https:\/\/blogs.scummvm.org\/josejx\/2014\/04\/01\/fixing-the-positions\/\">previous entry<\/a><\/i><\/p>\n<p>After the initial excitement of fixing the bug, <a href=\"https:\/\/github.com\/inguin\">Inguin<\/a> remembered that the Manatee was the reason why that code was written in the first place. We have to try it out, so let&#8217;s get to the MicroGroggery and try it out:<\/p>\n<ul>\n<li>dofile(&#8220;_jumpscripts.lua&#8221;)<\/li>\n<li>jump_script(&#8220;250&#8221;)<\/li>\n<li>switch_to_set(&#8220;mig&#8221;)<\/li>\n<\/ul>\n<p>Great, we&#8217;re there! After a brief conversation with the barkeep, we get to ride the Manatee. And then things go a little bit wrong:<\/p>\n<figure id=\"attachment_63\" aria-describedby=\"caption-attachment-63\" style=\"width: 640px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/04\/Manatee.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-63\" src=\"https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/04\/Manatee.png\" alt=\"\" width=\"640\" height=\"480\" srcset=\"https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/04\/Manatee.png 640w, https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/04\/Manatee-300x225.png 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><figcaption id=\"caption-attachment-63\" class=\"wp-caption-text\">Air Riding the Manatee!<\/figcaption><\/figure>\n<p>It turns out that the Chandelier wasn&#8217;t a great test of the position code. The base actor was at (0,0,0) and had no rotation. The Manatee (or more specifically: <i>mig.manatee_rotator<\/i>) has a rotation before we attach Guybrush&#8217;s actor to it. So, there&#8217;s a problem with attaching actors when there&#8217;s rotation. Let&#8217;s do some investigation and see what the behavior of the retail engine is, as compared to the current code in ResidualVM.<\/p>\n<p>The configuration for all of the tests start with this setup:<\/p>\n<ul>\n<li>Actor1 is located at [1,2,3]<\/li>\n<li>Actor2 is located at [2,4,6]<\/li>\n<li>Actor1 is rotated to (0, 90, 0) using <i>setrot<\/i><\/li>\n<li>We call <i>Actor1:attach(Actor2, nil)<\/i> to attach the two actors<\/li>\n<\/ul>\n<p>Once these steps have been completed, I looked at the information we can get from the Actors:<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"2\">\n<tbody>\n<tr>\n<th>Command<\/th>\n<th>ResidualVM<\/th>\n<th>Retail<\/th>\n<\/tr>\n<tr>\n<td>Actor1:getpos()<\/td>\n<td>(1,2,3)<\/td>\n<td>(1,2,3)<\/td>\n<\/tr>\n<tr>\n<td>Actor1:getworldpos()<\/td>\n<td>(1,2,3)<\/td>\n<td>(1,2,3)<\/td>\n<\/tr>\n<tr>\n<td>Actor1:getrot()<\/td>\n<td>(0,90,0)<\/td>\n<td>(0,90,0)<\/td>\n<\/tr>\n<tr>\n<td>Actor2:getpos()<\/td>\n<td>(1,2,3)<\/td>\n<td>(-3,2,1)<\/td>\n<\/tr>\n<tr>\n<td>Actor2:getworldpos()<\/td>\n<td>(4,4,2)<\/td>\n<td>(2,4,6)<\/td>\n<\/tr>\n<tr>\n<td>Actor2:getrot()<\/td>\n<td>(0,0,0)<\/td>\n<td>(0,-90,0)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>So, what does this tell us? For Actor1, the attaching doesn&#8217;t change his position or behavior and both engines do the same thing! Actor2, who was attached to Actor1 doesn&#8217;t fare quite as well. Starting with <i>getrot<\/i>, we see that the retail engine shows the angle relative to the attached actor. The world position from <i>getworldpos<\/i> is the original position before we attached the actors, while the position reported by <i>getpos<\/i> is wrong.<\/p>\n<p>Let&#8217;s try another test with this setup:<\/p>\n<ul>\n<li>Actor1 is located at [1,2,3]<\/li>\n<li>Actor2 is located at [2,4,6]<\/li>\n<li>Actor1 is rotated to (0, 90, 0) using <i>setrot<\/i><\/li>\n<li>Actor2 is rotated to (20, 0, 0) using <i>setrot<\/i><\/li>\n<li>We call <i>Actor1:attach(Actor2, nil)<\/i> to attach the two actors<\/li>\n<\/ul>\n<p>What happens this time?<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"2\">\n<tbody>\n<tr>\n<th>Command<\/th>\n<th>ResidualVM<\/th>\n<th>Retail<\/th>\n<\/tr>\n<tr>\n<td>Actor1:getpos()<\/td>\n<td>(1,2,3)<\/td>\n<td>(1,2,3)<\/td>\n<\/tr>\n<tr>\n<td>Actor1:getworldpos()<\/td>\n<td>(1,2,3)<\/td>\n<td>(1,2,3)<\/td>\n<\/tr>\n<tr>\n<td>Actor1:getrot()<\/td>\n<td>(0,90,0)<\/td>\n<td>(0,90,0)<\/td>\n<\/tr>\n<tr>\n<td>Actor2:getpos()<\/td>\n<td>(1,2,3)<\/td>\n<td>(-3,2,1)<\/td>\n<\/tr>\n<tr>\n<td>Actor2:getworldpos()<\/td>\n<td>(4,4,2)<\/td>\n<td>(2,4,6)<\/td>\n<\/tr>\n<tr>\n<td>Actor2:getrot()<\/td>\n<td>(20,0,0)<\/td>\n<td>(90,70,-90)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Finally, let&#8217;s look at what happens when we detach Actor2 from Actor1 using the second example:<\/p>\n<ul>\n<li>Use the setup from the previous example<\/li>\n<li>Then a2:detach()<\/li>\n<\/ul>\n<p>Here&#8217;s what happened this time:<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"2\">\n<tbody>\n<tr>\n<th>Command<\/th>\n<th>ResidualVM<\/th>\n<th>Retail<\/th>\n<\/tr>\n<tr>\n<td>Actor1:getpos()<\/td>\n<td>(1,2,3)<\/td>\n<td>(1,2,3)<\/td>\n<\/tr>\n<tr>\n<td>Actor1:getworldpos()<\/td>\n<td>(1,2,3)<\/td>\n<td>(1,2,3)<\/td>\n<\/tr>\n<tr>\n<td>Actor1:getrot()<\/td>\n<td>(0,90,0)<\/td>\n<td>(0,90,0)<\/td>\n<\/tr>\n<tr>\n<td>Actor2:getpos()<\/td>\n<td>(4,4,2)<\/td>\n<td>(2,4,6)<\/td>\n<\/tr>\n<tr>\n<td>Actor2:getworldpos()<\/td>\n<td>(4,4,2)<\/td>\n<td>(2,4,6)<\/td>\n<\/tr>\n<tr>\n<td>Actor2:getrot()<\/td>\n<td>(0,0,0)<\/td>\n<td>(0,0,-20)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>We can now make a few guesses as to what&#8217;s going wrong. In the next post, we&#8217;ll figure out how to fix the problem!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Continued from the previous entry After the initial excitement of fixing the bug, Inguin remembered that the Manatee was the reason why that code was written in the first place. We have to try it out, so let&#8217;s get to the MicroGroggery and try it out: dofile(&#8220;_jumpscripts.lua&#8221;) jump_script(&#8220;250&#8221;) switch_to_set(&#8220;mig&#8221;) Great, we&#8217;re there! After a brief [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-61","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/posts\/61","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/comments?post=61"}],"version-history":[{"count":2,"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/posts\/61\/revisions"}],"predecessor-version":[{"id":64,"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/posts\/61\/revisions\/64"}],"wp:attachment":[{"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/media?parent=61"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/categories?post=61"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/tags?post=61"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}