{"id":147,"date":"2014-06-21T18:41:00","date_gmt":"2014-06-21T18:41:00","guid":{"rendered":"https:\/\/blogs.scummvm.org\/josejx\/?p=147"},"modified":"2022-05-21T18:43:22","modified_gmt":"2022-05-21T18:43:22","slug":"returning-to-quaternions-and-rotations","status":"publish","type":"post","link":"https:\/\/blogs.scummvm.org\/josejx\/2014\/06\/21\/returning-to-quaternions-and-rotations\/","title":{"rendered":"Returning to Quaternions and Rotations"},"content":{"rendered":"<p><i>Continued from the <a href=\"https:\/\/blogs.scummvm.org\/josejx\/2014\/05\/12\/quaternion-progress\/\" target=\"_blank\" rel=\"noopener\">previous entry<\/a>.<\/i><\/p>\n<p>After a long hiatus, I&#8217;m working on completing the rotation and quaternion changes that arose as a part of fixing attaching and dettaching actors. To begin, I needed to rebase my old changes so that they applied to the current git master. With all of the progress that has been made since the start of GSoC, the patchset was out of date and doesn&#8217;t address all of the current uses of <i>Quaternions<\/i> and <i>Rotation3d<\/i>.<\/p>\n<p>In order to make this patchset easier to accept into ResidualVM, I&#8217;m splitting the work up into three distinct parts:<\/p>\n<ol>\n<li>Rework of <i>Rotation3d<\/i> to support the various Euler Angle orders<\/li>\n<li>The final expanded <i>Quaternion<\/i> implementation<\/li>\n<li>The completed attaching and detaching code<\/li>\n<\/ol>\n<p>The reasoning behind this approach is that a large portion of the current Quaternion usage is simply to convert from Euler Angles to a Matrix. By removing this extra step, the resulting code will be easier to read and more straightforward. After applying my previous changes to the <i>Rotation3d<\/i> class, I created tests to check that the code was capable of converting from Euler Angles to a Rotation Matrix, and back again. In this implmentation, the user can specify the Euler Angle order by using the <i>enum<\/i> <i>EulerOrder <\/i>values, and building the Rotation Matrix with the member function <i>buildFromXYZ<\/i> or using the constructor that takes three angles and the <i>EulerOrder<\/i>.<\/p>\n<p>Let&#8217;s take a brief detour here for a moment to explain how to add tests to ResidualVM&#8217;s test suite. ResidualVM uses <a href=\"http:\/\/cxxtest.com\/\" target=\"_blank\" rel=\"noopener\">CxxTest<\/a> as the framework to build unit tests. All of the tests can be found in the directory <a href=\"https:\/\/github.com\/residualvm\/residualvm\/tree\/master\/test\" target=\"_blank\" rel=\"noopener\">test<\/a>, with a directory inside that for each of the ResidualVM components tested. Currently, there are tests for the <a href=\"https:\/\/github.com\/residualvm\/residualvm\/tree\/master\/test\/audio\" target=\"_blank\" rel=\"noopener\">audio subsystem<\/a> and the <a href=\"https:\/\/github.com\/residualvm\/residualvm\/tree\/master\/test\/common\" target=\"_blank\" rel=\"noopener\">common functionality<\/a>. In this changeset, I&#8217;ve created a new directory, <i>math<\/i> and added a new file, <i>rotation3d.h<\/i> which contains the unit tests for the Rotation3d class.<\/p>\n<p>Unit tests are implemented by writing classes that contain the tests and CxxTest automatically generates the rest of the code to run the tests. So, to add a new test, we first include a header from CxxTest that defines the <i>TestSuite<\/i> class. We then define a class that inherits from this base class and then implement our tests with each unit test as a public member of our class. Each of these unit test functions return no value and have no parameters. To actually test a value, CxxTest provides <a href=\"http:\/\/cxxtest.com\/guide.html#testAssertions\" target=\"_blank\" rel=\"noopener\">assertions<\/a> which should be used to report the test result.<\/p>\n<p>Since math isn&#8217;t already a part of the testing structure, we&#8217;ll need to add a new directory to the unit test build system. To do this, you must add the test header files to the build by adding them to the <i>module.mk<\/i> file in the test root. So, to add our new math tests to the unit tests to be built, I modified the TEST variable with the text in red:<\/p>\n<ul>\n<li>TESTS := $(srcdir)\/test\/common\/*.h $(srcdir)\/test\/audio\/*.h <span style=\"color: #ff0000;\">$(srcdir)\/test\/math\/*.h<\/span><\/li>\n<\/ul>\n<p>I also needed to link the actual math library implementation to the unit test build, so I added the following to the TEST_LIBS variable:<\/p>\n<ul>\n<li>TEST_LIBS := audio\/libaudio.a <span style=\"color: #ff0000;\">math\/libmath.a<\/span> common\/libcommon.a<\/li>\n<\/ul>\n<p>And that&#8217;s it! To build and run our tests, from your build directory, simply run:<\/p>\n<ul>\n<li>make test<\/li>\n<\/ul>\n<p>The output will look like this (assuming I didn&#8217;t break anything!):<\/p>\n<figure id=\"attachment_149\" aria-describedby=\"caption-attachment-149\" style=\"width: 586px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/06\/testWorked.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-149\" src=\"https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/06\/testWorked.png\" alt=\"\" width=\"586\" height=\"264\" srcset=\"https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/06\/testWorked.png 586w, https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/06\/testWorked-300x135.png 300w\" sizes=\"auto, (max-width: 586px) 100vw, 586px\" \/><\/a><figcaption id=\"caption-attachment-149\" class=\"wp-caption-text\">Everything tested out okay!<\/figcaption><\/figure>\n<p>And failures will look like this when something does break, depending on the assertion type used:<\/p>\n<figure id=\"attachment_150\" aria-describedby=\"caption-attachment-150\" style=\"width: 616px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/06\/testFailed.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-150\" src=\"https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/06\/testFailed.png\" alt=\"\" width=\"616\" height=\"251\" srcset=\"https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/06\/testFailed.png 616w, https:\/\/blogs.scummvm.org\/josejx\/wp-content\/uploads\/sites\/23\/2014\/06\/testFailed-300x122.png 300w\" sizes=\"auto, (max-width: 616px) 100vw, 616px\" \/><\/a><figcaption id=\"caption-attachment-150\" class=\"wp-caption-text\">Oops, the test failed!<\/figcaption><\/figure>\n<p>And that&#8217;s it for testing! It&#8217;s very straightforward to add additional tests, so I&#8217;ll try to add code that performs testing in the future for applicable changes.<\/p>\n<p>Back to Rotation3d! In this incarnation of the updated Rotation3d code, I decided to return the rotation direction to the &#8220;left handed&#8221; DirectX direction of rotation that was previously in Rotation3d. This will remove the necessity for all of the <i>transpose()<\/i> calls that I had previously needed to insert to produce the same result as before.<\/p>\n<p>In addition to the basic assertions, I had previously created a test that compared the original implementation of Rotation3d to my new version for each of the uses in ResidualVM. I adapted these tests for the new implementation, but won&#8217;t submit them for inclusion because they duplicate a lot of code. The branch containing these tests can be found <a href=\"https:\/\/github.com\/JoseJX\/residualvm\/tree\/Rotation3D_OldTest\" target=\"_blank\" rel=\"noopener\">here<\/a>, while the Rotation3d changes can be found in <a href=\"https:\/\/github.com\/residualvm\/residualvm\/pull\/936\" target=\"_blank\" rel=\"noopener\">PR #936<\/a>.<\/p>\n<p>In the next post, we&#8217;ll look at the Quaternion implementation and finish working on attaching and dettaching.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Continued from the previous entry. After a long hiatus, I&#8217;m working on completing the rotation and quaternion changes that arose as a part of fixing attaching and dettaching actors. To begin, I needed to rebase my old changes so that they applied to the current git master. With all of the progress that has been [&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-147","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/posts\/147","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=147"}],"version-history":[{"count":2,"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/posts\/147\/revisions"}],"predecessor-version":[{"id":151,"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/posts\/147\/revisions\/151"}],"wp:attachment":[{"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/media?parent=147"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/categories?post=147"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.scummvm.org\/josejx\/wp-json\/wp\/v2\/tags?post=147"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}