web oriented universal language

Back to Personal Blog

Posted on 2008-09-22 by Nicolas Cannasse in General

After one year posting here, I finally terminated to restore my personal blog, with a new system entirely written in haXe which uses haXe/PHP. It's now available on http://ncannasse.fr

haXe 2.0 Available

Posted on 2008-07-29 by Nicolas Cannasse in General

After a few months of work, haXe 2.0 is finally available !

This new release include the following changes :

  • haXe/PHP support
  • new haxe.remoting implementation
  • crossplatform I/O and Bytes support
  • optional parameters default value
  • ... and much more

You can download 2.0 right now from http://haxe.org and read about all the changes that were made on http://haxe.org/doc/advanced/haxe2

Optimizing Perlin Noise...

Posted on 2008-07-20 by Nicolas Cannasse in General

I really love Mario Klingemann work, and I also enjoy performances and optimizations, so when he made a post on his blog earlier this month about optimization of Perlin Noise, I bookmarked it in order to have a look at it when back from holidays.

I then quickly ported the as code to haXe. First, most of type-casting things is not useful in haXe because :

  • arrays are already typed (even before flash10 vectors)
  • integer calculus and array access is already optimized

Since the perlin noise algorithm implemented here was relying heavily on integer calculus, I was expecting quite good results. It turned out that for 30 iterations, it took around 14.6 seconds on my new Quadcore CPU for AS3 version and... 5.4 seconds for the haXe version (woohooo almost 3 times faster !)

Now, having a look at the code, I saw that all the variables were used as statics. It was probably an "optimization" from original PerlinNoise author, which turned out to be bad because - remember it - STATICS ARE SLOW IN FP9 !

So I wrote a second version of the algorithm, without statics, and it went down to 2.7 seconds immediatly... After a bit more tunning, it reached the final 2.3 seconds, which correspond to 13 FPS for 256x256 bitmap and 6 times faster than the AS3 code.

Here's the final source-code, enjoy !

/**
Title:      Perlin noise
Version:    1.3
Author:      Ron Valstar
Author URI:    http://www.sjeiti.com/
Original code port from http://mrl.nyu.edu/~perlin/noise/
and some help from http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
AS3 optimizations by Mario Klingemann http://www.quasimondo.com
haXe port and optimization by Nicolas Cannasse http://haxe.org
*/
import flash.display.BitmapData;

class OptimizedPerlin {

  private static var P = [
    151,160,137,91,90,15,131,13,201,95,
    96,53,194,233,7,225,140,36,103,30,69,
    142,8,99,37,240,21,10,23,190,6,148,
    247,120,234,75,0,26,197,62,94,252,
    219,203,117,35,11,32,57,177,33,88,
    237,149,56,87,174,20,125,136,171,
    168,68,175,74,165,71,134,139,48,27,
    166,77,146,158,231,83,111,229,122,
    60,211,133,230,220,105,92,41,55,46,
    245,40,244,102,143,54,65,25,63,161,
    1,216,80,73,209,76,132,187,208,89,
    18,169,200,196,135,130,116,188,159,
    86,164,100,109,198,173,186,3,64,52,
    217,226,250,124,123,5,202,38,147,118,
    126,255,82,85,212,207,206,59,227,47,
    16,58,17,182,189,28,42,223,183,170,
    213,119,248,152,2,44,154,163,70,221,
    153,101,155,167,43,172,9,129,22,39,
    253,19,98,108,110,79,113,224,232,
    178,185,112,104,218,246,97,228,251,
    34,242,193,238,210,144,12,191,179,
    162,241,81,51,145,235,249,14,239,
    107,49,192,214,31,181,199,106,157,
    184,84,204,176,115,121,50,45,127,4,
    150,254,138,236,205,93,222,114,67,29,
    24,72,243,141,128,195,78,66,215,61,
    156,180,151,160,137,91,90,15,131,13,
    201,95,96,53,194,233,7,225,140,36,
    103,30,69,142,8,99,37,240,21,10,23,
    190,6,148,247,120,234,75,0,26,197,
    62,94,252,219,203,117,35,11,32,57,
    177,33,88,237,149,56,87,174,20,125,
    136,171,168,68,175,74,165,71,134,139,
    48,27,166,77,146,158,231,83,111,229,
    122,60,211,133,230,220,105,92,41,55,
    46,245,40,244,102,143,54,65,25,63,
    161,1,216,80,73,209,76,132,187,208,
    89,18,169,200,196,135,130,116,188,
    159,86,164,100,109,198,173,186,3,64,
    52,217,226,250,124,123,5,202,38,147,
    118,126,255,82,85,212,207,206,59,
    227,47,16,58,17,182,189,28,42,223,
    183,170,213,119,248,152,2,44,154,
    163,70,221,153,101,155,167,43,172,9,
    129,22,39,253,19,98,108,110,79,113,
    224,232,178,185,112,104,218,246,97,
    228,251,34,242,193,238,210,144,12,
    191,179,162,241,81,51,145,235,249,
    14,239,107,49,192,214,31,181,199,
    106,157,184,84,204,176,115,121,50,
    45,127,4,150,254,138,236,205,93,
    222,114,67,29,24,72,243,141,128,
    195,78,66,215,61,156,180
  ];

