{"id":143,"date":"2016-05-11T13:05:30","date_gmt":"2016-05-11T13:05:30","guid":{"rendered":"http:\/\/blog.qubekwest.com\/?p=143"},"modified":"2016-05-11T13:05:30","modified_gmt":"2016-05-11T13:05:30","slug":"cursor-crazy","status":"publish","type":"post","link":"https:\/\/blog.qubekwest.com\/?p=143","title":{"rendered":"Cursor Crazy"},"content":{"rendered":"<p>As I worked on the concept of a Feature, I also came up with the idea of a FeatureCursor to make drawing in a Feature a little easier to do. \u00a0A cursor is a lot like what you are probably thinking. \u00a0It&#8217;s a system for tracking a position within a Feature. \u00a0You can move it around and place blocks as you go. \u00a0There are also fun bulk block placement methods for drawing lines and quickly putting up walls and that sort of thing.<\/p>\n<p>At first, I imagined this cursor thing would only be useful in a Feature, but then I got to thinking a similar thing would be useful for drawing in the world directly too. \u00a0Then another one for filling in the blocks in a raw chunk came to mind. \u00a0That means these cursor things became something useful for all sorts of generators when constructing the world.<\/p>\n<p>There are several different concepts of geography space in QubeKwest. \u00a0The world itself operates in 3-tier geography space (blocks in chunks in clusters), Features operate in 2-tier geography space (blocks in chunks), and raw Chunks operate in 1-tier geography space (just the blocks they contain). \u00a0What that means is that the trickiest parts of getting cursors to work are making sure they move in the appropriate number of tiers correctly, that they follow the bounds of the space they are working in, and of course that placing blocks follows the correct rules.\u00a0\u00a0That meant a little bit of refactoring was in order.<\/p>\n<p>I didn&#8217;t want to have to rewrite the various line drawing and wall placing functions for each new type of cursor that I ended up making, which meant the creation of a new parent class called BlockCursor. \u00a0It is abstract and holds all the bulk placement methods so child cursors only need to provide how the cursor moves around and how blocks are placed for all of the same drawing methods to work across multiple cursors.<\/p>\n<p>For that to work however, I had to make sure none of the methods in BlockCursor ever tried to directly set the position of the cursor (because it can&#8217;t know what geography space is being used) or to draw anything using methods other than the ones provided by child cursors. \u00a0When I found a C++ implementation of\u00a0Bresenham&#8217;s line algorithm in 3D it became especially important that I didn&#8217;t have to maintain multiple versions of that method after I&#8217;d rewritten it in Java and made it work with cursors. \u00a0It&#8217;s a pretty hairy algorithm it get right and maintaining multiple versions of it for different cursors would be a terrible idea.<\/p>\n<p>After a bit of work, I am satisfied that my pattern for cursors is sound. \u00a0Whether that remains true mostly depends on whether or not actually using these cursors in the various generators proves to be a pain. \u00a0That is a bridge I will cross some other time so I can remain focused on actual progress.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As I worked on the concept of a Feature, I also came up with the idea of a FeatureCursor to make drawing in a Feature a little easier to do. \u00a0A cursor is a lot like what you are probably thinking. \u00a0It&#8217;s a system for tracking a position within a Feature. \u00a0You can move it &hellip; <a href=\"https:\/\/blog.qubekwest.com\/?p=143\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Cursor Crazy<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-143","post","type-post","status-publish","format-standard","hentry","category-dev"],"_links":{"self":[{"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=\/wp\/v2\/posts\/143","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=143"}],"version-history":[{"count":6,"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=\/wp\/v2\/posts\/143\/revisions"}],"predecessor-version":[{"id":151,"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=\/wp\/v2\/posts\/143\/revisions\/151"}],"wp:attachment":[{"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=143"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=143"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.qubekwest.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=143"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}