<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Andy Li’s Blog - 3D</title><link href="https://blog.onthewings.net/" rel="alternate"></link><link href="http://feeds.feedburner.com/tag/3d/feed/atom.xml" rel="self"></link><id>https://blog.onthewings.net/</id><updated>2012-03-04T22:19:00+08:00</updated><entry><title>Head-tracking motion-parallax 3D in haXe/Flash</title><link href="https://blog.onthewings.net/2012/03/04/head-tracking-motion-parallax-3d-in-haxe-flash/" rel="alternate"></link><published>2012-03-04T22:19:00+08:00</published><updated>2012-03-04T22:19:00+08:00</updated><author><name>Andy Li</name></author><id>tag:blog.onthewings.net,2012-03-04:/2012/03/04/head-tracking-motion-parallax-3d-in-haxe-flash/</id><summary type="html">&lt;iframe allowfullscreen="" class="video" frameborder="0" height="390" src="//www.youtube.com/embed/U6PePKJHOSw" width="640"&gt;&lt;/iframe&gt;
&lt;p&gt;Here above is my haXe implementation of head-tracking 3D, creating
motion-parallax effect using Away3D 4. You can play with the &lt;a href="http://andyli.github.com/MotionParallaxDemo/"&gt;live
demo&lt;/a&gt; or &lt;a href="https://github.com/andyli/MotionParallaxDemo"&gt;grab the source&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This type of head tracking &lt;span class="caps"&gt;VR&lt;/span&gt; has been around for quite a long time. The
first popular one should be &lt;a href="http://www.youtube.com/watch?v=Jd3-eiid-Uw"&gt;Johnny Lee’s Wiimote …&lt;/a&gt;&lt;/p&gt;</summary><content type="html">&lt;iframe allowfullscreen="" class="video" frameborder="0" height="390" src="//www.youtube.com/embed/U6PePKJHOSw" width="640"&gt;&lt;/iframe&gt;
&lt;p&gt;Here above is my haXe implementation of head-tracking 3D, creating
motion-parallax effect using Away3D 4. You can play with the &lt;a href="http://andyli.github.com/MotionParallaxDemo/"&gt;live
demo&lt;/a&gt; or &lt;a href="https://github.com/andyli/MotionParallaxDemo"&gt;grab the source&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This type of head tracking &lt;span class="caps"&gt;VR&lt;/span&gt; has been around for quite a long time. The
first popular one should be &lt;a href="http://www.youtube.com/watch?v=Jd3-eiid-Uw"&gt;Johnny Lee’s Wiimote hack&lt;/a&gt;, back in 2007,
 built in C# running as a desktop app. Two years later it appeared in