  var octaves : Int;

  var aOctFreq:Array<Float>; // frequency per octave
  var aOctPers:Array<Float>; // persistence per octave
  var fPersMax:Float;// 1 / max persistence

  var iXoffset:Float;
  var iYoffset:Float;
  var iZoffset:Float;

  var baseFactor:Float;

  public function new( ?seed, ?octaves, ?falloff ) {
    if( seed == null ) seed = 123;
    if( falloff == null ) falloff = .5;
    this.octaves = if( octaves == null ) 4 else octaves;
    baseFactor = 1 / 64;
    seedOffset(seed);
    octFreqPers(falloff);
  }

  public function fill( bitmap:BitmapData, _x:Float, _y:Float, _z:Float, ?_ ):Void {

    var baseX:Float;

    baseX = _x * baseFactor + iXoffset;
    _y = _y * baseFactor + iYoffset;
    _z = _z * baseFactor + iZoffset;

    var width:Int = bitmap.width;
    var height:Int = bitmap.height;

    var p = P;
    var octaves = octaves;
    var aOctFreq = aOctFreq;
    var aOctPers = aOctPers;

    for ( py in 0...height )
    {
      _x = baseX;

      for ( px in 0...width )
      {
        var s = 0.;

        for ( i in 0...octaves )
        {
          var fFreq = aOctFreq[i];
          var fPers = aOctPers[i];

          var x = _x * fFreq;
          var y = _y * fFreq;
          var z = _z * fFreq;

          var xf = x - (x % 1);
          var yf = y - (y % 1);
          var zf = z - (z % 1);

          var X = Std.int(xf) & 255;
          var Y = Std.int(yf) & 255;
          var Z = Std.int(zf) & 255;

          x -= xf;
          y -= yf;
          z -= zf;

          var u = x * x * x * (x * (x*6 - 15) + 10);
          var v = y * y * y * (y * (y*6 - 15) + 10);
          var w = z * z * z * (z * (z*6 - 15) + 10);

          var A  = (p[X]) + Y;
          var AA = (p[A]) + Z;
          var AB = (p[A+1]) + Z;
          var B  = (p[X+1]) + Y;
          var BA = (p[B]) + Z;
          var BB = (p[B+1]) + Z;

          var x1 = x-1;
          var y1 = y-1;
          var z1 = z-1;

          var hash = (p[BB+1]) & 15;
          var g1 = ((hash&1) == 0 ? (hash<8 ? x1 : y1) : (hash<8 ? -x1 : -y1)) + ((hash&2) == 0 ? hash<4 ? y1 : ( hash==12 ? x1 : z1 ) : hash<4 ? -y1 : ( hash==14 ? -x1 : -z1 ));

          hash = (p[AB+1]) & 15;
          var g2 = ((hash&1) == 0 ? (hash<8 ? x  : y1) : (hash<8 ? -x  : -y1)) + ((hash&2) == 0 ? hash<4 ? y1 : ( hash==12 ? x  : z1 ) : hash<4 ? -y1 : ( hash==14 ? -x : -z1 ));

          hash = (p[BA+1]) & 15;
          var g3 = ((hash&1) == 0 ? (hash<8 ? x1 : y ) : (hash<8 ? -x1 : -y )) + ((hash&2) == 0 ? hash<4 ? y  : ( hash==12 ? x1 : z1 ) : hash<4 ? -y  : ( hash==14 ? -x1 : -z1 ));

          hash = (p[AA+1]) & 15;
          var g4 = ((hash&1) == 0 ? (hash<8 ? x  : y ) : (hash<8 ? -x  : -y )) + ((hash&2) == 0 ? hash<4 ? y  : ( hash==12 ? x  : z1 ) : hash<4 ? -y  : ( hash==14 ? -x  : -z1 ));

          hash = (p[BB]) & 15;
          var g5 = ((hash&1) == 0 ? (hash<8 ? x1 : y1) : (hash<8 ? -x1 : -y1)) + ((hash&2) == 0 ? hash<4 ? y1 : ( hash==12 ? x1 : z  ) : hash<4 ? -y1 : ( hash==14 ? -x1 : -z  ));

          hash = (p[AB]) & 15;
          var g6 = ((hash&1) == 0 ? (hash<8 ? x  : y1) : (hash<8 ? -x  : -y1)) + ((hash&2) == 0 ? hash<4 ? y1 : ( hash==12 ? x  : z  ) : hash<4 ? -y1 : ( hash==14 ? -x  : -z  ));

          hash = (p[BA]) & 15;
          var g7 = ((hash&1) == 0 ? (hash<8 ? x1 : y ) : (hash<8 ? -x1 : -y )) + ((hash&2) == 0 ? hash<4 ? y  : ( hash==12 ? x1 : z  ) : hash<4 ? -y  : ( hash==14 ? -x1 : -z  ));

          hash = (p[AA]) & 15;
          var g8 = ((hash&1) == 0 ? (hash<8 ? x  : y ) : (hash<8 ? -x  : -y )) + ((hash&2) == 0 ? hash<4 ? y  : ( hash==12 ? x  : z  ) : hash<4 ? -y  : ( hash==14 ? -x  : -z  ));

          g2 += u * (g1 - g2);
          g4 += u * (g3 - g4);
          g6 += u * (g5 - g6);
          g8 += u * (g7 - g8);

          g4 += v * (g2 - g4);
          g8 += v * (g6 - g8);

          s += ( g8 + w * (g4 - g8)) * fPers;
        }

        var color = Std.int( ( s * fPersMax + 1 ) * 128 );

        bitmap.setPixel32( px, py, 0xff000000 | color << 16 | color << 8 | color );

        _x += baseFactor;
      }

      _y += baseFactor;
    }
  }

