{"id":70,"date":"2010-10-10T23:10:32","date_gmt":"2010-10-10T23:10:32","guid":{"rendered":"https:\/\/www.cores2.com\/blog\/?p=70"},"modified":"2010-11-24T00:27:04","modified_gmt":"2010-11-24T00:27:04","slug":"roller-coaster","status":"publish","type":"post","link":"https:\/\/www.cores2.com\/blog\/?p=70","title":{"rendered":"Roller Coaster"},"content":{"rendered":"<p>I&#8217;ve just finished programming a roller coaster application that was a way to learn Catmull-Rom Spline interpolation. The idea is simply to take a series of low-resolution points representing a general design of a roller coaster, then interpolate these points giving a smooth high-resolution path of the vehicle. What was nice about this application was not only learning about these scene-generation algorithms, but also to learn about OpenGL features I haven&#8217;t touched yet: lighting and the texture-material system. The track itself has a slight world-reflection on it (though you can&#8217;t see it in the video), as well as lights are scattered around the world.<\/p>\n<p>Check out the video, I give an explanation of other features found in the simulation:<\/p>\n<p style=\"text-align: center;\"><object classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" width=\"480\" height=\"385\" codebase=\"http:\/\/download.macromedia.com\/pub\/shockwave\/cabs\/flash\/swflash.cab#version=6,0,40,0\"><param name=\"allowFullScreen\" value=\"true\" \/><param name=\"allowscriptaccess\" value=\"always\" \/><param name=\"src\" value=\"http:\/\/www.youtube.com\/v\/ngYyRsQ_ez8?fs=1&amp;hl=en_US\" \/><param name=\"allowfullscreen\" value=\"true\" \/><embed type=\"application\/x-shockwave-flash\" width=\"480\" height=\"385\" src=\"http:\/\/www.youtube.com\/v\/ngYyRsQ_ez8?fs=1&amp;hl=en_US\" allowscriptaccess=\"always\" allowfullscreen=\"true\"><\/embed><\/object><\/p>\n<p><strong>Edit:<\/strong> I&#8217;ve been asked by a few programmers on how I calculated my point-normals, that is the normals I used as the camera&#8217;s &#8220;up&#8221; vector. My general approach was to trusts that the previous side vector was &#8220;good enough&#8221; for the current position and generate an estimated normal by crossing the &#8220;good enough&#8221; side vector and the accurate forward vector to generate the local-normal vector. To make sure this algorithm keeps working, I saved the side vector for the next point as a vector-cross of the current forward and the &#8220;good enough&#8221; normal, which can be used for the next point.<\/p>\n<p><strong>Edit 2:<\/strong> I&#8217;ve uploaded a non-voiced over high-resolution video of the roller coaster. See below:<\/p>\n<p style=\"text-align: center;\">\n<object width=\"480\" height=\"385\"><param name=\"movie\" value=\"http:\/\/www.youtube.com\/v\/jeBDzPYuZG4?fs=1&amp;hl=en_US\"><\/param><param name=\"allowFullScreen\" value=\"true\"><\/param><param name=\"allowscriptaccess\" value=\"always\"><\/param><embed src=\"http:\/\/www.youtube.com\/v\/jeBDzPYuZG4?fs=1&amp;hl=en_US\" type=\"application\/x-shockwave-flash\" allowscriptaccess=\"always\" allowfullscreen=\"true\" width=\"480\" height=\"385\"><\/embed><\/object><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve just finished programming a roller coaster application that was a way to learn Catmull-Rom Spline interpolation. The idea is simply to take a series of low-resolution points representing a general design of a roller coaster, then interpolate these points &hellip; <a href=\"https:\/\/www.cores2.com\/blog\/?p=70\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-70","post","type-post","status-publish","format-standard","hentry","category-news_updates"],"_links":{"self":[{"href":"https:\/\/www.cores2.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/70","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cores2.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cores2.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cores2.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cores2.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=70"}],"version-history":[{"count":0,"href":"https:\/\/www.cores2.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/70\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.cores2.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=70"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cores2.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=70"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cores2.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=70"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}