the browser, &lt;a href="http://ricardocabello.com/blog/post/643"&gt;a Flash version made by Mr. doob&lt;/a&gt;. But it was merely a
hack and far from accurate comparing to Johnny Lee’s. Boffswana also
created &lt;a href="http://www.boffswana.com/news/?p=498"&gt;one&lt;/a&gt; in the same year (2009), and then &lt;a href="http://www.boffswana.com/news/?p=950"&gt;an improved one&lt;/a&gt;
with better head tracking algorithm. Sadly Boffswana hasn’t release the source.&lt;/p&gt;
&lt;p&gt;Head tracking and camera movement is relatively simple, since there are
so many libs for these. The tricky part is the perspective
projection matrix. The projection point (the head), unlike most of the
implementation assumption, isn’t always perpendicular to the projection
surface (screen).&lt;/p&gt;
&lt;p&gt;Simplest implementation would ignore the problem. It places a camera at
the position of viewer’s head and render it to the screen, like what Mr.
doob did. The problem is illustrated below.&lt;/p&gt;
&lt;p&gt;When viewer’s head is perpendicular to the screen, everything is
perfectly aligned:&lt;/p&gt;
&lt;p&gt;&lt;img alt="when head is perpendicular to screen" src="/files/2012/animated.79104.gif"/&gt;&lt;/p&gt;
&lt;p&gt;However, when the viewer moves, for example to the left, there is
misalignment of the rendering on screen and the “actual” position of the
virtual object:&lt;/p&gt;
&lt;p&gt;&lt;img alt="when viewer moved to left" src="/files/2012/animated.61275.gif"/&gt;&lt;/p&gt;
&lt;p&gt;Knowing little about C#, it is hard for me to dig out Johnny Lee’s
matrix code. I found the suitable code form the paper “Generalized
Perspective Projection” from &lt;a href="http://csc.lsu.edu/~kooima/misc.html"&gt;Robert Kooima&lt;/a&gt;. It is written in C++,
but translating it to haXe isn’t hard, just remember matrix in OpenGL is
&lt;a href="http://en.wikipedia.org/wiki/Row-major_order#Column-major_order"&gt;column-major order&lt;/a&gt; but Flash’s is &lt;a href="http://en.wikipedia.org/wiki/Row-major_order#Row-major_order"&gt;row-major order&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Head-detection is done using &lt;a href="http://code.google.com/r/andy-hxmarilena/"&gt;my fork&lt;/a&gt; of &lt;a href="http://code.google.com/p/hxmarilena/"&gt;hxmarilena&lt;/a&gt;. My fork is
simply some &lt;span class="caps"&gt;API&lt;/span&gt; changes and switching the &lt;span class="caps"&gt;XML&lt;/span&gt; parsing from
&lt;a href="http://haxe.org/api/flash9/xml/xml"&gt;flash.xml.&lt;span class="caps"&gt;XML&lt;/span&gt;&lt;/a&gt; to &lt;a href="http://haxe.org/api/xml"&gt;Xml&lt;/a&gt; so it may be used in C++ target in the
future. In order to reduce jittering, I’ve included a simple optical
flow tracking on the head. It is a block-matching process applied to
four points on previous head detection result. The optical flow tracking
result is merged to head-detection result by a ratio. It improved a bit,
but I guess to address the problem it is better to port some better
algorithms, like &lt;a href="http://web.mac.com/jsaragih/FaceTracker/FaceTracker.html"&gt;FaceTracker&lt;/a&gt;, in the future.&lt;/p&gt;
&lt;p&gt;Finally, remember you can play with the &lt;a href="http://andyli.github.com/MotionParallaxDemo/"&gt;live demo&lt;/a&gt; and &lt;a href="https://github.com/andyli/MotionParallaxDemo"&gt;it is open
source&lt;/a&gt;.&lt;/p&gt;</content><category term="3D"></category><category term="experiment"></category><category term="Flash"></category><category term="Haxe"></category></entry><entry><title>Sandy3D, C++, Haxe</title><link href="https://blog.onthewings.net/2010/03/18/sandy3d-c-haxe/" rel="alternate"></link><published>2010-03-18T07:39:00+08:00</published><updated>2010-03-18T07:39:00+08:00</updated><author><name>Andy Li</name></author><id>tag:blog.onthewings.net,2010-03-18:/2010/03/18/sandy3d-c-haxe/</id><summary type="html">&lt;p&gt;I’ve been learning &lt;a href="http://haxe.org/"&gt;Haxe&lt;/a&gt; since the last few months. Beside the reason
of many Flash guys moved/moving to Haxe because of better performance of
compiled swf, I was tempted to try using its C++ target, which runs even
faster(at least in theory, in most parts). Its language …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I’ve been learning &lt;a href="http://haxe.org/"&gt;Haxe&lt;/a&gt; since the last few months. Beside the reason
of many Flash guys moved/moving to Haxe because of better performance of
compiled swf, I was tempted to try using its C++ target, which runs even
faster(at least in theory, in most parts). Its language feature is also
very nice, which is quite similar to &lt;span class="caps"&gt;AS3&lt;/span&gt; but more powerful in
many aspects. Check out its &lt;a href="http://haxe.org/doc/features"&gt;feature page&lt;/a&gt; if you want to know more.&lt;/p&gt;
&lt;p&gt;And because of I need to write some 3D stuff in a project, I tried
finding a Haxe 3D engine  that can compiled to C++, but who knows, there
wasn’t one. Actually the 3D engines in Haxe are all quite young. There
are 3 I found, all targeting only Flash: &lt;a href="http://www.flashsandy.org/"&gt;Sandy3D&lt;/a&gt;, originally written
in &lt;span class="caps"&gt;AS&lt;/span&gt;, has switched its trunk to Haxe; &lt;a href="http://www.away3d.com/"&gt;Away3D&lt;/a&gt;, again originally
written in &lt;span class="caps"&gt;AS&lt;/span&gt;, now has a Haxe branch inside its &lt;span class="caps"&gt;SVN&lt;/span&gt; in active
development; &lt;a href="http://code.google.com/p/haxe3d/"&gt;Haxe3D&lt;/a&gt;, developed by Nicolas(the creator of Haxe),
written in Haxe from the very beginning, seems to be very light-weight but
I can’t found much info about it.&lt;/p&gt;
&lt;p&gt;So I decide to work on one of them to enable a Haxe C++ 3D
engine. Because Sandy3D should be the most complete and stable one(which
actually stopped active development…), I chose it.&lt;/p&gt;
&lt;p&gt;In the development of it, some issues are related to &lt;a href="http://code.google.com/p/nekonme/"&gt;nme&lt;/a&gt;/&lt;a href="http://code.google.com/p/neash/"&gt;neash&lt;/a&gt;,
which are the re-invented cross-platform Haxe version of the Flash &lt;span class="caps"&gt;API&lt;/span&gt;.
With the help from &lt;a href="http://gamehaxe.com/"&gt;Hugh&lt;/a&gt; and Niel, project owner of &lt;a href="http://code.google.com/p/neash/"&gt;neash&lt;/a&gt; and
developer of Sandy3D, most of the problems are solved. However as I can
see, re-inventing the Flash &lt;span class="caps"&gt;API&lt;/span&gt; is a hard job as consideration of other
target is also needed, e.g.. &lt;span class="caps"&gt;JS&lt;/span&gt;/Canvas. &lt;a href="http://ideas.adobe.com/ct/ct_a_view_idea.bix?c=975F47A1-B925-4456-89DB-3BEFB1DA7780&amp;amp;idea_id=D62AC800-1BD6-4C79-85A7-6CCCE1C403AC"&gt;I really hope Adobe can help
this&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Currently some very basic demos of Sandy can be compiled to C++ and it
shows that, in OpenGL rendering mode, the performance can goes over 300%
of the Flash(Haxe, not &lt;span class="caps"&gt;AS3&lt;/span&gt;) version. However in normal rendering mode,
the frame rate may actually be reduced if the window size is large.
Anyway, I think the performance is quite depend on hardware/&lt;span class="caps"&gt;OS&lt;/span&gt;, also the
3D scene you’re showing.&lt;/p&gt;
&lt;p&gt;Thanks for the Sandy3D team, they added me as a committer in their
official Google project. And I have just committed the changes to the
trunk :) There should be a new release soon if everything is fine.&lt;/p&gt;
&lt;p&gt;A note to the ones can’t wait for a release:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install hxcpp, nme, neash from haxelib.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replace contents in neash’s neash/display/IBitmapDrawable.hx to a simple &lt;code&gt;typedef IBitmapDrawable = nme.display.IBitmapDrawable;&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To make mouse event work, in neash’s neash/Lib.hx, the code:
    &lt;pre&gt;