  function octFreqPers( fPersistence ) {

    var fFreq:Float, fPers:Float;

    aOctFreq = [];
    aOctPers = [];
    fPersMax = 0;

    for ( i in 0...octaves ) {
      fFreq = Math.pow(2,i);
      fPers = Math.pow(fPersistence,i);
      fPersMax += fPers;
      aOctFreq.push( fFreq );
      aOctPers.push( fPers );
    }

    fPersMax = 1 / fPersMax;
  }

  function seedOffset( iSeed : Int ) {
    iXoffset = iSeed = Std.int((iSeed * 16807.) % 2147483647);
    iYoffset = iSeed = Std.int((iSeed * 16807.) % 2147483647);
    iZoffset = iSeed = Std.int((iSeed * 16807.) % 2147483647);
  }
}

Strands™ Summer 2008 haXe Project Announcement

Posted on 2008-04-29 by Franco Ponticelli in General

We are pleased to announce that Strands.com, a provider of social recommendation technologies, is hosting a student open source coding summer project, focused solely on haXe.

You can find more information on the project and how to participate on this announcement page: http://labs.strands.com/Summer2008HaxeProject/

This project has very similar funding and terms to the 'other' open source summer coding project that you may be aware of. However, it is designed solely for current students in the haXe community.

Strands.com will provide funding for not more than 3 students, for not more than 2 projects. To see a list of suggested projects, please see the announcement page. We will prioritize the listed projects as well as those that get the most student interest.

Currently, the project involves myself (a PhD candidate at the Indiana University School of Informatics), and Franco Ponticelli, notable haXe community member and co-author of the recent book on haXe. We look forward to making this summer the "Summer of haXe"!

If you have any questions about the project, please use this mailing list.

Best,

- Justin and Franco

Physaxe : haXe Physics Engine

Posted on 2008-04-06 by Nicolas Cannasse in General

I'm please to announce the 1.0 Release of Physaxe : a haXe 2D Rigid Body Physics Engine heavily optimized for Flash Player 9.

A demo is always better than words, so you can play the following SWF, use 1-8 keys to change the demo and click to fire a block :

(if you want to check the real CPU spent by physaxe, you can press the 'D' key to disable drawing, which takes most of the CPU)

See the Physaxe project page for more informations.

Enjoy !

Nicolas

Calendar

July 2009
Mo Tu We Th Fr Sa Su
<< >>
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

Misc

 
Haxe Powered Rss flux Valid XHTML 1.0 Valid CSS