{"id":391,"date":"2009-08-30T00:44:47","date_gmt":"2009-08-30T07:44:47","guid":{"rendered":"https:\/\/actionsnippet.com\/?p=2064"},"modified":"2009-08-30T00:44:47","modified_gmt":"2009-08-30T07:44:47","slug":"3d-key-controls","status":"publish","type":"post","link":"https:\/\/actionsnippet.com\/?p=391","title":{"rendered":"3D Key Controls"},"content":{"rendered":"<pre class=\"brush: as3; title: ; notranslate\" title=\"\">\r\n&#x5B;SWF(backgroundColor=0x000000, width=500, height=500)]\r\nvar hsw:Number = stage.stageWidth \/ 2;\r\nvar hsh:Number = stage.stageHeight \/ 2;\r\nvar pointNum:int = 300;\r\nvar points3D:Vector.&lt;Number&gt; = new Vector.&lt;Number&gt;();\r\nvar points2D:Vector.&lt;Number&gt; = new Vector.&lt;Number&gt;();\r\nvar uvts:Vector.&lt;Number&gt; = new Vector.&lt;Number&gt;();\r\nvar sorted:Array = &#x5B;];\r\nvar pnt:Point = new Point();\r\nvar m:Matrix3D = new Matrix3D();\r\nvar v:Vector3D = new Vector3D();\r\nfor (var i:int = 0; i&lt;pointNum; i++){\r\n\tv.x = 300;\r\n\tv.y = v.z = 0;\r\n\tm.identity();\r\n\tm.appendRotation(Math.random()*360, Vector3D.X_AXIS);\r\n\tm.appendRotation(Math.random()*360, Vector3D.Y_AXIS);\r\n\tm.appendRotation(Math.random()*360, Vector3D.Z_AXIS);\r\n\tv = m.transformVector(v);\r\n\tpoints3D.push(v.x, v.y, v.z);\r\n\tpoints2D.push(0,0);\r\n\tuvts.push(0,0,0);\r\n\tsorted.push(new Vector3D());\r\n}\r\npoints3D.fixed = true;\r\npoints2D.fixed = true;\r\nuvts.fixed = true;\r\nvar p:PerspectiveProjection = new PerspectiveProjection();\r\nvar proj:Matrix3D = p.toMatrix3D();\r\nvar rx:Number = 0, ry:Number = 0;\r\naddEventListener(Event.ENTER_FRAME, onLoop);\r\nfunction onLoop(evt:Event):void {\r\n\tvar i:int, j:int;\r\n\tm.identity();\r\n\tif (key&#x5B;Keyboard.RIGHT]){\r\n\t\trx+=3\r\n\t}else\r\n\tif (key&#x5B;Keyboard.LEFT]){\r\n\t\trx-=3\r\n\t}else\r\n\tif (key&#x5B;Keyboard.UP]){\r\n\t\try-=3\r\n\t}else\r\n\tif (key&#x5B;Keyboard.DOWN]){\r\n\t\try+=3\r\n\t}\r\n\tm.appendRotation(rx, Vector3D.Y_AXIS);\r\n\tm.appendRotation(ry, Vector3D.X_AXIS);\r\n\tm.appendTranslation(0, 0, 1000);\r\n\tm.append(proj);\r\n\tUtils3D.projectVectors(m, points3D, points2D, uvts);\r\n\tfor (i = 0, j = 0; i&lt;points2D.length; i+=2, j++){\r\n\t\tsorted&#x5B;j].x = points2D&#x5B;i] + hsw;\r\n\t\tsorted&#x5B;j].y = points2D&#x5B;i + 1] + hsh;\r\n\t\tsorted&#x5B;j].z = uvts&#x5B;j * 3 + 2];\r\n\t}\r\n\tsorted.sortOn(&quot;z&quot;, Array.NUMERIC);\r\n\tgraphics.clear();\r\n\tgraphics.lineStyle(2, 0x000000, 0.1);\r\n\tfor(i = 0; i&lt;sorted.length; i++){\r\n\t\tvar zpos:Number = sorted&#x5B;i].z * 12000;\r\n\t\tvar c:int = zpos * 14;\r\n\t\tc = (c &gt; 255) ? 255 : c;\r\n\t\tgraphics.beginFill(100&lt;&lt;16 | 100 &lt;&lt; 8 |c);\r\n\t\tgraphics.drawCircle(sorted&#x5B;i].x, sorted&#x5B;i].y,zpos);\r\n\t\tgraphics.endFill();\r\n\t}\r\n}\r\n\r\n\/\/ permanently applies the matrix to the points3D vector\r\nfunction applyTransform():void{\r\n\tm.identity();\r\n\tm.appendRotation(rx, Vector3D.Y_AXIS);\r\n\tm.appendRotation(ry, Vector3D.X_AXIS);\r\n\tvar temp:Vector.&lt;Number&gt; = new Vector.&lt;Number&gt;();\r\n\tm.transformVectors(points3D, temp);\r\n\tpoints3D = temp;\r\n\tpoints3D.fixed = true;\r\n\trx = 0, ry = 0;\r\n}\r\n\r\n\/\/ basic key setup\r\nvar key:Object = new Object();\r\nstage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyPressed);\r\nstage.addEventListener(KeyboardEvent.KEY_UP, onKeyReleased);\r\nfunction onKeyPressed(evt:KeyboardEvent):void {\r\n\tkey&#x5B;evt.keyCode] = true;\r\n\tkey.keyCode = evt.keyCode;\r\n}\r\nfunction onKeyReleased(evt:KeyboardEvent):void { \r\n  applyTransform();\r\n  key&#x5B;evt.keyCode] = false;\r\n}\r\n<\/pre>\n<p>In response to Thomas Francis&#8217;s question, this snippet takes the <a href=\"https:\/\/actionsnippet.com\/?p=2058\" target=\"blank\">Simple z-sorting<\/a> snippet and shows how one might go about adding some basic key controls to it. It works by permanently applying x and y rotation transformations to the set of 3D points every time a key is released.<\/p>\n<p><a href=\"http:\/\/wonderfl.net\/code\/17b4f1e08a317766a2d99dab99069b917f3ca23b\" target=\"blank\">Check out the swf&#8230;<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/actionsnippet.com\/wp-content\/keys3d.gif\" \/><\/a><\/p>\n<p>If you need to be able to rotate on both the x and y axis at the same time &#8211; and just need more flexibility&#8230; one way to do it would be to use <a href=\"http:\/\/en.wikipedia.org\/wiki\/Quaternions_and_spatial_rotation\" target=\"blank\">quaternions<\/a> &#8211; which may be tricky &#8211; but there are plenty of examples out there in java, processing and C\/C++ just waiting to be ported (been on the todo list for some time actually).<\/p>\n<p><i>Haven&#8217;t been posting every day because I&#8217;ve been out of the country and away from my computer&#8230; have a backlog of snippets that need to be cleaned up and put in the pipeline&#8230;<\/i><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#x5B;SWF(backgroundColor=0x000000, width=500, height=500)] var hsw:Number = stage.stageWidth \/ 2; var hsh:Number = stage.stageHeight \/ 2; var pointNum:int = 300; var points3D:Vector.&lt;Number&gt; = new Vector.&lt;Number&gt;(); var points2D:Vector.&lt;Number&gt; = new Vector.&lt;Number&gt;(); var uvts:Vector.&lt;Number&gt; = new Vector.&lt;Number&gt;(); var sorted:Array = &#x5B;]; var pnt:Point = new Point(); var m:Matrix3D = new Matrix3D(); var v:Vector3D = new Vector3D(); for (var [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[101,33,75,79],"tags":[3,14,4],"class_list":["post-391","post","type-post","status-publish","format-standard","hentry","category-3d","category-graphics","category-keys","category-vector","tag-actionscript","tag-as3","tag-flash"],"_links":{"self":[{"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/posts\/391","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=391"}],"version-history":[{"count":0,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/posts\/391\/revisions"}],"wp:attachment":[{"href":"https:\/\/actionsnippet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=391"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=391"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=391"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}