Warning: Use of undefined constant image_setup - assumed 'image_setup' (this will throw an Error in a future version of PHP) in /home/westleyw/public_html/wp-content/themes/autofocus/functions.php on line 576

Warning: Use of undefined constant image_setup - assumed 'image_setup' (this will throw an Error in a future version of PHP) in /home/westleyw/public_html/wp-content/themes/autofocus/functions.php on line 577

Warning: Declaration of Jetpack_IXR_Client::query() should be compatible with IXR_Client::query(...$args) in /home/westleyw/public_html/wp-content/plugins/jetpack/class.jetpack-ixr-client.php on line 91

Warning: Cannot modify header information - headers already sent by (output started at /home/westleyw/public_html/wp-content/themes/autofocus/functions.php:576) in /home/westleyw/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/westleyw/public_html/wp-content/themes/autofocus/functions.php:576) in /home/westleyw/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/westleyw/public_html/wp-content/themes/autofocus/functions.php:576) in /home/westleyw/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/westleyw/public_html/wp-content/themes/autofocus/functions.php:576) in /home/westleyw/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/westleyw/public_html/wp-content/themes/autofocus/functions.php:576) in /home/westleyw/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/westleyw/public_html/wp-content/themes/autofocus/functions.php:576) in /home/westleyw/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/westleyw/public_html/wp-content/themes/autofocus/functions.php:576) in /home/westleyw/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/westleyw/public_html/wp-content/themes/autofocus/functions.php:576) in /home/westleyw/public_html/wp-includes/rest-api/class-wp-rest-server.php on line 1794
{"id":519,"date":"2013-07-03T20:08:06","date_gmt":"2013-07-04T02:08:06","guid":{"rendered":"http:\/\/www.westleywood.com\/?p=519"},"modified":"2013-07-03T20:08:06","modified_gmt":"2013-07-04T02:08:06","slug":"terrain-editor-morphing-the-terrain","status":"publish","type":"post","link":"http:\/\/www.westleywood.com\/2013\/07\/terrain-editor-morphing-the-terrain\/","title":{"rendered":"Terrain Editor (Morphing The Terrain)"},"content":{"rendered":"

Picking The Terrain<\/h3>\n

The first piece of information needed when morphing a terrain is to find out where the user wants to morph the terrain. \u00a0By using a small equation with the DirectX D3DXIntersect() function we can determine where the user wishes to pick the terrain. \u00a0Here<\/a>\u00a0is a good place to get started and learn how the basics of D3DXIntersect() works.<\/p>\n

Once the basic functionality of D3DXIntersect() is implemented you can use this equation to determine the exact position that the user is picking.<\/p>\n

Picked Position = Origin + (Direction * Distance)<\/em><\/p>\n

Next, you can do a simple distance calculation to create a list of vertex positions’ that lie inside the defined radius. \u00a0This becomes your list of vertices to modify. \u00a0So when morphing is applied it will only be applied to these vertices.<\/p>\n

\u00a0Morphing Up<\/h3>\n

I morphed the terrain up with respect to the distance a vertex point was from the picked position. \u00a0First I determined the scale of the morph based on its distance away from the center of the terrain and the radius of the defined brush.<\/p>\n

Scale = cos( PI\/2 * ( Brush Radius – (Brush Radius – Distance) ) \/ Brush Radius)<\/em><\/p>\n

Then I added the scaled user defined increment to the vertex’s Y position. \u00a0This produces a smooth cosign curve over the picked position.<\/p>\n

By passing in a negative increment value, the Morph Up function becomes a Morph Down function. \u00a0Doing the equivalent shape of Morph Up, but in the negative\/downward direction.<\/p>\n

\u00a0Smoothing<\/h3>\n

Smoothing the terrain is quite simple and is basically averaging all of the selected vertices’ heights. \u00a0First, get the average height of all the selected vertices. \u00a0Next, get the difference between the average height and the current vertex height. \u00a0Finally, scale the difference and add it back to the original height. \u00a0The scale is specified by the user.<\/p>\n

Vertex Y Position = Vertex Y Position + Scale * (Average Height – Vertex Y Position)<\/em><\/p>\n

By passing in a negative scale the Smooth function becomes an Extrude function. \u00a0Moving the vertices away from the average height position.<\/p>\n

Updating The Terrain<\/h3>\n

Locking Vertices and Indices of a mesh can be fairly process intensive. \u00a0So when doing this type of editing it can be helpful to store the Vertices and Indices in a local array or list. \u00a0Then make all your edits to the locally stored Vertex and Index lists and set a flag to signal that the mesh needs to be updated. \u00a0This allows for you to make multiple edits to the same vertices and only lock the mesh once for the final updated vertex.<\/p>\n

Helpful Thing I Learned<\/h3>\n

In order to edit a ID3DXMesh you will not be able to use a managed pool of memory. \u00a0So the locally stored vertices and indices also help in reconstructing the mesh after the device has been lost and reset.<\/p>\n

Even though you may not make any changes to the Indices within the index buffer of the mesh. \u00a0I found that I needed to still reset the indices at the same time I reset the vertices.<\/p>\n

If you are doing any light calculations it is nice to recalculate the normals after updating the vertices.<\/p>\n

Using some sort of shadowing can help define the shape of the terrain. \u00a0I used my modified SSAO shader to dynamically give detail to the curves of the terrain.<\/p>\n","protected":false},"excerpt":{"rendered":"Picking The Terrain\nThe first piece of information needed when morphing a terrain is to find out where the user wants to morph the terrain. \u00a0By …","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/www.westleywood.com\/wp-json\/wp\/v2\/posts\/519"}],"collection":[{"href":"http:\/\/www.westleywood.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.westleywood.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.westleywood.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.westleywood.com\/wp-json\/wp\/v2\/comments?post=519"}],"version-history":[{"count":23,"href":"http:\/\/www.westleywood.com\/wp-json\/wp\/v2\/posts\/519\/revisions"}],"predecessor-version":[{"id":573,"href":"http:\/\/www.westleywood.com\/wp-json\/wp\/v2\/posts\/519\/revisions\/573"}],"wp:attachment":[{"href":"http:\/\/www.westleywood.com\/wp-json\/wp\/v2\/media?parent=519"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.westleywood.com\/wp-json\/wp\/v2\/categories?post=519"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.westleywood.com\/wp-json\/wp\/v2\/tags?post=519"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}