// Process pending timers ...&lt;br/&gt;
neash.Timer.CheckTimers();&lt;br/&gt;
// Send frame-enter event&lt;br/&gt;
var event = new Event( Event.ENTER_FRAME );&lt;br/&gt;
mStage.Broadcast(event);
    &lt;/pre&gt;
    should be moved to the end of the do-while loop, just before &lt;code&gt;mStage.RenderAll();&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For mouse event in OpenGL mode to work, additional fix which required a recompile of nme is needed. I haven’t tried yet. Now just ignore this…&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You should be able to use Sandy3D in C++ without the above patches for the next release of nme/neash. But for now, please do it.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;span class="caps"&gt;BTW&lt;/span&gt;, I am also &lt;del&gt;porting&lt;/del&gt; ported &lt;a href="http://casalib.org/"&gt;casalib&lt;/a&gt;, which I often use in &lt;span class="caps"&gt;AS3&lt;/span&gt;
development, to Haxe, see &lt;a href="http://github.com/andyli/casahx"&gt;casahx&lt;/a&gt;.&lt;/p&gt;</content><category term="3D"></category><category term="Haxe"></category><category term="Sandy3D"></category></entry><entry><title>Vector Sound Wave Morphing</title><link href="https://blog.onthewings.net/2009/05/20/vector-sound-wave-morphing/" rel="alternate"></link><published>2009-05-20T06:53:00+08:00</published><updated>2009-05-20T06:53:00+08:00</updated><author><name>Andy Li</name></author><id>tag:blog.onthewings.net,2009-05-20:/2009/05/20/vector-sound-wave-morphing/</id><summary type="html">&lt;p&gt;This my my final project for the course “Interactivity I”. For this
final project, my aim is to explore the vector nature of sound wave
while making a tool to let people create their own waveform which can
then be saved for other use.&lt;/p&gt;
&lt;p&gt;The waveform in the program consists …&lt;/p&gt;</summary><content type="html">&lt;p&gt;This my my final project for the course “Interactivity I”. For this
final project, my aim is to explore the vector nature of sound wave
while making a tool to let people create their own waveform which can
then be saved for other use.&lt;/p&gt;
&lt;p&gt;The waveform in the program consists of 10 control points. The first
point and the last point are fixed at zero so that the wave can be
looped smoothly to form a sound wave. The controls points can be
adjusted by dragging or by using keyboard. The points are assigned with
keys labelled near them, which are number keys (+shift to move points up
instead of down). I recommend using the keyboard as you may adjust
multiple points at the same time (which feels like using multitouch
surface 8-) ).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://degrafa.org/"&gt;Degrafa&lt;/a&gt; is used to construct the wave form. I choose to use cubic
bezier curve as it is easier for me to implement the algorithm (with the
still-in-beta &lt;a href="http://algorithmist.wordpress.com/2009/01/19/degrafa-cubic-bezier-y-at-x/"&gt;AdvancedCubicBezier&lt;/a&gt; which available via &lt;span class="caps"&gt;SVN&lt;/span&gt;).&lt;/p&gt;
&lt;p&gt;The 3D cylinder is made by Flash Player 10’s 3D &lt;span class="caps"&gt;API&lt;/span&gt;. It looks quite nice
as similar to landscapes.&lt;/p&gt;
&lt;p&gt;Sound is synthesized dynamically in real-time (with some delay… okay?
;-) ). If you hear some “clicks” or “pops”, try to export the sound
first by clicking on the export button at the bottom-right corner (it
will be in wav format, encoded by the &lt;a href="http://code.google.com/p/popforge/source/browse/trunk/flash/PopforgeLibrary/src/de/popforge/format/wav/WavEncoder.as"&gt;WavEncoder from popforge&lt;/a&gt;) .&lt;/p&gt;
&lt;p&gt;If you hear nothing, you may try to increase the buffer size or use the
export function.&lt;/p&gt;
&lt;p&gt;&lt;object data="/files/2009/vectorsoundwave.swf" height="450" id="swf86781" style="visibility: visible;" type="application/x-shockwave-flash" width="600"&gt;&lt;param name="wmode" value="opaque"/&gt;&lt;param name="menu" value="true"/&gt;&lt;param name="quality" value="high"/&gt;&lt;param name="bgcolor" value="#FFFFFF"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="/files/2009/vectorsoundwave.zip"&gt;source&lt;/a&gt;&lt;/p&gt;</content><category term="3D"></category><category term="CityU"></category><category term="experiment"></category><category term="Flash"></category><category term="Flex"></category></entry><entry><title>Data structure assignment - Coin Collecting Game</title><link href="https://blog.onthewings.net/2008/11/03/data-structure-assignment-coin-collecting-game/" rel="alternate"></link><published>2008-11-03T04:56:00+08:00</published><updated>2008-11-03T04:56:00+08:00</updated><author><name>Andy Li</name></author><id>tag:blog.onthewings.net,2008-11-03:/2008/11/03/data-structure-assignment-coin-collecting-game/</id><summary type="html">&lt;p&gt;It is just a simple game (If it is really a game), but I was having fun
with Flex and PaperVision3D.&lt;/p&gt;
&lt;p&gt;&lt;object data="/files/2008/coincollectinggame.swf" height="500" id="swf38911" style="visibility: visible;" type="application/x-shockwave-flash" width="480"&gt;&lt;param name="wmode" value="opaque"/&gt;&lt;param name="menu" value="true"/&gt;&lt;param name="quality" value="high"/&gt;&lt;param name="bgcolor" value="#FFFFFF"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;/object&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;It is just a simple game (If it is really a game), but I was having fun
with Flex and PaperVision3D.&lt;/p&gt;
&lt;p&gt;&lt;object data="/files/2008/coincollectinggame.swf" height="500" id="swf38911" style="visibility: visible;" type="application/x-shockwave-flash" width="480"&gt;&lt;param name="wmode" value="opaque"/&gt;&lt;param name="menu" value="true"/&gt;&lt;param name="quality" value="high"/&gt;&lt;param name="bgcolor" value="#FFFFFF"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;/object&gt;&lt;/p&gt;</content><category term="3D"></category><category term="Flex"></category></entry><entry><title>Crazy 3D modelling technology … Video Trace</title><link href="https://blog.onthewings.net/2008/06/22/crazy-3d-modaling-technology-video-trace/" rel="alternate"></link><published>2008-06-22T21:40:00+08:00</published><updated>2008-06-22T21:40:00+08:00</updated><author><name>Andy Li</name></author><id>tag:blog.onthewings.net,2008-06-22:/2008/06/22/crazy-3d-modaling-technology-video-trace/</id><summary type="html">&lt;p&gt;&lt;a href="http://www.acvt.com.au/research/videotrace/"&gt;VideoTrace: Rapid interactive scene modelling from video&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a really crazy modeling technology…&lt;br/&gt;
Use a video clip that has some view points (in different angles) to an
object, trace the object with a few clicks in several frames, and you
get the 3D model (mapped with auto-generated bitmaps from …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="http://www.acvt.com.au/research/videotrace/"&gt;VideoTrace: Rapid interactive scene modelling from video&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a really crazy modeling technology…&lt;br/&gt;
Use a video clip that has some view points (in different angles) to an
object, trace the object with a few clicks in several frames, and you
get the 3D model (mapped with auto-generated bitmaps from the clip).&lt;/p&gt;</content><category term="3D"></category></entry></feed>