<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Zaki.Asia &#187; Tech</title>
	<atom:link href="http://zaki.asia/category/tech/feed/" rel="self" type="application/rss+xml" />
	<link>http://zaki.asia</link>
	<description>Virtual Worlds - Real Experience</description>
	<lastBuildDate>Fri, 16 Jul 2010 05:29:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
			<item>
		<title>Referrer spam in statpress</title>
		<link>http://zaki.asia/2010/07/14/referrer-spam-in-statpress/</link>
		<comments>http://zaki.asia/2010/07/14/referrer-spam-in-statpress/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 07:50:40 +0000</pubDate>
		<dc:creator>Zaki</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[referrer spam]]></category>
		<category><![CDATA[statpress]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://zaki.asia/?p=339</guid>
		<description><![CDATA[Today I got really fed up with statpress referrer spam, so I decided to implement a dead simple referrer check function into statpress. The function works very similar to the current IP banning, so it wasn&#8217;t very difficult to get it to work. If I get angry again, I might create a new statpress Option/Page ...]]></description>
			<content:encoded><![CDATA[<p>Today I got really fed up with statpress referrer spam, so I decided to implement a dead simple referrer check function into statpress. The function works very similar to the current IP banning, so it wasn&#8217;t very difficult to get it to work. If I get angry again, I might create a new statpress Option/Page to make the word banning easier or even make it non-destructive by only marking the referrer as spam. Of course other than the proactive banning, one might want to sanitize the referrrers in the statpress table as well. For me, I just cleared all the referrers with bad words in them, but didn&#8217;t bother to entirely remove the entries as I wanted to keep count of the actual access count.</p>
<p>Here are my simple changes to statpress.php:</p>
<pre class="brush: php;">
// A function to check whether a referrer should be
// omitted due to a manual ban
// To add/remove referrer bans, edit
// wp-content/plugins/statpress/def/banreferrers.dat
function iriCheckBanReferrer($arg)
{
    $lines = file(ABSPATH.'wp-content/plugins/'.
                  dirname(plugin_basename(__FILE__)).
                  '/def/banreferrers.dat');
    foreach($lines as $line_num =&gt; $banref)
    {
        if(strpos($arg,rtrim($banref,&quot;\n&quot;))===FALSE) continue;
        return true; // banned
    }
    return false;
}

// In function iriStatAppend()
$referrer = (isset($_SERVER['HTTP_REFERER']) ?
             htmlentities($_SERVER['HTTP_REFERER']) :
             '');
// BANNED REFERRERS
if (iriCheckBanReferrer($referrer)) $referrer = '';
// END BANNED REFERRERS
</pre>
<p>Then all I needed to do is create a banreferrers.dat file in the plugins/statpress/def directory containing one bad word/domain per line and now hopefully a lot less referrer spam will appear in the statpress overview. For now this will suffice for me.</p>
]]></content:encoded>
			<wfw:commentRss>http://zaki.asia/2010/07/14/referrer-spam-in-statpress/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>F# Discriminated Unions</title>
		<link>http://zaki.asia/2010/07/06/f-discriminated-unions/</link>
		<comments>http://zaki.asia/2010/07/06/f-discriminated-unions/#comments</comments>
		<pubDate>Mon, 05 Jul 2010 15:50:53 +0000</pubDate>
		<dc:creator>Zaki</dc:creator>
				<category><![CDATA[F#]]></category>
		<category><![CDATA[f#]]></category>

		<guid isPermaLink="false">http://zaki.asia/?p=307</guid>
		<description><![CDATA[This is another in a series of posts about my experiences and experiments learning F#. This time I start to look into more involved functional programming elements, starting with discriminated unions and how they are implemented internally. Compared to previous posts, this one will also start to show just how much of the heavy lifting the compiler does for us (which is what in my opinion "more abstract" means: how much of the code is autogenerated and how much of the programming process consists of driving a semi-automatic code generator)]]></description>
			<content:encoded><![CDATA[<p>In F# discriminated unions are providing a base for the powerful pattern matching. Let&#8217;s examine what happens behind the scene when someone enters the following innocent-looking code:</p>
<pre class="brush: fsharp;">
type Test =
  | Option1 of float
  | Option2 of int
</pre>
<p>If we take the generated assembly apart, this simple code generates a relatively large amount of code. First of all, a class (type) named <em>Test </em>is going to be created. What is more surprising is that five nested classes will also be defined. Of this five, two seems to be crucial as we&#8217;ll see while the others seem to be more about administration.</p>
<p>Talking about administration, the resulting type implements a fair amount of interfaces automatically.</p>
<p><em>IEquatable </em>adds three <em>Equals </em>methods: one with the <em>Test </em>type, but also two with object type (one of which allows a second <em>IEqualityComparer </em>parameter). Similarly <em>IComparable </em>and <em>IComparable&lt;Test&gt;</em> are implemented. In addition <em>IStructuralEquatable</em> and <em>IStructuralComparable </em>are also implemented. I won&#8217;t talk about these methods.</p>
<p>What is more important is that one nested class that is inherited from <em>Test </em>will be created for each option, named <em>Option1 </em>and <em>Option2</em>. Both of these classes will contain a property named <em>Item </em>and not surprisingly Item will be <em>float64 </em>in <em>Option1 </em>and <em>int32 </em>in <em>Option2</em>.</p>
<p><em>Test </em>will also contain two more boolean properties: <em>IsOption1 </em>and <em>IsOption2 </em>which return whether this refers to an instance of the respective type.</p>
<p>Finally <em>Test </em>provides two factory constructors named <em>NewOption1 </em>and <em>NewOption2 </em>which create either of the nested option instances. Its constructor in fact is not public (and doesn&#8217;t do anything except create the useless parent <em>Test </em>instance).</p>
<p>An implementation in C# therefore (removing much of the automatically generated interface implementations and helper methods) would look like this. The generated IL is very similar to that of the original F# code.</p>
<pre class="brush: csharp;">
public class Test
{
    public class Option1 : Test
    {
        public Option1(double v) { item = v; }
        readonly double item;
        double Item { get { return item; } }
    }

    public class Option2 : Test
    {
        public Option2(int v) { item = v; }
        readonly int item;
        int Item { get { return item; } }
    }

    public sealed class Tags
    {
        public const int Option1 = 0;
        public const int Option2 = 1;
    }

    Test() {}

    public static Test NewObject1(float v) { return new Option1(v); }
    public static Test NewObject2(int v) { return new Option2(v); }

    public bool IsOption1 { get { return (this is Option1); } }
    public bool IsOption2 { get { return (this is Option2); } }
    public int Tag {
        get { return ((this is Option1) ? Tags::Option1 : Tags::Option2); }
    }
}
</pre>
<p>There are two further nested classes named <em>Option1@DebugTypeProxy</em> and <em>Option2@DebugTypeProxy</em>, but I&#8217;m not really sure what their functionality is. Also, there is that <em>Tags </em>nested class with its const definitions and the <em>Tag </em>property in <em>Test </em>whose role is also not completely clear from this IL code. It can be related to enums or maybe to do with performance</p>
<p>After comparing the two implementations, it is very easy to appreciate how &#8211; in probably Don Syme&#8217;s favorite word &#8211; succinct F# really is (and that&#8217;s even before diving into heavyweight functional programming.</p>
]]></content:encoded>
			<wfw:commentRss>http://zaki.asia/2010/07/06/f-discriminated-unions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>F# Currying</title>
		<link>http://zaki.asia/2010/06/30/f-currying/</link>
		<comments>http://zaki.asia/2010/06/30/f-currying/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 13:00:32 +0000</pubDate>
		<dc:creator>Zaki</dc:creator>
				<category><![CDATA[F#]]></category>
		<category><![CDATA[f#]]></category>

		<guid isPermaLink="false">http://zaki.asia/?p=258</guid>
		<description><![CDATA[In this post I'm looking into how partial function application (or currying) works behind the scenes in F#.]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s look at how currying works behind the scenes. It is not very surprising that this code</p>
<pre class="brush: fsharp;">
let adder x y = x + y
let partial x = adder 2 + y
</pre>
<p>is compiled to</p>
<pre class="brush: il;">

.method public static int32  adder(int32 x, int32 y) cil managed
{
 .custom instance void \
      Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) \
      = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 )
 // Code size       5 (0x5)
 .maxstack  4
 IL_0000:  nop
 IL_0001:  ldarg.0
 IL_0002:  ldarg.1
 IL_0003:  add
 IL_0004:  ret
} // end of method Program::adder

.method public static int32  partial(int32 x) cil managed
{
 // Code size       9 (0x9)
 .maxstack  4
 IL_0000:  nop
 IL_0001:  ldc.i4.2
 IL_0002:  ldarg.0
 IL_0003:  call       int32 Program::adder(int32,int32)
 IL_0008:  ret
} // end of method Program::partial
</pre>
<p>which comes down to the following common C# code</p>
<pre class="brush: csharp;">

public class Test
 {
    public static int adder(int x, int y) { return (x + y); }
    public static int partial(int x) { return (adder(x, 2)); }
 }
</pre>
<p>and it does generate a similar IL code:</p>
<pre class="brush: il;">

.method public hidebysig static int32  adder(int32 x,int32 y) cil managed
{
 // Code size       9 (0x9)
 .maxstack  2
 .locals init ([0] int32 CS$1$0000)
 IL_0000:  nop
 IL_0001:  ldarg.0
 IL_0002:  ldarg.1
 IL_0003:  add
 IL_0004:  stloc.0
 IL_0005:  br.s       IL_0007
 IL_0007:  ldloc.0
 IL_0008:  ret
} // end of method Test::adder
.method public hidebysig static int32  partial(int32 x) cil managed
{
 // Code size       13 (0xd)
 .maxstack  2
 .locals init ([0] int32 CS$1$0000)
 IL_0000:  nop
 IL_0001:  ldarg.0
 IL_0002:  ldc.i4.2
 IL_0003:  call       int32 CSharpTest.Test::adder(int32,int32)
 IL_0008:  stloc.0
 IL_0009:  br.s       IL_000b
 IL_000b:  ldloc.0
 IL_000c:  ret
} // end of method Test::partial
</pre>
]]></content:encoded>
			<wfw:commentRss>http://zaki.asia/2010/06/30/f-currying/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>F# Swap</title>
		<link>http://zaki.asia/2010/06/30/f-sharp-swap/</link>
		<comments>http://zaki.asia/2010/06/30/f-sharp-swap/#comments</comments>
		<pubDate>Tue, 29 Jun 2010 17:20:46 +0000</pubDate>
		<dc:creator>Zaki</dc:creator>
				<category><![CDATA[F#]]></category>
		<category><![CDATA[f#]]></category>

		<guid isPermaLink="false">http://zaki.asia/?p=217</guid>
		<description><![CDATA[Reading about functional programming, I got curious the other day: one of the canonical examples is swapping the elements in a tuple but what exactly happens internally? After all, whatever language is used, eventually it will be translated to native code. F# is very easy to work with in this sense, because it will be ...]]></description>
			<content:encoded><![CDATA[<p>Reading about functional programming, I got curious the other day: one of the canonical examples is swapping the elements in a tuple but what exactly happens internally? After all, whatever language is used, eventually it will be translated to native code.</p>
<p>F# is very easy to work with in this sense, because it will be compiled to IL first, so if I only run ILdasm on it, an equivalent C# code could be created.</p>
<pre class="brush: fsharp;">let a(x,y) = (y,x)</pre>
<p>This innocent short code will generate the following IL code</p>
<pre class="brush: il;">
.method public static class \
        System.Tuple`2&lt;!!b,!!a&gt; a&lt;a,b&gt;(!!a x,!!b y) cil managed
{
 // Code size       9 (0x9)
 .maxstack  4
 IL_0000: nop
 IL_0001: ldarg.1
 IL_0002: ldarg.0
 IL_0003: newobj instance void class System.Tuple`2&lt;!!b,!!a&gt;::.ctor(!0, !1)
 IL_0008: ret
}
</pre>
<p>Aha! So we are not fiddling around with temporary variables (which wouldn&#8217;t work anyway because variables are immutable by default in F#), instead the simplest of things happens here: a new variable is constructed with the parameters swapped and then returned.</p>
<p>In C#, Swap could be written along these lines</p>
<pre class="brush: csharp;">
public static Tuple&lt;T2, T1&gt; Swap&lt;T1, T2&gt;(T1 a0, T2 a1)
{
    return (new Tuple&lt;T2, T1&gt;(a1, a0));
}
</pre>
<p>In fact the C# code generates an almost identical IL code (although honestly I&#8217;m not sure what the final branch is supposed to be, as it doesn&#8217;t do anything apparently useful)</p>
<pre class="brush: il;">
.method public hidebysig static class System.Tuple`2&lt;!!T2,!!T1&gt;  \
        Swap&lt;T1,T2&gt;(!!T1 a0, !!T2 a1) cil managed
{
  // Code size       13 (0xd)
  .maxstack  3
  .locals init ([0] class System.Tuple`2&lt;!!T2,!!T1&gt; CS$1$0000)
  IL_0000:  nop
  IL_0001:  ldarg.1
  IL_0002:  ldarg.0
  IL_0003:  newobj instance void class System.Tuple`2&lt;!!T2,!!T1&gt;::.ctor(!0, !1)
  IL_0008:  stloc.0
  IL_0009:  br.s IL_000b
  IL_000b:  ldloc.0
  IL_000c:  ret
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://zaki.asia/2010/06/30/f-sharp-swap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OSGrid in Rei</title>
		<link>http://zaki.asia/2009/12/21/osgrid-in-rei/</link>
		<comments>http://zaki.asia/2009/12/21/osgrid-in-rei/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 10:26:02 +0000</pubDate>
		<dc:creator>Zaki</dc:creator>
				<category><![CDATA[OpenSim]]></category>
		<category><![CDATA[3Di]]></category>
		<category><![CDATA[Rei]]></category>

		<guid isPermaLink="false">http://zaki.asia/?p=163</guid>
		<description><![CDATA[A look at 3Di Viewer "Rei" logging in to two of OSGrid's most popular regions: Lbsa Plaza and Wright Plaza.]]></description>
			<content:encoded><![CDATA[<h3>Textures</h3>
<p>Before Rei was released at the end of September, it was called 3Di OpenViewer. As it stands, that viewer didn&#8217;t need to download textures through the region server, rather, it would download assets (textures, meshes, avatars) directly from an asset server. For this reason, when someone logged in to an upstream OpenSim grid with 3Di OpenViewer, textures and avatars would not appear.</p>
<p>But that changed when we released Rei as an open-source viewer at the end of September. At that time, textures were already being fetched from OpenSim. You can go ahead and grab the installer from github and it will display textures. What it won&#8217;t do with textures is correctly apply UV coordinates in some (fortunately very rare) twisted-hollow-prim cases (but it was more about PrimMesher than Rei). Since September, we have done many improvements to PrimMesher &#8211; and Rei too, so now even those rare cases appear correctly (big thanks to the bug reporters). Texture downloads are slow unfortunately, but more on that later.</p>
<h3>Avatars</h3>
<p>Now this is a very delicate issue. The heart of the issue is that currently there is no non-LL viewer that supports SecondLife(tm) avatars. Let me say that again: there are no viewers that support SL(tm) avatars. Naali has a built-in mesh (the same as the old viewer), IdealistViewer has a built-in mesh, LookingGlass doesn&#8217;t yet have avatars (correct me if it does), Xenki doesn&#8217;t have an avatar yet as far as I know either.</p>
<p>The closest a viewer gets to SL avatar support is the PandaViewer by dahlia (<a href="http://vimeo.com/6812213" target="_blank">http://vimeo.com/6812213</a>) , which supports avatar shapes and actually looks really nice. Unfortunately it&#8217;s not open source (yet?), nor is it available in any form.</p>
<p>The thing with avatar support is that it&#8217;s pretty difficult to do right. No, not only technically, but there&#8217;s the issue of using or not using Linden Labs(tm)&#8217;s original mesh. You can find <a href="http://secondlife.com/community/avatar.php" target="_blank">downloadable meshes</a>, but there is a nice warning hidden neatly inside an obj file:</p>
<blockquote><p># This model is released for use by residents of Second Life.<br />
# It may be imported into external 3D modeling, texturing, and animation applications to aid in the creation of character animations and textures for Second Life, as well as for any non-commercial purpose.<br />
# Use or modification of this model for any other commercial purpose is prohibited without the express written consent of Linden Lab.</p></blockquote>
<p>With all this said, we are looking at SL(tm) avatar support. It definitely won&#8217;t happen before the end of this year, the target is early next year.</p>
<h3>OpenSim support</h3>
<p>Of course Rei still has issues with upstream OpenSim support. This is partially due to the very very bad way textures are downloaded (through a single server, in UDP). The truth is, even SL(tm) viewer chokes on those: in heavy regions it would download the low resolution image, but the full image is never actually downloaded. My personal opinion is that the sooner we can break free from that way of transferring assets to clients, the better (guess how 3Di OpenViewer delivers content). Hopefully OpenSim will not remain an SL(tm) clone and there will be lots of innovations in the virtual world space coming from OpenSim. Rei is supposed to show what is possible when we can control both the viewer and the server side without the fear of not being able to work on one or the other for six months.</p>
<h3>The current state</h3>
<p>Below are two videos of Rei logging in to OSGrid&#8217;s Lbsa Plaza and Wright Plaza.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="640" height="505" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/cgNL4-oMLOc&amp;hl=en_US&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="640" height="505" src="http://www.youtube.com/v/cgNL4-oMLOc&amp;hl=en_US&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="640" height="505" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/FBbR4txM9M4&amp;hl=en_US&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="640" height="505" src="http://www.youtube.com/v/FBbR4txM9M4&amp;hl=en_US&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>So, what do you think of the viewer so far? What sort of improvements do you think would be nice? What do you think is missing, other than the avatar support?</p>
<p>In general, what are the things you absolutely expect from a virtual world viewer?</p>
<p>Let me know in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://zaki.asia/2009/12/21/osgrid-in-rei/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Wii Controller Plugin for 3Di Viewer &#8220;Rei&#8221;</title>
		<link>http://zaki.asia/2009/11/20/wii-controller-plugin-for-3di-rei/</link>
		<comments>http://zaki.asia/2009/11/20/wii-controller-plugin-for-3di-rei/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 08:56:53 +0000</pubDate>
		<dc:creator>Zaki</dc:creator>
				<category><![CDATA[OpenSim]]></category>
		<category><![CDATA[3Di]]></category>
		<category><![CDATA[Rei]]></category>

		<guid isPermaLink="false">http://zaki.asia/?p=157</guid>
		<description><![CDATA[With 3Di Viewer "Rei" it is possible to extend the core viewer with new functionality using plugins. This post introduces a plugin that lets you use a Wiimote to control your avatar in the virtual world. Right in the browser.]]></description>
			<content:encoded><![CDATA[<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="640" height="505" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/g_xum05b6xQ&amp;hl=en_US&amp;fs=1&amp;hd=1" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="640" height="505" src="http://www.youtube.com/v/g_xum05b6xQ&amp;hl=en_US&amp;fs=1&amp;hd=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<h3>Wii Controller Plugin</h3>
<p>3Di Viewer &#8220;Rei&#8221; provides a great flexibility when it comes to adding custom functionality to the core viewer by making it possible to create binary plugins. Just drop these binaries into the Rei folder and let the viewer find and load it automatically the next time it starts. While these plugins are still in their early phase &#8211; we can do a lot more to ease the process of deploying plugins and resolving their dependencies &#8211; you can get a glimpse at their power already.</p>
<p>The WiiControllerPlugin is a fun project, a proof-of-concept, rather than a commercial solution, so before you dive in, be warned, that it is sometimes rough around the edges. With that out of the way, if you have Rei, head over to http://github.com/zaki/ReiWiiControllerPlugin and grab the binary from the Download section. Just copy the contents into the Rei installation folder (usually C:\Program Files\3Di\Rei). And&#8230; that&#8217;s basically it.</p>
<h3>How to connect the controller?</h3>
<p>To use a Wiimote, you will need a Wiimote, a nunchuck and a bluetooth adapter. I&#8217;ve heard that Toshiba adapters works best, but I have used Broadcomm&#8217;s chips successfully as well. It is said that the Microsoft stack doesn&#8217;t work most of the time with the Wiimote.</p>
<p>Before you start the viewer, connect/pair the Wiimote via bluetooth. If you find it difficult to connect, I found that keeping (1) and (2) pressed simultaneously while connecting helps a lot.</p>
<p>Once the Wiimote is connected, start Rei and if everything goes well, the primary Wiimote will have its first LED turned on. You are now ready.</p>
<h3>How to use the Wiimote?</h3>
<p>The WiiControllerPlugin allows you to use the Wiimote and the nunchuck to control your avatar and the camera. The nunchuck&#8217;s joystick, or the directional controller on the wiimote can be used to make you avatar walk. Up will always make your avatar walk forward, regardless of the position of the camera.</p>
<p>The camera is controlled with a combination of the wiimote and the nunchuck. Zoom in and out by holding down (Z) and tilting the nunchuck forward and backward. Hold the wiimote straight up; while you press (B), you can tilt the wiimote in four directions to rotate the camera around your avatar. Remember, you don&#8217;t have to look away from the screen to change the camera angle.</p>
<p>If you get lost with the camera, you can always press (C) to go back to behind your avatar. Pressing (C) also switches to &#8220;follow&#8221; mode, so your camera will &#8220;stick&#8221; to  your avatar and will follow it from behind if you move. Pressing (C) another time will switch back to the free camera mode.</p>
<p>If you get tired of moving with the wiimote and want to switch back to using the keyboard or mouse, you can disable avatar movements by pressing (-). Your wiimote&#8217;s will light the third LED when it&#8217;s disabled. Press (-) again to enable moving by the wii controller.</p>
<h3>About the demo</h3>
<p>The video above contains a very dull maze, in which there are colored balls that hurt or heal you when you touch them (I&#8217;ve never said I was a great contents designer, have I <img src='http://zaki.asia/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ) The demo shows how easy it is to integrate custom features with an unmodified OpenSim grid. All that was used is simple LSL script that detects collisions and gives commands via llSay. These commands can be intercepted by javascript and further dispatched to all plugins, that can act accordingly. In this case a simple health bar is adjusted.</p>
<p>As my LSL was sending plaintext commands like &#8220;heal,20&#8243;, the necessary javascript looks really simple:</p>
<pre class="brush: jscript;">
function DispatchCommand(message)
{
	var strList = new Array();
	strList = message.split(&quot;,&quot;);

	if (strList.length == 2)
	{
		ctrl.Callback(strList[0], strList[1]);
	}
}
</pre>
<p>If you have a question, or have a good idea about plugins, or the WiiControllerPlugin, please share it in the comments.</p>
<hr /><span>Please note: WiiControllerPlugin is not endorsed by Nintendo. WiiControllerPlugin depends on  WiiMoteLib, which is release under the license MS-PL. For more details, see <a title="WiiMoteLib@CodePlex" href="http://wiimotelib.codeplex.com/" target="_blank">http://wiimotelib.codeplex.com/</a></span></p>
]]></content:encoded>
			<wfw:commentRss>http://zaki.asia/2009/11/20/wii-controller-plugin-for-3di-rei/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Plugins for Rei</title>
		<link>http://zaki.asia/2009/11/11/plugins-for-rei/</link>
		<comments>http://zaki.asia/2009/11/11/plugins-for-rei/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 09:09:23 +0000</pubDate>
		<dc:creator>Zaki</dc:creator>
				<category><![CDATA[OpenSim]]></category>
		<category><![CDATA[3Di]]></category>
		<category><![CDATA[Rei]]></category>

		<guid isPermaLink="false">http://zaki.asia/?p=140</guid>
		<description><![CDATA[A look at the new plugin system for 3Di Viewer "Rei" that allows developers to introduce new viewer functionality without changing the viewer's source code.]]></description>
			<content:encoded><![CDATA[<p><!--:en--></p>
<h2>Plugins</h2>
<p>In “Rei”, there is a curious little green “health” bar above the avatar’s head. That bar is not something that is built in to the viewer, rather, a simple plugin provides the functions that are necessary to have a very rudimentary health bar. Of course this TestPlugin is only to show what sort of things are possible with “Rei”.</p>
<p><a href="http://zaki.asia/images/TestPlugin.jpg"><img title="TestPlugin" src="http://zaki.asia/images/TestPlugin.jpg" alt="" height="150" /></a><a href="http://zaki.asia/images/TestPlugin_Damage.jpg"><img class=" alignnone" title="TestPlugin - Damage" src="http://zaki.asia/images/TestPlugin_Damage.jpg" alt="" height="150" /></a><a href="http://zaki.asia/images/TestPlugin_Heal.jpg"><img class=" alignnone" title="TestPlugin - Heal" src="http://zaki.asia/images/TestPlugin_Heal.jpg" alt="" height="150" /></a><a href="http://zaki.asia/images/TestPlugin_Dead.jpg"><img class=" alignnone" title="TestPlugin - Dead" src="http://zaki.asia/images/TestPlugin_Dead.jpg" alt="" height="150" /></a></p>
<h3><a href="http://zaki.asia/images/TestPlugin_JS.jpg"><img class="aligncenter" title="Javascript" src="http://zaki.asia/images/TestPlugin_JS.jpg" alt="" width="485" height="114" /></a></h3>
<h2>What do plugins do?</h2>
<p>Plugins are intended for two main purposes. First, to communicate &#8211; through javascript &#8211; with the 2D web, and second, to interact with objects within the 3d scene. Of course a plugin is a .NET assembly, so it can pretty much do anything, but the main functions it is intended for are the above two. For instance TestPlugin provides two javascript functions: one to inflict damage and one to heal, basically allowing a regular 2d web application, for instance an SNS site or an online game, to change the health meter of the avatar within the 3d world according its own rules. Responding to these javascript functions then, the plugin interacts with the 3d world by rendering its own little health bar above the user’s head.</p>
<h2>How to write plugins?</h2>
<p>To make things as simple as possible, “Rei” uses the same method for developing plugins as OpenSim. Essentially one writes an addin for the <em>/OpenViewer/Managers</em> extension by implementing the IManagerPlugin interface and then creating and embedding a plugin manifest to the assembly.</p>
<h3>IManagerPlugin</h3>
<p>All plugins need to implement IManagerPlugin, which means implementing a few methods:</p>
<pre class="brush: plain;">void Initialise(Viewer viewer);</pre>
<p>-<strong> Initialise </strong>is the method that will be called right after constructing the plugin class. This will be only called once for the life of the plugin and is used to create objects that will persist through the entire lifetime such as static resources (textures, models), configurations.</p>
<pre class="brush: plain;">void Initialize();</pre>
<p>- <strong>Initialize</strong> (note the <strong>z</strong> in the name) will be called when “Rei” is getting ready to enter a region. This happens on the first startup as well as after logout or before entering a new region after a teleport. This is to make sure that unnecessary scene objects do not make it over to a new environment, therefore Initialize would create objects that persist only through the lifetime of one region, such as dynamic resources (textures, meshes) or dynamic information (region data, prim data)</p>
<pre class="brush: plain;">void Update(uint frame);</pre>
<p>-<strong> Update</strong> is called every frame. This is the place to calculate the next state of the plugin, including objects in the 3d scene. This is the only place where it is allowed to change properties of any object that is within the scenegraph. By using the frame parameter, it is possible to count or skip frames.</p>
<pre class="brush: plain;">void Draw();</pre>
<p>- <strong>Draw</strong> is also called every frame and it is where drawing directly to the 3d canvas is possible. Generally it is recommended to use proper scenenodes that draw automatically, instead of drawing directly.</p>
<pre class="brush: plain;">void Cleanup();</pre>
<p>- Just like Initialize is called before “Rei” is ready to log in to a new region, <strong>Cleanup</strong> is called every time a region is no longer needed, such as when logging out or when leaving a region by teleport. Cleanup is responsible of releasing resources that were allocated by Initialize (but not Initialise!)</p>
<pre class="brush: plain;">RefController Reference { get; set; }</pre>
<p>- This property is the entry point to &#8220;Rei&#8221;s core. Through this object it is possible to call into the public api of the viewer or to access javascript. <strong>Reference</strong> must always be initialized from the viewer parameter passed in to Initialise()</p>
<h3>Communication with Javascript</h3>
<h5>Plugin to Javascript: Dispatch</h5>
<p>A plugin can call Reference.Viewer.Adapter.Dispatch(string action, string message) when it wants to send a message to javascript. If a handler was added to the javascript library for the particular action, this dispatch will be processed by passing the message to the handler function. For future compatibility it is recommended although not required that the message be passed in json format.</p>
<h5>Javascript to Plugin: Callback</h5>
<p>The Adapter supplies a Callback delegate and a registry to handle calls from Javascript. A plugin can register a callback method that it is interested in receiving by calling</p>
<pre class="brush: plain;">Reference.Viewer.Adapter.RegisterCallback</pre>
<p>. It must pass the name of the method it wants to listen to and the method to call when the event arrives. The way a Callback works is very much like delegates work in the .NET framework.</p>
<p>From the javascript side, one can use</p>
<pre class="brush: plain;">ctrl.Callback(&quot;method&quot;, parameters)</pre>
<p>and all plugins that are listening to “method” will receive a callback to their registered functions. For an example of Callbacks, you can see the DoDamage and DoHeal from test.js and TestPlugin.cs</p>
<h5>Plugin to Plugin: Message</h5>
<p>It is also possible to send messages from one plugin to another, even without being aware of the other plugin. The mechanism is very similar to Callbacks: a plugin registers a message handler by calling</p>
<pre class="brush: plain;">Reference.Viewer.Adapter.RegisterMessage</pre>
<p>. The first parameter must be the name of the message to listen to and the second one is a message handler delegate.</p>
<p>A plugin can then raise a Message by calling</p>
<pre class="brush: plain;">Rerence.Viewer.Adapter.SendMessage(&quot;message&quot;, parameters)</pre>
<p>and all plugins that subscribed to the message being sent will receive it.</p>
<hr />A draft of this post also appears on the github wiki for 3Di Viewer &#8220;Rei&#8221;. For more up-to-date information, refer to <a title="Rei Plugin Development" href="http://wiki.github.com/3di/3di-viewer-rei/plugin-development" target="_blank">this page</a>.</p>
<p><!--:--></p>
]]></content:encoded>
			<wfw:commentRss>http://zaki.asia/2009/11/11/plugins-for-rei/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Irrlicht.NETCP and 3Di Rei on Linux</title>
		<link>http://zaki.asia/2009/11/05/irrlicht-netcp-rei-on-linux/</link>
		<comments>http://zaki.asia/2009/11/05/irrlicht-netcp-rei-on-linux/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 03:49:06 +0000</pubDate>
		<dc:creator>Zaki</dc:creator>
				<category><![CDATA[OpenSim]]></category>
		<category><![CDATA[Irrlicht]]></category>
		<category><![CDATA[Rei]]></category>

		<guid isPermaLink="false">http://zaki.asia/?p=116</guid>
		<description><![CDATA[[update] I have started a cleaner code line which is now rebased to Irrlicht 1.7.1. Find the codes on [line] Irrlicht.NETCP I&#8217;ve spent the last couple of weeks working towards rebasing the now abandoned Irrlicht.NETCP to use the latest Irrlicht released: 1.6. There are multiple reasons to do so, probably the most straightforward is to ...]]></description>
			<content:encoded><![CDATA[<p>[update] I have started a cleaner code line which is now rebased to Irrlicht 1.7.1. Find the codes on</p>
<a class="button_link" href="#"><span>Github: Irrlicht.NET</span></a>
<p>[line]</p>
<h3>Irrlicht.NETCP</h3>
<p>I&#8217;ve spent the last couple of weeks working towards rebasing the now abandoned Irrlicht.NETCP to use the latest Irrlicht released: 1.6. There are multiple reasons to do so, probably the most straightforward is to get the bugfixes or some of the new features, like the new light manager. However the less direct reason to do the rebase is that it includes Mac support out of the box &#8211; and now that I have a macbook sitting on my desk at work (albeit, temporarily), that is something of very high interest for me. In my dreamland, OpenGL ES support (for the iPhone) would work without much work too &#8211; hey, I can dream, can&#8217;t I.</p>
<p>So, for this rebase, I&#8217;ve started a new repo on github, that I hope will soon become the official repository for 3Di Viewer &#8220;Rei&#8221;, and maybe even for users of Irrlicht.NETCP (if any are still left, but who knows, maybe this can spark some new interest). The repository starts with a clean Irrlicht 1.6 SDK and gradually adds the fixes and features that are necessary for Rei (but of course those are fixes and features that would probably come up in other development as well).</p>
<p>On top of the improvements to Irrlicht, there is one huge patch, that makes the IrrlichtW wrapper compatible with 1.6. This mostly consists of type changes in the method interfaces and other minor details, but the patch itself is pretty monstrous, as many things changed at the same time. It is only after this collective patch, that the .NETCP library is usable again (it won&#8217;t even compile before this fix, so be careful with the history).</p>
<p>Later, IrrlichtML fixes were added. ML stands for multilingual and these changes are required even though things finally started  moving away from c8* to proper strings and io::paths in the core, stuff like IME support was not included and the unicode support is still horrible to say the least.</p>
<h3>Getting Irrlicht.NETCP</h3>
<p>If you want to give the new Irrlicht.NETCP libraries a try, head to github: <a title="Irrlicht.NETCP" href="http://github.com/zaki/irrlicht.netcp" target="_blank">http://github.com/zaki/irrlicht.netcp</a> and check out the sources (either using git, or click on download in github). For the impatient, I&#8217;ve also uploaded binary files for 32-bit windows (Release mode).</p>
<p>To compile the libraries yourself, you will have to compile three components: Irrlicht SDK, IrrlichtW and Irrlicht.NET, in basically this order. To compile Irrlicht SDK, go to Irrlicht SDK\source\Irrlicht and open Irrlicht9.0.sln in Visual Studio 2008 and build. IrrlichtW&#8217;s solution is found in IrrlichtW, named IrrlichtW.sln</p>
<p>Irrlicht.NET uses Prebuild to create its solution files, so before you can compile, the file runprebuild2008.bat needs to be run. That creates the solution file Irrlicht.NET.sln, that can be opened and built in VS.</p>
<h3>Rei and Irrlicht.NETCP</h3>
<p>To use the new binaries with &#8220;Rei&#8221;, some minor changes need to be made to Rei&#8217;s source. I committed these changes to my github repository: <a title="3Di Viewer &quot;Rei&quot;" href="http://github.com/zaki/3di-viewer-rei" target="_blank">http://github.com/zaki/3di-viewer-rei</a>, however the changes are not in the master branch, which I try to keep as a clean integration copy (therefore there is a little time delay). Get the Irrlicht 1.6 supporting sources from the &#8216;linux&#8217; branch.</p>
<h3>One more thing&#8230;</h3>
<p>Ahem&#8230; did I just say &#8216;linux&#8217; branch? Well, that&#8217;s probably because I&#8217;ve also started working on Rei linux support and so far things look quite bright (as opposed to the MacOSX support, but maybe later about that). I managed to make Rei run on my Ubuntu machine in standalone mode using Irrlicht.NETCP and mono. There are still a ton of things that need fixing, but it&#8217;s only a matter of time before a consistent framerate is achieved &#8211; I had driver issues and occasional performance problems, probably not unrelated. There are some problems with JPEG2000 support that I didn&#8217;t have time to look at yet and haven&#8217;t written shaders (OpenGL seems to hate HLSL shaders for some reason <img src='http://zaki.asia/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> , but everything in its own time.</p>
<p>So if you feel particularly adventurous, go ahead and grab the sources from the &#8216;linux&#8217; branch &#8211; Irrlicht.NETCP&#8217;s master branch now includes linux support -, compile them on your linux machine and do let me know how it works for you.</p>
<p style="text-align: center;"><a href="http://zaki.asia/images/3DiRei_onLinux.png"><img class="aligncenter" title="Rei on Linux" src="http://zaki.asia/images/3DiRei_onLinux.png" alt="" width="586" height="608" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://zaki.asia/2009/11/05/irrlicht-netcp-rei-on-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Intelligent evolution</title>
		<link>http://zaki.asia/2009/09/16/intelligent-evolution/</link>
		<comments>http://zaki.asia/2009/09/16/intelligent-evolution/#comments</comments>
		<pubDate>Tue, 15 Sep 2009 19:26:43 +0000</pubDate>
		<dc:creator>Zaki</dc:creator>
				<category><![CDATA[Fiction]]></category>

		<guid isPermaLink="false">http://zaki.asia/?p=106</guid>
		<description><![CDATA[The two publications appeared practically at the same time and they started an argument of epic proportions within the scientific community. Both scientists claimed nothing less than having solved the mystery of the origin of life &#8211; and not less important &#8211; of humankind. Two distinctly different, even contradicting theories, two proofs. Both of them ...]]></description>
			<content:encoded><![CDATA[<p>The two publications appeared practically at the same time and they started an argument of epic proportions within the scientific community. Both scientists claimed nothing less than having solved the mystery of the origin of life &#8211; and not less important &#8211; of humankind. Two distinctly different, even contradicting theories, two proofs. Both of them offering a complete solution: from the proposed axioms, both of them explained the diversity &#8211;  the development of the individual and the similarities between species not only those currently existing but even those long extinct.</p>
<p>Some questions did remain unanswered though. The two schools differed greatly on their views on the mass extinctions during which time whole families of species have disappeared leaving only a faint trace in the form of fossil evidence: a skeleton here and there or an object we could connect to ancient &#8211; primitive &#8211; species. The community was simply amazed when remains of a smaller colony from a couple of thousands of years ago was unearthed, but even that could not compare to what excitement spread through scientific journals when fossils of a long disappeared ancient species were found in a rare excavation. Scientists from both camps would throw themselves at the new samples, trying to fit the new pieces of the puzzle to their theories.</p>
<p>One group has claimed, that species evolved through a very coordinated, but seemingly random process from other &#8211; usually more primitive &#8211; species. Through time, organs that were more useful for survival have been &#8211; in a manner &#8211; selected. It&#8217;s as if there was an algorithm in nature that experiments with randomly changing the variables, keeping results that it deems good while terminating those it finds unworthy. This algorithm has been present for millions if not billions of years (some even went as far as proposing that the same process can be found before life itself appeared). There was however a strange gap between humans of the long gone past and humans of the present &#8211; as if only the right fossils that would bridge this gap were hiding  somewhere, waiting to be found one day.</p>
<p>Followers of this theory &#8211; called evolutions &#8211; found that pieces of evidence fit their theory perfectly. They argued, that evolution of the present humans from ancient human forms is completely possible, as the natural selection process would experiment practically randomly, therefore given enough time, ancestor  species could be significantly different from descendant species.<br />
The other group also proposed a complete explanation, however their theory immediately caused an uproar in the scientific community. They claimed that present form humans have not appeared through a lengthy process of evolution, rather, it was created through an intelligent design. Their theory proposed that present day humans were created by an ancient, intelligent entity, or even by the &#8211; in lack of a better word &#8211; consciousness of some ancient species.<br />
Many would instantly distance themselves from members of this second group and some even went as far as calling the professor that first published this  theory an idiot. As the arguments started to spiral out of hand, finally a well-known scientific association has organized a public forum for members of  these groups where they were given the chance to present their findings and evidence. In the heated debate, followers of the school of evolution would claim that intelligent design is unscientific, while proponents of intelligent design would argue on the improbability of random evolution. A noted professor of  the second group was quoted to say:</p>
<p>&#8220;I firmly believe that humans were created by in ancient intelligent designer. The probability of complex organs evolving at random is not in accordance with nature. The probability of a complex structure evolving randomly is provably smaller than the theoretically conceivable smallest probability in the Universe. It is laughable to assume that the organ we know as our brains have evolved at random from lesser life forms. I don&#8217;t think it is even theoretically possible  that the our alleged ancestors&#8217; primitive carbohydrate-based organs would spontaneously evolve into our immeasurably complex silicon chips.&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://zaki.asia/2009/09/16/intelligent-evolution/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slowly getting there&#8230;</title>
		<link>http://zaki.asia/2009/09/08/3di-openviewer-textures/</link>
		<comments>http://zaki.asia/2009/09/08/3di-openviewer-textures/#comments</comments>
		<pubDate>Mon, 07 Sep 2009 16:20:37 +0000</pubDate>
		<dc:creator>Zaki</dc:creator>
				<category><![CDATA[OpenSim]]></category>
		<category><![CDATA[3Di]]></category>
		<category><![CDATA[Rei]]></category>

		<guid isPermaLink="false">http://zaki.asia/?p=96</guid>
		<description><![CDATA[Pretty close, but still not close enough. I guess, I&#8217;ll need to take a deep, hard look at PrimMesher too.]]></description>
			<content:encoded><![CDATA[<p><!--:en--><a href="http://zaki.asia/images/osgrid_textures.jpg"><img title="3Di OpenViewer on OSGrid" src="/images/osgrid_textures.jpg" alt="3Di OpenViewer on OSGrid" width="100%" /></a></p>
<p><a href="http://zaki.asia/images/osgrid_hippo.jpg"><img title="Hippo Viewer on OSGrid" src="/images/osgrid_hippo.jpg" alt="Hippo Viewer on OSGrid" width="100%" /></a></p>
<p>Pretty close, but still not close enough. I guess, I&#8217;ll need to take a deep, hard look at PrimMesher too.<!--:--></p>
]]></content:encoded>
			<wfw:commentRss>http://zaki.asia/2009/09/08/3di-openviewer-textures/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
