<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-27518612</id><updated>2011-08-22T14:22:09.761+02:00</updated><category term='algorithmic'/><category term='gpu'/><category term='media'/><category term='agile'/><category term='ai'/><category term='sqa'/><category term='python'/><category term='news'/><category term='books'/><category term='security'/><category term='raytracing'/><category term='optimization'/><category term='fractals'/><category term='parallel'/><category term='design'/><category term='hlsl'/><category term='network'/><category term='code'/><category term='projects'/><category term='postmortem'/><category term='game'/><category term='c++'/><category term='comments'/><title type='text'>gyakoo blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default?start-index=101&amp;max-results=100'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>146</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-27518612.post-5021189852931607904</id><published>2010-09-30T18:15:00.004+02:00</published><updated>2010-09-30T19:00:01.015+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Posting on ...</title><content type='html'>Lastly I've been posting links, status and thoughts on twitter, buzz and linkedin. It's an experiment, to try keep posting more often.&lt;br /&gt;&lt;br /&gt;If you wish, you can follow me in twitter&lt;br /&gt;&lt;a href="http://twitter.com/gyakoo"&gt;http://twitter.com/gyakoo&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;google buzz&lt;br /&gt;&lt;a href="http://www.google.com/profiles/113671123506775220559#buzz"&gt;google profile&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;or linkedin&lt;br /&gt;&lt;a href="http://es.linkedin.com/in/gyakoo/"&gt;http://es.linkedin.com/in/gyakoo/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-5021189852931607904?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/5021189852931607904/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=5021189852931607904&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5021189852931607904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5021189852931607904'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2010/09/posting-on.html' title='Posting on ...'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-8411121366610771552</id><published>2010-09-12T18:22:00.009+02:00</published><updated>2010-09-13T10:58:17.199+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Implementing a script language I</title><content type='html'>There are a lot of literature and articles about using &lt;a href="http://en.wikipedia.org/wiki/List_of_programming_languages_by_category#Scripting_languages"&gt;script languages&lt;/a&gt; in games (lua, python, unrealscript, lisp, javascript, c# ...) or applications like 3dStudio Max, Maya, even FXComposer. In some projects I've bound the C++ code with Python or Lua (the most popular languages AFAIK), by using the language SDK or wrapping it around with &lt;a href="http://www.boost.org/doc/libs/1_44_0/libs/python/doc/index.html"&gt;boost::python&lt;/a&gt; or &lt;a href="http://www.rasterbar.com/products/luabind.html"&gt;Luabind &lt;/a&gt;for advanced object oriented features.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To bind your application with those script languages, optimally and without memory leaks, is something which requires mid progamming skills about stack based virtual machine, reference counting objects, and sometimes a lot of C++ template stuff. Obviously, there're design issues about when, where and what is the script language used for. There's a great (and old) presentation by Tim Sweeney about their (Epic) thinking about how should be the &lt;a href="http://gyakoo.blogspot.com/2008/05/next-mainstream-programming-language.html"&gt;next mainstream programming language&lt;/a&gt;. Slides talk about the importance to choice a well designed script language in next gen games.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Python and others languages are designed for generic purposes. Actually they're good enough for most of applications, but sometimes you need more specific features built-in in languages, like parallel and concurrency support or processes synchronization. Recently, languages like &lt;a href="http://www.haskell.org/"&gt;haskell&lt;/a&gt;, &lt;a href="http://es.wikipedia.org/wiki/Lisp"&gt;lisp &lt;/a&gt;or &lt;a href="http://www.erlang.org/"&gt;erlang&lt;/a&gt; are being considered because of their usefulness in concurrent environments, whether it is by functional programming or &lt;a href="http://en.wikipedia.org/wiki/Actor_model"&gt;actor model&lt;/a&gt; paradigm.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We're working with a propietary MMO technology which uses its own script language. That language has specific keywords to synchronize client and server processes, to make remote procedure calls, to work with the server-centric data definition and objects' global states, to specify replication issues in fields and classes, and to merge classes in the way of component (behaviors) pattern, among other features (GUI, plugins, external functions, nodes ...). A language, in cases like that, which provides specific field application issues, increases productivity while technical risks are maintained low. It's a big advantage to count on it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Several weeks ago, while I was working on my own project, at home, I decided to implement my own script language. That's a complex, titanic and unnecessary work, because is very difficult to program a better script language that existent ones, and I should to use them, but I kept thinking about it. Compiler subject has been always fascinating to me, and I started a project with some simple features in mind. Rapidly I figured out a lot of problems, specially those related with performance, but I've to say that I'm learning really useful things about compiler internals details, and to respect the work lua or python's developers have done.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;At this point, I've implemented successfully a script language with an hybrid lua/python syntax and the following features:&lt;/div&gt;&lt;div&gt;- Stack based virtual machine&lt;/div&gt;&lt;div&gt;- Main language constructions (conditionals, loops, expressions, subroutines...)&lt;/div&gt;&lt;div&gt;- Object oriented&lt;/div&gt;&lt;div&gt;- Dynamic typing&lt;/div&gt;&lt;div&gt;- Native types: int, double, string, unicode, dictionary and list&lt;/div&gt;&lt;div&gt;- Binding with C++ functions&lt;/div&gt;&lt;div&gt;- Reference counting for objects&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And currently I'm working on:&lt;/div&gt;&lt;div&gt;- Binding with C++ objects&lt;/div&gt;&lt;div&gt;- Concurrent paradigm&lt;/div&gt;&lt;div&gt;- Optimization&lt;/div&gt;&lt;div&gt;- Debugging issues&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But the roadmap is very large. I'm applying extreme programming, with a little bit tech design, and doing refactoring every few steps. I'm very proud about simplicity of C++ code, actually I'm doing big efforts to achieve it, maintaining things as small and simple as possible. Also, there is not memory leaks, and binding with C++ is really simple, in fact is simpler than the others languages'. But that simplicity has a cost, performance. I'm not doing benchmarking, at least for the time being, but I suspect that optimization will be mandatory. Anyway I'm considering it while program, but without enter in paranoia mode.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;I will post more technical details about how I did it&lt;/b&gt; in stages like lexer, parser, generating abstract syntax tree (AST), optimizing the tree, generating final stack VM code, code optimization and execution in virtual machine. Contexts/scopes are interesting to implement, and classes and objects too.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Below you've a code snippet:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Vector3 =&lt;br /&gt;{&lt;br /&gt;    x = 0.0,&lt;br /&gt;    y = 0.0,&lt;br /&gt;    z = 0.0,&lt;br /&gt;&lt;br /&gt;    _init( _x, _y, _z )&lt;br /&gt;    {&lt;br /&gt;        this.x=_x;&lt;br /&gt;        this.y=_y;&lt;br /&gt;        this.z=_z;&lt;br /&gt;    }&lt;br /&gt; &lt;br /&gt;    add( o )&lt;br /&gt;    {&lt;br /&gt;        this.x = this.x + o.x;&lt;br /&gt;        this.y = this.y + o.y;&lt;br /&gt;        this.z = this.z + o.z;&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;suma(a,b)&lt;br /&gt;{&lt;br /&gt;    return Vector3( a.x+b.x,a.y+b.y,a.z+b.z );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// -- Main code&lt;br /&gt;v0 = Vector3(1,2,3);&lt;br /&gt;v1 = Vector3(3,3,3);&lt;br /&gt;c = suma(v0,v1);&lt;br /&gt;v0.add( v1 );&lt;br /&gt;if ( c.x == v0.x &amp;amp;&amp;amp; c.y == v0.y &amp;amp;&amp;amp; c.z == v0.z )&lt;br /&gt;{&lt;br /&gt;    print( "Equals" );&lt;br /&gt;}else&lt;br /&gt;{&lt;br /&gt;    print( "Differents" );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As you can see, my approach is to use tables (dicts) like objects. This is used in Lua too, and other languages, but the difference here is I'm trying to do it in an easier way. The syntax is almost minimal, and you can invoke a table with the () operator, and when exists a constructor (I called it '_init') it is called to create a new object. 'print' is an external c++ function and you have others like 'std.execfile' or 'std.execstring', grouped.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I've created a powerful variant type which supports (via tagged union) reference objects, script code, native types, even C++ code, so, the C function 'print' is a variable in global context which is a CFunc, but you can pass it to a function, or you can overwrite it.&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;meta( func, param )&lt;br /&gt;{&lt;br /&gt;    func( param );&lt;br /&gt;}&lt;br /&gt;doit( m )&lt;br /&gt;{&lt;br /&gt;    m(print, 3);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;doit( meta );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;About the final stack based machine code, below you have the extensive code corresponding to the first snippet. Explaination in next posts:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[CODE]&lt;br /&gt;[Func] $00001&lt;br /&gt;load _x&lt;br /&gt;push this&lt;br /&gt;push x&lt;br /&gt;dotlv&lt;br /&gt;store&lt;br /&gt;load _y&lt;br /&gt;push this&lt;br /&gt;push y&lt;br /&gt;dotlv&lt;br /&gt;store&lt;br /&gt;load _z&lt;br /&gt;push this&lt;br /&gt;push z&lt;br /&gt;dotlv&lt;br /&gt;store&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[Func] $00002&lt;br /&gt;push this&lt;br /&gt;push x&lt;br /&gt;dot&lt;br /&gt;push o&lt;br /&gt;push x&lt;br /&gt;dot&lt;br /&gt;add&lt;br /&gt;push this&lt;br /&gt;push x&lt;br /&gt;dotlv&lt;br /&gt;store&lt;br /&gt;push this&lt;br /&gt;push y&lt;br /&gt;dot&lt;br /&gt;push o&lt;br /&gt;push y&lt;br /&gt;dot&lt;br /&gt;add&lt;br /&gt;push this&lt;br /&gt;push y&lt;br /&gt;dotlv&lt;br /&gt;store&lt;br /&gt;push this&lt;br /&gt;push z&lt;br /&gt;dot&lt;br /&gt;push o&lt;br /&gt;push z&lt;br /&gt;dot&lt;br /&gt;add&lt;br /&gt;push this&lt;br /&gt;push z&lt;br /&gt;dotlv&lt;br /&gt;store&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[Func] suma&lt;br /&gt;push a&lt;br /&gt;push x&lt;br /&gt;dot&lt;br /&gt;push b&lt;br /&gt;push x&lt;br /&gt;dot&lt;br /&gt;add&lt;br /&gt;push a&lt;br /&gt;push y&lt;br /&gt;dot&lt;br /&gt;push b&lt;br /&gt;push y&lt;br /&gt;dot&lt;br /&gt;add&lt;br /&gt;push a&lt;br /&gt;push z&lt;br /&gt;dot&lt;br /&gt;push b&lt;br /&gt;push z&lt;br /&gt;dot&lt;br /&gt;add&lt;br /&gt;lst 3&lt;br /&gt;call Vector3&lt;br /&gt;ret&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;pushtable&lt;br /&gt;load $00001&lt;br /&gt;store _init&lt;br /&gt;del $00001&lt;br /&gt;load $00002&lt;br /&gt;store add&lt;br /&gt;del $00002&lt;br /&gt;push 0.000000&lt;br /&gt;store x&lt;br /&gt;push 0.000000&lt;br /&gt;store y&lt;br /&gt;push 0.000000&lt;br /&gt;store z&lt;br /&gt;poptable&lt;br /&gt;store Vector3&lt;br /&gt;push 1&lt;br /&gt;push 2&lt;br /&gt;push 3&lt;br /&gt;lst 3&lt;br /&gt;call Vector3&lt;br /&gt;store v0&lt;br /&gt;push 3&lt;br /&gt;push 3&lt;br /&gt;push 3&lt;br /&gt;lst 3&lt;br /&gt;call Vector3&lt;br /&gt;store v1&lt;br /&gt;load v0&lt;br /&gt;load v1&lt;br /&gt;lst 2&lt;br /&gt;call suma&lt;br /&gt;store c&lt;br /&gt;push v0&lt;br /&gt;push add&lt;br /&gt;dot&lt;br /&gt;load v1&lt;br /&gt;lst 1&lt;br /&gt;call&lt;br /&gt;push c&lt;br /&gt;push x&lt;br /&gt;dot&lt;br /&gt;push v0&lt;br /&gt;push x&lt;br /&gt;dot&lt;br /&gt;eq&lt;br /&gt;push c&lt;br /&gt;push y&lt;br /&gt;dot&lt;br /&gt;push v0&lt;br /&gt;push y&lt;br /&gt;dot&lt;br /&gt;eq&lt;br /&gt;and&lt;br /&gt;push c&lt;br /&gt;push z&lt;br /&gt;dot&lt;br /&gt;push v0&lt;br /&gt;push z&lt;br /&gt;dot&lt;br /&gt;eq&lt;br /&gt;and&lt;br /&gt;jz 66&lt;br /&gt;push Equals&lt;br /&gt;lst 1&lt;br /&gt;call print&lt;br /&gt;jmp 69&lt;br /&gt;push Differents&lt;br /&gt;lst 1&lt;br /&gt;call print&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-8411121366610771552?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/8411121366610771552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=8411121366610771552&amp;isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8411121366610771552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8411121366610771552'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2010/09/implementing-script-language-i.html' title='Implementing a script language I'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-2984782307790577371</id><published>2010-09-02T07:54:00.004+02:00</published><updated>2010-09-02T18:18:50.899+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>A long time ago...</title><content type='html'>Hi, I'm back, after about 1 year since I wrote the last post. A lot of things has happened in my life, personal and professional.&lt;br /&gt;&lt;br /&gt;I left the company and moved to another city where I'm currently working on a massively multiplayer online game, mainly focused to learn the Spanish language, but it's almost a traditional MMORPG eventually. It's a big project with a considerable budget, to develop in several years. I'm really excited with it.&lt;br /&gt;&lt;br /&gt;...and I got married last July, after ten years sharing my life with a great person, who understands all my freak passions :)&lt;br /&gt;&lt;br /&gt;From now I will try post in this blog more regularly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-2984782307790577371?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/2984782307790577371/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=2984782307790577371&amp;isPopup=true' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/2984782307790577371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/2984782307790577371'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2010/09/long-time-ago.html' title='A long time ago...'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-2343565292512477353</id><published>2009-10-19T12:27:00.004+02:00</published><updated>2010-09-02T07:54:54.380+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='media'/><title type='text'>Something about security</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://nostarch.com/hacking2.htm"&gt;&lt;/a&gt; Exploiting of systems is a subject of which I'd like to know more about. I think it's good to understand how avoid future hacking, but really you neither find much information on web nor books related. I've found &lt;a href="http://nostarch.com/hacking2.htm"&gt;a book&lt;/a&gt; which maybe could help us to improve these skills. Topics in book include: &lt;blockquote&gt;&lt;ul&gt;&lt;li&gt;Program computers using C, assembly language, and shell scripts&lt;/li&gt;&lt;li&gt;Corrupt system memory to run arbitrary code using buffer overflows and format strings&lt;/li&gt;&lt;li&gt;Inspect processor registers and system memory with a debugger to gain a real understanding of what is happening&lt;/li&gt;&lt;li&gt;Outsmart common security measures like nonexecutable stacks and intrusion detection systems&lt;/li&gt;&lt;li&gt;Gain access to a remote server using port-binding or connect-back shellcode, and alter a server's logging behavior to hide your presence&lt;/li&gt;&lt;li&gt;Redirect network traffic, conceal open ports, and hijack TCP connections&lt;/li&gt;&lt;li&gt;Crack encrypted wireless traffic using the FMS attack, and speed up brute-force attacks using a password probability matrix&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;And related to that, in the video below, speakers Michael Stail and Felix Domke talk about &lt;i&gt;The XBox 360 Security System and its Weaknesses&lt;/i&gt;. They first talk about all weaknesses in old Xbox I, and one by one they're going giving technical information about how they fixed them.&lt;br /&gt;&lt;center&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/uxjpmc8ZIxM&amp;amp;hl=es&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/uxjpmc8ZIxM&amp;amp;hl=es&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-2343565292512477353?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/2343565292512477353/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=2343565292512477353&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/2343565292512477353'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/2343565292512477353'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/10/something-about-security.html' title='Something about security'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-1036869394656509834</id><published>2009-10-17T08:15:00.006+02:00</published><updated>2009-10-17T20:15:36.603+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Please, no more discussion about C vs C++</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.classes.cs.uchicago.edu/archive/2006/summer/15200-91/cplusplus.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 200px; height: 190px;" src="http://www.classes.cs.uchicago.edu/archive/2006/summer/15200-91/cplusplus.jpg" alt="" border="0" /&gt;&lt;/a&gt;I'm really thinking that C vs C++ discussion will never end. I just read a &lt;a href="http://www.gigamonkeys.com/blog/2009/10/16/coders-c++.html"&gt;Peter Seibel post&lt;/a&gt; about interviews he has written in his book &lt;i&gt;Coders at Work&lt;/i&gt;, asking to fifteen top programmers and computer scientist around the world about what are their opinions in using C++ language.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well, maybe you're going to be surprised since most of them think that C++ is a bad, too complex, useless language, and they prefer C when they need performance. That's what a couple of well considered programmers said.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Reading the post, I can see that they had that opinion mainly focusing in how the complex the C++ is. They said that sometimes programmers use only a subset of the language. They think that what you mostly need to do with an OO language, you best do it with some other like Java or Python, because they're better structured languages and things can be done in the same way by different programmers. They insist in the complexity of language and the different compiler implementations, which is a pain in compatibility issues.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway, although I'm not by far as good programmer as they are (years of experience are talking here), I think they're old-school programmers, I mean, &lt;b&gt;C++ has been changing&lt;/b&gt; along these years and already there exist &lt;b&gt;another standard revision&lt;/b&gt;, as well as compilers do. In reference to the language complexity, all is about using it. If you're a Java experienced programmer and you want to program in C++ after a lot of years, it is obvious that C++ is very complex for you in the beginning. You'll get confused with OO artifacts (which is half-implemented in C++, it is true), or by the using of pointers and references. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;C++ is a great language, as well as C and Java and others, depending on what you need to do. The google jam code contest is a good example about it. I've a good colleague that tried to resolve its exercises by using C++, but he said me that more rounds he passed more difficult the questions were, but difficult in the sense of he hadn't enough time to program the result algorithm, not by the algorithm's complexity itself. He was spending a lot of time with language (C++) to do simple tasks like word parsing, splitting a string ... I wonder if he had used python, I'm pretty sure he had obtained a better results.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A place where you can find a lot of C++ code is in the videogames industry, but anyway there is a common evolution there, the using of more high level scripting language, loosing a bit of performance but gaining flexibility and avoiding bugs. That evolution is focused also in tries to make an better script parallel language. And talking about parallelism, it is true that C++ might be a bit painful. That's because the lack of a memory model like Java has. But next language standard has done efforts in that field.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To summarize, my honest opinion about using C++ is that if you've got a couple of good programmers that understand well the language, and they're pragmatic, you could program a very good product (in the performance sense) by using C++, but even so there are parts of a system that is better program in another not-so-risky language. To make good use of the C++ you need good and experienced C++ programmers. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;C++ is a dangerous language, like a knife is. But that has not made it so bad. All depend on who is using it and how he/she uses it. You don't let a child that plays with a knife, don't you?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-1036869394656509834?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/1036869394656509834/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=1036869394656509834&amp;isPopup=true' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/1036869394656509834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/1036869394656509834'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/10/please-no-more-discussion-about-c-vs-c.html' title='Please, no more discussion about C vs C++'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-6921499293957256273</id><published>2009-10-15T15:11:00.005+02:00</published><updated>2009-10-15T16:53:24.315+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>C++ or C (in this era?)</title><content type='html'>A post from &lt;a href="http://www.johndcook.com/blog/2009/09/15/linus-torvalds-cpp/"&gt;The Endeavour&lt;/a&gt; blog about a Linus Torval's &lt;a href="http://article.gmane.org/gmane.comp.version-control.git/57918"&gt;response&lt;/a&gt; in a forum, makes me remember the ethernal dilemma about OO and Procedural methodologies flamewar, C++ vs C, STL vs C, Java vs C, well whatever vs C...&lt;br /&gt;&lt;br /&gt;Linus:&lt;br /&gt;&lt;blockquote&gt;C++ is a horrible language. It's made more horrible by the fact that a lot&lt;br /&gt;of substandard programmers use it, to the point where it's much much&lt;br /&gt;easier to generate total and utter crap with it. Quite frankly, even if&lt;br /&gt;the choice of C were to do &lt;b&gt;*nothing*&lt;/b&gt; but keep the C++ programmers out,&lt;br /&gt;that in itself would be a huge reason to use C.&lt;br /&gt;...&lt;br /&gt;&lt;/blockquote&gt;John:&lt;br /&gt;&lt;blockquote&gt;...&lt;br /&gt;Well, I’m nowhere near as talented a programmer as Linus Torvalds, but I totally disagree with him. If it’s easy to generate crap in a relatively high-level and type-safe language like C++, then it must be child’s play to generate crap in C. It’s not fair to compare world-class C programmers like Torvalds and his peers to average C++ programmers. &lt;strong&gt;Either compare the best with the best or compare the average with the average&lt;/strong&gt;.&lt;br /&gt;...&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;John's impressions are clever and looks like more polite, against Linus's outspoken attitude but completely honest, but anyway after read a lot of controversial comments and what Stroustup &lt;a href="http://gyakoo.blogspot.com/2009/09/bjarne-stroustup-on-c0x-cvu.html"&gt;said&lt;/a&gt; about his C++, finally I think that why do we have to chose one of them? Are always things black or white? I neither agree nor disagree with extreme positions ... people like discussions!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-6921499293957256273?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/6921499293957256273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=6921499293957256273&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6921499293957256273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6921499293957256273'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/10/c-or-c-in-this-era.html' title='C++ or C (in this era?)'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-6289979704204029531</id><published>2009-10-10T12:32:00.022+02:00</published><updated>2009-10-13T08:44:48.889+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='postmortem'/><title type='text'>A real life agile development? Posmortem.</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mikesmart.com/application_development/agile_development.htm"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 230px; height: 200px;" src="http://www.mikesmart.com/images/application_development/AgileDevelopment.gif" alt="" border="0" /&gt;&lt;/a&gt;What do you think about &lt;a href="http://en.wikipedia.org/wiki/Agile_software_development"&gt;agile software development&lt;/a&gt;? Is it suitable for all kind of software? Maybe it isn't, but, are you sure that you can't apply principles of &lt;a href="http://agileprogramming.org/"&gt;agile programming&lt;/a&gt; to some parts of your non-agile development process? Well, like almost everything in the life, it isn't a black or white response, but a gray one.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Whether you have the chance to apply it or not, learn more about this topic is very useful to improve your programmer or analyst toolboox, and always you can extract only the interesting part to integrate it in your daily process, I think. At least that was what &lt;a href="http://www.optenet.com/"&gt;we&lt;/a&gt; did for the last year, creating a big &lt;a href="http://gyakoo.blogspot.com/2009/09/sqa-automation.html"&gt;infrastructure&lt;/a&gt; from the scratch, with a quite few resources and always with short schedules for intermediate deliverables. Follow is almost like a &lt;a href="http://www.pragmaticsw.com/Newsletters/newsletter_2004_12_SP.htm"&gt;project postmortem&lt;/a&gt;, mostly at management level, I hope you find it useful, that is this post's target.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;The target&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Currently, the result of our work is helping to the &lt;a href="http://en.wikipedia.org/wiki/Quality_assurance#QA_in_software_development"&gt;SQA &lt;/a&gt;department to do their work faster and more reliable, and the tools we've created are being used in the production's department to trace and debug the applications they create. The statistics we generate and store by executing automated testcases, are very important for the management process. We are consolidating the basis of how the different modules of production's department are shipping and integrating theirs products (at least we're trying to). Also, we've created an intranet where all the company can communicate their issues to SQA department, with a normalized procedure to do that.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It's an unfinished work, but for the things we got successfully, I'll try to expose here how we did it and what problems we found. How did we resolve them? What did we learn?  &lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Team and work&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.americantrails.org/i/resourceimages/Youth-maine-Teamwork.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 200px; height: 163px;" src="http://www.americantrails.org/i/resourceimages/Youth-maine-Teamwork.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;div&gt;Let's see, as you'll see in next paragraphs we needed to use an agile process, but the first and most important thing we didn't want was to spend a lot of time in the programmer training in terms like &lt;i&gt;iteration, continuous process, pig/chicken roles, scrum master, features documents&lt;/i&gt; ... I assimilated all those concepts and then integrated them into our work pipeline, without give bored talks about agile to the team. We wanted to work and &lt;b&gt;ship deliverables in a rapid pace&lt;/b&gt;, because we had short milestones and in the meantime we were developing tools, libraries, cluster, web, database and their integration, we wanted to improve &lt;i&gt;certain numbers&lt;/i&gt; for the management. Well, really only a number. That &lt;i&gt;number&lt;/i&gt; was the hardest part in the entire project. It was showing how many automated test cases we had, since it was used in the calculation of &lt;a href="http://en.wikipedia.org/wiki/Rate_of_return"&gt;rate of return&lt;/a&gt; to justify our team work. Yes, everything must be viewed as a money problem in the end. But we can't increase that number without create a minimal technical infrastructure! It's a cyclical dependency!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So a work division was neccesary, due the limited number of developer we had. The division was accomplished in two ways: &lt;b&gt;making sub-teams&lt;/b&gt;, one for tools, the other one for that magic number. And also, in certain moments, developers split their &lt;b&gt;labor in two parts&lt;/b&gt;, programming some hours, and helping with the number the rest of the day. As you already know, developers are the most valuable asset in the company, so obviously we had to permute them to avoid their demotivation, and as result the entire team have a good cross-knowledge about the project. It is important. Nobody, individually speaking, is most important than other, only the global team and the inter-relationships are essentials.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Taking the control over the project&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;As you can read, targets were high enough being our resources so limited. We needed a process to handle that. More specifically an agile development process. I think here is where the project manager (in other cases the lead programmer doing management functions), have to do their work. By having in mind targets and times, as well as resources (how many programmers?) and their development (mixing junior and senior developers), you have to get the things running and giving us results.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Another of the things I wanted was to have &lt;b&gt;the technical control&lt;/b&gt; about everything. It is an impossible issue, but you know that things can diverge. People have tendency to do the things the best they can, and although it isn't a bad action, when you're a lead developer you need to achieve a mix between fast and quality. Also as I said before, intermediate results were needed. So, we were updating a prioritized list of features every we wanted a new sub-product, feature, tools or procedure. Returning to the technical control, I meant that I always was getting feedback from developers. Helping them to solve any problem that can block them, and giving them advices about more technical parts that I have the experience about. Maybe it sounds a bit hard for people, but it isn't at all. You have to balance again between training, personal improvement and slight control, leaving to developers do their work, with their own ideas and code style, but continously retargeting them to the global team direction. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway, I insist it can be viewed as a dictatorial technical leadership, but it is not at all. This it is because we had a lot of &lt;a href="http://en.wikipedia.org/wiki/Brainstorm"&gt;brainstorming&lt;/a&gt; meetings, and every decision and action was previously agreed with the sqa director and with the team as far as possible. In fact, I think you cannot make a really good decision entirely with your own. You need some feedback from your team and colleagues. Maybe your original decision will go as it, but by talking with people you can make some changes or to prepare some things for the future, and actually, they will be who develop that feature, so at least you need bear them in mind. What do you think? :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Continuous meetings&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.home-designing.com/wp-content/uploads/2009/06/informal-meeting-room.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 256px; height: 182px;" src="http://www.home-designing.com/wp-content/uploads/2009/06/informal-meeting-room.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;div&gt;To correctly apply agile principles, and to receive feedback continuously, we had daily meeting with developers working on a task. But I was clear here. Meetings was driven by something, with a clear target and no more than fifteen minutes long. These were tracking meetings, where the team talked about their progress and problems found, and I repeated targets, priorities and tasks for incoming labor day.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Exceptions were the brainstorming meetings, where we met for a period of an hour or more, talking about how to implement a feature for a new sub project, different approaches to a solution, how a specific technique could affect to other parts of architecture, ... Those meetings were very productive, and everyone can contribute with their own thoughts. Finally I gathered all that information and a solution came to us at the same time the team felt useful and made up relationships between them.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The place where we met was basically in the same place where we work. Trying not to disturb any co worker, we met around a &lt;b&gt;white board&lt;/b&gt; where we made a note of everything we talked about. Again everyone can write down on the white board, and those notes were translated into tasks, a class diagram update, a feature, or a change in a function prototype in the emailing library.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But things aren't so easy as you think. People must to pay attention to meeting's driver, you need to avoid parallel discussions, and try to let only the topics around the main goal of the meeting, because fifteen minutes perhaps aren't enough, but it's what we have. &lt;b&gt;Important things first.&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Communication and continuous refinements&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;To perform a &lt;i&gt;continuous&lt;/i&gt; refinement process obviously you need what I said before, a &lt;i&gt;continuous&lt;/i&gt; feedback, and in one hand you have a &lt;i&gt;continuous&lt;/i&gt; meetings with team and in other hand you've the control over what the developer is doing every moment. That's a lot of &lt;i&gt;continuous&lt;/i&gt; stuff! So we reach a conclusion here: &lt;b&gt;communication&lt;/b&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The success of any project, or at least a key factor, from my point of view, is the communication among team. Let me explain it. You always should to boost the communication between developers, and the simplest thing you could do is when a developer ask you for a doubt about a technical aspect or whathever, you already know the entire project and what is doing everyone in every moment, so you could forward him to talk with his team mate, depending on doubt he asked you. That is useful and in a short time you can see how people are talking amongst them when is needed. You're building a team. Doesn't matter if you have a team with a couple of gurus or &lt;a href="http://blog.leetsoft.com/2007/8/8/there-s-no-one-programmer-who-does-the-work-of-ten-other-programmers"&gt;über programmers&lt;/a&gt; if there not exists communication because they're almost autistics, or even worse, all of them are trying to impose their solutions. The &lt;a href="http://en.wikipedia.org/wiki/Synergy"&gt;synergy&lt;/a&gt; is the most important part in your team, and it is difficult to achieve: &lt;b&gt;the &lt;/b&gt;&lt;a href="http://en.wikipedia.org/wiki/Knowhow"&gt;&lt;b&gt;know-how&lt;/b&gt;&lt;/a&gt;. I had luck to work with great and honest people there.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Once you have a communicative team, there are a lot of daily work to lead their efforts to build a product. As I said, in progress tracking meetings you can view how your list of tasks (or gantt chart) is being completed, letting you update priorities. But the real problem comes with &lt;b&gt;unexpected events&lt;/b&gt;. What does happen when your director changes priorities? or even what if your director gets a developer out of the project? Well, there is no a perfect solution for these misfortunes. Here I have to say that sometimes some sub-projects gone frozen for a time while the entire team was changing the global targets, and in other moments you end up with only two developers when you had five. At least we had a agile team, which responses to changes very quickly, and all the developers understood this. Also at any moment, due the cross knowledge, a junior script writer can sit down to fix in c# a issue related with the debugger tool we were creating, for example, as well as a c++ senior developer can help with cluster maintenance at adminitration level, setting interfaces because he already knows how to do it. This also is a good thing to enrich the people.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But even so, there is a big work to &lt;b&gt;break down complex requeriments&lt;/b&gt; into simpler tasks, to achieve rapid results in a week. That is what I did with the building of Studio Application, a complex .net desktop application which is used to generate automated testcases, integrating a lot of processes, techniques and languages. The first step I did was to analyze the requeriments, making a high level list of features needed. After that, a blocks diagram was created, following a class diagram. Once an overall classes and sequences diagrams were created, it was easier to distribute tasks to people, bearing in mind a milestone for a week. In a week we gone through the results and we had a minimal functional application. The remaining work was refinements, week after week, until we reach a quality product. But a good design is needed because you have to create code structure in order that it is extensible, for the next refinement weeks. It is always a painful work when code is not prepared for extensibility, anyway. And a grateful one when things run ok.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There is another minor problem with continuous refinement: &lt;b&gt;features or tasks starvation&lt;/b&gt;. Maybe you're updating priorities in your project plan, and there are features that they're not as important than others, or maybe they're less motivating than others. You should to set priorities with that in mind, because among features, you'll find bugs and other issues that need to be fixed in order to unblock certain other developments, and they can be pushed down in the list.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Conclusions&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.elpais.com/recorte/20070827elpepudep_15/XLCO/Ies/Campbell_campeona_gracias_foto_finish.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 220px; height: 156px;" src="http://www.elpais.com/recorte/20070827elpepudep_15/XLCO/Ies/Campbell_campeona_gracias_foto_finish.jpg" alt="" border="0" /&gt;&lt;/a&gt;To adopt an agile software development process should be a &lt;b&gt;natural process&lt;/b&gt;. It is good all the documentation and theory about agile methodologies out there, but if you force the team to adopt that cool methodology &lt;i&gt;you read a month ago in a magazine&lt;/i&gt;, without taking in mind that it's almost a way of react before a changing environment, maybe it will cost more than you expected. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Because the &lt;b&gt;team cannot change suddenly&lt;/b&gt;, in fact, the agile process is focused to train the team to do that! It is important go floating with the work flow of your team and slightly retarget their motivations, doing something similar that we did.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway, all what I've written here is mostly the beautiful parts of our work. Once you have seen all process from another point of view, when (important) things have finished and when you get results, it's very easy to see what you failed and what was a success, but anyway it &lt;b&gt;depends on the company&lt;/b&gt;, &lt;b&gt;project and people&lt;/b&gt; you have. In our case we learned a lot of interesting ways to do the things, but also ways to don't do them. Again, this isn't a magic recipe or the correct way to do the things, and what worked ok to us, not necessarily is suitable to another company. But it was only a postmortem!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Sorry for the long post.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-6289979704204029531?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/6289979704204029531/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=6289979704204029531&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6289979704204029531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6289979704204029531'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/10/real-life-agile-development-posmortem.html' title='A real life agile development? Posmortem.'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-815143534254418870</id><published>2009-10-09T14:53:00.005+02:00</published><updated>2009-10-15T16:16:07.503+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><title type='text'>Hacker's Delight</title><content type='html'>Since I read an article from &lt;a href="http://entland.homelinux.com/blog/2008/11/04/hackers-delight/"&gt;EntBlog&lt;/a&gt; about this book, I pushed it in my pending books queue. And ... finally a good colleague at Optenet give it to me like a present. I'm really excited. Thank you &lt;a href="http://www.realsim.net/menu.html"&gt;dude&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.hackersdelight.org/"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 240px; height: 240px;" src="http://4.bp.blogspot.com/_UXKUeU6z7xE/Ss8zg1uH53I/AAAAAAAAAY8/73xr0GeeycA/s320/hackers_delight.jpg" alt="" id="BLOGGER_PHOTO_ID_5390583918255138674" border="0" /&gt;&lt;/a&gt;&lt;/center&gt;Sure I'll learn a lot of interesting things.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-815143534254418870?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/815143534254418870/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=815143534254418870&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/815143534254418870'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/815143534254418870'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/10/hackers-delight.html' title='Hacker&apos;s Delight'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_UXKUeU6z7xE/Ss8zg1uH53I/AAAAAAAAAY8/73xr0GeeycA/s72-c/hackers_delight.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-8443024302443245121</id><published>2009-10-08T23:33:00.007+02:00</published><updated>2009-10-09T00:45:43.952+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Games are not only graphics (again) and other anecdotes</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_UXKUeU6z7xE/Ss5pTstUr2I/AAAAAAAAAYs/jiB5sYMMa_M/s1600-h/polygons.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 295px; height: 230px;" src="http://3.bp.blogspot.com/_UXKUeU6z7xE/Ss5pTstUr2I/AAAAAAAAAYs/jiB5sYMMa_M/s320/polygons.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5390361591148752738" /&gt;&lt;/a&gt;Today a person asked me for books to learn to "program videogames". Well, despite that this question is more difficult to answer than you initially can think, I knew what he actually meant and I asked him (intentionally): &lt;div&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;b&gt;Me&lt;/b&gt;: What do you mean with "program videogames"? - &lt;b&gt;He&lt;/b&gt;: Well, you know, to draw 3D meshes with textures and so, these things...&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Nooo, graphics again! There is no problem, but, how many times I've heard this wrong association?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;I said him&lt;/b&gt;: &lt;i&gt;Why don't you begin with other things different from graphics?&lt;/i&gt; And &lt;b&gt;his &lt;/b&gt;&lt;b&gt;response was&lt;/b&gt;: &lt;i&gt;Bah, that another stuff (non-graphics) is easy, at least I can understand it without problems, but I've never done graphics programming. &lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Wow!, Overall engine architecture, entities system, networking or even AI? Gameplay and entities behavior is really exciting. Sound system or script binding. And a parallel engine architecture, with tasks scheduling is also cool. Another good stuff is the filters pipeline, more related with graphics if you want. These are complicated ones, but are videogames too. And there are a lot of more things I can't talk you about. Also, XNA or Ogre3D are good start points. Even you can download my simple &lt;a href="http://gyakoo.blogspot.com/2009/07/space-invaders-cdx.html"&gt;c++ space invaders &lt;/a&gt;game and modify it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;He:&lt;/b&gt; Yes, yes, but, what about graphics? Draw models. Textures!&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Ok then, definitely he wants draw primitives :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_UXKUeU6z7xE/Ss5prZx3X0I/AAAAAAAAAY0/kObnknrNTG0/s1600-h/greg.gif"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 292px; height: 292px;" src="http://1.bp.blogspot.com/_UXKUeU6z7xE/Ss5prZx3X0I/AAAAAAAAAY0/kObnknrNTG0/s320/greg.gif" border="0" alt="" id="BLOGGER_PHOTO_ID_5390361998384389954" /&gt;&lt;/a&gt;&lt;div&gt;This conversation makes me remember other anecdote, whith a good co-worker who wanted program a fluid simulation, if I can help him. &lt;b&gt;I asked him:&lt;/b&gt; &lt;i&gt;what kind of simulation, a &lt;/i&gt;&lt;a href="http://www.youtube.com/watch?v=GnVw9GA2wZg"&gt;&lt;i&gt;water shader effect&lt;/i&gt;&lt;/a&gt;&lt;i&gt;, a &lt;/i&gt;&lt;a href="http://www.youtube.com/watch?v=n5lOjME8B6M"&gt;&lt;i&gt;particle based simulation&lt;/i&gt;&lt;/a&gt;&lt;i&gt; or simply something like the &lt;/i&gt;&lt;a href="http://www.youtube.com/watch?v=dcS12sDIhIQ"&gt;&lt;i&gt;old plasma demo effect&lt;/i&gt;&lt;/a&gt;&lt;i&gt;?- &lt;b&gt;He:&lt;/b&gt; &lt;/i&gt;&lt;i&gt;No no, I want make a good fluid simulation, and I think I can, in fact I've already done something.&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;b&gt;Me:&lt;/b&gt; Really? You're a crack!, Have you ever been working with &lt;/i&gt;&lt;a href="http://en.wikipedia.org/wiki/Computational_fluid_dynamics"&gt;&lt;i&gt;CFD &lt;/i&gt;&lt;/a&gt;&lt;i&gt;or Navier-Stokes equations?. I don't know much about it, so I can't help you, tell me more, I said.&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;b&gt;He:&lt;/b&gt; Well, I don't know that CFD or equations. I don't need them, I think I'm going to deduce them.&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;I finally said&lt;/b&gt;: &lt;i&gt;Ah ok, why don't, good luck, and don't forget to show me any result you get&lt;/i&gt; :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Good people, best regards to them.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-8443024302443245121?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/8443024302443245121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=8443024302443245121&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8443024302443245121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8443024302443245121'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/10/games-are-not-only-graphics-again-and.html' title='Games are not only graphics (again) and other anecdotes'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_UXKUeU6z7xE/Ss5pTstUr2I/AAAAAAAAAYs/jiB5sYMMa_M/s72-c/polygons.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-7647328884189199412</id><published>2009-10-06T10:23:00.012+02:00</published><updated>2009-10-08T18:18:49.460+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithmic'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><title type='text'>It's all about complexity</title><content type='html'>&lt;a href="http://en.wikipedia.org/wiki/Big_O_notation"&gt;Complexity Order I mean&lt;/a&gt;. Algorithmic is an useful tool which every programmer needs to know. As you already know, you could find/do a very very fast routine to compare two strings, by using new SIMD instructions built in the &lt;a href="http://en.wikipedia.org/wiki/SSE4"&gt;SS4&lt;/a&gt;, as the PCMPEQQ for example, and reordering instructions to minimize cache fails and take advantage of out of order micro execution. But if you're applying a direct algorithm to traverse words or a direct structure to store them, there is nothing you can do when you get an asynthotic input. It is the beauty about algorithmic, an university's subject that all the software engineers should know, and apply it in their daily technology decisions (whenever they can), because the system's behavior with large input matters and can makes the difference.&lt;br /&gt;&lt;br /&gt;I remember, when I was studying at &lt;a href="http://www.uca.es/"&gt;UCA&lt;/a&gt;, we did practices about algorithmic and complexity order theory by measuring different algorithms times to the same problem. We sampled the time that an algorithm takes for different input sizes, so you're sampling the complexity order curve/function and then by comparing all the algorithms-times, you can see how they behave asynthotically, in a graphic manner.&lt;br /&gt;&lt;br /&gt;I've been using this technique since then, when I need to test different approaches to same problem, or when I need to empirically demonstrate a data structure, for example. In &lt;a href="http://gyakoo.blogspot.com/2009/07/absence-and-dns-server.html"&gt;another post&lt;/a&gt; in this blog I talked about a special radix tree to store IP numbers, demonstrating you'll get a constant complexity order O(k) when search for an IP, independently you store all internet IPs (another thing is the complexity order in space). This means that you'll perform same number of instructions to search any number.&lt;br /&gt;&lt;br /&gt;So you have, O(1) &amp;lt; O(logn) &amp;lt; O(n) &amp;lt; O(n·logn) &amp;lt; O(n^2) &amp;lt; O(n^a) &amp;lt; O(a^n) &amp;lt; O(n!), being O(1) the best you can get in time and space. Related with this you have the &lt;a href="http://en.wikipedia.org/wiki/NP-complete"&gt;NP complete problems&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Sometimes when trying to get a best time complexity, probably you'll get worse the spatial one, and vice versa. Another important note about measuring times is the time precision. Although you use a high performance counter, you cannot measure how much time takes two std vector's inserts, because current microprocessors are very fast. You should use a big N input, repeated M times, because memory never is enough (you can't insert 1·10^12 words in a vector, at least you shouldn't), and then divide the time to compute the average time. Selection of N and M is important. Also, you need to know that another daemons or processes are continuously interrupting the algorithm, maybe the compiler can generate an optimize version of your algorithm (only improving the multiplicative constant). All these variables can corrupt the times you get, so the conclusion is do not use the times as it, but the graphical comparisons between algorithms' times, or in other words, you need to extract all the multiplicative constants and think only in terms of sampled curves' behavior.&lt;br /&gt;&lt;br /&gt;In the code below you see a snippet to measure a std list insert varying N.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;unsigned long step = (MAX-MIN)/N_POINTS;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;// Varying our input N&lt;/span&gt;&lt;br /&gt;for ( unsigned long N = MIN; N &amp;lt; MAX; N+=step )&lt;br /&gt;{   &lt;br /&gt;double time = 0.0;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0);"&gt;// Repeating M times&lt;/span&gt;&lt;br /&gt;for ( unsigned long m = 0; m &amp;lt; M; ++m )&lt;br /&gt;{&lt;br /&gt;  Clock cl;&lt;br /&gt;  cl.Start();&lt;br /&gt;  &lt;span style="color: rgb(0, 102, 0);"&gt;// Algorithm test comes here.&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(0, 102, 0);"&gt;// Trying to insert N numbers in a stl list&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(102, 102, 102);"&gt;std::list&amp;lt;int&amp;gt; lis;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;    for ( unsigned long i = 0; i &amp;lt; N; ++i )&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;    {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;        lis.push_back( i );&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;    }&lt;/span&gt;&lt;br /&gt;  time += cl.Stop();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;printf ( "%lu\t%0.10lf\n", N, time/(N*M) );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This code will print an output like follow:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;99999 0.0000001016 &lt;br /&gt;6759999 0.0000001023 &lt;br /&gt;13419999 0.0000001042 &lt;br /&gt;20079999 0.0000001021 &lt;br /&gt;26739999 0.0000001028 &lt;br /&gt;33399999 0.0000001037 &lt;br /&gt;40059999 0.0000001016 &lt;br /&gt;46719999 0.0000001051 &lt;br /&gt;53379999 0.0000001017 &lt;br /&gt;60039999 0.0000001020 &lt;br /&gt;66699999 0.0000001012 &lt;br /&gt;73359999 0.0000001021 &lt;br /&gt;80019999 0.0000001005 &lt;br /&gt;86679999 0.0000001011 &lt;br /&gt;93339999 0.000000101&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This data can be obtained for several algorithms. All those data then can be graphically represented using a plot program, like &lt;a href="http://www.gnuplot.info/"&gt;gnuplot&lt;/a&gt; for example.&lt;br /&gt;&lt;br /&gt;Follow are curves for insert algorithms in &lt;span style="font-weight: bold;"&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;&amp;lt;list&amp;gt;&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;&amp;lt;map&amp;gt;&lt;/span&gt; Before you look through the image below, it would be interesting you know what are the complexity order for insertions in these containers. In &lt;a href="http://www.cplusplus.com/reference/stl/"&gt;this page&lt;/a&gt; you can see all O for stl containers. O(1) for vector and list. And * for map. Well, the time complexity requirements imposed by the standard for each map operation suggest a balanced binary search tree mostly. Let's see the results:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_UXKUeU6z7xE/SssZ5_d1K-I/AAAAAAAAAYU/r-E5Wh1x0Zg/s1600-h/ins-comp.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 225px;" src="http://2.bp.blogspot.com/_UXKUeU6z7xE/SssZ5_d1K-I/AAAAAAAAAYU/r-E5Wh1x0Zg/s320/ins-comp.jpg" alt="" id="BLOGGER_PHOTO_ID_5389429863158721506" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Wow!, it is interesting that the vector (&lt;span style="color: rgb(204, 0, 0);"&gt;red line&lt;/span&gt;) and the list (&lt;span style="color: rgb(0, 0, 153);"&gt;blue line&lt;/span&gt;) are constant ( O(1) ). In other words, doesn't matter how N increase, always you'll get a constant time. And the map (&lt;span style="color: rgb(0, 204, 0);"&gt;green line&lt;/span&gt;) follows a logarithmic curve ( O(logn) ). Obviously a linear interpolation between measuring points are used. &lt;br /&gt;&lt;br /&gt;As you can view, vector has O(1) in push_back operations. Wait a minute! When a vector increases beyond its capacity, a memory resize is needed, and a copy for all elements is performed. So, why is it O(1)? It's a O(n) just because asynthotically you'll need to make N copies... Well, there exists a thing called &lt;a href="http://en.wikipedia.org/wiki/Amortized_analysis"&gt;amortized analysis&lt;/a&gt; to deal with it. In fact, in the wikipage about amortized analysis, the example used to describe it, is the array push back operation. &lt;br /&gt;&lt;br /&gt;Also you can get from graphic that vector is faster than list when inserting elements, due to multiplicative constant, being smaller in vector structure. But remember, with this implementation and in the CPU I used. This is can be because in list you need to make pointers operations when a new node is added, in vector you only need access to last available memory slot to put the element. Also in list you need to create every new node (memory alloc operation).&lt;br /&gt;&lt;br /&gt;Another comparison graphic below, measuring &lt;span style="font-weight:bold;"&gt;find operations&lt;/span&gt; in the three same containers.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_UXKUeU6z7xE/SsshLpqC9oI/AAAAAAAAAYc/6szGlNnvrlQ/s1600-h/fin-comp.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 226px;" src="http://2.bp.blogspot.com/_UXKUeU6z7xE/SsshLpqC9oI/AAAAAAAAAYc/6szGlNnvrlQ/s320/fin-comp.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5389437863123416706" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;But, what happened to green line (map's find operation)? This is a common issue you'll get when comparing very different measuring scales. Map's searches are so fast, comparing with the vector or list ones. So, you cannot see the green line because is very near to X axis, in other words, with low times. You need to change scale, but anyway you can see here that vector and list find operations are linear ( O(n) ), with different constants (again vector has lower constant). To view if map searching operation behaves like a logarithmic one, we represent independently the third curve.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_UXKUeU6z7xE/SssjWvWaXiI/AAAAAAAAAYk/IAyvjmFZNeA/s1600-h/mapfin.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 223px;" src="http://2.bp.blogspot.com/_UXKUeU6z7xE/SssjWvWaXiI/AAAAAAAAAYk/IAyvjmFZNeA/s320/mapfin.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5389440252653493794" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;And finally, it behaves like a logarithmic curve!.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-7647328884189199412?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/7647328884189199412/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=7647328884189199412&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7647328884189199412'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7647328884189199412'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/10/its-all-about-complexity.html' title='It&apos;s all about complexity'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_UXKUeU6z7xE/SssZ5_d1K-I/AAAAAAAAAYU/r-E5Wh1x0Zg/s72-c/ins-comp.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-8514808682170567093</id><published>2009-10-06T10:00:00.004+02:00</published><updated>2009-10-06T10:04:26.039+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>The Duct Tape Programmer</title><content type='html'>Do you think you're a &lt;a href="http://www.joelonsoftware.com/items/2009/09/23.html"&gt;Duct Tape Programmer&lt;/a&gt;? It's more difficult than people think. Another Spolsky's great article.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;And the duct-tape programmer is not afraid to say, “multiple inheritance sucks. Stop it. Just stop.”&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;...you’re not here to write code; you’re here to ship products.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;One principle duct tape programmers understand well is that any kind of coding technique that’s even slightly complicated is going to doom your project. Duct tape programmers tend to avoid C++, templates, multiple inheritance, multithreading, COM, CORBA, and a host of other technologies that are all totally reasonable, when you think long and hard about them, but are, honestly, just a little bit too hard for the human brain.&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-8514808682170567093?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/8514808682170567093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=8514808682170567093&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8514808682170567093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8514808682170567093'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/10/duct-tape-programmer.html' title='The Duct Tape Programmer'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-4398113578657456045</id><published>2009-10-01T18:58:00.004+02:00</published><updated>2009-10-01T19:37:40.000+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='sqa'/><title type='text'>Journal Hook</title><content type='html'>Following last Windows focused post, I come to talk you about hooks. Well, I'm not an expert about hooks, but basically, a Windows' hook is a procedure that you can register in the operating system to intercept events before they reach an application. More information in &lt;a href="http://msdn.microsoft.com/en-us/library/ms997537.aspx"&gt;msdn&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://msdn.microsoft.com/en-us/library/ms997537.aspx"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 605px; height: 328px;" src="http://i.msdn.microsoft.com/ms997537.hooks32_1%28en-us,MSDN.10%29.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Well, in our try to automatize systems, we need to create a mechanism to intercept all mouse and keyboard messages generated by user in desktop. So, we can record something similar to &lt;span style="font-style: italic;"&gt;macros&lt;/span&gt; in Windows, and later playback them. For example, we need to automate the Skype user interaction, or the Outlook application, and then play the macro.&lt;br /&gt;&lt;br /&gt;It's a very interesting thing because, WM_MOUSEMOVE is a message too ;), and we could save it for example to perform some QA automated tests in a game, moving the avatar around scenario, capturing mouse moving and keyboard strokes. There are a lot of applications about hooks, and there are more hooks than only Journaling which is only a kind of hook.&lt;br /&gt;&lt;br /&gt;Here you have a very simple application that creates this hook and records all messages. &lt;span style="font-weight: bold;"&gt;Just a note&lt;/span&gt;: Be careful when you're executing from Visual Studio IDE, because if you set a &lt;span style="font-weight: bold;"&gt;breakpoint&lt;/span&gt; in code, the hook cannot be established correctly. Maybe it could be generated by VS thread (attached to process) which avoid messages to hook, I don't know, but it is a very rare bug, difficult to find, and can drives a team's member crazy. In fact, done it.&lt;br /&gt;&lt;br /&gt;The idea behind, you intercept all messages and serializes them&lt;span style="font-style: italic;"&gt; (lparam, wparam, time, message number, even the hwnd but have no sense)&lt;/span&gt; and when you want play them you've to feed to journal playback hook with those messages. In the code below, (all) the messages are stored in a plain txt file, but its performance can be pretty bad due to the big number of messages intercepted. You can buffer and then flush them. Also you can change this, for example, sending them by network or something. Let your imagination flies.&lt;br /&gt;&lt;br /&gt;Finally, it is not a new thing, you can google for "&lt;span style="font-style: italic;"&gt;winmacro&lt;/span&gt;" and you'll find an open software (with source code) which does this journaling stuff, but with an own interface and more control. Anyway, in my code below you only have a record feature. Playback in another post...&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dimensoft.com/data/code/journal_record.cpp"&gt;CPP file here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#include &amp;lt;windows.h&amp;gt;&lt;windows.h&gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;stdio.h&gt;// -- wow, two global objects!&lt;br /&gt;static HHOOK gHookHandle = 0;&lt;br /&gt;static FILE* gFile = NULL;&lt;br /&gt;&lt;br /&gt;LRESULT CALLBACK JournalRecordProc(int code ,WPARAM wparam,LPARAM lparam)&lt;br /&gt;{&lt;br /&gt;if ( code == HC_ACTION )&lt;br /&gt;{ &lt;br /&gt; EVENTMSG* mesg = (EVENTMSG *)lparam; &lt;br /&gt; // -- Serializes entire message&lt;br /&gt; fprintf_s( gFile, "%d %d %d %d %d\n", mesg-&gt;message, mesg-&gt;paramL, mesg-&gt;paramH, mesg-&gt;time, (UINT)mesg-&gt;hwnd );&lt;br /&gt; // -- Exiting when PAUSE key is pressed&lt;br /&gt; if ( mesg-&gt;message == WM_KEYDOWN &amp;amp;&amp;amp; GetAsyncKeyState(VK_PAUSE) )&lt;br /&gt; {&lt;br /&gt;  const LRESULT result = CallNextHookEx( gHookHandle, code, wparam, lparam);&lt;br /&gt;  UnhookWindowsHookEx( gHookHandle );&lt;br /&gt;  gHookHandle = 0;&lt;br /&gt;  PostQuitMessage(0);&lt;br /&gt;  return result;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;return CallNextHookEx( gHookHandle, code, wparam, lparam );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// WinMain&lt;br /&gt;// --------&lt;br /&gt;int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )&lt;br /&gt;{&lt;br /&gt;// -- Record hook and file to store messages&lt;br /&gt;if ( (gHookHandle = SetWindowsHookEx(WH_JOURNALRECORD, JournalRecordProc, hInstance, 0) ) == NULL )&lt;br /&gt; return 1;&lt;br /&gt;if ( (gFile = fopen( "msgs.txt", "wt" ) ) == NULL  )&lt;br /&gt; return 1;&lt;br /&gt;fprintf_s( gFile, "# Message ParamL ParamH Time HWND\n" );&lt;br /&gt;&lt;br /&gt;// -- Main message dispatching&lt;br /&gt;MSG msg = {0};&lt;br /&gt;GetMessage(&amp;amp;msg, 0, NULL, NULL );&lt;br /&gt;while ( msg.message != WM_QUIT )&lt;br /&gt;{&lt;br /&gt; TranslateMessage( &amp;amp;msg );&lt;br /&gt; DispatchMessage( &amp;amp;msg ); &lt;br /&gt; GetMessage(&amp;amp;msg, 0, NULL, NULL );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// -- Closing&lt;br /&gt;fclose( gFile );&lt;br /&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/stdio.h&gt;&lt;/windows.h&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-4398113578657456045?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/4398113578657456045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=4398113578657456045&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4398113578657456045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4398113578657456045'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/10/journal-hook.html' title='Journal Hook'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-4702380547824075312</id><published>2009-10-01T18:31:00.004+02:00</published><updated>2009-10-01T18:41:05.785+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='media'/><title type='text'>Advanced Windows Debugging</title><content type='html'>My company just bought it. &lt;a href="http://advancedwindowsdebugging.com/"&gt;A must-to-have book.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://advancedwindowsdebugging.com"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 240px; height: 320px;" src="http://1.bp.blogspot.com/_UXKUeU6z7xE/SsTalwmT9SI/AAAAAAAAAYM/fENS8KBOa6U/s320/photo.jpg" alt="" id="BLOGGER_PHOTO_ID_5387671396477564194" border="0" /&gt;&lt;/a&gt; &lt;center&gt;&lt;span style="font-size:85%;"&gt;Me, pretty happy&lt;/span&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-4702380547824075312?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/4702380547824075312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=4702380547824075312&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4702380547824075312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4702380547824075312'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/10/advanced-windows-debugging.html' title='Advanced Windows Debugging'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_UXKUeU6z7xE/SsTalwmT9SI/AAAAAAAAAYM/fENS8KBOa6U/s72-c/photo.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-5423796877343159966</id><published>2009-09-26T16:49:00.008+02:00</published><updated>2009-09-26T17:18:13.359+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='media'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>Colin McRae: Dirt</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.codemasters.co.uk/games/index.php?gameid=2012"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 225px; height: 320px;" src="http://3.bp.blogspot.com/_UXKUeU6z7xE/Sr4uv_jbcxI/AAAAAAAAAYE/LrszTgJzmCU/s320/colin-mcrae-dirt-xbox-3601.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5385793606430454546" /&gt;&lt;/a&gt;This so addictive game really impressed me by its playability. The graphics aren't bad, and you have a lot of gaming modes, vehicles and tracks. When you're playing for a while, you get an inmersive experience, and is cool how you're running at 160km/h, listening to your co-driver giving you track information, while the car is skidding near to the trees.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And the menus are incredible. As you can see in the video below, menus are in real 3D space, with special effects and movement. An off voice is telling you tips and tricks, depending on your selected race configuration, and you can review all kind of statistics about your profile progress while the race is loading.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And finally, the best of all, I bought an original copy only for 9.95€. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/n9NWK4qPOgU&amp;amp;hl=es&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/n9NWK4qPOgU&amp;amp;hl=es&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-5423796877343159966?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/5423796877343159966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=5423796877343159966&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5423796877343159966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5423796877343159966'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/09/colin-mcrae-dirt.html' title='Colin McRae: Dirt'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_UXKUeU6z7xE/Sr4uv_jbcxI/AAAAAAAAAYE/LrszTgJzmCU/s72-c/colin-mcrae-dirt-xbox-3601.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-7494064864036542283</id><published>2009-09-23T11:48:00.002+02:00</published><updated>2009-09-23T12:05:08.812+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Bjarne Stroustup on C++0x {cvu}</title><content type='html'>Yesterday, a coworker passed me a pdf extracted form the {cuv} magazine, Sep09, where Bjarne Stroustup talks briefly about the incoming c++ standard revision, c++0x. Last revision was c++98.&lt;br /&gt;&lt;br /&gt;At the beginning of article, he says:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;‘What will C++ be once we have the facilities offered by the upcoming&lt;br /&gt;standard?’ This is not an innocent ‘just philosophical’ question. Consider&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;how many programmers have been harmed by believing that ‘C++ is an&lt;br /&gt;object-oriented language&lt;/span&gt;’ and ‘religiously’ built all code into huge class&lt;br /&gt;hierarchies, missing out on simpler, more modular approaches and on&lt;br /&gt;generic programming. Of course C++ also supports OOP, but a simple&lt;br /&gt;label – especially if supported by doctrinaire teaching – can do harm by&lt;br /&gt;overly narrowing a programmer’s view of what can be considered&lt;br /&gt;reasonable code.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Is interesting what the main creator of c++ thinks about using it in complex Object Oriented systems.&lt;br /&gt;&lt;br /&gt;You can download the &lt;a href="http://www.dimensoft.com/data/A9ROqIdHeM.pdf"&gt;pdf here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-7494064864036542283?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/7494064864036542283/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=7494064864036542283&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7494064864036542283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7494064864036542283'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/09/bjarne-stroustup-on-c0x-cvu.html' title='Bjarne Stroustup on C++0x {cvu}'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-3736193776449304608</id><published>2009-09-23T08:41:00.005+02:00</published><updated>2009-09-23T09:49:27.111+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='raytracing'/><category scheme='http://www.blogger.com/atom/ns#' term='gpu'/><category scheme='http://www.blogger.com/atom/ns#' term='media'/><category scheme='http://www.blogger.com/atom/ns#' term='fractals'/><title type='text'>Elevated</title><content type='html'>Did you remember the last breakpoint's 4k intro winner?: Yes, you did, Elevated!&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object height="340" width="560"&gt;&lt;param name="movie" value="http://www.youtube.com/v/_YWMGuh15nE&amp;amp;hl=es&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/_YWMGuh15nE&amp;amp;hl=es&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="340" width="560"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;How did he done it? How did he compress all assets in only 4 kilobytes? Well, he actually didn't compress any asset: he generates textures, geometry, sounds, ... procedurally, using parametric functions, and programming hacky code to save until last byte, also he used &lt;a href="http://www.google.es/search?q=raymarching&amp;amp;ie=utf-8&amp;amp;oe=utf-8&amp;amp;aq=t&amp;amp;rls=com.ubuntu:es-ES:unofficial&amp;amp;client=firefox-a"&gt;raymarching&lt;/a&gt; algorithms (some similar to raytracing on GPU) to generate all the geometry in only two triangles, by programming a very complex pixel shader. Also, like most of 4k intros, a special linker can be used to reduce final object code. &lt;a href="http://www.crinkler.net/"&gt;Crinkler&lt;/a&gt; or similar. That linker, instead of MS or GNU ones, is capable of compress with high rates, ignoring most of unused standard libraries. Iñigo Quilez (RGBA) has presented a "&lt;span style="font-style:italic;"&gt;behind the scenes&lt;/span&gt;" &lt;a href="http://iquilezles.org/www/material/function2009/function2009.htm"&gt;presentation here&lt;/a&gt;. Amazing!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-3736193776449304608?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/3736193776449304608/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=3736193776449304608&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/3736193776449304608'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/3736193776449304608'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/09/elevated.html' title='Elevated'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-8173986858663485363</id><published>2009-09-22T20:15:00.002+02:00</published><updated>2009-09-22T20:17:45.068+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ai'/><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>Fantastic AI in Neurogence</title><content type='html'>In &lt;a href="http://neurogence.blogspot.com"&gt;Neurogence&lt;/a&gt;, my another blog related with Artificial Intelligence, I've post an article about how I implemented the Artificial Intelligence for players in a non-interactive football game: &lt;a href="http://www.fantasticleague.com"&gt;Fantastic League&lt;/a&gt;, when I was working at &lt;a href="http://www.gextech.com"&gt;Gextech&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://neurogence.blogspot.com/2009/09/fantastic-ai.html"&gt;Post here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-8173986858663485363?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/8173986858663485363/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=8173986858663485363&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8173986858663485363'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8173986858663485363'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/09/fantastic-ai-in-neurogence.html' title='Fantastic AI in Neurogence'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-1346614292905000200</id><published>2009-09-09T11:34:00.004+02:00</published><updated>2009-09-09T12:46:09.733+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='sqa'/><category scheme='http://www.blogger.com/atom/ns#' term='parallel'/><title type='text'>SQA Automation</title><content type='html'>Last months I've been working on the automation system for our products, here at &lt;a href="http://www.optenet.com"&gt;Optenet&lt;/a&gt;. As senior software architect I've been in charge of analysis, design, implementation and team management for several internal tools and procedures to automate sqa test cases, having developed with success:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; A set of &lt;span style="font-weight: bold;"&gt;libraries&lt;/span&gt; to automate all company's common tasks to test features and functionality related with our filtering solutions. Libraries to generate protocols traffic, web requesting, mail sending,... &lt;/li&gt;&lt;li&gt;A set of &lt;span style="font-weight: bold;"&gt;procedures&lt;/span&gt; to automate manual test cases, making use of the library above. We use selenium and qantium (an own .net component similar to selenium).&lt;/li&gt;&lt;li&gt;A &lt;span style="font-weight: bold;"&gt;clusters&lt;/span&gt; system, where to run automated test cases in parallel. Our clusters can run up to 50 test cases simultaneously. The typical test case's duration can be about 10/11 minutes. Also, the cluster is capable of resolving dependencies, and supports both technologies, selenium and qantium.&lt;/li&gt;&lt;li&gt;A &lt;span style="font-weight: bold;"&gt;.net application&lt;/span&gt; where non-technical people can automate test cases, without programming knowledge. It works like Visual Studio, acting like the designer. This application generates (transparent) source code for testcases, depending on actions registered about web clicking and other specific actions, which is sending to cluster to run. Also this tool communicates with database the results and stores in it the testcase in xml format.&lt;/li&gt;&lt;li&gt;A .net &lt;span style="font-weight: bold;"&gt;debugger&lt;/span&gt; for test case visual debugging like visual studio, so the user can be in realtime how the testcase is being executed in its solution.&lt;/li&gt;&lt;li&gt;A solution to integrate our modular and advanced product configuration, making use of &lt;span style="font-weight: bold;"&gt;virtualization&lt;/span&gt; (vmware mainly) with an internal network.&lt;/li&gt;&lt;li&gt;Other minor stuff related with scripting and &lt;span style="font-weight: bold;"&gt;technologies integration&lt;/span&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Technically speaking we've integrated a lot of technologies, machines, languages and procedures. Creating an internal and powerful protocol based on byte-code communication between processes along multiple machines. We've used c++, c#, asp.net, python, perl, shell scripting, com, soap and our protocol (like mpi) among others.&lt;br /&gt;&lt;br /&gt;You can see a very basic and summarized presentation below.&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;div style="width: 425px; text-align: left;" id="__ss_1971615"&gt;&lt;a style="margin: 12px 0pt 3px; font-family: Helvetica,Arial,Sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 14px; line-height: normal; font-size-adjust: none; font-stretch: normal; display: block; text-decoration: underline;" href="http://www.slideshare.net/gyakoo/sqa-automation" title="Sqa Automation"&gt;Sqa Automation&lt;/a&gt;&lt;object style="margin: 0px;" height="355" width="425"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=sqaautomationpreliminar-090909040657-phpapp02&amp;amp;stripped_title=sqa-automation"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=sqaautomationpreliminar-090909040657-phpapp02&amp;amp;stripped_title=sqa-automation" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="355" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;"&gt;View more &lt;a style="text-decoration: underline;" href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a style="text-decoration: underline;" href="http://www.slideshare.net/gyakoo"&gt;gyakoo&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-1346614292905000200?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/1346614292905000200/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=1346614292905000200&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/1346614292905000200'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/1346614292905000200'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/09/sqa-automation.html' title='SQA Automation'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-7735269012451449861</id><published>2009-09-03T15:08:00.008+02:00</published><updated>2009-09-06T10:36:00.630+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Break in August</title><content type='html'>&lt;ul&gt;&lt;li&gt;Relax: No sport, no computers, no freakism, swimming pool.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Reading classics: &lt;a href="http://en.wikipedia.org/wiki/Ringworld"&gt;Ringworld&lt;/a&gt; (Larry Niven), &lt;a href="http://en.wikipedia.org/wiki/Ender%27s_Game"&gt;Ender's game&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Ender%27s_Shadow"&gt;Ender's shadows&lt;/a&gt; (Orson Scott Card),&lt;a href="http://en.wikipedia.org/wiki/The_Fencing_Master"&gt;The Fencing Master&lt;/a&gt; (A. Perez Reverte), &lt;a href="http://en.wikipedia.org/wiki/Gateway_%28novel%29"&gt;Gateway&lt;/a&gt; (Frederik Pohl), &lt;a href="http://es.wikipedia.org/wiki/Cuentos_completos_I"&gt;The complete stories I&lt;/a&gt; (I. Asimov)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Holidays in Paris and Disneyland.&lt;/li&gt;&lt;li&gt;Planning my incoming wedding (Yes, I'll get married next year).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Fixing the car.&lt;/li&gt;&lt;li&gt;... and ... working hard.&lt;/li&gt;&lt;/ul&gt;That was my August.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-7735269012451449861?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/7735269012451449861/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=7735269012451449861&amp;isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7735269012451449861'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7735269012451449861'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/09/break-in-august.html' title='Break in August'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-7175605240902284627</id><published>2009-07-23T12:36:00.004+02:00</published><updated>2009-07-23T12:41:18.161+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><title type='text'>C++0x wiki page</title><content type='html'>As you already know, the new c++ standard is code named c++0x.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/C%2B%2B0x"&gt;Here&lt;/a&gt; you have a good wiki page where to learn more about changes and improvements:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/C%2B%2B0x"&gt;http://en.wikipedia.org/wiki/C%2B%2B0x&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-7175605240902284627?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/7175605240902284627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=7175605240902284627&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7175605240902284627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7175605240902284627'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/07/c0x-wiki-page.html' title='C++0x wiki page'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-4398843747237536907</id><published>2009-07-15T20:23:00.007+02:00</published><updated>2009-07-15T20:44:24.114+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='hlsl'/><category scheme='http://www.blogger.com/atom/ns#' term='gpu'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='fractals'/><title type='text'>Mandelbrot on GPU</title><content type='html'>Mandel fractal, what a classic!,&lt;br /&gt;here you have a very simple code in HLSL using Shader Model 3 to draw the fractal using the GPU.&lt;br /&gt;&lt;br /&gt;Using floats is not recommended due to low precision, but in SM3 we have not double types yet (only in SM4+), as well as only up to 256 iteration loops. But to represent the overall fractal, in the range CMin = { -2.0f, -1.0f } CMax = { +1.0f, 1.0f } it is enough.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_UXKUeU6z7xE/Sl4itAjf1sI/AAAAAAAAAXs/J0iQGj_4ohU/s1600-h/mandelgpu.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 250px;" src="http://4.bp.blogspot.com/_UXKUeU6z7xE/Sl4itAjf1sI/AAAAAAAAAXs/J0iQGj_4ohU/s320/mandelgpu.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5358758763255813826" /&gt;&lt;/a&gt;&lt;br /&gt;Apart from the shader code, in C++ you should have a quad covering the entire screen area and then apply this shader before to draw it. So, you don't use any texture, instead the color for each pixel is computed by computing the fractal value for that pixel.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;float2 CMin = { -2.0f, -1.0f };&lt;br /&gt;float2 CMax = { +1.0f, 1.0f };&lt;br /&gt;float2 pixelSize = {1.0f,1.0f};&lt;br /&gt;int Mode = 0;&lt;br /&gt;//////// COMPLEX N. COMPUTATIONS ////////////&lt;br /&gt;float2 mulcomplex(float2 A, float2 B)&lt;br /&gt;{&lt;br /&gt;    return float2(A.x*B.x-A.y*B.y, A.y*B.x+A.x*B.y);&lt;br /&gt;}&lt;br /&gt;float2 sqcomplex(float2 c)&lt;br /&gt;{&lt;br /&gt;    return mulcomplex(c,c);&lt;br /&gt;}&lt;br /&gt;float2 expcomplex(float2 c)&lt;br /&gt;{&lt;br /&gt;    float ex = pow(2.7182818f,c.x);&lt;br /&gt;    return float2( ex*cos(c.y), ex*sin(c.y) );&lt;br /&gt;}&lt;br /&gt;float lencomplex(float2 c)&lt;br /&gt;{&lt;br /&gt;    return sqrt( c.x*c.x + c.y*c.y );&lt;br /&gt;}&lt;br /&gt;///////// STRUCTURES //////////////////////////&lt;br /&gt;struct VSINOUT&lt;br /&gt;{&lt;br /&gt;    float4 pos : POSITION;&lt;br /&gt;    float2 uv  : TEXCOORD0;&lt;br /&gt;};&lt;br /&gt;///////// VERTEX SHADING //////////////////////&lt;br /&gt;VSINOUT vs_basic(VSINOUT vsin)&lt;br /&gt;{&lt;br /&gt;    VSINOUT vsout;&lt;br /&gt;    vsout.pos = vsin.pos;&lt;br /&gt;    vsout.uv = vsin.uv;&lt;br /&gt;    return vsout;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;///////// PIXEL SHADING //////////////////////&lt;br /&gt;float4 ps_mandel(float2 uv:TEXCOORD0) : COLOR&lt;br /&gt;{ &lt;br /&gt;    float2 C = float2(CMin.x + uv.x*(CMax.x-CMin.x)*pixelSize.x,&lt;br /&gt;                      CMin.y + uv.y*(CMax.y-CMin.y)*pixelSize.y);&lt;br /&gt;    float2 Z = float2(0.0f,0.0f);&lt;br /&gt;    float2 lastZ = Z;&lt;br /&gt;    int maxiters = 254;&lt;br /&gt;    int iter = 0;&lt;br /&gt;    while ( iter &amp;lt; maxiters )&lt;br /&gt;    {&lt;br /&gt;        lastZ = Z;&lt;br /&gt;        Z = sqcomplex(Z) + C;&lt;br /&gt;        if ( Z.x*Z.x + Z.y*Z.y &amp;gt;= 200.0f ) break;&lt;br /&gt;        iter = iter + 1;&lt;br /&gt;    }&lt;br /&gt;    float4 color = float4(0,0,0,1);&lt;br /&gt;    if ( iter &amp;lt; maxiters )&lt;br /&gt;    {&lt;br /&gt;        float dt = 1.718281f/253.0f;&lt;br /&gt;        float cf = saturate( log(1.0f+dt*iter*8.0f));&lt;br /&gt;        color = float4(0.0f,0.0f,cf,1.0f);&lt;br /&gt;    }&lt;br /&gt;    return color;&lt;br /&gt;}&lt;br /&gt;///// TECHNIQUES /////////////////////////////&lt;br /&gt;technique Main&lt;br /&gt;{&lt;br /&gt;    pass p0&lt;br /&gt;    { &lt;br /&gt;        VertexShader = compile vs_3_0 vs_basic();&lt;br /&gt;        PixelShader = compile ps_3_0 ps_mandel();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-4398843747237536907?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/4398843747237536907/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=4398843747237536907&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4398843747237536907'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4398843747237536907'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/07/mandelbrot-on-gpu.html' title='Mandelbrot on GPU'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_UXKUeU6z7xE/Sl4itAjf1sI/AAAAAAAAAXs/J0iQGj_4ohU/s72-c/mandelgpu.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-1708967266460047830</id><published>2009-07-14T19:54:00.007+02:00</published><updated>2009-07-15T09:35:52.605+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='media'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>Space Invaders C++/DX</title><content type='html'>&lt;div style="text-align: left;"&gt;A two months ago I was thinking in a very simple idea, but difficult in essence: Could I program an entire game only in a few hours?. Well, it's a trap question. Of course I can, if the game is a pong or .... a space invaders, not a MMO.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img src="http://2.bp.blogspot.com/_UXKUeU6z7xE/SlzMnK2L3cI/AAAAAAAAAXU/9Ci3H3wEZ8o/s200/spaceinv0.jpg" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 145px;" alt="" id="BLOGGER_PHOTO_ID_5358382629962636738" border="0" /&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It's not impossible if you keep in mind a very basic concept, and you're pragmatic when programming. An opportunity came, to show to myself if I was able to do it, and started to work. I had to control my creative personality, both in design and implementation, because you have no idea how your programmer brain can diverge when you're encapsulating code in a class, or creating an entity system, but I done it (I think so). As you see, the main handicap with this project was the time constraint.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You can download the project here: &lt;a href="http://www.dimensoft.com/data/dx-space-invaders.zip"&gt;DX Space invaders&lt;/a&gt; (source + binaries)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img src="http://3.bp.blogspot.com/_UXKUeU6z7xE/SlzNbEqsogI/AAAAAAAAAXc/B9TTw6-B02k/s200/spaceinv1.jpg" style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 145px;" alt="" id="BLOGGER_PHOTO_ID_5358383521657037314" border="0" /&gt;&lt;/div&gt;&lt;div&gt;The project was structured in modules: a namespace in a cpp object that contains all necessary to encapsulate its tasks. They're a kind of singleton classes. You have modules like Sounds, Graphics, System and Game. The last one is the most interesting, it contains all entity code and game logic for invaders and stages. Sorry for the poor encapsulation there, but I didn't refactorize it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A curiosity: there aren't news/deletes in code. During game, system doesn't use dynamic memory. All remain in stack.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-1708967266460047830?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/1708967266460047830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=1708967266460047830&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/1708967266460047830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/1708967266460047830'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/07/space-invaders-cdx.html' title='Space Invaders C++/DX'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_UXKUeU6z7xE/SlzMnK2L3cI/AAAAAAAAAXU/9Ci3H3wEZ8o/s72-c/spaceinv0.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-1047972439328834712</id><published>2009-07-13T14:52:00.009+02:00</published><updated>2009-07-15T09:35:25.452+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><category scheme='http://www.blogger.com/atom/ns#' term='parallel'/><title type='text'>Absence and DNS server</title><content type='html'>Hi all,&lt;br /&gt;&lt;br /&gt;after about three months of absence, I come back here to post my geek thinks and things. In that time, my life hasn't really changed, or at least visibly changed, but my person does. I'm starting another post to share with you a philosophical dissertation about my current life, but now, let's freaking:&lt;br /&gt;&lt;br /&gt;Lastly I've b&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_UXKUeU6z7xE/Sls29uiuETI/AAAAAAAAAXM/3CTwEZ62f8c/s1600-h/dns.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 200px; height: 124px;" src="http://2.bp.blogspot.com/_UXKUeU6z7xE/Sls29uiuETI/AAAAAAAAAXM/3CTwEZ62f8c/s200/dns.png" alt="" id="BLOGGER_PHOTO_ID_5357936615780913458" border="0" /&gt;&lt;/a&gt;een implementing (among other things) a single standard &lt;a href="http://en.wikipedia.org/wiki/Domain_Name_System"&gt;DNS server&lt;/a&gt; to support &lt;a href="http://http//en.wikipedia.org/wiki/Reverse_DNS_lookup"&gt;inverse queries&lt;/a&gt; (see &lt;a href="http://www.faqs.org/rfcs/rfc1035.html"&gt;RFC1035&lt;/a&gt;), in C++.&lt;br /&gt;Well, it was an interesting exercise, specially in the optimization side of the program, because of the stability and performance issues due to large amount of incoming connections and stored IPs/domain associations. The server was developed in six days and neither STL nor another third party library was used. As you know, I actually love to do this kind of things for learning purposes.&lt;br /&gt;&lt;br /&gt;You can &lt;span style="font-weight: bold;"&gt;download&lt;/span&gt; the project from: &lt;a class="moz-txt-link-freetext" href="http://www.dimensoft.com/data/code/dnsserv.tgz"&gt;http://www.dimensoft.com/data/code/dnsserv.tgz&lt;/a&gt;&lt;br /&gt;The sources are both for linux and win32 platforms, but only makefile for linux is provide (you should to create a VS solution or similar for windows).&lt;br /&gt;&lt;br /&gt;Some interesting things and features:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I had to learn how a DNS server works, at least for inverse queries: Given an IP, the DNS server resolves which hostname is associated to it.&lt;/li&gt;&lt;li&gt;I had to learn how a DNS packets are formatted, researching in &lt;a href="http://www.blogger.com/www.ietf.org/rfc/rfc1035.txt"&gt;RFC1035.&lt;/a&gt; It was a hard part because of some responds packets didn't work and the dns client didn't recognize them. I had to sniff packets using tcpdump (&lt;a href="http://www.wireshark.org/"&gt;wireshark&lt;/a&gt;) and decode them with real traffic using real dns servers.&lt;/li&gt;&lt;li&gt;UDP protocol.&lt;/li&gt;&lt;li&gt;Socket, thread, lock and condition classes multiplatform for linux and win32. The rest of code is ansi c++.&lt;/li&gt;&lt;li&gt;To support simultaneous queries from clients I implemented a special kind of &lt;a style="font-weight: bold;" href="http://en.wikipedia.org/wiki/Thread_pool_pattern"&gt;threads' pool&lt;/a&gt;. It uses N threads, each containing a tasks' queue. When a query packet is received by UDP, the best worker thread (balancing load or simply by &lt;a href="http://en.wikipedia.org/wiki/Round_robin_DNS"&gt;round robin&lt;/a&gt; algorithm) is selected and the task for this query is created and enqueued it. The threads are waiting for a thread condition, which is signaled when a new task is enqueued. So with this we avoid &lt;a href="http://en.wikipedia.org/wiki/Spinlock"&gt;spinlocks&lt;/a&gt; by reading and checking the queue's size. By default, 4 threads and 128 max. connections (queue size) per thread are used.&lt;/li&gt;&lt;li&gt;Currently each thread performs the IP searching in structure, being a bottleneck here, so we could have another threads' pool for IP searching.&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/IPv4"&gt;IPv4&lt;/a&gt;, this is, 4 bytes = 2³² ips = 32 bits to represents an IP.&lt;/li&gt;&lt;li&gt;Find an optimal (both in space and time) structure to store IP/host domains associations was not an easy issue. In fact I think this is the hardest part of this program. Finally I used a &lt;a style="font-weight: bold;" href="http://en.wikipedia.org/wiki/Trie"&gt;prefix tree&lt;/a&gt; to store IPs. A spatial optimization for this could be a &lt;a href="http://en.wikipedia.org/wiki/Radix_tree"&gt;radix-tree&lt;/a&gt; (aka patricia trie), which collapses single paths in a leaf. The one used here is the prefix tree, which has 4 levels of depth. Each node contains an array of up to 256 possible children nodes, ordered for &lt;a href="http://en.wikipedia.org/wiki/Binary_search_algorithm"&gt;binary searching&lt;/a&gt; algorithm. So, we have a constant complexity order in searchs, O(k), with a multiplicative constant of 32 comparisons ( log2(256) * 4 ). This is because the sorting of arrays and binary search, otherwise we would have also O(k) but with a multiplicative constant of 1024 (256*4). In our case, O(k) means that doesn't matter how big the tree is or the number of stored IP, always we will perform same number of comparisons in worst case to find our domain name.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;You can read more notes about solution in &lt;a href="http://www.dimensoft.com/data/code/dns-readme.txt"&gt;README&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-1047972439328834712?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/1047972439328834712/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=1047972439328834712&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/1047972439328834712'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/1047972439328834712'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/07/absence-and-dns-server.html' title='Absence and DNS server'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_UXKUeU6z7xE/Sls29uiuETI/AAAAAAAAAXM/3CTwEZ62f8c/s72-c/dns.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-2592514622217596449</id><published>2009-03-31T00:26:00.005+02:00</published><updated>2009-03-31T08:51:45.622+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>How to design a good API</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://en.wikipedia.org/wiki/API"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 200px; height: 138px;" src="http://4.bp.blogspot.com/_UXKUeU6z7xE/SdFQmqbK9SI/AAAAAAAAAXE/HAp-fsxX7GY/s200/api.png" alt="" id="BLOGGER_PHOTO_ID_5319121260054770978" border="0" /&gt;&lt;/a&gt;Is a matter of fact that a good &lt;a href="http://en.wikipedia.org/wiki/API"&gt;API&lt;/a&gt; design matters. Everybody knows this issue, but really are the principles of &lt;a href="http://www.d.umn.edu/%7Egshute/softeng/principles.html"&gt;good design&lt;/a&gt; applied in companies? Well, it depends but in general it is difficult, sometimes due to deadlines and the thinking on a rapid results more than to spend time on design robust systems.&lt;br /&gt;I think that &lt;a href="http://en.wikipedia.org/wiki/Software_engineering"&gt;software engineering&lt;/a&gt; is essential, a minimal UML diagram used to discuss some aspects of architecture sometimes help us to design a good API, because this is only a contract between creators and users (another developers), and at least we need to meet them all together. There are a lot of developers who think that UML is lost time. Some managers think it too. And then the problems arrive in a few weeks or months, usually as bugs, maintenance or growth difficulties.&lt;br /&gt;With a simple whiteboard, a meeting place, a team leader and a little bit time, we can design very good systems. A leader or a project manager needs more than one brain, and it is often forgotten. It's good for manager, developers and the entire company, but always there are people who don't see it. API aren't easy to design, but once you've got it, give us a powerful tool and a very valuable asset for company.&lt;br /&gt;Please think as an engineer.&lt;br /&gt;--&lt;br /&gt;References:&lt;br /&gt;&lt;a href="http://lcsd05.cs.tamu.edu/slides/keynote.pdf"&gt;How to design a good API and Why it matters (pdf)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://apidesign.org/"&gt;APIDesign.org&lt;/a&gt;&lt;br /&gt;&lt;a href="http://api-writing.blogspot.com/"&gt;API-writing blog&lt;/a&gt;&lt;br /&gt;&lt;a href="http://discuss.fogcreek.com/joelonsoftware/default.asp?cmd=show&amp;amp;ixPost=15878"&gt;Fog creek on API design&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.artima.com/forums/forum.jsp?forum=17"&gt;Artima forums: Design&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.faqs.org/docs/artu/ch04s02.html"&gt;Compactness and Orthogonality&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-2592514622217596449?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/2592514622217596449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=2592514622217596449&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/2592514622217596449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/2592514622217596449'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/03/how-to-design-good-api.html' title='How to design a good API'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_UXKUeU6z7xE/SdFQmqbK9SI/AAAAAAAAAXE/HAp-fsxX7GY/s72-c/api.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-8770783383367338372</id><published>2009-03-28T00:49:00.003+01:00</published><updated>2009-03-28T19:06:53.387+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='media'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>Onlive and Zeebo</title><content type='html'>The future of gaming is here.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.onlive.com/index.html"&gt;Onlive&lt;/a&gt; is a microconsole (a platform) who receives the game you're playing via video streaming, something like youtube but applied to games. It uses an own video compression algorithm which gives high compression ratios, but it depends on your connection bandwidth to play in HD or not. There are already a couple of companies supporting and working on it.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.zeeboinc.com/"&gt;Zeebo&lt;/a&gt; is similar, but it is a console yet with only a (free!) internet connection to download games we want to play. It doesn't use disks.&lt;/li&gt;&lt;/ul&gt;As you can see, the future is the online distribution, to make life &lt;span style="font-weight: bold;"&gt;easier&lt;/span&gt; (no more PC requeriments), &lt;span style="font-weight: bold;"&gt;cheaper&lt;/span&gt; (these platforms will be cheap, but with a monthly/annual payment), and &lt;span style="font-weight: bold;"&gt;sure&lt;/span&gt; (avoiding piracy, or trying to).&lt;br /&gt;Well, I don't know if these new platforms will be really the future, in any case, I would like to check if the games (server) will respond rapidly when you are playing with a very quickly game like a FPS. Also, the image quality maybe won't be as good as in current consoles. (why do we want HD images if a lot of people are always playing videotubes/gametubes?)&lt;br /&gt;Only time will tell.&lt;br /&gt;--&lt;br /&gt;References:&lt;br /&gt;&lt;a href="http://www.gamedaily.com/articles/news/gdc-exclusive-david-perrys-entry-into-serverbased-gaming/?biz="&gt;More gamestreaming: Gaikai&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.eurogamer.net/articles/gdc-why-onlive-cant-possibly-work-article?page=1"&gt;Why Onlive can't possibly work&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-8770783383367338372?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/8770783383367338372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=8770783383367338372&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8770783383367338372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8770783383367338372'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/03/onlive-and-zeebo.html' title='Onlive and Zeebo'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-5736438318179401132</id><published>2009-03-27T23:08:00.007+01:00</published><updated>2009-03-28T00:04:30.147+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='media'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>EGO Technology</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://en.wikipedia.org/wiki/Neon_Engine"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 176px; height: 150px;" src="http://1.bp.blogspot.com/_UXKUeU6z7xE/Sc1WIlWLP3I/AAAAAAAAAW8/DppSzOZkgi0/s200/egologo.png" alt="" id="BLOGGER_PHOTO_ID_5318001440458489714" border="0" /&gt;&lt;/a&gt;We always are talking about the most known game engines, like the Unreal's, CryEngine, Gamebryo, IdTech or Source. Those engines are very good (and expensive too), and obviously there are a lot of marketing with them, but did you know another next-gen technologies used in games today?&lt;br /&gt;&lt;br /&gt;A couple of days ago, I'd news about the new Codemasters' technology: &lt;a href="http://en.wikipedia.org/wiki/Neon_Engine"&gt;EGO&lt;/a&gt;. It's an evolution from their Neon engine and is being entirely developed by them, since three years ago. It's a company's investment to improve all their new titles, as well as an intelligent movement to make easier the transition for next generations. EGO supports next-gen multicore in both consoles and PC, car physics (bringing deformations to new levels of realism), next-gen graphics, tools and a lot of features that make it truly powerful, and a very good choice to be used in next-gen AAA titles.&lt;br /&gt;&lt;br /&gt;The last point is that EGO is actually a fact, in other words, is being successfully used for titles like &lt;a href="http://www.codemasters.co.uk/flashpoint/index.php"&gt;Operation Flashpoint 2: Dragon Rising&lt;/a&gt; and &lt;a href="http://www.racedrivergrid.com/"&gt;Racedriver: GRID&lt;/a&gt;, with incredible results.&lt;br /&gt;&lt;br /&gt;In my opinion there are not too much companies who have the opportunity (vision and risk too) to invest in proprietary technology, like Codemasters is doing, but I think that needs a better marketing work, for example, a good website like UnrealEngine has, showing its features. Anyway I'm sure they're working on it.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object width="500" height="315"&gt;&lt;param name="movie" value="http://www.youtube.com/v/snzA4E46ra4&amp;amp;hl=es&amp;amp;fs=1&amp;amp;color1=0x006699&amp;amp;color2=0x54abd6&amp;amp;border=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/snzA4E46ra4&amp;amp;hl=es&amp;amp;fs=1&amp;amp;color1=0x006699&amp;amp;color2=0x54abd6&amp;amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="500" height="315"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;References:&lt;br /&gt;&lt;a href="http://www.gamespot.com/news/6183762.html"&gt;Gamespot: Codemasters' EGO has landed&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.codemasters.co.uk/index.php"&gt;Codemasters&lt;/a&gt;&lt;br /&gt;&lt;a href="http://http//en.wikipedia.org/wiki/List_of_game_engines"&gt;List of game engines&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-5736438318179401132?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/5736438318179401132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=5736438318179401132&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5736438318179401132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5736438318179401132'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/03/ego-technology.html' title='EGO Technology'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_UXKUeU6z7xE/Sc1WIlWLP3I/AAAAAAAAAW8/DppSzOZkgi0/s72-c/egologo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-8642372441874999321</id><published>2009-03-26T01:01:00.008+01:00</published><updated>2009-03-27T21:31:25.716+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='news'/><category scheme='http://www.blogger.com/atom/ns#' term='media'/><title type='text'>Monsters Vs Aliens</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.monstersvsaliens.com/"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 200px; height: 192px;" src="http://4.bp.blogspot.com/_UXKUeU6z7xE/ScrMxc1uCrI/AAAAAAAAAW0/zYEc-nXpCNQ/s200/Monsters+vs+Aliens.jpg" alt="" id="BLOGGER_PHOTO_ID_5317287459991456434" border="0" /&gt;&lt;/a&gt;Possibly another hit from the creators of &lt;a href="http://www.shrek.com/"&gt;Shrek&lt;/a&gt; and &lt;a href="http://www.kungfupanda.com/"&gt;Kung-fu Panda&lt;/a&gt;. It looks great.&lt;br /&gt;Since 2001 I was waiting for another comic monsters related movie in 3D. In that year Pixar released &lt;a href="http://en.wikipedia.org/wiki/Monsters,_Inc."&gt;Monsters Inc&lt;/a&gt;, the best 3D film ever (to me), difficult to beat, seriously, but seeing what the Dreamworks' guys have done in Kung-Fu Panda, MvA could be the next Oscar for the best animated feature film (&lt;a href="http://www.i4u.com/article23353.html"&gt;Pixar won the last edition with Wall-E&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Anyway we need to wait for incoming &lt;a href="http://www.pixar.com/featurefilms/up/"&gt;Pixar's Up&lt;/a&gt;, which is again directed by &lt;a href="http://en.wikipedia.org/wiki/Pete_Docter"&gt;Peter Docter&lt;/a&gt;, director of Monsters Inc, so it's very good new to me again. Coincidences?. And what about our &lt;a href="http://www.sonypictures.com/movies/planet51/"&gt;Planet 51&lt;/a&gt;? This year looks promising for computer animation industry.&lt;br /&gt;I hope you enjoy it, I will do it.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.monstersvsaliens.com/"&gt;&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-8642372441874999321?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/8642372441874999321/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=8642372441874999321&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8642372441874999321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8642372441874999321'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/03/monsters-vs-aliens.html' title='Monsters Vs Aliens'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_UXKUeU6z7xE/ScrMxc1uCrI/AAAAAAAAAW0/zYEc-nXpCNQ/s72-c/Monsters+vs+Aliens.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-3876108593464604333</id><published>2009-03-21T20:25:00.001+01:00</published><updated>2009-03-21T20:28:38.749+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='news'/><category scheme='http://www.blogger.com/atom/ns#' term='media'/><title type='text'>Incredible short</title><content type='html'>Half-life 3?, a Samsung's promotional video?, an amateur's video?&lt;br /&gt;&lt;br /&gt;&lt;object width="480" height="295"&gt;&lt;param name="movie" value="http://www.youtube.com/v/IU_reTt7Hj4&amp;amp;hl=es&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/IU_reTt7Hj4&amp;amp;hl=es&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="295"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-3876108593464604333?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/3876108593464604333/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=3876108593464604333&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/3876108593464604333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/3876108593464604333'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/03/incredible-short.html' title='Incredible short'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-5011666621950495286</id><published>2009-03-21T11:12:00.003+01:00</published><updated>2009-03-21T12:02:27.798+01:00</updated><title type='text'>Puzzles and interviews</title><content type='html'>Do you like the puzzles? Ok, and... What if those puzzles are asked you in an interview?&lt;br /&gt;In my opinion, I think that the companies who do some kind of coding test or interesting interview questions are good companies.&lt;br /&gt;Years ago, a &lt;a href="http://www.nebula-ent.com/index.html"&gt;good friend&lt;/a&gt; talk to me about it. In fact, in my &lt;a href="http://www.optenet.com/"&gt;current company&lt;/a&gt; I did an online C/C++ questionnaire and then an exercise in office. The exercise wasn't too difficult, but enough to check distinct levels of programming style.&lt;br /&gt;Something similar I did four years ago, for &lt;a href="http://www.gextech.com/"&gt;Gextech&lt;/a&gt;, and I remember a question in special, something like:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;What would you like to be, if you'd reborn?&lt;/span&gt;&lt;span&gt;&lt;br /&gt;Damn it!, I didn't study this question on school. What do I have to answer? Well,..... I would be a Cactus!&lt;br /&gt;&lt;span style="font-style: italic;"&gt;A cactus?, why?&lt;/span&gt;&lt;br /&gt;Because I like the sunshine and the peace that a cactus have. (I thought this was the last question to me..., but not).&lt;br /&gt;&lt;span&gt;Reading in &lt;a href="http://www.codinghorror.com/blog"&gt;Coding Horror&lt;/a&gt;, an &lt;a href="http://www.codinghorror.com/blog/archives/001243.html"&gt;article about puzzles and curious interview questions&lt;/a&gt; I've found this web: &lt;a href="http://www.techinterview.org/"&gt;techInterview.com&lt;/a&gt;, where you have the most freak interview questions I ever heard about. I recommend you read them if you want to move to a company you think will do these kind of interviews.&lt;br /&gt;In any case, do you think these kind of questions or puzzles are always valid? I don't think so. There are a lot of people that get nervous and block themselves, but they could be valid candidates, maybe with a more systematic or a mid-term thinking, sometimes doing the work with more careful, and you can't guess it if you only judge them with a puzzle.&lt;br /&gt;You can't build a good team with only top brilliant freaks. You'll need more meticulous people, perhaps slower than others, but with a better sense of safe work. It depends of course. Not all puzzle-solver people are freaks, and vice versa, but you understand what I say. Don't you? ;)&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-5011666621950495286?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/5011666621950495286/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=5011666621950495286&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5011666621950495286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5011666621950495286'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/03/puzzles-and-interviews.html' title='Puzzles and interviews'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-3426083460682296181</id><published>2009-03-20T11:48:00.004+01:00</published><updated>2009-03-20T12:17:36.025+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Programming Paradigms</title><content type='html'>How many programming paradigms do you actually know? Let's enumerate the most used:&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Declarative&lt;/span&gt;, like Prolog&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Imperative&lt;/span&gt;&lt;ul&gt;&lt;li&gt;Structured, like C&lt;/li&gt;&lt;li&gt;Object Oriented, like Java&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Event driven&lt;/span&gt;, like C# or OO Pascal (Delphi)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;More...? Well, in this page you'll see quite a few: &lt;a href="http://en.wikipedia.org/wiki/Programming_paradigm"&gt;Programming Paradigms&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I recommend those rare like &lt;a href="http://en.wikipedia.org/wiki/Nondeterministic_programming"&gt;Nondeterministic&lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Feature_Oriented_Programming"&gt;Feature Oriented&lt;/a&gt; ones. They're interesting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-3426083460682296181?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/3426083460682296181/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=3426083460682296181&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/3426083460682296181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/3426083460682296181'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/03/programming-paradigms.html' title='Programming Paradigms'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-505061909558088555</id><published>2009-03-17T13:49:00.010+01:00</published><updated>2009-03-20T12:18:06.137+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='news'/><title type='text'>Neurogence. My new AI blog.</title><content type='html'>For a long time I was thinking about to post more articles on AI in this blog. As the matter of fact even I wanted to post a series of techniques, algorithms, ideas about AI for gaming, but never I did it.&lt;br /&gt;This thinking comes again to me recently, because of I'm reading two books  about AI, and have &lt;span style="font-style: italic;"&gt;cleaned&lt;/span&gt; all my knowledge base about the artificial intelligence discipline, to re-start with a new (and hope more robust) approach. These books are:&lt;br /&gt;&lt;br /&gt;- &lt;span style="font-style: italic;"&gt;Roger Penrose's The emperor's new mind&lt;/span&gt;: A deep reflexion and demonstration about why the AI as science will not be able to build really thinking machines like in Sci-Fi books and films.&lt;br /&gt;&lt;br /&gt;- &lt;span style="font-style: italic;"&gt;An academic 1.3k pages book&lt;/span&gt;, written by several university teachers in Spain, with a lot of solutions, applications, methodologies, tools, algorithms, techniques and theory in general.&lt;br /&gt;&lt;br /&gt;I was working for three years in a &lt;a href="http://www.fantasticleague.com/"&gt;non-interactive football game&lt;/a&gt; in AI for players. Finite state machines for low level (animation selection and blending) and a fixed/imperative rule based system for high level (strategy and position in field) techniques were used. Vector forces and some trigonometric/linear algebra was necessary of course. But no neuronal networks, no genetic algorithms, no learning machines, and even so the results were very good for our purposes (a mix between AI and statistical sequences).&lt;br /&gt;I've found some people with the thinking of &lt;span style="font-style: italic;"&gt;"NN are the solution to all our problems"&lt;/span&gt; or &lt;span style="font-style: italic;"&gt;"with a genetic algorithm we solve it"&lt;/span&gt; or even &lt;span style="font-style: italic;"&gt;"A* for every situation"&lt;/span&gt;. Sometimes, we don't need to make our lives harder just because, and a good understanding about the difference between AI as science or AI as Knowledge Engineering is elemental to put limits to AI, and go right to the point.&lt;br /&gt;&lt;br /&gt;And so &lt;a href="http://neurogence.blogspot.com"&gt;Neurogence&lt;/a&gt; is created. This is my new blog about AI in general (not only for games).&lt;br /&gt;Initially this blog site will contain a few articles, news and links. I'll need more time to make a good site. I've a lot of ideas about this blog, but the time is insufficient, you know, I hope you like it. By the way, if somebody wants to contribute to Neurogence, let me know by send a mail to &lt;a href="mailto:gyakoo@gmail.com"&gt;gyakoo@gmail.com&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-505061909558088555?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/505061909558088555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=505061909558088555&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/505061909558088555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/505061909558088555'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/03/neurogence-my-new-ai-blog.html' title='Neurogence. My new AI blog.'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-604795408618587958</id><published>2009-03-14T10:25:00.003+01:00</published><updated>2009-03-20T12:18:25.111+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='news'/><title type='text'>Links Soup</title><content type='html'>Today I just woke up thinking to post a few links:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It curious how OS interfaces have changed along time:&lt;a href="http://www.webdesignerdepot.com/2009/03/operating-system-interface-design-between-1981-2009/"&gt; OS interface design between 1980-2009&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Did you know Autodesk's Kynapse?. It's a middleware for AI in games, mainly focused on dynamic pathfinding. I recommend to watch the demo videos: &lt;a href="http://usa.autodesk.com/adsk/servlet/index?siteID=123112&amp;amp;id=11390544"&gt;Autodesk's Kynapse&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Unreal Engine 3, for XBox360, PS3 and PC (DirectX10): &lt;a href="http://www.unrealtechnology.com/technology.php"&gt;Unreal Engine 3 technology&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.gdconf.com/"&gt;GDC2009&lt;/a&gt; is inminent.&lt;/li&gt;&lt;li&gt;Current book I'm reading, about Physics/Maths and AI: &lt;a href="http://en.wikipedia.org/wiki/The_Emperor%27s_New_Mind"&gt;Roger Penrose's The Emperor's New Mind&lt;/a&gt;. &lt;span style="font-style: italic;"&gt;(thanks Antonio)&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.que.es/cine/estrellas/fotos/estudio-039planet-51039/20090310/10727-estudio-039planet-51039.html"&gt;Planet 51's new images. &lt;/a&gt;&lt;span style="font-style: italic;"&gt;(spanish)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://apb.com/"&gt;APB&lt;/a&gt; is the new MMOG game by Real Time Worlds.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.joelonsoftware.com/items/2009/03/09.html"&gt;How to be a program manager&lt;/a&gt;. Joel Spolsky.&lt;/li&gt;&lt;li&gt;Why doesn't the Spanish state provide more support to videogame industry? &lt;a href="http://www.larazon.es/noticia/las-subvenciones-superan-la-recaudacion"&gt;However to the cinema&lt;/a&gt;... &lt;span style="font-style: italic;"&gt;(spanish)&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Have a good weekend&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-604795408618587958?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/604795408618587958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=604795408618587958&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/604795408618587958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/604795408618587958'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/03/links-soup.html' title='Links Soup'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-4736676267533224456</id><published>2009-03-08T00:14:00.002+01:00</published><updated>2009-03-20T12:18:25.111+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='news'/><title type='text'>God of War III trailer</title><content type='html'>It is impressive, graphics, gameplay, ambient and music. &lt;br /&gt;Try to watch it in HD, if you can:&lt;br /&gt;&lt;br /&gt;&lt;object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"  codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" id="gtembed" width="480" height="392"&gt; &lt;param name="allowScriptAccess" value="sameDomain" /&gt;  &lt;param name="allowFullScreen" value="true" /&gt; &lt;param name="movie" value="http://www.gametrailers.com/remote_wrap.php?mid=46469"/&gt; &lt;param name="quality" value="high" /&gt; &lt;embed src="http://www.gametrailers.com/remote_wrap.php?mid=46469" swLiveConnect="true" name="gtembed" align="middle" allowScriptAccess="sameDomain" allowFullScreen="true" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="480" height="392"&gt;&lt;/embed&gt; &lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-4736676267533224456?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/4736676267533224456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=4736676267533224456&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4736676267533224456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4736676267533224456'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/03/god-of-war-iii-trailer.html' title='God of War III trailer'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-6281481247203043017</id><published>2009-03-07T00:38:00.007+01:00</published><updated>2009-03-09T08:31:18.904+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='parallel'/><title type='text'>Framework for distributed computing</title><content type='html'>Lastly I've been designing a simple framework to distribute tasks in a cluster environment (a multi computer system where nodes are connected via network). One of the most used framework to do this is the &lt;a href="http://en.wikipedia.org/wiki/Berkeley_Open_Infrastructure_for_Network_Computing"&gt;BOINC&lt;/a&gt; project, which was created originally for the project &lt;a href="http://en.wikipedia.org/wiki/SETI@home"&gt;SETI@home&lt;/a&gt;. Obviously my framework doesn't try to simulate the BOINC's, but it tries to explore the main idea behind.&lt;br /&gt;&lt;br /&gt;There is a web page for the project where you can view how it is implemented, examples and you can download it. It's called  gydis (gyakoo distributed computing library) :)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dimensoft.com/data/gydis"&gt;Gydis project website.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Basically it is a set of classes which offer you an easy API to create a job and to distribute it in the cluster. By using the power of python's introspection a protocol communication between nodes using a own remote object is created.&lt;br /&gt;&lt;br /&gt;The main idea is you must to inherit from a &lt;span style="font-weight: bold;"&gt;Job&lt;/span&gt; object (same syntax like a Thread class), to implement its &lt;span style="font-style: italic;"&gt;run&lt;/span&gt; method and call to &lt;span style="font-style: italic;"&gt;start&lt;/span&gt; to schedule the job in cluster. For job grouping you must to do the same but with &lt;span style="font-weight: bold;"&gt;JobGroup&lt;/span&gt; class, implement its &lt;span style="font-style: italic;"&gt;reduce&lt;/span&gt; method and call to &lt;span style="font-style: italic;"&gt;start&lt;/span&gt; to schedule all its jobs and wait for them, until results are computed and your reduce method is called back to combine them.&lt;br /&gt;&lt;br /&gt;Here you have two (stupid) examples of use, but you can do a lot of things with this.&lt;br /&gt;&lt;h2 id="examples"&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h2&gt; &lt;h4&gt;Single Job&lt;/h4&gt; The example below shows how to calculate a single factorial of 15 on a node. Yes it's a dumb example, but basic enough to show you how to create a Job and schedule it in cluster.&lt;br /&gt;&lt;pre style="background-color: rgb(240, 240, 240); width: 600px;"&gt;import &lt;i style="color: blue;"&gt;job&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;class &lt;b&gt;SimpleFacJob&lt;/b&gt;(&lt;i style="color: blue;"&gt;job.Job&lt;/i&gt;):&lt;br /&gt;    def __init__(self,n):&lt;br /&gt;        job.Job.__init__(self,"controller-hostname")&lt;br /&gt;        self.n = n&lt;br /&gt;&lt;br /&gt;    def fac(self,n):&lt;br /&gt;        if n &lt;= 2   : return 2&lt;br /&gt;        else        : return n * self.fac(n-1)        &lt;br /&gt;&lt;br /&gt;    &lt;i style="color: rgb(136, 136, 136);"&gt;# Executed remotely on a node.&lt;/i&gt;&lt;br /&gt;    def &lt;b&gt;run&lt;/b&gt;(self):&lt;br /&gt;        self.result = self.fac(self.n)&lt;br /&gt;&lt;br /&gt;    &lt;i style="color: rgb(136, 136, 136);"&gt;# Called locally (here) when job finishes.&lt;/i&gt;&lt;br /&gt;    def &lt;b&gt;response&lt;/b&gt;(self):    &lt;br /&gt;        print "Job result=",self.result&lt;br /&gt;&lt;br /&gt;if __name__ == "__name__":&lt;br /&gt;    j = SimpleFacJob( 15 )      &lt;i style="color: rgb(136, 136, 136);"&gt;# Create the job.&lt;/i&gt;&lt;br /&gt;    j.start()                   &lt;i style="color: rgb(136, 136, 136);"&gt;# Launch the job to cluster&lt;/i&gt;&lt;br /&gt;    &lt;i style="color: rgb(136, 136, 136);"&gt;# Wait until finalization&lt;/i&gt;&lt;br /&gt;    while not j.result:&lt;br /&gt;        pass&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt; &lt;h4&gt;Single Job Group&lt;/h4&gt; Now another dumb example, we are going to calculate a factorial of 11 by computing eleven factorials of 10 and then sum them.  We create ten jobs, each one computing factorial of 10. The &lt;b&gt;reduce&lt;/b&gt; method will be a sum. &lt;pre style="background-color: rgb(240, 240, 240); width: 600px;"&gt;import &lt;i style="color: blue;"&gt;job&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;class SimpleFacJob(&lt;i style="color: blue;"&gt;job.Job&lt;/i&gt;):&lt;br /&gt;    &lt;i style="color: rgb(136, 136, 136);"&gt;# See the example above&lt;/i&gt;&lt;br /&gt;    &lt;b&gt;...&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;class &lt;b&gt;FacSum&lt;/b&gt;(&lt;i style="color: blue;"&gt;job.JobGroup&lt;/i&gt;):&lt;br /&gt;&lt;br /&gt;    &lt;i style="color: rgb(136, 136, 136);"&gt;# Adds all results&lt;/i&gt;&lt;br /&gt;    def &lt;b&gt;reduce&lt;/b&gt;(self):    &lt;br /&gt;        r = 0&lt;br /&gt;        for j in self.jobs:&lt;br /&gt;            r += j.result&lt;br /&gt;        print "Reduced to:", r&lt;br /&gt;        return r&lt;br /&gt;&lt;br /&gt;if __name__ == "__name__":&lt;br /&gt;    jobs = []&lt;br /&gt;    &lt;i style="color: rgb(136, 136, 136);"&gt;# We create eleven jobs, each one with factorial(10) computation&lt;/i&gt;&lt;br /&gt;    for i in range(0,11): &lt;br /&gt;        jobs.append( SimpleFacJob(10) )&lt;br /&gt;&lt;br /&gt;    jg = FacSum( jobs )    &lt;i style="color: rgb(136, 136, 136);"&gt;# Creating the group of jobs&lt;/i&gt;&lt;br /&gt;    jg.start()             &lt;i style="color: rgb(136, 136, 136);"&gt;# Launch the group to cluster&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;    &lt;i style="color: rgb(136, 136, 136);"&gt;# Wait until finalization&lt;/i&gt;&lt;br /&gt;    while not jg.result:&lt;br /&gt;        pass&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Currently it's the version 0.1 so you'll find bugs, and the documentation is not completed yet, but I hope that this prototype will be continued.&lt;br /&gt;Any recommendation to &lt;a href="mailto:gyakoo@gmail.com"&gt;gyakoo@gmail.com&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-6281481247203043017?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/6281481247203043017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=6281481247203043017&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6281481247203043017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6281481247203043017'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/03/framework-to-distribute-tasks-in.html' title='Framework for distributed computing'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-3481346437075767893</id><published>2009-03-02T11:58:00.003+01:00</published><updated>2009-03-07T10:41:07.890+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='media'/><title type='text'>Music Composition</title><content type='html'>Well, last weekend I've been surfing between some projects done during last years, and surprise!, I've found some music files composed using fruity loops. BTW I remember that won a mod tracking contest prize in PCMania (a well known spanish magazine) about ten years ago, but I lost them of all. Anyway here you have some rescued trance/goa/progressive modules, enjoy them.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;img style="cursor: pointer; width: 20px; height: 20px;" src="http://4.bp.blogspot.com/_UXKUeU6z7xE/Sap_EITjLRI/AAAAAAAAAWI/k6a0nmkrIP0/s200/icoMusic.gif" alt="" id="BLOGGER_PHOTO_ID_5308194819735235858" border="0" /&gt;&lt;a href="http://www.dimensoft.com/data/music/Electrobean/Chasse.mp3"&gt;Chasse&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;img style="cursor: pointer; width: 20px; height: 20px;" src="http://4.bp.blogspot.com/_UXKUeU6z7xE/Sap_EITjLRI/AAAAAAAAAWI/k6a0nmkrIP0/s200/icoMusic.gif" alt="" id="BLOGGER_PHOTO_ID_5308194819735235858" border="0" /&gt;&lt;a href="http://www.dimensoft.com/data/music/Electrobean/Neikan.mp3"&gt;Neikan&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;img style="cursor: pointer; width: 20px; height: 20px;" src="http://4.bp.blogspot.com/_UXKUeU6z7xE/Sap_EITjLRI/AAAAAAAAAWI/k6a0nmkrIP0/s200/icoMusic.gif" alt="" id="BLOGGER_PHOTO_ID_5308194819735235858" border="0" /&gt;&lt;a href="http://www.dimensoft.com/data/music/Electrobean/Pianel.mp3"&gt;Pianel&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;img style="cursor: pointer; width: 20px; height: 20px;" src="http://4.bp.blogspot.com/_UXKUeU6z7xE/Sap_EITjLRI/AAAAAAAAAWI/k6a0nmkrIP0/s200/icoMusic.gif" alt="" id="BLOGGER_PHOTO_ID_5308194819735235858" border="0" /&gt;&lt;a href="http://www.dimensoft.com/data/music/Electrobean/Refask.mp3"&gt;Refask&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;img style="cursor: pointer; width: 20px; height: 20px;" src="http://4.bp.blogspot.com/_UXKUeU6z7xE/Sap_EITjLRI/AAAAAAAAAWI/k6a0nmkrIP0/s200/icoMusic.gif" alt="" id="BLOGGER_PHOTO_ID_5308194819735235858" border="0" /&gt;&lt;a href="http://www.dimensoft.com/data/music/Electrobean/Wisdom.mp3"&gt;Wisdom&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;img style="cursor: pointer; width: 20px; height: 20px;" src="http://4.bp.blogspot.com/_UXKUeU6z7xE/Sap_EITjLRI/AAAAAAAAAWI/k6a0nmkrIP0/s200/icoMusic.gif" alt="" id="BLOGGER_PHOTO_ID_5308194819735235858" border="0" /&gt;&lt;a href="http://www.dimensoft.com/data/music/Electrobean/Yassto.mp3"&gt;Yassto&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-3481346437075767893?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/3481346437075767893/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=3481346437075767893&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/3481346437075767893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/3481346437075767893'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/03/music-composing.html' title='Music Composition'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_UXKUeU6z7xE/Sap_EITjLRI/AAAAAAAAAWI/k6a0nmkrIP0/s72-c/icoMusic.gif' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-4693852746550872150</id><published>2009-02-26T13:24:00.002+01:00</published><updated>2009-03-07T10:41:30.541+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><title type='text'>An abstract file access system</title><content type='html'>Sometimes our products need to release all data assets as images, sounds, models, configuration files, ... packed in a single file, often called packets.&lt;br /&gt;This allow us to hide some files, best management of update/modding packets, compress data or avoid asset ripping.&lt;br /&gt;In many situations, a zip packing structure could be used, in others, a tar, or a own structure with checksums or additional information.&lt;br /&gt;But we need to split here two concepts: &lt;span style="font-weight: bold;"&gt;Compression&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;packing&lt;/span&gt;. It's trivial but necessary to know that a zip file is a packet/file format, meanwhile the deflate/inflate algorithms (used by zlib) are compression techniques. Zip uses zlib for every stored file.&lt;br /&gt;Also, whether we want implement a library for this purpose, we need to provide, a single api mechanism to access transparently to a file using native os file-system (throughput C API) or to a file stored in our packets.&lt;br /&gt;Lastly I've developed a library to do this. With an own packet format and using the free LZO compression algorithm (one of the fastest I know), you can access to your data from a packet(s) or from normal files with follow code:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#include "gfs.h"&lt;br /&gt;int main(int , const char** )&lt;br /&gt;{&lt;br /&gt;    // gyakoo filesystem initialization&lt;br /&gt;    gfs::init();&lt;br /&gt;   &lt;br /&gt;    // Adds a packet search path.&lt;br /&gt;    gfs g;&lt;br /&gt;    g.add( gfs::PACKET, "data.pak" );&lt;br /&gt;    {&lt;br /&gt;        char chunk[4096];&lt;br /&gt;        // pickup a file from abstract file system.&lt;br /&gt;        gfile* f = g.grab( "images/texture.jpg" );&lt;br /&gt;        if ( f != 0 &amp;amp;&amp;amp; f-&gt;length() &gt; 0 )&lt;br /&gt;        {&lt;br /&gt;            // read in 4k chunks the file.&lt;br /&gt;            while ( ! f-&gt;eof() )&lt;br /&gt;            {&lt;br /&gt;                unsigned long r = gf-&gt;read( chunk, 4096 );&lt;br /&gt;                // do something with chunk ( r is number of bytes read )&lt;br /&gt;            }&lt;br /&gt;            f-&gt;close();&lt;br /&gt;            delete f;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You could change the packet adding &lt;i&gt;g.add( gfs::PACKET, "data.pak" );&lt;/i&gt; by a folder using &lt;i&gt; g.add( gfs::FOLDER, "data/" );&lt;/i&gt; and the code doesn't need to be changed to access to the file.&lt;br /&gt;&lt;br /&gt;With this library, I release a command line tool, like the &lt;b&gt;tar&lt;/b&gt; one, to create, visualize and make another operations with packets and files.&lt;br /&gt;&lt;br /&gt;The internal format of packet uses md5 for name, to avoid variable-length reading, and tries to minimize the seeks and read operations. &lt;br /&gt;Here you have the format of packet: &lt;a href="http://www.dimensoft.com/data/gfs-specs.txt"&gt;specs.txt&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And here you have the source of library (linux and makefile): &lt;a href="http://www.dimensoft.com/data/gfs-0.1.tgz"&gt;gfs-0.1.tgz&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Bon Appétit&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-4693852746550872150?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/4693852746550872150/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=4693852746550872150&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4693852746550872150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4693852746550872150'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/02/abstract-file-access-system.html' title='An abstract file access system'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-290126888212731293</id><published>2009-01-17T13:24:00.003+01:00</published><updated>2009-03-07T10:43:24.227+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='media'/><title type='text'>Planet 51</title><content type='html'>&lt;center&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://planet51.com"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer; width: 342px; height: 389px;" src="http://www.codepixel.com/images/stories/news/500/planet51.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br/&gt;&lt;br /&gt;&lt;br /&gt;Finally Sony Pictures has released the trailer of upcoming &lt;a href="http://www.ilion.com"&gt;Ilion&lt;/a&gt;'s title "&lt;a href="http://planet15.com"&gt;Planet 51&lt;/a&gt;". The film will be in theaters in the last quarter of this year 2009.&lt;br /&gt;&lt;br /&gt;After watch the trailer, have to comment that the &lt;a href="http://www.ilion.com"&gt;Ilion&lt;/a&gt;'s guys have worked hard and the results looks great, with an original and very comic story. With this I think that national products always can be as good as international ones (&lt;a href="http://www.pixar.com"&gt;pixar&lt;/a&gt;, &lt;a href="http://www.dreamworksanimation.com/"&gt;dreamworks skg&lt;/a&gt;, &lt;a href="http://www.blueskystudios.com/"&gt;bluesky&lt;/a&gt;, ...) because in Spain we've a lot of talented people, maybe new and old studios would need more capital investment, although I suppose things aren't as easy.&lt;br /&gt;&lt;br /&gt;I recommend you see the trailer.&lt;br /&gt;&lt;br /&gt;Congratulations and good luck.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-290126888212731293?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/290126888212731293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=290126888212731293&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/290126888212731293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/290126888212731293'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2009/01/planet-51.html' title='Planet 51'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-7462542686815362728</id><published>2008-12-11T00:00:00.003+01:00</published><updated>2008-12-11T01:04:13.099+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>Fable II</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_UXKUeU6z7xE/SUBX9jHX-3I/AAAAAAAAAQA/ZVaAc7PRpOs/s1600-h/fable2box.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 227px; height: 320px;" src="http://4.bp.blogspot.com/_UXKUeU6z7xE/SUBX9jHX-3I/AAAAAAAAAQA/ZVaAc7PRpOs/s320/fable2box.jpg" alt="" id="BLOGGER_PHOTO_ID_5278315478188030834" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;One month ago I bought &lt;a href="http://www.lionhead.com/fable2/Default.aspx"&gt;Fable II&lt;/a&gt;, and since then I can't stop to play it. Is incredible what &lt;a href="http://es.wikipedia.org/wiki/Peter_Molyneux"&gt;Molyneux&lt;/a&gt; and his team have created. An unique fantasy world, with special care about expressions, actions and all the socials stuff around main character. It is curious how your actions change the aspect of your avatar along time. (In my case, the avatar goes to same direction as me, eating a lot of cake pies to recover health but gaining weight as secondary effect of that).&lt;br /&gt;&lt;br /&gt;Also, a feature that keep me always alert in game, is that you can do everything you want. You  could to kill all citizens in a region. You could help them or simply you could ignore them.&lt;br /&gt;You could make one family, or more, with or without children, or simply lead a solitary existence, practicing sex with *you want*. There are much more other actions you can do. Therefore, all these actions make you more sexy, scary, respectable, ... to people. Again in my game, people want to give me presents when they see me and acclaim to me for help them with bandits. So, if I would, I could play for a long time only performing alternative missions, working in a tavern or forge to carry money to my family, gain honor and reputation, stealing ...&lt;br /&gt;&lt;br /&gt;Like every other action rpg game, you have different skills, and you can specialize. Again, depending on which skills you increase, your human aspect could change to be taller, stronger or with glow symbols on skin in the case of magic skills. There are a lot of swords, axes, guns, crossbows. And the fight system is very elaborate and polished. It is very easy fight against eight or more enemies at same time, doing combos and changing target very fast with only stick and one button. Avatar's animations are beautiful and very fast. You can throw magic spells, with different levels, but it is difficult because to charge a high level you need maintain freeze and the enemies could damage you. Anyway this is again very balance, same as experience sphere collecting.&lt;br /&gt;&lt;br /&gt;It is the game that I was waiting for. Beautiful, with a very special world, a great history and a very fast gameplay system, among another must-to-play features.&lt;br /&gt;&lt;br /&gt;I could talk much more about Fable II, but first I have to finish it, although I'm starting to think that this game never ends.&lt;br /&gt;&lt;br /&gt;Very good game. You should play it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-7462542686815362728?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/7462542686815362728/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=7462542686815362728&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7462542686815362728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7462542686815362728'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/12/fable-ii.html' title='Fable II'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_UXKUeU6z7xE/SUBX9jHX-3I/AAAAAAAAAQA/ZVaAc7PRpOs/s72-c/fable2box.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-159339685043963864</id><published>2008-11-26T18:33:00.006+01:00</published><updated>2008-11-27T16:29:25.155+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><title type='text'>Trying to optimize a dictionary</title><content type='html'>It is truth that sometimes when programming, specially when you are designing data structures for your application, a dictionary-like structure is needed.&lt;br /&gt;Also it is called hash tables/trees, maps, associative containers ... A stl map often is implemented using a hash tree.&lt;br /&gt;&lt;br /&gt;You could need a fast way to map a type into another. A dictionary is a mapping between a word (string) and another user defined type, like an integer, a vector or even another string.&lt;br /&gt;&lt;br /&gt;It is important that the accesses (mapping) will be as fast as possible.&lt;br /&gt;The c++ standard library stl provides the follow complexity orders depending on container/operation pair:&lt;br /&gt;&lt;a send="true" class="moz-txt-link-freetext" href="http://www.cplusplus.com/reference/stl/"&gt;http://www.cplusplus.com/reference/stl/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In fact, most of stl implementations are very fast, and it is difficult improve them maintaining the flexibility and portability. It is difficult, not impossible.&lt;br /&gt;&lt;br /&gt;Last days I have been implementing an associative container using a hash table, to optimize words storing, without use a std::map. In other words, a dictionary.&lt;br /&gt;First benchmarks throws a improvement in performance, better than using std::map&amp;lt; std::string, type &amp;gt;, but with some disadvantages such as a certain loss of flexibility, although we could fix this.&lt;br /&gt;&lt;br /&gt;&lt;a href="javascript:toggleVisible('TRYINGOPTIMIZEDICTIONARY');"&gt;show/hide ...&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The very first (and easiest too) way to make a dictionary is using stl:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;typedef std::map&amp;lt; std::string, float &amp;gt; TDictionary;&lt;br /&gt;TDictionary   mydict;&lt;br /&gt;&lt;br /&gt;mydict[ "enemies" ] = 5.0f;&lt;br /&gt;mydict[ "life" ] = 100.0f;&lt;br /&gt;mydict[ "shadowfactor" ] = 0.8f;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;But, what about systems without stl? or systems with poor/slow implementation of it? or system where you use plain C?&lt;br /&gt;And, what if you need a more efficient way to do a dictionary, when doesn't matter loss of flexibility?&lt;br /&gt;We could google for public libraries, or write it ourselves.&lt;br /&gt;&lt;br /&gt;Well, the other day, I found a problem with this kind of handicaps and implemented the follow very specialized hash table. I'm sure that you could find a better implementation or even some mistakes in code. In both cases please let me know.&lt;br /&gt;The explanation and pros/cons will be shown later:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// -------------------------------------------------&lt;br /&gt;// DefaultHasher&lt;br /&gt;// -------------------------------------------------&lt;br /&gt;struct DefaultHasher&lt;br /&gt;{&lt;br /&gt;    inline unsigned long operator()( const char* data, int len )&lt;br /&gt;    {&lt;br /&gt;        register unsigned long h = 0;&lt;br /&gt;        register int i = len-1;&lt;br /&gt;       &lt;br /&gt;        for ( ; i &amp;gt;= 0; --i )    h = 37*h + data[i];&lt;br /&gt;           &lt;br /&gt;        return h;&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;// -------------------------------------------------&lt;br /&gt;// Dictionary&lt;br /&gt;// -------------------------------------------------&lt;br /&gt;template&amp;lt;   typename K,&lt;br /&gt;            typename V,&lt;br /&gt;            int CAPACITY         = 8167,&lt;br /&gt;            int INITVSIZE        = 32,&lt;br /&gt;            typename STRHASH     = DefaultHasher &amp;gt;&lt;br /&gt;class Dictionary&lt;br /&gt;{  &lt;br /&gt;protected:&lt;br /&gt;    struct sNode&lt;br /&gt;    {&lt;br /&gt;        K    key;&lt;br /&gt;        V    val;&lt;br /&gt;    };&lt;br /&gt;    struct sHead&lt;br /&gt;    {&lt;br /&gt;        int     mSize;&lt;br /&gt;        sNode*  mData;&lt;br /&gt;    };&lt;br /&gt;public:&lt;br /&gt;    Dictionary     (){ memset( mData, 0, sizeof(sHead*)*CAPACITY ); }&lt;br /&gt;    ~Dictionary    (){ destroy(); }&lt;br /&gt;    void destroy   ()&lt;br /&gt;    {&lt;br /&gt;        for ( int i = CAPACITY-1; i &amp;gt;= 0; --i )&lt;br /&gt;        {&lt;br /&gt;            register sHead*&amp;amp; sh = mData[i];&lt;br /&gt;            if ( sh != 0 )&lt;br /&gt;            {&lt;br /&gt;                delete [](sh-&amp;gt;mData);&lt;br /&gt;                delete sh;&lt;br /&gt;                sh = 0;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }   &lt;br /&gt;    void add( const K&amp;amp; word, const V&amp;amp; value )&lt;br /&gt;    {   &lt;br /&gt;        const int ndx = hashkey(word);       &lt;br /&gt;        if ( mData[ndx] == 0 )&lt;br /&gt;        {&lt;br /&gt;            // this entry doesn't exist, creates it.&lt;br /&gt;            sHead* se = ( mData[ndx] = new sHead );&lt;br /&gt;            se-&amp;gt;mData = new sNode[ INITVSIZE ];&lt;br /&gt;            se-&amp;gt;mSize = INITVSIZE;&lt;br /&gt;            memset( se-&amp;gt;mData, 0, sizeof(sNode)*INITVSIZE );           &lt;br /&gt;            se-&amp;gt;mData-&amp;gt;key = word;&lt;br /&gt;            se-&amp;gt;mData-&amp;gt;val = value;&lt;br /&gt;        }else&lt;br /&gt;        {&lt;br /&gt;            // entry exists, push back to vector.&lt;br /&gt;            register int i = 0;&lt;br /&gt;            register const int siz = mData[ndx]-&amp;gt;mSize;&lt;br /&gt;            sNode* vec = mData[ndx]-&amp;gt;mData;&lt;br /&gt;            while ( vec[i].key != 0 &amp;amp;&amp;amp; vec[i].key != word &amp;amp;&amp;amp; i &amp;lt; siz ){ ++i;}&lt;br /&gt;            if ( i &amp;lt; siz )&lt;br /&gt;            {&lt;br /&gt;                vec[i].key = word;&lt;br /&gt;                vec[i].val = value;&lt;br /&gt;            }else&lt;br /&gt;            {&lt;br /&gt;                // cannot insert. ¿resize current array 'vec'?&lt;br /&gt;                assert( false &amp;amp;&amp;amp; "Hash table error inserting\n" );&lt;br /&gt;            }&lt;br /&gt;        }       &lt;br /&gt;    }   &lt;br /&gt;    inline void add( const char* word, const V&amp;amp; value, int len = -1 )&lt;br /&gt;    {&lt;br /&gt;        add( mFuncHash(word, len == -1 ? strlen(word) : len), value );&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    V* exists( const K&amp;amp; word )&lt;br /&gt;    {&lt;br /&gt;        assert( word != 0 ); // don't search for zero hash words&lt;br /&gt;        V* ret = 0;&lt;br /&gt;        const int ndx = hashkey(word);&lt;br /&gt;        sHead* dat = mData[ndx];&lt;br /&gt;        if ( dat != 0 )&lt;br /&gt;        {&lt;br /&gt;            ret = seqSearch(dat, word);&lt;br /&gt;        }&lt;br /&gt;        return ret;&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    inline V* exists( const char* word, int len = -1 )&lt;br /&gt;    {&lt;br /&gt;        return exists( mFuncHash( word, len==-1 ? strlen(word) : len ) );&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;protected:   &lt;br /&gt;    inline int hashkey( const K&amp;amp; w ){ return w % CAPACITY; }&lt;br /&gt;    inline V* seqSearch( sHead* ent, const K&amp;amp; k )&lt;br /&gt;    {&lt;br /&gt;        register int i = 0;&lt;br /&gt;        register sNode* arr = ent-&amp;gt;mData;&lt;br /&gt;        while ( arr[i].key != k &amp;amp;&amp;amp; arr[i].key != 0 &amp;amp;&amp;amp; i &amp;lt; ent-&amp;gt;mSize ) { ++i; }&lt;br /&gt;        return (i &amp;lt; ent-&amp;gt;mSize &amp;amp;&amp;amp; arr[i].key == k) ? &amp;amp;arr[i].val : 0;&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;protected:&lt;br /&gt;    sHead*        mData[CAPACITY];&lt;br /&gt;    STRHASH       mFuncHash;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Before to explain it, I have to say that think it isn't completed yet, and not fully tested against more scenarios, but in a rapid benchmark using 81500 words extracted from a txt dictionary, I had the follow results in an Intel Core 2 Duo, with GNU CPP Compiler 4.2 and -O3 optimization flag:&lt;br /&gt;&lt;br /&gt;Inserting all 81500 words and then searching for each one:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;std::map&amp;lt; std::string, std::vector&amp;lt;int&amp;gt; &amp;gt;       average ~ 0.213 seconds&lt;br /&gt;std::map&amp;lt; unsigned long, SimpleArray&amp;lt;int&amp;gt; &amp;gt;     average ~ 0.062 seconds&lt;br /&gt;Dictionary&amp;lt; unsigned long, std::vector&amp;lt;int&amp;gt; &amp;gt;   average ~ 0.040 seconds&lt;br /&gt;Dictionary&amp;lt; unsigned long, SimpleArray&amp;lt;int&amp;gt; &amp;gt;   average ~ 0.029 seconds&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It is about 2x times faster than using same types and 7x faster than original dictionary, although I have to say that it makes use of several tricks.&lt;br /&gt;&lt;br /&gt;- Briefly, it is a fixed-size array of pointers, initially nulls. When you inserting a word, first it is converted to a number using a hash function, and then indexed in main array using a modulus operator. If target position is null, a sHead structure is created and the node is inserted, otherwise we have a collision, and then we travel an array with collisioned elements. If found an equal word (number), node's value is overwritten, otherwise the node is pushed back.&lt;br /&gt;- Analogous operation is done when search for a word.&lt;br /&gt;&lt;br /&gt;Most important features are:&lt;br /&gt;&lt;br /&gt;* First at all, the key factor here is that we transform each word (string) in its numerical representation, using a simple and fast hash function, called DefaultHasher. Thus, we store only an unsigned long for each word, instead string itself, and the comparisons between words are done very quickly (to compare two 32bits integer is faster than comparing n-length strings). But there are some problems here with this approximation:&lt;br /&gt;    - We lost the word itself because we store numbers. This could be fixed adding a string field to sNode structure.&lt;br /&gt;    - Collisions in hash function (two distincts words generate same number) will give false positives . We could use a &lt;a send="true" href="http://en.wikipedia.org/wiki/Perfect_hash_function"&gt;perfect hash function&lt;/a&gt; to resolve it.&lt;br /&gt;&lt;br /&gt;* Also, as you can see, the size of hash table is fixed, as well as each entry's vector. This problem could be resolved testing bounds and reallocating dynamic memory, but in this case we would have to make it carefully, because heap fragmentation and elements' copying when resizing.&lt;br /&gt;&lt;br /&gt;* The correct selection of CAPACITY constant is essential, because it is used in modulus operation when indexing string hash number ( ::hashkey() ). It is important to select a &lt;a send="true" href="http://primes.utm.edu/"&gt;prime number&lt;/a&gt; not too close to a power of two for a good indexing distribution (search in google for uniform distributed hash functions). Sometimes a MAD (Multiple Add Divide) operation is used to index, using (A*hashvalue+B) % CAPACITY. In other case, when you use a poor indexing function, is probably that the number of collisions per entry increase and the entries' vectors too much populated, with consequently dynamic memory work.&lt;br /&gt;&lt;br /&gt;* Also, the INITVSIZE is very important, because indicates number of elements for each table entry. A large number will decrease performance (both temporal and spatial) when allocating new entries, and a small number could be even worse in this version, making a fail when there are too many collisions in the same entry. I have seen that with smaller initvsize numbers better results.&lt;br /&gt;&lt;br /&gt;* In this version, the memory comsumption complexity order is about O( CAPACITY * INITVSIZE ). This consumption depends on K and V sizes, so be careful with these numbers.&lt;br /&gt;&lt;br /&gt;Yes, I know. After all, to get a boost in performance using this implementation implies a good tunning work in settings. To know the limits of input data is important to do this, but I think that if we perform some changes in code in order to flexibility ... Anyway, for my purposes this version was good enough.&lt;br /&gt;&lt;br /&gt;---------------&lt;br /&gt;Finally, as shown, a SimpleArray class is used as mapped type for dictionary. Again, it is a poorly tested class to manage an array of types, with its limitations, but with good results to me and when use it carefully.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// ------------------------------------------&lt;br /&gt;// SimpleArray&lt;br /&gt;// ------------------------------------------&lt;br /&gt;template&amp;lt; typename T, bool USEMEMCPY = true &amp;gt;&lt;br /&gt;class SimpleArray&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;    SimpleArray(int initsize = 0 ): mCur(0), mSize(0), mData(0)&lt;br /&gt;    {&lt;br /&gt;        if ( initsize &amp;gt; 0 )&lt;br /&gt;            resize( initsize );&lt;br /&gt;    }   &lt;br /&gt;    ~SimpleArray()&lt;br /&gt;    {&lt;br /&gt;        destroy();&lt;br /&gt;    }&lt;br /&gt;    inline void clear(){ mCur = 0; }&lt;br /&gt;    inline void add( const T&amp;amp; val )&lt;br /&gt;    {&lt;br /&gt;        if ( mCur &amp;gt;= mSize )&lt;br /&gt;        {&lt;br /&gt;            resize( mSize * 2 );&lt;br /&gt;        }&lt;br /&gt;        mData[mCur] = val;&lt;br /&gt;        mCur++;&lt;br /&gt;    }&lt;br /&gt;    inline T&amp;amp;   get( int ndx )    { return mData[ndx]; }&lt;br /&gt;    inline int  size()            { return mCur; }&lt;br /&gt;    inline void destroy()       &lt;br /&gt;    {&lt;br /&gt;        if ( mData != 0 )&lt;br /&gt;        {&lt;br /&gt;            delete []mData;&lt;br /&gt;            mData = 0;&lt;br /&gt;            mSize = mCur = 0;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    SimpleArray( const SimpleArray&amp;lt;T&amp;gt;&amp;amp; o ): mCur(0), mSize(0), mData(0)&lt;br /&gt;    {&lt;br /&gt;        *this = o;&lt;br /&gt;    }&lt;br /&gt;    inline const SimpleArray&amp;lt;T&amp;gt;&amp;amp; operator =( const SimpleArray&amp;lt;T&amp;gt;&amp;amp; o )&lt;br /&gt;    {&lt;br /&gt;        if ( o.mData != mData )&lt;br /&gt;        {&lt;br /&gt;            destroy();&lt;br /&gt;            resize( o.mSize );&lt;br /&gt;            mCur = o.mCur;&lt;br /&gt;            if ( mCur &amp;gt; 0 ) copy(mData, o.mData, mCur);&lt;br /&gt;        }&lt;br /&gt;        return *this;&lt;br /&gt;    }&lt;br /&gt;    inline T&amp;amp; operator[]( int ndx ){ return mData[ndx]; }&lt;br /&gt;protected:&lt;br /&gt;    void resize( int newsize )&lt;br /&gt;    {&lt;br /&gt;        if ( newsize &amp;gt; 0 )&lt;br /&gt;        {       &lt;br /&gt;            T* tmp = mData;&lt;br /&gt;            mData = new T[ newsize ];&lt;br /&gt;            if ( tmp != 0 )&lt;br /&gt;            {&lt;br /&gt;                copy(mData, tmp, mSize );&lt;br /&gt;                delete []tmp;&lt;br /&gt;            }   &lt;br /&gt;            mSize = newsize;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    inline void copy( T* dst, const T* src, int c )&lt;br /&gt;    {&lt;br /&gt;        if ( USEMEMCPY )&lt;br /&gt;            memcpy( dst, src, sizeof(T)*c );&lt;br /&gt;        else&lt;br /&gt;            for ( int i = c-1; i &amp;gt;= 0; --i )&lt;br /&gt;            {&lt;br /&gt;                dst[i] = src[i];&lt;br /&gt;            }&lt;br /&gt;    }&lt;br /&gt;protected:&lt;br /&gt;    int  mCur;&lt;br /&gt;    int  mSize;&lt;br /&gt;    T*   mData;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The USEMEMCPY template parameter acts like a #define (the compiler generates conditional code, depending on true/false). When it is true, the libc memcpy function is used when reallocating and copying. You should use True to gain performance if using native types or basic structures as template argument for T. If the value of USEMEMCPY parameter is False, then objects are copied using the assign operator (=) which could invoke an operator overload. Use False if T is a complex type with specialized copy constructor and assignment.&lt;br /&gt;&lt;br /&gt;Again, you could improve and enrich this class.&lt;br /&gt;&lt;br /&gt;PS: In the for loops, like the Dictionary's Hasher, SimpleArray's copier, ... you can make use of unrolling (with steps of two) to help the optimizer to use cpu's pipelining, but caution with indices when odd sizes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-159339685043963864?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/159339685043963864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=159339685043963864&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/159339685043963864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/159339685043963864'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/11/trying-to-optimize-dictionary.html' title='Trying to optimize a dictionary'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-1674683664031060817</id><published>2008-11-18T20:30:00.007+01:00</published><updated>2008-11-26T23:12:57.439+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Binary constant in C/C++</title><content type='html'>Many times, when programming in C/C++, and depending on level, you use decimal, hexadecimal and even octal literal constants, specially when you're involved on bits stuff, like flags.&lt;br /&gt;A common C/C++ programmer's complaint is that language doesn't have native support for binary literals.&lt;br /&gt;Today I needed this kind of code sugar and implemented the next code snippet.&lt;br /&gt;It's only a form, and I suppose there will be another ones. This implementation is resolved at compiling time. Let's see:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#define _B8BE(s) ( ((int)s[7]=='0'?0:1&lt;&lt;0) |    \&lt;br /&gt;                   (s[6]=='0'?0:1&lt;&lt;1) |        \&lt;br /&gt;                   (s[5]=='0'?0:1&lt;&lt;2) |        \&lt;br /&gt;                   (s[4]=='0'?0:1&lt;&lt;3) |        \&lt;br /&gt;                   (s[3]=='0'?0:1&lt;&lt;4) |        \&lt;br /&gt;                   (s[2]=='0'?0:1&lt;&lt;5) |        \&lt;br /&gt;                   (s[1]=='0'?0:1&lt;&lt;6) |        \&lt;br /&gt;                   (s[0]=='0'?0:1&lt;&lt;7) )&lt;br /&gt;// Using it:&lt;br /&gt;const val = _B8BE("01100011");&lt;br /&gt;const exists = (flags &amp; _B8BE("01001100")) != 0;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A words about this:&lt;br /&gt;- It's for 8 bits, and macro should be invoked using just 8 characters.&lt;br /&gt;- BE are stands for Big-Endian, because the most significant bit is the bit numbered 0 (the first character), and it is the first character at memory.&lt;br /&gt;&lt;br /&gt;The most important thing is that the compiler changes the expression by its constant, and this macro does not decrease the performance. We're going to see how the compiler works:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// binary.c&lt;br /&gt;&lt;br /&gt;#define _B8BE(s) ( ((int)s[7]=='0'?0:1&lt;&lt;0) |  \&lt;br /&gt;                  (s[6]=='0'?0:1&lt;&lt;1) |        \&lt;br /&gt;                  (s[5]=='0'?0:1&lt;&lt;2) |        \&lt;br /&gt;                  (s[4]=='0'?0:1&lt;&lt;3) |        \&lt;br /&gt;                  (s[3]=='0'?0:1&lt;&lt;4) |        \&lt;br /&gt;                  (s[2]=='0'?0:1&lt;&lt;5) |        \&lt;br /&gt;                  (s[1]=='0'?0:1&lt;&lt;6) |        \&lt;br /&gt;                  (s[0]=='0'?0:1&lt;&lt;7) )&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt; return _B8BE("10100000");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;When compiling with optimization flag, generating assembly output:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ gcc -S -O3 binary.c&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We can see a code like :this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; .file "binary.c"&lt;br /&gt; .text&lt;br /&gt; .p2align 4,,15&lt;br /&gt;.globl main&lt;br /&gt; .type main, @function&lt;br /&gt;main:&lt;br /&gt; leal 4(%esp), %ecx&lt;br /&gt; andl $-16, %esp&lt;br /&gt; pushl -4(%ecx)&lt;br /&gt; movl $160, %eax            ; here you have the "10100000" generated by compiler.&lt;br /&gt; pushl %ebp&lt;br /&gt; movl %esp, %ebp&lt;br /&gt; pushl %ecx&lt;br /&gt; popl %ecx&lt;br /&gt; popl %ebp&lt;br /&gt; leal -4(%ecx), %esp&lt;br /&gt; ret&lt;br /&gt; .size main, .-main&lt;br /&gt; .ident "GCC: (Ubuntu 4.3.2-1ubuntu11) 4.3.2"&lt;br /&gt; .section .note.GNU-stack,"",@progbits&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Finally, you could create more macros with a distinct numbers of bits, endianess or syntax.&lt;br /&gt;Last words, I suppose that googling you'll find more code and info about this issue.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-1674683664031060817?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/1674683664031060817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=1674683664031060817&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/1674683664031060817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/1674683664031060817'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/11/binary-constant-in-cc.html' title='Binary constant in C/C++'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-4980002299944457186</id><published>2008-11-16T20:58:00.007+01:00</published><updated>2008-11-26T23:13:18.050+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><title type='text'>Code optimization (I)</title><content type='html'>In next series of posts I would like to expose techniques and methods that currently I'm studying to improve the performance of C/C++ chunks of code. These optimizations are not based on algorithmic order, but on multiplicative constants that commonly are ignored on algorithmic complexity. When you have an algorithm to do any task, and it is difficult to improve it talking in complexity terms, the constant and code optimization are very important.&lt;br /&gt;&lt;br /&gt;Verification of compiler result code (with and without optimization flags) is essential. Also we will make use of intel's specific SIMD instruction (SSE instruction set) to parallelize vectorial operations (commonly used on computer graphics). Other thing we will do is to check how works the Intel's compiler, giving a well optimized code in x86 platforms. And more...&lt;br /&gt;&lt;br /&gt;Of course I'll give you references where to learn more and better these concepts and techniques, but a simple google's search will be enough in most of cases.&lt;br /&gt;&lt;br /&gt;In this first post, I'll review the simplest form of parallelization. CPU pipelining, with a trivial example.&lt;br /&gt;&lt;br /&gt;Let's go.&lt;br /&gt;&lt;br /&gt;One of the things you can learn from the University's subject "Parallel System Architecture" is that most of modern microprocessors have a very low level form of parallelization, called segmentation, also known as &lt;a href="http://en.wikipedia.org/wiki/Instruction_pipeline"&gt;pipelining.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This technique is used to increase the number of instructions executed in each clock time, by splitting it into smaller tasks that can be executed simultaneously. In order to use this method, actually you can't do nothing to use it directly, but you can perform small changes on code to decrease data dependencies between instructions.&lt;br /&gt;&lt;br /&gt;For example, the below shows how a simple loop unrolling can improve slightly a function that computes the scalar product of two vectors:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;// Dot product between two 8-dims vectors.&lt;br /&gt;// Classical method.&lt;br /&gt;float dotprod0(const float* v0, const float* v1)&lt;br /&gt;{&lt;br /&gt;  float dp = 0.0f;&lt;br /&gt;  for ( int i = 0; i &amp;lt; 8; ++i )&lt;br /&gt;  {&lt;br /&gt;      dp += v0[i] * v1[i];&lt;br /&gt;  }&lt;br /&gt;  return dp;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;// Dot product between two 8-dims vectors, making use of&lt;br /&gt;// loop unrolling to take advantage of pipelining.&lt;br /&gt;float dotprod1(const float* v0, const float* v1)&lt;br /&gt;{&lt;br /&gt;  float dp = 0.0f;&lt;br /&gt;  for ( int i = 0; i &amp;lt; 8; i+=2 )&lt;br /&gt;  {&lt;br /&gt;      dp += v0[i] * v1[i];&lt;br /&gt;      dp += v0[i+1] * v1[i+1];&lt;br /&gt;  }&lt;br /&gt;  return dp;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;To prove the improvement of second method, we could to use the processor &lt;a href="http://en.wikipedia.org/wiki/Time_Stamp_Counter"&gt;time stamp counter&lt;/a&gt;, if available. So we can get clock cycles used by two functions.&lt;br /&gt;Under Windows platform you can use &lt;a href="http://msdn.microsoft.com/en-us/library/ms644904.aspx"&gt;QueryPerformanceCounter&lt;/a&gt; function, and in a Linux system, the standard &lt;a href="http://www.cplusplus.com/reference/clibrary/ctime/clock.html"&gt;clock()&lt;/a&gt; function gives the number of clock ticks since program start.&lt;br /&gt;&lt;br /&gt;In our example, we are going to use directly the &lt;a href="http://faydoc.tripod.com/cpu/rdtsc.htm"&gt;RDTSC&lt;/a&gt; instruction. There are a lot of information on web about &lt;a href="http://cs.smu.ca/%7Ejamuir/rdtscpm1.pdf"&gt;performance measurement and monitoring&lt;/a&gt; using this instruction.&lt;br /&gt;So we have next function:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// Return no. of clock cycles since program was launched.&lt;br /&gt;// We store registers eax and edx and pack it in 64 bits.&lt;br /&gt;static inline long long rdtsc()&lt;br /&gt;{&lt;br /&gt;  unsigned a, d;&lt;br /&gt;  asm volatile ( "cpuid    \n"&lt;br /&gt;                 "rdtsc    \n"  : "=a" (a), "=d" (d) );&lt;br /&gt;  return ((long long)a) | (((long long)d) &amp;lt;&amp;lt; 32);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In the previous function we are using the "cpuid" instruction to force all instruction to complete. (We will discuss this "cpuid" instruction and its uses later). So, this instruction is used to synchronize processor execution, avoiding misleading cycle count caused by &lt;a href="http://en.wikipedia.org/wiki/Out-of-order_execution"&gt;out-of-order execution&lt;/a&gt; of modern processors (i.e. pipelining). Finally, we need to execute several times the same code chunk, to detect the cpu context switches and cache warm-up effects on clock cycles. Last measurements should give constant results.&lt;br /&gt;So we have:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// test for classical dotprod method.&lt;br /&gt;{  &lt;br /&gt; long long r0 = rdtsc();&lt;br /&gt; float dp = dotprod0(v0,v1);&lt;br /&gt; long long r0 = rdtsc();&lt;br /&gt;    printf ( "dotprod=%.2f (%lld) clock cycles\n", p, r1-r0 );&lt;br /&gt;}&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;... repeat &amp;gt; 5 times ...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;// test for second dotprod method.&lt;br /&gt;{&lt;br /&gt; long long r0 = rdtsc();&lt;br /&gt; float dp = dotprod1(v0,v1);&lt;br /&gt; long long r0 = rdtsc();&lt;br /&gt; printf ( "dotprod=%.2f (%lld) clock cycles\n", p, r1-r0 );&lt;br /&gt;}&lt;br /&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;... repeat &amp;gt; 5 times ...&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And the results are (using gnu c++ compiler with no optimization):&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;Method 1&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;==========&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1190) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1105) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1122) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1105) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1071) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1071) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1088) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1088) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1088) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1139) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;Method 2&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;==========&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1241) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;  &amp;lt;== cache warm up&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1003) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1003) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1003) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1020) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1003) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1020) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1003) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1003) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;tt&gt;&lt;span style="font-size:85%;"&gt;dotprod=159.00 (1003) clock cycles&lt;/span&gt;&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;As you can see, the second method throws less number of clock cycles, only doing a small code change, taking advantage of cpu pipelining, minimizing data dependencies.&lt;br /&gt;&lt;br /&gt;Next: CPUID instruction and compiler's assembly output.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-4980002299944457186?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/4980002299944457186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=4980002299944457186&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4980002299944457186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4980002299944457186'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/11/code-optimizing-i.html' title='Code optimization (I)'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-1661742260660192585</id><published>2008-11-14T14:21:00.006+01:00</published><updated>2008-11-26T23:13:35.300+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Accessing to character in explicit string.</title><content type='html'>I did not know the follow C syntax to access to specific character in a string. It is interesting to inline functions that use some kind of &lt;a href="http://en.wikipedia.org/wiki/Lookup_table"&gt;LUT&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;int dummy_function( int param )&lt;br /&gt;{&lt;br /&gt;     return (int)( "j4Cg+\x64\x5F_"[ param % 8 ] );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You should remember that an ASCII character takes values between 0 and 255, and to use specific control ones you need to use a 8-bit numeric escape sequence '\xnn', where nn is an hexadecimal code for ASCII character. Also, if you have Unicode support, you can use the 16-bit sequence '\unnnn' and the 32-bit version '\Unnnnnnnn'.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-1661742260660192585?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/1661742260660192585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=1661742260660192585&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/1661742260660192585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/1661742260660192585'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/11/accessing-to-character-in-explicit.html' title='Accessing to character in explicit string.'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-6863291883060296476</id><published>2008-11-12T21:45:00.006+01:00</published><updated>2008-11-26T23:14:10.500+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='raytracing'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><title type='text'>Ray-Triangle intersection</title><content type='html'>Lastly I've implemented a function to compute the intersection between a ray and a triangle, in my personal raytracing project I'm working on. It is old problem in computer graphics, but always interesting.&lt;br /&gt;&lt;br /&gt;I don't know if there is another better (in performance terms and with no precomputed data), but I decided to program one based on "&lt;a href="http://www.cs.virginia.edu/%7Egfx/Courses/2003/ImageSynthesis/papers/Acceleration/Fast%20MinimumStorage%20RayTriangle%20Intersection.pdf"&gt;Fast, minimum storage ray/triangle intersection&lt;/a&gt;" paper, from Möller and Trumbore.&lt;br /&gt;&lt;br /&gt;It is called "minimum storage" because doesn't need to store the triangle's normal. This method either tests against plane extracted from triangle.&lt;br /&gt;&lt;br /&gt;Well, the method and a C example code is on paper for anybody, but I'll try to explain here briefly.&lt;br /&gt;&lt;br /&gt;First we can write a point in a triangle using a barycentric form, as:&lt;br /&gt;&lt;center&gt;&lt;pre&gt;T(u,v) = (1-u-v)·V0 + u·V1 + v·V2&lt;/pre&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;A point inside triangle must have &lt;center&gt;&lt;pre&gt;u &gt;= 0, v &gt;= 0 and u + v &lt;= 1&lt;/pre&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;Then, if we use the ray equation:&lt;br /&gt;&lt;center&gt;&lt;pre&gt;O + t·D = (1-u-v)·V0 + u·V1, v·V2&lt;/pre&gt;&lt;/center&gt;&lt;br /&gt;expanding and rearranging the equation, translating coordinates to the origin, it gives:&lt;br /&gt;&lt;center&gt;&lt;pre&gt;-D·t + E1·u + E2·v = T&lt;br /&gt;where:&lt;br /&gt;E1 = V1-O&lt;br /&gt;E2 = V2-O&lt;br /&gt;T  = V0-O&lt;br /&gt;&lt;/pre&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;If we use a matricial form, like this:&lt;br /&gt;&lt;center&gt;&lt;pre&gt;&lt;br /&gt;[-D E1 E2] · [t    = T&lt;br /&gt;      u&lt;br /&gt;               v]       &lt;br /&gt;&lt;/pre&gt;&lt;/center&gt;&lt;br /&gt;then we can apply i.e. Cramer's rule to resolve it. The key point here is the follow linear algebra relation:&lt;br /&gt;&lt;center&gt;&lt;pre&gt;&lt;br /&gt;det([A B C]) = -(A x C)·B = -(B x C)·A&lt;br /&gt;&lt;/pre&gt;&lt;/center&gt;&lt;br /&gt;thus we have:&lt;br /&gt;&lt;center&gt;&lt;pre&gt;&lt;br /&gt;t = Q·E2 / P·E1&lt;br /&gt;u = P·T / P·E1&lt;br /&gt;v = Q·D / P·E1&lt;br /&gt;where,&lt;br /&gt;P = D x E2&lt;br /&gt;Q = T x E1&lt;br /&gt;&lt;/pre&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;If we only need to test intersection in the positive face of triangle, it must to be fulfilled P·E1 &gt; 0, but if we don't care, only need P·E1 != 0.&lt;br /&gt;We could use parametric coordinates (u,v) for texture mapping. t is the distance in ray.&lt;br /&gt;&lt;br /&gt;Next I suggest an implementation in pseudocode, only performing some computation tasks when needed.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# R is the ray and Vi are the three triangle vertices, all of them in world coordinates.&lt;br /&gt;# I is true if intersection detected, false otherwise.&lt;br /&gt;# t, u, v, are parametric coordinates, only valid when I is true.&lt;br /&gt;&lt;br /&gt;ray_vs_triangle: R, V0, V1, V2 -&gt; I, t, u, v&lt;br /&gt;   I &lt;- False    &lt;br /&gt;   E2 &lt;- V2 - V0    &lt;br /&gt;   E1 &lt;- V1 - V0    &lt;br /&gt;   P &lt;- cross_product( R.direction, E2 )    &lt;br /&gt;   det &lt;- dot_product( P, E1 )    &lt;br /&gt;   if det &gt; Epsilon&lt;br /&gt;      T &lt;- R.origin - V0       &lt;br /&gt;      Q &lt;- cross_product( T, E1 )       &lt;br /&gt;      u &lt;- dot_product( P, T ) / det       &lt;br /&gt;      if u &gt; Epsilon&lt;br /&gt;         v &lt;- dot_product( Q, R.direction ) / det          &lt;br /&gt;         if v &gt; Epsilon ^ u+v &lt; 1+Epsilon&lt;br /&gt;            t &lt;- dot_product( Q, E2 )&lt;br /&gt;            I &lt;- True&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-6863291883060296476?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/6863291883060296476/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=6863291883060296476&amp;isPopup=true' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6863291883060296476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6863291883060296476'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/11/ray-triangle-intersection.html' title='Ray-Triangle intersection'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-9074882562796838016</id><published>2008-11-10T15:30:00.003+01:00</published><updated>2008-11-26T23:14:28.976+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Ubuntu 8.10 (The intrepid ibex)</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.ubuntu.com/themes/ubuntu07/images/ubuntulogo.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 202px; height: 55px;" src="http://www.ubuntu.com/themes/ubuntu07/images/ubuntulogo.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The new &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu 8.10&lt;/a&gt; - The intrepid ibex has been released (on October 2008).&lt;br /&gt;&lt;br /&gt;Well, I have to say that it is great.&lt;br /&gt;&lt;br /&gt;Until now I have been using Ubuntu 8.04 (Hardy Heron), released on April 2008, and my experience is that it is incredible for programmers with no fear to return to command line tools (too much Visual Studio can make you to forgot common and useful practices).&lt;br /&gt;&lt;br /&gt;After unpack my brand-new laptop (I never had one), with a GeForce 9600GT (yes, it support CUDA), I found that lastest nVidia drivers (177) were automatically downloaded and installed without problems. (In 8.04 the installation was manual).&lt;br /&gt;&lt;br /&gt;I have to install wine for 3d benchmark supporting, because I want to install 3DMark (and emulate it) in order to compare performance under Linux and Windows Vista.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://osnews.com/story/19769/Ubuntu-8.04-vs.-Windows-XP-Application-Performance-Benchmark"&gt;Here&lt;/a&gt; you can find an application-level performance comparison between Ubuntu and Windows XP.&lt;br /&gt;&lt;br /&gt;And, finally I'm warning you all if you're thinking that I am a converted linuxer. No I'm not. I still love Visual Studio. The new 2008 version is amazing.&lt;br /&gt;&lt;br /&gt;In next posts I will talk about performance issues that I have been working, using SIMD instructions of Intel (SSE instruction set), using Intel C Compiler (which uses cpu cache dependant optimized code) and GNU C's one, viewing assembler code produced by an optimizer and comparing several methods to do vectorial/matricial operations. Yes I'll return to assembly (fpu stack and so), only to review result code). Thus, I'll comment compiler intrinsics, helping to compiler to optimize code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-9074882562796838016?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/9074882562796838016/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=9074882562796838016&amp;isPopup=true' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/9074882562796838016'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/9074882562796838016'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/11/ubuntu-810-intrepid-ibex.html' title='Ubuntu 8.10 (The intrepid ibex)'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-748499025729504269</id><published>2008-11-05T21:45:00.003+01:00</published><updated>2008-11-26T23:14:44.770+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Huelga de informáticos y writing in english.</title><content type='html'>Como algunos sabreis:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;"El pasado 23 de octubre el Ministerio de Educación presentó las fichas de los nuevos títulos de grado y master de todas las ingenierías menos la de informática cumpliendose así los peores presagios. La excusa ha sido que nuestra ingeniería no tiene atribuciones y que la informática es una materia transversal y por lo tanto no debe de concentrarse en una titulación concreta."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Aunque todo es relativo, supongo que los informáticos con experiencia no serán infravalorados por las empresas, pero de alguna u otra manera afectará.&lt;br /&gt;&lt;br /&gt;Hay una huelga el día 19 de Noviembre, podeis ver más información en los siguientes enlaces.&lt;br /&gt;&lt;a href="http://huelgainformatica.es/"&gt;http://huelgainformatica.es/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.cpiia.org/index.php?option=com_content&amp;amp;task=view&amp;amp;id=169&amp;amp;Itemid=1"&gt;http://www.cpiia.org/index.php?option=com_content&amp;amp;task=view&amp;amp;id=169&amp;amp;Itemid=1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;Por otro lado, voy a intentar escribir a partir de ahora las entradas en inglés.&lt;br /&gt;&lt;br /&gt;Yes, I know. My english is so bad, but I need to improve it in the sense of write, understand and speaking it, and I think that it is a very good initiative to me, that's I hope. So, sorry with mistakes.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;"If you don't use it, you loose it."&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-748499025729504269?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/748499025729504269/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=748499025729504269&amp;isPopup=true' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/748499025729504269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/748499025729504269'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/11/huelga-de-informticos-y-writing-in.html' title='Huelga de informáticos y writing in english.'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-4578407943743328888</id><published>2008-10-24T23:16:00.017+02:00</published><updated>2008-11-26T23:15:06.765+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='raytracing'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Ambient Occlusion (II)</title><content type='html'>Finalmente cambié la función de generación de rayos en el hemisferio de la superficie.&lt;br /&gt;Ahora sigo una función de densidad, extraida de una lectura en el Siggraph 2003, titulada "&lt;a href="www.cs.rutgers.edu/%7Edecarlo/readings/mcrt-sg03c.pdf"&gt;Monte Carlo Raytracing&lt;/a&gt;", organizada por &lt;a href="http://graphics.ucsd.edu/~henrik/"&gt;Henrik Wann Jensen&lt;/a&gt;, el creador de Photon Mapping.&lt;br /&gt;&lt;br /&gt;Intepretando lo que he podido el apartado 2. Function Inversion, se extrae, para una función de densidad determinada, el siguiente par de coordenadas polares, aleatorias, en el hemisferio:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_UXKUeU6z7xE/SQI_Oet3tTI/AAAAAAAAAPg/p-mLJ8L8vew/s1600-h/angles.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 328px; height: 30px;" src="http://1.bp.blogspot.com/_UXKUeU6z7xE/SQI_Oet3tTI/AAAAAAAAAPg/p-mLJ8L8vew/s400/angles.png" alt="" id="BLOGGER_PHOTO_ID_5260836832718337330" border="0" /&gt;&lt;/a&gt;El primero es el ángulo desde la normal,, entre 0 y PI/2, mientras que el segundo es el azimut entre 0 y 2PI.&lt;br /&gt;El exponente &lt;span style="font-weight: bold;"&gt;n&lt;/span&gt; sirva para indicar la apertura del cono en el hemisferio, similar al exponente de la función specular Phong. Si &lt;span style="font-weight: bold;"&gt;n&lt;/span&gt; vale 0 tenemos el hemisferio completo.&lt;br /&gt;&lt;br /&gt;Una vez tenemos este par de ángulos, en coordenadas polares, lo transformamos a coordenadas cartesianas así:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_UXKUeU6z7xE/SQJB3ADCNmI/AAAAAAAAAPo/2hqZ-o73Gsc/s1600-h/acartesianas.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 298px; height: 23px;" src="http://3.bp.blogspot.com/_UXKUeU6z7xE/SQJB3ADCNmI/AAAAAAAAAPo/2hqZ-o73Gsc/s400/acartesianas.png" alt="" id="BLOGGER_PHOTO_ID_5260839727883499106" border="0" /&gt;&lt;/a&gt;Ahora ya tenemos el vector unitario aleatorio en el hemisferio, solo que no está orientado a la normal. Debemos de realizar un cambio de base, y para ello extraemos la base de la normal, &lt;span style="font-weight: bold;"&gt;u, v&lt;/span&gt; y &lt;span style="font-weight: bold;"&gt;w&lt;/span&gt;, siendo &lt;span style="font-weight: bold;"&gt;w&lt;/span&gt; la propia normal. Una vez lo tenemos generamos la siguiente matriz de rotación, y la multiplicamos por el vector obtenido arriba.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_UXKUeU6z7xE/SQJB3YWxuJI/AAAAAAAAAPw/m0U4HyEF0E4/s1600-h/basemat.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 198px; height: 79px;" src="http://3.bp.blogspot.com/_UXKUeU6z7xE/SQJB3YWxuJI/AAAAAAAAAPw/m0U4HyEF0E4/s400/basemat.png" alt="" id="BLOGGER_PHOTO_ID_5260839734408755346" border="0" /&gt;&lt;/a&gt;A continuación el código para generar NSAMPLES samples usando esta función de densidad:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// generamos la base (N es la normal).&lt;br /&gt;v3f w( N );&lt;br /&gt;v3f t( w );&lt;br /&gt;t[ minMagnitude(t) ] = 1.0f;  // aseguramos que t no es colinear con w.&lt;br /&gt;v3f u( t.cross( w ).normalize() );&lt;br /&gt;v3f v( w.cross( u ).normalize() ); &lt;br /&gt;&lt;br /&gt;// genemos todos los bases&lt;br /&gt;v3f samples[ NSAMPLES ];&lt;br /&gt;for ( int i = NSAMPLES-1; i &gt;= 0; --i )&lt;br /&gt;{&lt;br /&gt;    // muestreamos dos variables aleatorias en [0,1]&lt;br /&gt;    float r1 = rndRange(0.0f,1.0f);&lt;br /&gt;    float r2 = rndRange(0.0f,1.0f);&lt;br /&gt;&lt;br /&gt;    // función densidad para obtener los angulos&lt;br /&gt;    float n = 0.0f;&lt;br /&gt;    float a1 = acosf( pow( 1.0f - r1, 1.0f / ( n + 1.0f ) ) );&lt;br /&gt;    float a2 = piby2 * r2;   &lt;br /&gt;&lt;br /&gt;    // transformamos a coord. cartesianas&lt;br /&gt;    v3f _a( cosf(a2)*sinf(a1), sinf(a1)*sinf(a2), cosf(a1) );   &lt;br /&gt;    &lt;br /&gt;    // cambio de coordenadas a la normal.&lt;br /&gt;    float a = _a.x;&lt;br /&gt;    float b = _a.y;&lt;br /&gt;    float c = _a.z;   &lt;br /&gt;    samples[i] = v3f( a*u.x + b*v.x + c*w.x,&lt;br /&gt;                      a*u.y + b*v.y + c*w.y,&lt;br /&gt;                      a*u.z + b*v.z + c*w.z );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Una vez que ya tenemos éstos samples, lanzamos dichos rayos desde el origen del punto y calculamos la media ponderada. A continuación el pseudo-código de la computación de la intensidad de ambient occlusion, en el punto &lt;span style="font-weight:bold;"&gt;O&lt;/span&gt;, con la normal &lt;span style="font-weight:bold;"&gt;N&lt;/span&gt;. &lt;span style="font-weight:bold;"&gt;D&lt;/span&gt; es la distancia máxima permitida para la occlusion.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;hits &lt;- 0.0&lt;br /&gt;para cada sample S en samples[]:&lt;br /&gt;    ray &lt;- (O, S)&lt;br /&gt;    r &lt;- trazar_rayo( ray )&lt;br /&gt;    si r.intersecta ^ r.t &gt; Epsilon ^ r.t &lt; D :&lt;br /&gt;        hits &lt;- hits + ( 1.0 - r.t / D )&lt;br /&gt;&lt;br /&gt;intensidad &lt;- 1.0 - hits / NSAMPLES&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A mayor número de samples (NSAMPLES) lanzados (distribuídos), más cubrimos el hemisferio con lo que el mapa de oclusión será más suave y preciso. En el ejemplo que muestro más abajo lanzo en un rango de 32 a 64 samples.&lt;br /&gt;&lt;br /&gt;Otra nota de esto, es que es una técnica que no tiene en cuenta ninguna luz en escena, solo la geometría, es por eso por lo que se llama "ambient" por lo de la luz ambiental.&lt;br /&gt;&lt;br /&gt;La intensidad ambiente obtenida la podemos combinar con la componente difusa. La manera en la que se combina aún no sé muy bien como puede ser, pero una forma en la que yo lo he hecho para el ejemplo de abajo es:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;intens = compute_amb_occ( O, N, D, 64 )&lt;br /&gt;intens.r = ambient.r + kDiffuse.r * intens.r * dotnl;&lt;br /&gt;intens.g = ambient.g + kDiffuse.g * intens.g * dotnl;&lt;br /&gt;intens.b = ambient.b + kDiffuse.b * intens.b * dotnl;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;kDiffuse&lt;/span&gt; es el color difuso del material. &lt;span style="font-weight:bold;"&gt;dotnl&lt;/span&gt; es la función Lambertiana. &lt;span style="font-weight:bold;"&gt;ambient&lt;/span&gt; es la iluminación ambiente general.&lt;br /&gt;&lt;br /&gt;Los resultados los siguientes, para un color difuso beige para todos los materiales. (click para agrandar).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_UXKUeU6z7xE/SQJKfncieLI/AAAAAAAAAP4/SdhVxhItnVw/s1600-h/diff.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 159px;" src="http://1.bp.blogspot.com/_UXKUeU6z7xE/SQJKfncieLI/AAAAAAAAAP4/SdhVxhItnVw/s400/diff.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5260849221747243186" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Si haceis zoom podeis ver zonas con geometría alrededor, sutilmente más oscurecidas, dando una sensación más real. De todas formas, en esta escena el mapa de oclusión es bastante sutil.&lt;br /&gt;Además, el tiempo de renderizado se ha disparado bastante, de unos 14 minutos la escena com AO, y de 20 segundos la escena sin ella. ¿donde quedó el realtime?&lt;br /&gt;&lt;br /&gt;Lo próximo... mejorar el rendimiento y materiales.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-4578407943743328888?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/4578407943743328888/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=4578407943743328888&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4578407943743328888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4578407943743328888'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/10/ambient-occlusion-ii.html' title='Ambient Occlusion (II)'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_UXKUeU6z7xE/SQI_Oet3tTI/AAAAAAAAAPg/p-mLJ8L8vew/s72-c/angles.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-7368130775194215588</id><published>2008-10-23T11:30:00.009+02:00</published><updated>2008-11-26T23:15:34.311+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='raytracing'/><title type='text'>Raytracing: Ambient Occlusion</title><content type='html'>Aquí estoy de nuevo, a las tantas, con el mismo tema.&lt;br /&gt;Después del comentario de Javi Santana he decidido meterle manos al &lt;a href="http://en.wikipedia.org/wiki/Ambient_occlusion"&gt;Ambient Occlusion&lt;/a&gt;, una técnica de aproximación a la iluminación global, en la que se calcula la intensidad de la componente ambiente de cada pixel, teniendo en cuenta la geometría del entorno cercano.&lt;br /&gt;Para ello se lanzan N rayos en el hemisferio que forma la normal al punto, y estos rayos se pueden seleccionar (sampling) de varias formas: De una forma sistemática como con coordenadas polares (alrededor de la normal), o distribuciones [pseudo]aleatorias (ver Monte Carlo).&lt;br /&gt;La idea es aproximar la siguiente integral:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_UXKUeU6z7xE/SQBF9xtnPlI/AAAAAAAAAOo/TlgsYYb53aU/s1600-h/ambocc_integ.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 210px; height: 42px;" src="http://1.bp.blogspot.com/_UXKUeU6z7xE/SQBF9xtnPlI/AAAAAAAAAOo/TlgsYYb53aU/s400/ambocc_integ.png" alt="" id="BLOGGER_PHOTO_ID_5260281292387728978" border="0" /&gt;&lt;/a&gt;Donde la función de visibilidad V nos da 0 ó 1, dependiendo de el rayo está oculto o no.&lt;br /&gt;&lt;br /&gt;Os muestro los mapas de oclusión en mi primera aproximación:&lt;br /&gt;- 64 Rayos aleatorios en el hemisferio.&lt;br /&gt;&lt;br /&gt;* Un rango de distancia para considerar oculto un sample. Cada sample que está oculto, se multiplica por un ratio entre distancia al punto y distancia del rango anterior. Los samples que no colisionan no se suman. Luego se computa la media de estos valores. Sería una media ponderada.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_UXKUeU6z7xE/SQBIl8TCWqI/AAAAAAAAAPI/D5NnqSFsUNs/s1600-h/ambocc_averagedistfac.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 200px;" src="http://4.bp.blogspot.com/_UXKUeU6z7xE/SQBIl8TCWqI/AAAAAAAAAPI/D5NnqSFsUNs/s400/ambocc_averagedistfac.png" alt="" id="BLOGGER_PHOTO_ID_5260284181447072418" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;* Similar al anterior, con un rango, pero sin multiplicar por el ratio, solamente 0 si no está oculto o 1 si está oculto. Luego se hace la media aritmética.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_UXKUeU6z7xE/SQBIwvkIYsI/AAAAAAAAAPQ/lK5oNgZzltM/s1600-h/ambocc_range_average10.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://1.bp.blogspot.com/_UXKUeU6z7xE/SQBIwvkIYsI/AAAAAAAAAPQ/lK5oNgZzltM/s400/ambocc_range_average10.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5260284367007670978" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;* Una prueba, en la que no se desechan las colisiones fuera del rango, solamente se utiliza el rango para ponderar (siempre de 0 a 1) cada muestra. No me gusta mucho el resultado.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_UXKUeU6z7xE/SQBI4HXl2vI/AAAAAAAAAPY/P3bTP6GVgqo/s1600-h/ambocc_range_averagedistfar.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://4.bp.blogspot.com/_UXKUeU6z7xE/SQBI4HXl2vI/AAAAAAAAAPY/P3bTP6GVgqo/s400/ambocc_range_averagedistfar.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5260284493656611570" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Se puede ver como hay defectos en el plano derecho. No sé exactamente aún a qué es debido, pero me temo que el sampleo aleatorio en el hemisferio no está del todo fino.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-7368130775194215588?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/7368130775194215588/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=7368130775194215588&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7368130775194215588'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7368130775194215588'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/10/raytracing-ambient-occlusion.html' title='Raytracing: Ambient Occlusion'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_UXKUeU6z7xE/SQBF9xtnPlI/AAAAAAAAAOo/TlgsYYb53aU/s72-c/ambocc_integ.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-8320884059870155842</id><published>2008-10-22T02:06:00.006+02:00</published><updated>2008-11-26T23:16:18.184+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='raytracing'/><title type='text'>Raytracing. Phong shading.</title><content type='html'>Sí, lo sé, estas no son horas. Son aproximadamente las 2:30 am, pero es cuando he podido descansar de los compromisos laborales. :S&lt;br /&gt;&lt;br /&gt;En estos ratos de relax, sigo con el raytracer, y lo último ha sido meterle iluminación &lt;a href="http://en.wikipedia.org/wiki/Phong_shading"&gt;Phong&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Como sabéis este modelo es una función empírica, no basada en las propiedades físicas de la luz y los materiales, pero es resultona, y sencilla de calcular. Muy básicamente, la intensidad final es calculada mediante la contribución de las componentes ambiente, difusa y especular, y todas dependen del número de luces (sus vectores de incidencia) y de los materiales.&lt;br /&gt;&lt;br /&gt;Existe un modelo mejorado de esta &lt;a href="http://en.wikipedia.org/wiki/Bidirectional_reflectance_distribution_function"&gt;BRDF&lt;/a&gt;, llamado &lt;a href="http://www.google.es/url?sa=t&amp;amp;source=web&amp;amp;ct=res&amp;amp;cd=1&amp;amp;url=http%3A%2F%2Fwww.cs.utah.edu%2F%7Eshirley%2Fpapers%2Fjgtbrdf.pdf&amp;amp;ei=lW3-SKCYJZLyQNvr7f8C&amp;amp;usg=AFQjCNGMISDBxlaKPYXtZx8HUMKhI_cMPA&amp;amp;sig2=3xVQBtCYFwxlzqS5hLPKkg"&gt;Anisotropic Phong&lt;/a&gt; el cual está bastante interesante.&lt;br /&gt;&lt;br /&gt;Os pongo una imagen de muestra, antes sus caracteristicas y la del raytracer:&lt;br /&gt;- antialiasing stochastic supersampling, 16 muestras.&lt;br /&gt;- mismo material para *todo*. exponente specular = 10.0&lt;br /&gt;- un único punto de luz omnidireccional, sin función de atenuación (ya la tengo lista aunque no se está usando).&lt;br /&gt;- iluminación local, profundidad de rayos= 1, no reflexión no refracción.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_UXKUeU6z7xE/SP5w8EhWDUI/AAAAAAAAAOg/PWp6WSg23dw/s1600-h/phong.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_UXKUeU6z7xE/SP5w8EhWDUI/AAAAAAAAAOg/PWp6WSg23dw/s400/phong.png" alt="" id="BLOGGER_PHOTO_ID_5259765592123379010" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;Features nuevas:&lt;br /&gt;&lt;/span&gt;- Phong shading.&lt;br /&gt;- Mejora del binding con python, para poder seleccionar si mostrar (creando una ventana opengl), o guardar el frame a disco (tga/bmp/dds).&lt;br /&gt;- Un thread independiente para renderizar la imagen, y el thread principal para mostrar la ventana opengl, o una barra de progreso en shell. El thread de render va escribiendo sobre la imagen, y el thread principal opengl la va leyendo y mostrando, o espera a que acabe.&lt;br /&gt;- A little bit mejora sobre el cálculo de color de sombra, ahora tiene en cuenta el valor difuso que hay en la sombra, el ambiente y un valor de la intensidad de sombra.&lt;br /&gt;&lt;br /&gt;No es mucho, pero en estos ratos libres que tengo no me da más tiempo.&lt;br /&gt;&lt;br /&gt;¿Siguiente? Quiero ir poquito a poco...&lt;br /&gt;pero para que os hagais una idea de todo lo que un raytracer moderno puede llegar a tener: (mejor seguir mirando en un entorno de epsilon features)...&lt;br /&gt;&lt;br /&gt;- Interseción con otras primitivas y mallas.&lt;br /&gt;- Multiples luces / tipos de luces y factores de atenuación.&lt;br /&gt;- Precálculo de rayos, para poder cambiar la intensidad de las luces y sus componentes en tiempo real, una vez que se ha renderizado la escena.&lt;br /&gt;- Sampling de texturas.&lt;br /&gt;- Materiales.&lt;br /&gt;- Reflexión y transmisión de los rayos.&lt;br /&gt;- Shaders programables (en python).&lt;br /&gt;- Técnicas de sombras suaves, depth of field ...  con &lt;a href="http://web.cs.wpi.edu/%7Ematt/courses/cs563/talks/dist_ray/dist.html"&gt;oversampling&lt;/a&gt;.&lt;br /&gt;- &lt;a href="http://en.wikipedia.org/wiki/Photon_mapping"&gt;Photon Mapping&lt;/a&gt;/&lt;a href="http://en.wikipedia.org/wiki/Metropolis_light_transport"&gt;MLI&lt;/a&gt;. Quiero probar con una incursión al mundo de la iluminación global (¿saldré vivo?)&lt;br /&gt;- Cantidad de cosas... pero poco a poco. Os pondré varios links muy chulos que he encontrado.&lt;br /&gt;&lt;br /&gt;un saludo a todos, me voy a la cama.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-8320884059870155842?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/8320884059870155842/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=8320884059870155842&amp;isPopup=true' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8320884059870155842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8320884059870155842'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/10/raytracing-phong-shading.html' title='Raytracing. Phong shading.'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_UXKUeU6z7xE/SP5w8EhWDUI/AAAAAAAAAOg/PWp6WSg23dw/s72-c/phong.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-7175359067381364129</id><published>2008-10-19T12:16:00.004+02:00</published><updated>2008-11-26T23:16:45.791+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Fantastic League</title><content type='html'>Gracias a un &lt;a href="http://www.laurent.es/book/index.htm"&gt;ex-compañero&lt;/a&gt; de trabajo, he podido saber que el proyecto en el que estuve trabajando durante casi 3 años, por fín ha sido publicado en una conocida web de apuestas.&lt;br /&gt;&lt;br /&gt;Lo podeis encontrar en &lt;a href="http://www.digibet.com/"&gt;www.digibet.com&lt;/a&gt; (pestaña Fantastic League), necesitaréis real player.&lt;br /&gt;&lt;br /&gt;La web oficial en &lt;a href="http://www.fantasticleague.com/"&gt;www.fantasticleague.com&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;Grandes recuerdos, grandes jornadas y grandes dolores de cabeza y estómago, pero verlo en funcionamiento me hace sentirme orgulloso de mi parte del trabajo y del equipo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-7175359067381364129?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/7175359067381364129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=7175359067381364129&amp;isPopup=true' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7175359067381364129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7175359067381364129'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/10/fantastic-league.html' title='Fantastic League'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-6869173499876354364</id><published>2008-10-17T00:49:00.004+02:00</published><updated>2008-11-26T23:17:16.211+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='raytracing'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Raytracing. Escena en python.</title><content type='html'>A petición de Javi Santana, muestro el ejemplo de escena en python, la cual es interpretada por el motor.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;from raytracing import *&lt;br /&gt;import raytracing&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;PARAMS= RaytraceParams()&lt;br /&gt;PARAMS.width = 1024&lt;br /&gt;PARAMS.height= 768&lt;br /&gt;PARAMS.AASamples = 24&lt;br /&gt;PARAMS.ambient = rgbf( 0.0, 0.0, 0.03 );&lt;br /&gt;PARAMS.observer.position = v3f(-1.0,2.0,4.0)&lt;br /&gt;PARAMS.observer.lookat( v3f(0,0,0) )&lt;br /&gt;PARAMS.observer.nearDistance = 0.5&lt;br /&gt;PARAMS.observer.farDistance = 15.0&lt;br /&gt;PARAMS.observer.fovY = 0.785398163&lt;br /&gt;PARAMS.imageflags = IMGFLAGS.FLIP_Y&lt;br /&gt;PARAMS.ambient = rgbf(0,0,0.05)&lt;br /&gt;&lt;br /&gt;SCENE = Scene()&lt;br /&gt;SCENE.sceneName = "Mi escena desde python"&lt;br /&gt;   &lt;br /&gt;# Creamos las esferas&lt;br /&gt;for i in range(-2,3):&lt;br /&gt;    for j in range(-2,3):&lt;br /&gt;        SCENE.addPrimitive( PrimSphere.create( v3f(i,0.3,j), 0.3 ) )&lt;br /&gt;&lt;br /&gt;# Creamos los planos&lt;br /&gt;SCENE.addPrimitive( PrimPlane.create( v3f(0,1,0), 0 ) )&lt;br /&gt;SCENE.addPrimitive( PrimPlane.create( v3f(1,0,0), 2.5 ) )&lt;br /&gt;SCENE.addPrimitive( PrimPlane.create( v3f(-1,0,0), 2.5 ) )&lt;br /&gt;SCENE.addPrimitive( PrimPlane.create( v3f(0,0,1), 5.0 ) )&lt;br /&gt;&lt;br /&gt;SCENE.render( PARAMS )&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-6869173499876354364?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/6869173499876354364/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=6869173499876354364&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6869173499876354364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6869173499876354364'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/10/raytracing-escena-en-python.html' title='Raytracing. Escena en python.'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-1544930619895510971</id><published>2008-10-16T21:23:00.004+02:00</published><updated>2008-11-26T23:17:50.208+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='raytracing'/><title type='text'>Raytracing (II)</title><content type='html'>Un par de técnicas simples añadidas al raytracer:&lt;br /&gt;&lt;br /&gt;* &lt;a href="http://en.wikipedia.org/wiki/Supersampling"&gt;Antialiasing&lt;/a&gt;: Se trata de lanzar x rayos más por cada pixel del plano de barrido, luego computar la intensidad final del pixel, utilizando las distintas intensidades, normalmente la media aritmética. Específicamente he usado el Stochastic Sampling, esto es, en lugar de dividir el pixel en un grid, se pilla aleatoriamente y se calcula la intensidad de ese rayo en concreto en función de la distancia al centro del pixel. En este caso he usado 16 muestras por pixel, lo que realmente equivale a renderizar la imagen 16 veces su resolución (4x4). El resultado es interesante.&lt;br /&gt;&lt;br /&gt;* Una función de variación leve, mediante una semilla, para la "perfección" difusa que muestra la &lt;a href="http://en.wikipedia.org/wiki/Lambertian_diffuse_lighting_model"&gt;ley del coseno de Lambert,&lt;/a&gt;. Esto es simplemente una prueba. La intensidad de la componente difusa se obtiene mediante el producto escalar del vector normal a la superficie del punto de intersección del rayo, y el vector hacia la fuente de luz usada (lo que viene siendo la técnica dot(NL) ). Pues probé a meterle un pequeño ruido y el resultado le da un poco de granularidad a la imagen.&lt;br /&gt;&lt;br /&gt;* Binding con python, de forma que la escena está en python. Tanto la definición de las primitivas y luces (escena virtual), como los parámetros de render. Es interesante, ya que ahora tengo una especie de POV.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Imagen sin antialiasing:&lt;/b&gt; (click para agrandar)&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_UXKUeU6z7xE/SPeXnTZuPZI/AAAAAAAAAOQ/VBY3u_4nvf0/s1600-h/Pantallazo-Mi+escena+desde+python-1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_UXKUeU6z7xE/SPeXnTZuPZI/AAAAAAAAAOQ/VBY3u_4nvf0/s400/Pantallazo-Mi+escena+desde+python-1.png" alt="" id="BLOGGER_PHOTO_ID_5257837791457197458" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Imagen con antialiasing:&lt;/b&gt; (click para agrandar):&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_UXKUeU6z7xE/SPeXnV9-Q0I/AAAAAAAAAOY/Fa-DnSvMPRM/s1600-h/Pantallazo-Mi+escena+desde+python-4.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_UXKUeU6z7xE/SPeXnV9-Q0I/AAAAAAAAAOY/Fa-DnSvMPRM/s400/Pantallazo-Mi+escena+desde+python-4.png" alt="" id="BLOGGER_PHOTO_ID_5257837792146113346" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;PD: El framerate cae muy mucho, así que de realtime... :(, pero bueno, aún hay que meterle un algoritmo de voxelización para acelerar los cálculos.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-1544930619895510971?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/1544930619895510971/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=1544930619895510971&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/1544930619895510971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/1544930619895510971'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/10/raytracing-ii.html' title='Raytracing (II)'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_UXKUeU6z7xE/SPeXnTZuPZI/AAAAAAAAAOQ/VBY3u_4nvf0/s72-c/Pantallazo-Mi+escena+desde+python-1.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-2878129264639859711</id><published>2008-10-16T12:19:00.005+02:00</published><updated>2008-11-26T23:18:04.398+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='raytracing'/><title type='text'>Raytracing en tiempo real</title><content type='html'>Tengo las primeras imágenes de un Raytracer en tiempo real que estoy programando.&lt;br /&gt;Por ahora tengo lo básico, el lanzado de rayos, detección de colisiones con primitivas básicas, iluminación difusa, fuente de luz y sombras. Le quiero meter más features.&lt;br /&gt;&lt;br /&gt;Por ahora lo tengo a unos 12fps para 640x480, pero le estoy ya metiendo directivas OpenMP para que me cree automáticamente hilos de ejecución a la hora del barrido de la pantalla, así que cada uno se dedique a una parte de la misma.&lt;br /&gt;&lt;br /&gt;También podría usar GPU, pero prefiero primero dominar el raytracing en CPU, y ver hasta que punto puedo paralelizarlo.&lt;br /&gt;&lt;br /&gt;Para los que no lo sepais, el raytracing es una alternativa para renderizar una escena en la que se trazan rayos desde el punto de vista del observador (uno por pixel) y se detecta el color que tiene ese pixel con un modelo de iluminación determinado. Hay otros métodos para renderizar una escena, como el rasterizarla (tal y como las tarjetas 3d hacen actualmente para los gráficos en tiempo real) o el radiosity, el cual es el más lento, con trazados de rayos desde los puntos de luz y calculando la contribución de la luz en determinados patches. Los resultados de este último son muy buenos.&lt;br /&gt;El método que estoy haciendo, de raytracing, es el utilizado por infinidad de paquetes como POV, OpenRT, yafray o Maxwell rendering, solo que cada uno utiliza sus modelos de iluminación y técnicas particulares.&lt;br /&gt;&lt;br /&gt;La construcción de un raytracer sencillo como el que muestro, es una tarea didáctica muy interesante, y solo involucra algunos bucles y calculos vectoriales, nada complejo, y lo recomiendo para aprender bastante de muchos temas de gráficos. Eso sí, se puede complicar todo lo que se quiera.&lt;br /&gt;&lt;br /&gt;Para más información, teneis la wikipedia.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_UXKUeU6z7xE/SPcXhjuHJxI/AAAAAAAAANo/-MIu7DcteBc/s1600-h/Pantallazo-Real-Time+Raytracing.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_UXKUeU6z7xE/SPcXhjuHJxI/AAAAAAAAANo/-MIu7DcteBc/s320/Pantallazo-Real-Time+Raytracing.png" alt="" id="BLOGGER_PHOTO_ID_5257696955270113042" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_UXKUeU6z7xE/SPcXv1kGyzI/AAAAAAAAANw/1Lt9bUItmZs/s1600-h/Pantallazo-Real-Time+Raytracing-1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_UXKUeU6z7xE/SPcXv1kGyzI/AAAAAAAAANw/1Lt9bUItmZs/s320/Pantallazo-Real-Time+Raytracing-1.png" alt="" id="BLOGGER_PHOTO_ID_5257697200578153266" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_UXKUeU6z7xE/SPc0VzQJEgI/AAAAAAAAAOA/LuBvhOp3SSs/s1600-h/Pantallazo-Mi+escena+desde+python.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_UXKUeU6z7xE/SPc0VzQJEgI/AAAAAAAAAOA/LuBvhOp3SSs/s320/Pantallazo-Mi+escena+desde+python.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5257728639118152194" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_UXKUeU6z7xE/SPc0WE8uFXI/AAAAAAAAAOI/B9uPafkD9lk/s1600-h/Pantallazo-Mi+escena+desde+python-1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_UXKUeU6z7xE/SPc0WE8uFXI/AAAAAAAAAOI/B9uPafkD9lk/s320/Pantallazo-Mi+escena+desde+python-1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5257728643868530034" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-2878129264639859711?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/2878129264639859711/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=2878129264639859711&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/2878129264639859711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/2878129264639859711'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/10/raytracing-en-tiempo-real.html' title='Raytracing en tiempo real'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_UXKUeU6z7xE/SPcXhjuHJxI/AAAAAAAAANo/-MIu7DcteBc/s72-c/Pantallazo-Real-Time+Raytracing.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-6107579884410248138</id><published>2008-09-25T23:44:00.004+02:00</published><updated>2008-11-26T23:18:29.116+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><title type='text'>Introducción a la programación paralela</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.popularlibros.com/libros/INTRODUCCION-A-LA-PROGRAMACION-PARALELA/L0430001268/978-84-9732-674-2&lt;br /&gt;"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://1.bp.blogspot.com/_UXKUeU6z7xE/SNwH5EgS3hI/AAAAAAAAAJg/nomq8HCNTVk/s320/muestraPortada.php.jpeg" alt="" id="BLOGGER_PHOTO_ID_5250079942650289682" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Hace poco me he comprado el libro "Introducción a la programación paralela" porque lo descubrí por casualidad trasteando por la casa del libro.&lt;br /&gt;&lt;br /&gt;Me puse a ojearlo y la verdad es que me gustó bastante.&lt;br /&gt;&lt;br /&gt;Ya sabeis que el futuro está en la paralelización (a todos los niveles), y hay que estar prevenido. El libro está escrito por cuatro profesores de universidad (española), y tiene fecha de 2008. Trata:&lt;br /&gt;- Nociones, conceptos y teoría de computación paralela. Tipos, historia...&lt;br /&gt;- Análisis matemático de los algoritmos paralelos. Algoritmia para saber la ganancia en determinados problemas, al aplicar modelos de computación orientados al paralelismo.&lt;br /&gt;- Explica detalles técnicos e introduce dos lenguajes/entornos de programación paralela: OpenMP y MPI, para sistemas de memoria compartida y de pasos de mensajes respectivamente.&lt;br /&gt;- Expone problemas habituales (computables), a los que se les aplican las técnicas de paralelismo, como diferenciación, sistemas matriciales, ...&lt;br /&gt;- Tiene ejercicios y problemas propuestos.&lt;br /&gt;- ... Muchas cosas más ...&lt;br /&gt;&lt;br /&gt;La verdad es una auténtica adquisición, por solo 35€, de la que estoy muy contento, y estoy aprendiendo bastante. Y tiene poco de "introducción" la verdad.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.popularlibros.com/libros/INTRODUCCION-A-LA-PROGRAMACION-PARALELA/L0430001268/978-84-9732-674-2 "&gt;http://www.popularlibros.com/libros/INTRODUCCION-A-LA-PROGRAMACION-PARALELA/L0430001268/978-84-9732-674-2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Un saludo compis.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-6107579884410248138?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/6107579884410248138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=6107579884410248138&amp;isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6107579884410248138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6107579884410248138'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/09/introduccin-la-programacin-paralela.html' title='Introducción a la programación paralela'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_UXKUeU6z7xE/SNwH5EgS3hI/AAAAAAAAAJg/nomq8HCNTVk/s72-c/muestraPortada.php.jpeg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-1832903471149692887</id><published>2008-09-10T23:15:00.005+02:00</published><updated>2008-11-26T23:19:14.393+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Offtopic: Media</title><content type='html'>Aunque me he comprado auténticos clásicos en este tiempo (juegos, pelis y lps), tengo que decir que estoy especialmente contento con las dos últimas adquisiciones:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Terminator 2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Sí, vale. La tenía en VHS en casa de mis padres, pero quería tenerla en DVD.&lt;br /&gt;¿Antigua? Sí, pero marcó época para mí.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;7€&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;SFDK - Los Veteranos&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Estos sevillanos tienen un arte tremendo.&lt;br /&gt;Tienen su propia discográfica. Letras increíbles. Llevo tiempo escuchándoles.&lt;br /&gt;Les deseo toda la suerte del mundo.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;8€&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Saludos compis.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-1832903471149692887?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/1832903471149692887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=1832903471149692887&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/1832903471149692887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/1832903471149692887'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/09/offtopic-media.html' title='Offtopic: Media'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-6137191755105263125</id><published>2008-07-31T07:39:00.003+02:00</published><updated>2008-11-26T23:19:34.544+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Resign Patterns</title><content type='html'>No podeis dejar de echar un ojo al siguiente artículo, donde se comentan patrones de diseños "chungos", en su mayoría extraídos de código antiguo. Son prácticas que no deberían de volver a cometerse. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.lsd.ic.unicamp.br/~oliva/fun/prog/resign-patterns"&gt;http://www.lsd.ic.unicamp.br/~oliva/fun/prog/resign-patterns&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-6137191755105263125?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/6137191755105263125/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=6137191755105263125&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6137191755105263125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6137191755105263125'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/07/resign-patterns.html' title='Resign Patterns'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-6107117809098462309</id><published>2008-06-10T10:50:00.004+02:00</published><updated>2008-11-26T23:19:53.481+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Bjarne Stroustrup's Homepage</title><content type='html'>Un link que todo amante de C++ debería tener entre sus favoritos:&lt;br /&gt;El website personal del creador.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.research.att.com/~bs/" title="Bjarne Stroustrup's Home" &gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 219px; height: 184px;" src="http://www.research.att.com/%7Ebs/Bjarne.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www.research.att.com/%7Ebs/"&gt;http://www.research.att.com/~bs/&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Dentro de la misma podeis acceder a una FAQ bastante interesante sobre estilo y técnica programando en C++:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.research.att.com/%7Ebs/bs_faq2.html"&gt;http://www.research.att.com/~bs/bs_faq2.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-6107117809098462309?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/6107117809098462309/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=6107117809098462309&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6107117809098462309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6107117809098462309'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/06/bjarne-stroustrups-homepage.html' title='Bjarne Stroustrup&apos;s Homepage'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-7518870347532616088</id><published>2008-06-09T11:03:00.016+02:00</published><updated>2008-11-26T23:20:18.390+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Simple Var &amp; VarManager</title><content type='html'>Últimamente he estado investigando un poco acerca de la reflexión/introspección del código C++. Fruto de ello, en mi librería (o plataforma o motor), del que algún día tengo que hablar algo más, he creado una serie de clases para soportar la reflexión C++. Esto lleva a crear una serie de artefactos sobre el lenguaje, haciendo uso de clases globales que registran tipos de datos, prototipos de métodos, etc... y para facilitar la escritura usando macros que se sustituyen por código según los parámetros pasados.&lt;br /&gt;También están los patrones de diseño &lt;a href="http://en.wikipedia.org/wiki/Factory_method_pattern"&gt;Factory &lt;/a&gt;y &lt;a href="http://en.wikipedia.org/wiki/Builder_pattern"&gt;Builder&lt;/a&gt;.&lt;br /&gt;&lt;a href="http://groups.google.com/group/comp.object/browse_thread/thread/db4b3914ddea5131/25e7e96e2e91983b?lnk=st&amp;amp;q=&amp;amp;rnum=1#25e7e96e2e91983b"&gt;Aquí &lt;/a&gt;podéis leer la diferencia entre ellos.&lt;br /&gt;En el inmediato siguiente post, os enseño el código de Factoría que tengo y muestro su utilización.&lt;br /&gt;&lt;br /&gt;Pero ahora, voy a mostrar unas clases que representan un tipo Variant, del que hablé en &lt;a href="http://gyakoo.blogspot.com/2007/06/variant-type.html"&gt;otro de mis posts.&lt;/a&gt; Y una clase que recoge en un diccionario&lt;string,variant&gt; estas variables.&lt;br /&gt;Aunque en mi antiguo puesto creamos un sistema de variables variants, contenidas en diccionarios, y un sistema de reflexión basado en estos y el patrón de factoría, que se enlazaba (binding) con el sistema de script lua, he considerado rehacer este sistema y hacerlo más simple en mi librería. También he intentado minimizar el uso de memoría dinámica (heap), así como las funciones virtuales y tipos polimórficos. Pero claro, esto tiene la desventaja de que mi sistema es menos "flexible" o "extensible" por así decirlo, aunque va bastante rápido y es bastante estable, al no hacer uso extensivo de punteros, memoría dinámica, objetos con contador de referencias...&lt;br /&gt;&lt;br /&gt;&lt;/string,variant&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.dimensoft.com/data/code/misc/var.h"&gt;Var.h&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.dimensoft.com/data/code/misc/var.cpp"&gt;Var.cpp&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Primero voy mostrar ejemplos de uso, luego paso a describiros otras maneras de implementación y por qué finalmente utilizé esta, y finalmente os mostraré las utilidades de usar algo así.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Uso aislado de la variable Var&lt;/span&gt;&lt;br /&gt;&lt;table style="width: 640px; height: 147px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="background-color: rgb(204, 204, 204);"&gt;&lt;pre&gt;&lt;br /&gt;// -- Var es un flotante&lt;br /&gt;gy::Var v = 3.0f;&lt;br /&gt;funcFloat( v.asF() );&lt;br /&gt;&lt;br /&gt;// -- Ahora es una cadena&lt;br /&gt;v = "hola mundo!";&lt;br /&gt;funcPrint( v.asS() );&lt;br /&gt;&lt;br /&gt;// -- Copia en w, la cual es una cadena.&lt;br /&gt;gy::Var w = v;&lt;br /&gt;funcPrint( w.asS() );&lt;br /&gt;&lt;br /&gt;// -- Recibirá aquellos tipos que Var tenga sobrecargado su construcción&lt;br /&gt;void funcSomething( const Var&amp;amp; _v )&lt;br /&gt;{&lt;br /&gt;   std::cout &amp;lt;&amp;lt; "El tipo de var es: " &amp;lt;&amp;lt; _v.getType();&lt;br /&gt;}&lt;br /&gt;funcSomething( 3.0f );&lt;br /&gt;funcSomething( "hola" );&lt;br /&gt;funcSomething( 200 );&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Uso simple de VarMan&lt;/span&gt;&lt;br /&gt;&lt;table style="width: 640px; height: 147px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="background-color: rgb(204, 204, 204);"&gt;&lt;pre&gt;&lt;br /&gt;//-- Recibe parametros de entidad y muestra su tipo&lt;br /&gt;void funcEntity( const gy::VarMan&amp;amp; vm )&lt;br /&gt;{&lt;br /&gt;   gy::Var* e = vm.get("entityType");&lt;br /&gt;   if ( v != 0 )&lt;br /&gt;   {&lt;br /&gt;      std::cout &amp;lt;&amp;lt; "Type: " &amp;lt;&amp;lt; v-&amp;gt;asS() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;En el siguiente ejemplo se muestra la manera de utilizar el VarMan para contener variables jerárquicamente. Realmente no hace uso de ninguna estructura jerárquica de datos, sino más bien está colapsada en el propio diccionario principal de VarMan. Esto  mejora el rendimiento de acceso, al no tener que recorrer ningún arbol, aunque por ejemplo, tendría sus problemas en multithreading, ya que si estuviera en árbol, quizás podría darle una rama del árbol a un hilo, sin tener que interferir con otro hilo que esté trabajando en otra rama, pero de todas formas estas clases no son Thread-Safe (por ahora).&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Creación de VarMan con VMBuilder&lt;/span&gt;&lt;br /&gt;&lt;table style="width: 640px; height: 147px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="background-color: rgb(204, 204, 204);"&gt;&lt;pre&gt;&lt;br /&gt;VarMan vm;&lt;br /&gt;VMBuilder(vm)&lt;br /&gt;   .def( "entityType", "Box" )&lt;br /&gt;   .def( "name", "PandoraBox" )&lt;br /&gt;   .begin_space( "position" )&lt;br /&gt;      .def( "x", 1.0f )&lt;br /&gt;      .def( "y", 2.0f )&lt;br /&gt;      .def( "z", 3.0f )&lt;br /&gt;   .end_space()&lt;br /&gt;   .begin_space( "color" )&lt;br /&gt;      .begin_space( "diffuse" )&lt;br /&gt;         .def( "r", 100 )&lt;br /&gt;         .def( "g", 240 )&lt;br /&gt;         .def( "b", 50 )&lt;br /&gt;      .end_space()&lt;br /&gt;      .begin_space( "specular" )&lt;br /&gt;         .def( "r", 200 )&lt;br /&gt;         .def( "g", 200 )&lt;br /&gt;         .def( "b", 200 )&lt;br /&gt;      .end_space()&lt;br /&gt;   .end_space()&lt;br /&gt;;&lt;br /&gt;funcEntityHier( vm );&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Ahora, para acceder a estas variables de manera igualmente jerárquica podemos hacerlo de las siguientes formas:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Lectura de VarMan simple y con VMTraveler&lt;/span&gt;&lt;br /&gt;&lt;table style="width: 640px; height: 147px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="background-color: rgb(204, 204, 204);"&gt;&lt;pre&gt;&lt;br /&gt;// -- Lectura simple&lt;br /&gt;// -- El '.' nos sirve para acceder al sub-espacio&lt;br /&gt;void funcEntityHier( const gy::VarMan&amp;amp; vm )&lt;br /&gt;{&lt;br /&gt;   std::cout &amp;lt;&amp;lt; "Posicion: "&lt;br /&gt;                   &amp;lt;&amp;lt; vm.get("posicion.x")-&amp;gt;asF() &amp;lt;&amp;lt; ", "                         &lt;br /&gt;                   &amp;lt;&amp;lt; vm.get("posicion.y")-&amp;gt;asF() &amp;lt;&amp;lt; ", "                         &lt;br /&gt;                   &amp;lt;&amp;lt; vm.get("posicion.z")-&amp;gt;asF() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;// -- Lectura por sub-spacios&lt;br /&gt;void funcEntityHier( const gy::VarMan&amp;amp; vm )&lt;br /&gt;{&lt;br /&gt;   // -- Acceso directo al espacio "color"&lt;br /&gt;   gy::VMTraveler col( vm, "color" );&lt;br /&gt;   float diff[3] = { col.get("diffuse.r")-&amp;gt;asF(),&lt;br /&gt;                     col.get("diffuse.g")-&amp;gt;asF(),&lt;br /&gt;                     col.get("diffuse.b")-&amp;gt;asF() };&lt;br /&gt;&lt;br /&gt;   // -- Acceso al espacio color.specular, usando el anterior&lt;br /&gt;   gy::VMTraveler spec( col, "specular" );&lt;br /&gt;   float sp[3] =   { spec.get("r")-&amp;gt;asF(),&lt;br /&gt;                     spec.get("g")-&amp;gt;asF(),&lt;br /&gt;                     spec.get("b")-&amp;gt;asF() };&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Por último, podemos recorrer el VarMan mediante iteradores:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Recorrido con iteradores VarMan&lt;/span&gt;&lt;br /&gt;&lt;table style="width: 640px; height: 147px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="background-color: rgb(204, 204, 204);"&gt;&lt;pre&gt;&lt;br /&gt;// -- Recorremos todo, mostrando la variable y su tipo.&lt;br /&gt;void funcPrintAll( gy::VarMan&amp;amp; vm )&lt;br /&gt;{&lt;br /&gt;   gy::VarMan::iterator it = vm.getIterator();&lt;br /&gt;   while ( it-&gt;isEnded() )&lt;br /&gt;   {&lt;br /&gt;      std::cout &amp;lt;&amp;lt; it.getName() &amp;lt;&amp;lt; " = " &amp;lt;&amp;lt; it.getVar()-&amp;gt;getType() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;// -- Tambien sobrecarga const&lt;br /&gt;void funcPrintAll( const gy::VarMan&amp;amp; vm )&lt;br /&gt;{&lt;br /&gt;   gy::VarMan::const_iterator it = vm.getIterator();&lt;br /&gt;   while ( it-&gt;isEnded() )&lt;br /&gt;   {&lt;br /&gt;      std::cout &amp;lt;&amp;lt; it.getName() &amp;lt;&amp;lt; " = " &amp;lt;&amp;lt; it.getVar()-&amp;gt;getType() &amp;lt;&amp;lt; std::endl;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;¿Otras maneras de implementación de Var Managers?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Existen otras maneras de implementar un Variant así como un Var Manager de estos.&lt;br /&gt;&lt;br /&gt;Una opción alternativa puede ser la de crear un interfaz de Variant, el cual tenga unos métodos virtuales tales que implementen las distintas variables. De esta manera podemos tener variant con diferentes tipos de variables.&lt;br /&gt;&lt;table style="width: 640px; height: 147px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="background-color: rgb(204, 204, 204);"&gt;&lt;pre&gt;&lt;br /&gt;struct IVar&lt;br /&gt;{&lt;br /&gt;   virtual float asF() = 0;&lt;br /&gt;   virtual const char* asS() = 0;&lt;br /&gt;   ...&lt;br /&gt;};&lt;br /&gt;struct VarFloat&lt;br /&gt;{&lt;br /&gt;   float asF() { return mFloat; }&lt;br /&gt;   const char* asS() { /* convertir float a cadena y devolver*/ }&lt;br /&gt;   ...&lt;br /&gt;protected:&lt;br /&gt;   float mFloat;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;struct VarString ...&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Luego tendríamos un VarManager que no es más que un diccionario del mismo tipo que &lt;i&gt;VarMan&lt;/i&gt;, cuyo tipo sería el puntero al &lt;i&gt;IVar&lt;/i&gt;, el cual es polimórfico.&lt;br /&gt;Incluso, una variable que especialice &lt;i&gt;IVar&lt;/i&gt; podría ser un propio VarManager, de esta forma podríamos tener un árbol real dentro de un VarManager, sin artefactos de nombres compuestos por ".".&lt;br /&gt;Personalmente evité, como os comenté antes, usar este tipo de implementación, ya que hace un uso extensivo del heap y de las funciones virtuales. Además, hay que tener cuidado con las copias y las referencias a los punteros de las variables. Para ello se usa objetos contadores de referencias así como un tipo &lt;a href="http://www.boost.org/doc/libs/1_35_0/libs/smart_ptr/smart_ptr.htm"&gt;smart pointers&lt;/a&gt;.&lt;br /&gt;&lt;i&gt;Nota: De esta forma lo usábamos en el trabajo.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Algunos usos más obvios de estos VarManagers&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Métodos / funciones con número, tipo y nombres de argumentos variables.&lt;/li&gt;&lt;li&gt;Prototipo único de constructor, para el patrón de factoría es genial, ya que tenemos una clase base que se construye con un VarMan. Todas las clases que hereden han de tener un constructor con VarMan, así podemos tener un único tipo de creación de objeto. Un ejemplo muy simple sería:&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;table style="width: 640px; height: 147px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="background-color: rgb(204, 204, 204);"&gt;&lt;pre&gt;&lt;br /&gt;class Base&lt;br /&gt;{&lt;br /&gt;   Base( const VarMan&amp;amp; initParams ){ ... }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Derived : public Base&lt;br /&gt;{&lt;br /&gt;   Derived( const VarMan&amp;amp; initParams ) : Base(initParams) { ... }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// -- Factoría muy simple.&lt;br /&gt;template&amp;lt;class T&amp;gt;&lt;br /&gt;T* create( const VarMan&amp;amp; initParams )&lt;br /&gt;{&lt;br /&gt;   // Aqui se asume que T tiene un constructor que recibe un VarMan&lt;br /&gt;   return new T( initParams );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// -- Construimos el vm y creamos&lt;br /&gt;VarMan vmbas, vmder;&lt;br /&gt;...&lt;br /&gt;boost::scoped_ptr&amp;lt;Base&amp;gt; bas ( create&amp;lt;Base&amp;gt;( vmbas ) );&lt;br /&gt;boost::scoped_ptr&amp;lt;Base&amp;gt; dev ( create&amp;lt;Derived&amp;gt;( vmder ) );&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Otro uso que podemos darle a nuestro VarMan puede ser el de diccionario de variables de configuración, tal que podamos leer de un fichero de texto/script externo y usar el VarMan como almacen de estos parámetros leídos. Además se podrían modificar y volver a guardar en el fichero. Se puede implementar externamente o mediante métodos de serialización. El pseudocódigo sería:&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;table style="width: 640px; height: 147px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="background-color: rgb(204, 204, 204);"&gt;&lt;pre&gt;&lt;br /&gt;// -- Usando serializacion&lt;br /&gt;class VarMan&lt;br /&gt;{&lt;br /&gt;   ...&lt;br /&gt;   // -- Escribe en "sd" los datos del diccionario interno&lt;br /&gt;   void serialize( SerializeData&amp; sd ) { ... }&lt;br /&gt;&lt;br /&gt;   // -- Lee de "sd" los datos de diccionario y lo vuelca en nuestro interno.&lt;br /&gt;   void deserialize( const SerializeData&amp; sd ){ ... }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// -- IO de ficheros de texto.&lt;br /&gt;class VarMan&lt;br /&gt;{&lt;br /&gt;   ...&lt;br /&gt;   void readFromFile( const char* file ) { ... }&lt;br /&gt;&lt;br /&gt;   void writeToFile ( const char* file ) { ... }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;El formato del fichero puede ser cualquiera. Puede ser un fichero ini, o en algún formato propio. También puede ser un formato similar al de algún lenguaje de script que tengamos en el motor implementado/binded. Por ejemplo puede ser un diccionario de Python o una tabla de Lua. Esto nos ayuda a la hora de parsearlo ya el intérprete de estos lenguajes lo hacen por nosotros, además de que así facilitamos la compartición de datos entre el script y nuestro sistema.&lt;br /&gt;Un ejemplo de formato propio podría ser:&lt;br /&gt;&lt;table style="width: 640px; height: 147px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="background-color: rgb(204, 204, 204);"&gt;&lt;pre&gt;&lt;br /&gt;entityType = "Box",&lt;br /&gt;name = "PandoraBox",&lt;br /&gt;position = {&lt;br /&gt;   x = 1.0,&lt;br /&gt;   y = 2.0,&lt;br /&gt;   z = 3.0&lt;br /&gt;},&lt;br /&gt;color = {&lt;br /&gt;   diffuse = {&lt;br /&gt;      r = 100,&lt;br /&gt;      g = 240,&lt;br /&gt;      b = 50&lt;br /&gt;   },&lt;br /&gt;   specular = {&lt;br /&gt;      r = 200,&lt;br /&gt;      g = 200,&lt;br /&gt;      b = 200&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Aunque también en formato ini, colapsando la jerarquía:&lt;br /&gt;&lt;table style="width: 640px; height: 147px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="background-color: rgb(204, 204, 204);"&gt;&lt;pre&gt;&lt;br /&gt;entityType = "Box",&lt;br /&gt;name = "PandoraBox",&lt;br /&gt;position.x = 1.0&lt;br /&gt;position.y = 2.0&lt;br /&gt;position.z = 3.0&lt;br /&gt;color.diffuse.r = 100&lt;br /&gt;color.diffuse.g = 240&lt;br /&gt;color.diffuse.b = 50&lt;br /&gt;color.specular.r = 200&lt;br /&gt;color.specular.g = 200&lt;br /&gt;color.specular.b = 200&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Habría que parsearlos.&lt;br /&gt;&lt;br /&gt;Espero que os sea de utilidad. Saludos.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-7518870347532616088?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/7518870347532616088/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=7518870347532616088&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7518870347532616088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7518870347532616088'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/06/simple-var-varmanager.html' title='Simple Var &amp; VarManager'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-6159790082952527762</id><published>2008-06-08T21:12:00.003+02:00</published><updated>2008-11-26T23:20:40.047+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Wikibook: Eficiencia en C++</title><content type='html'>Leo a través del grupo comp.lang.c++, que han creado una wiki para mostrar distintos consejos a la hora de escribir un código C++ más eficiente. Tiene algunas cosas interesantes, y está abierto a colaboraciones. Esperemos que vaya creciendo.&lt;br /&gt;&lt;a href="http://en.wikibooks.org/wiki/Optimizing_C%2B%2B"&gt;Optimizing C++&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Y como muestra, un botón:&lt;br /&gt;&lt;h3&gt;&lt;span class="mw-headline"&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;/h3&gt;&lt;blockquote&gt;&lt;h3&gt;&lt;span class="mw-headline"&gt;Template code independent of parameters&lt;/span&gt;&lt;/h3&gt; &lt;p&gt;&lt;b&gt;If in a class template a non-trivial member function do not depend on any template parameter, define a non-member function having the same body, and replace the original function body with a call to the new function.&lt;/b&gt;&lt;/p&gt; &lt;p&gt;Let's assume you wrote the following code:&lt;/p&gt; &lt;div dir="ltr" style="text-align: left;"&gt; &lt;pre class="source-cpp"&gt;&lt;span class="kw2"&gt;template&lt;/span&gt; &lt;typename&gt;&lt;br /&gt;&lt;span class="kw2"&gt;class&lt;/span&gt; C &lt;span class="br0"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="kw2"&gt;public&lt;/span&gt;:&lt;br /&gt;   C&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;: x_&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="nu0"&gt;0&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; &lt;span class="br0"&gt;{&lt;/span&gt; &lt;span class="br0"&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span class="kw4"&gt;int&lt;/span&gt; f&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="kw4"&gt;int&lt;/span&gt; i&lt;span class="br0"&gt;)&lt;/span&gt; &lt;span class="br0"&gt;{&lt;/span&gt; body&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;; &lt;span class="kw1"&gt;return&lt;/span&gt; i; &lt;span class="br0"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="kw2"&gt;private&lt;/span&gt;:&lt;br /&gt;   T x_;&lt;br /&gt;&lt;span class="br0"&gt;}&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Try to replace the above code with the following:&lt;/p&gt; &lt;div dir="ltr" style="text-align: left;"&gt; &lt;pre class="source-cpp"&gt;&lt;span class="kw2"&gt;template&lt;/span&gt; &lt;typename&gt;&lt;br /&gt;&lt;span class="kw2"&gt;class&lt;/span&gt; C &lt;span class="br0"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="kw2"&gt;public&lt;/span&gt;:&lt;br /&gt;   C&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;: x_&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="nu0"&gt;0&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt; &lt;span class="br0"&gt;{&lt;/span&gt; &lt;span class="br0"&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span class="kw4"&gt;void&lt;/span&gt; f&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="kw4"&gt;int&lt;/span&gt; i&lt;span class="br0"&gt;)&lt;/span&gt; &lt;span class="br0"&gt;{&lt;/span&gt; &lt;span class="kw1"&gt;return&lt;/span&gt; f_&lt;span class="br0"&gt;(&lt;/span&gt;i&lt;span class="br0"&gt;)&lt;/span&gt;; &lt;span class="br0"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="kw2"&gt;private&lt;/span&gt;:&lt;br /&gt;   T x_;&lt;br /&gt;&lt;span class="br0"&gt;}&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="kw4"&gt;void&lt;/span&gt; f_&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="kw4"&gt;int&lt;/span&gt; i&lt;span class="br0"&gt;)&lt;/span&gt; &lt;span class="br0"&gt;{&lt;/span&gt; body&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;; &lt;span class="kw1"&gt;return&lt;/span&gt; i; &lt;span class="br0"&gt;}&lt;/span&gt; &lt;/pre&gt;&lt;/div&gt; &lt;p&gt;For every instantiation of a class template that uses a function of that class template, the whole code of the function is instantiated. If a function in that class template do not depend on any template parameters, at every instantiation the function machine code is duplicated. Such code replication bloats the program.&lt;/p&gt; &lt;p&gt;In a class template or in a function template, a big function could have a large part that do not depend on any template parameters. In such a case, first, factor out such a code portion as a distinct function, and then apply this guideline.&lt;/p&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-6159790082952527762?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/6159790082952527762/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=6159790082952527762&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6159790082952527762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6159790082952527762'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/06/wikibook-eficiencia-en-c.html' title='Wikibook: Eficiencia en C++'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-7088446398756339932</id><published>2008-05-11T16:55:00.004+02:00</published><updated>2008-11-26T23:21:22.739+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>GOA - Free to play</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.goa.com/" title="GOA - Free to play"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp2.blogger.com/_UXKUeU6z7xE/SCcKrw-yMXI/AAAAAAAAAJQ/h7lvhSiMWWs/s320/goa.jpg" alt="" id="BLOGGER_PHOTO_ID_5199136041821417842" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www.goa.com/"&gt;GOA &lt;/a&gt;es un portal de comunidad que ofrece videojuegos multijugador (por ahora tres), de un buen nivel de calidad y acabado cartoon.&lt;br /&gt;&lt;br /&gt;Me ha sorprendido porque solo tienes que darte de alta y descargarte el juego que quieras. Gratis. Jugarás contra otros usuarios online. Yo lo he hecho con Kart n' Crazy y es bastante chulo.&lt;br /&gt;&lt;br /&gt;También tiene una opción de pago, en la cual, los usuarios tendrán una serie de valores añadidos a los juegos, aunque no por pagar tienen más ventajas a la hora del juego en sí.&lt;br /&gt;&lt;br /&gt;Tengo que buscar otras iniciativas parecidas. Recomiendo que se le eche un vistazo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-7088446398756339932?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/7088446398756339932/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=7088446398756339932&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7088446398756339932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7088446398756339932'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/05/goa-free-to-play.html' title='GOA - Free to play'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_UXKUeU6z7xE/SCcKrw-yMXI/AAAAAAAAAJQ/h7lvhSiMWWs/s72-c/goa.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-5531775422417010417</id><published>2008-05-10T11:50:00.004+02:00</published><updated>2008-11-26T23:21:50.258+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='media'/><title type='text'>GoW2  Trailer</title><content type='html'>Hoy exclusiva mundial, Trailer de Gears of Wars 2.&lt;br /&gt;&lt;br /&gt;Bigger and better, como dice el director de diseño. Desde luego es bastante impresionante la lucha que aparece en el video, contra los monstruos esos bípedos gigantes con cañon en la espalda (no me acuerdo de su nombre).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.gametrailers.com"&gt;http://www.gametrailers.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Las habilidades del personaje parecen haber mejorado ligeramente, además de que están usando la nueva versión &lt;span style="font-weight:bold;"&gt;Unreal Engine 3.5&lt;/span&gt;, cuya presentación en el GDC08 la teneis aquí:&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="355"&gt;&lt;param name="movie" value="http://www.youtube.com/v/4oxOCd4UVjU&amp;hl=en"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/4oxOCd4UVjU&amp;hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Aquí teneis una versión con mejor calidad del UE3.5: &lt;a href="http://www.gametrailers.com/player/30825.html"&gt;http://www.gametrailers.com/player/30825.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-5531775422417010417?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/5531775422417010417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=5531775422417010417&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5531775422417010417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5531775422417010417'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/05/gow2-trailer.html' title='GoW2  Trailer'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-168191865345016179</id><published>2008-05-07T09:30:00.005+02:00</published><updated>2008-11-26T23:22:54.945+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='media'/><title type='text'>Descargas</title><content type='html'>Al fin he podido hospedar algunos de los desarrollos que he realizado.&lt;br /&gt;Poco a poco iré subiendo otros que tengo más pequeños y que aún no he podido recopilar, tales como demos y cosas de esas.&lt;br /&gt;En la barra de la derecha, en &lt;span style="font-weight: bold;"&gt;.Descargas &lt;/span&gt;lo teneis.&lt;br /&gt;Para ejecutarlos necesitareis tener una tarjeta gráfica aceleradora 3D normal, así como instalar las &lt;a href="http://www.dimensoft.com/data/vcredist_x86.exe"&gt;dependencias del Visual C++ 2005&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.dimensoft.com/data/XungoGame.rar"&gt;Xungo Game&lt;/a&gt;: Es el prototipo de juego para probar temas de gravedad en juego 2D. No tiene prácticamente nada, más que un personaje que se mueve por las paredes y salta, porque lo hice en un fin de semana. Entrada &lt;a href="http://gyakoo.blogspot.com/2007/12/fin-de-semana-gravitacional.html"&gt;aquí&lt;/a&gt;.&lt;/li&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_UXKUeU6z7xE/R1MVADpfKzI/AAAAAAAAAIY/9mVPlr4E15E/s1600-R/01.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 167px; height: 125px;" src="http://bp0.blogger.com/_UXKUeU6z7xE/R1MVADpfKzI/AAAAAAAAAIY/9mVPlr4E15E/s1600-R/01.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.dimensoft.com/data/SURCOS.rar"&gt;Soldados&lt;/a&gt;: Demo de un juego simulador de combate urbano. Los modelos, mapa y animaciones los hice yo (así se ve de mal, así que sed buenos please ;), con un poco de ayuda en el modelado del soldado. Se hizo en dos meses partiendo de cero, usando Ogre3D un pelín tuneado. Aquí podeis ver el postmortem (&lt;a href="http://gyakoo.blogspot.com/2007/06/postmortem-soldiers-i.html"&gt;I&lt;/a&gt; y &lt;a href="http://gyakoo.blogspot.com/2007/06/postmortem-soldiers-ii.html"&gt;II&lt;/a&gt;).&lt;br /&gt;&lt;/li&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_UXKUeU6z7xE/RoLoiagKi4I/AAAAAAAAADs/JBAvih7FpLE/s320/Surcos_01.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 163px; height: 121px;" src="http://bp3.blogger.com/_UXKUeU6z7xE/RoLoiagKi4I/AAAAAAAAADs/JBAvih7FpLE/s320/Surcos_01.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.dimensoft.com/data/whakman.rar"&gt;Whakman&lt;/a&gt;: Hice una prueba de programación durante el proceso de selección en Grin Entertainment. La prueba consistía en varias preguntas teóricas y prácticas, con análisis algorítmico, así como una prueba de programar un juego desde cero, dados unos sprites, usando Python y pygame. Al final no entré, los motivos me los guardo, aunque se que algunos de vosotros lo sabéis. Podéis ver la entrada &lt;a href="http://gyakoo.blogspot.com/2007/07/python-pygame-y-whakman.html"&gt;aquí&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_UXKUeU6z7xE/RqojbAKePCI/AAAAAAAAAFc/6XVgDS7LW5U/s320/whakman01.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 173px; height: 134px;" src="http://bp2.blogger.com/_UXKUeU6z7xE/RqojbAKePCI/AAAAAAAAAFc/6XVgDS7LW5U/s320/whakman01.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.dimensoft.com/data/brif/fire.jnlp"&gt;BRIF&lt;/a&gt;: No os he hablado de esto. Es una demo, escrita en Java3D y ejecutada a través del protocolo JNLP (Web Start). Simulador para la formación de brigadas de extinción de incendios forestales. Escrita usando JME. Se ejecuta desde el propio enlace, como si fuera un ejecutable, solo que lanza el Web Start, se descarga automáticamente los paquetes necesarios y se comienza a jugar.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Como os comento, iré subiendo más cosas que tengo por ahí sueltas. Así como el source de algunos de ellos.&lt;br /&gt;&lt;br /&gt;Un saludo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-168191865345016179?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/168191865345016179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=168191865345016179&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/168191865345016179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/168191865345016179'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/05/descargas.html' title='Descargas'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_UXKUeU6z7xE/R1MVADpfKzI/AAAAAAAAAIY/9mVPlr4E15E/s72-Rc/01.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-2954098749710241782</id><published>2008-05-06T14:07:00.002+02:00</published><updated>2008-11-26T23:23:47.016+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='media'/><title type='text'>Euphoria</title><content type='html'>Euphoria es un entorno de desarrollo para animaciones procedimentales en personajes bípedos, por la empresa &lt;a href="http://www.naturalmotion.com/euphoria.htm"&gt;Natural Motion&lt;/a&gt;.&lt;br /&gt;Llevan varios años desarrollando ésto, y en su gama de productos también tienen herramientas para animación en cine. Además, se han aliado con algunas compañías, como LucasArts, para sacar un producto que luce como sigue:&lt;br /&gt;&lt;br /&gt;&lt;object height="355" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/_VokRXBpf-w&amp;amp;hl=en"&gt;&lt;param name="wmode" value="transparent"&gt;&lt;embed src="http://www.youtube.com/v/_VokRXBpf-w&amp;amp;hl=en" type="application/x-shockwave-flash" wmode="transparent" height="355" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Gracias &lt;a href="http://www.alvaromartin.net"&gt;The Prompt&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-2954098749710241782?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/2954098749710241782/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=2954098749710241782&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/2954098749710241782'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/2954098749710241782'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/05/euphoria.html' title='Euphoria'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-4531811646789413240</id><published>2008-05-06T13:43:00.006+02:00</published><updated>2008-11-26T23:23:47.017+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='media'/><title type='text'>The Next Mainstream Programming Language</title><content type='html'>&lt;span style="font-size:85%;"&gt;Enlace por  &lt;a href="http://www.alvaromartin.net/"&gt;The Prompt&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-size:85%;"&gt;Interesante presentación, por Tim Sweeney, sobre lenguajes de programación y la tecnología de desarrollo de videojuegos&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;object codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" id="-609392858" name="-609392858" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" align="middle" height="500" width="80%"&gt;  &lt;param name="movie" value="http://documents.scribd.com/ScribdViewer.swf?document_id=5687&amp;amp;access_key=3phiypcj6g68j&amp;amp;page=&amp;amp;version=1&amp;amp;auto_size=true"&gt;   &lt;param name="quality" value="high"&gt;   &lt;param name="play" value="true"&gt;  &lt;param name="loop" value="true"&gt;   &lt;param name="scale" value="showall"&gt;  &lt;param name="wmode" value="opaque"&gt;   &lt;param name="devicefont" value="false"&gt;  &lt;param name="bgcolor" value="#ffffff"&gt;   &lt;param name="menu" value="true"&gt;  &lt;param name="allowFullScreen" value="true"&gt;   &lt;param name="allowScriptAccess" value="always"&gt;   &lt;param name="salign" value=""&gt;  &lt;embed src="http://documents.scribd.com/ScribdViewer.swf?document_id=5687&amp;amp;access_key=3phiypcj6g68j&amp;amp;page=&amp;amp;version=1&amp;amp;auto_size=true" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" play="true" loop="true" scale="showall" wmode="opaque" devicefont="false" bgcolor="#ffffff" name="-609392858_object" menu="true" allowfullscreen="true" allowscriptaccess="always" salign="" type="application/x-shockwave-flash" align="middle" height="500" width="100%"&gt;&lt;/embed&gt; &lt;/object&gt;&lt;div style="font-size: 10px; text-align: center; width: 100%;"&gt;&lt;a href="http://www.scribd.com/doc/5687/The-Next-Mainstream-Programming-Language-A-Game-Developers-Perspective-by-Tim-Sweeney"&gt;The Next Mainstream Programming Language: A Game Developer's Perspective by Tim Sweeney&lt;/a&gt;&lt;/div&gt;&lt;div style="display: none;"&gt; Read this doc on Scribd: &lt;a href="http://www.scribd.com/doc/5687/The-Next-Mainstream-Programming-Language-A-Game-Developers-Perspective-by-Tim-Sweeney"&gt;The Next Mainstream Programming Language: A Game Developer's Perspective by Tim Sweeney&lt;/a&gt; &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-4531811646789413240?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/4531811646789413240/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=4531811646789413240&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4531811646789413240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4531811646789413240'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/05/next-mainstream-programming-language.html' title='The Next Mainstream Programming Language'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-7998972361386006915</id><published>2008-04-30T13:36:00.003+02:00</published><updated>2008-11-26T23:24:17.830+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Google Talk Chatback Badge</title><content type='html'>Google no se puede estar quieta.&lt;br /&gt;&lt;br /&gt;Quizás algunos lo conocereis, ha sacado ahora un servicio mediante el cual incrustas un iframe en la página que tú quieras, y te aparece un pequeño balloon para que cualquier usuario, tenga o no cuenta en gmail, y a través de la web, pueda enviarte mensajes instantáneos a tu cuenta.&lt;br /&gt;&lt;br /&gt;Enlace aquí: &lt;a href="http://www.google.com/talk/service/badge/New"&gt;http://www.google.com/talk/service/badge/New&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Eso sí, yo tengo que estar conectado:&lt;br /&gt;&lt;iframe src="http://www.google.com/talk/service/badge/Show?tk=z01q6amlqi65915jlr9f6f6bifrj4riugggq0jd91cmuhp00upc523jceshb18orp76ss9fhkhklkepg9kc5v2bb74ik5khoagcquhc9j5li1j8etqqu08k66jdr96sn1u5knsh2i1a9oqhku6k5csp50kdi4cq3k1u48pqnu&amp;amp;w=200&amp;amp;h=60" frameborder="0" allowtransparency="true" width="200" height="60"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-7998972361386006915?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/7998972361386006915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=7998972361386006915&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7998972361386006915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7998972361386006915'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/04/google-talk-chatback-badge.html' title='Google Talk Chatback Badge'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-5331751313522814357</id><published>2008-04-27T10:51:00.003+02:00</published><updated>2008-11-26T23:24:17.831+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Alternativa3D y Efecto Mar Muerto</title><content type='html'>Hola a todos de nuevo, hacía bastantes meses que no volvía a postear nada, pero es que he estado tan ocupado en mi nuevo trabajo, y ha sido tan intensa mi vida en este tiempo, que ni siquiera he podido acercarme a 10kb de las páginas que suelo mirar, por no decir de mantener mi blog.&lt;br /&gt;&lt;br /&gt;Pero bueno, las penas os las contaré en otro momento, por ahora un par de noticias que me han gustado en especial:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Alternativa3D&lt;/span&gt; (visto en ExeBlog): Es un motor 3D por software para flash, y no está nada mal. &lt;a href="http://www.exelweiss.com/blog/414/alternativa3d-nuevo-motor-3d-para-flash/"&gt;http://www.exelweiss.com/blog/414/alternativa3d-nuevo-motor-3d-para-flash/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Efecto Mar Muerto &lt;/span&gt;(visto desde CodePixel): Es un artículo que explica ese extraño fenómeno que se dan en algunas empresas punteras en tecnología cuando comienzan a irse una serie d. Interesante de leer. &lt;a href="http://www.codepixel.com/content/view/5152/1/"&gt;http://www.codepixel.com/content/view/5152/1/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Pues por ahora estos dos temas, que no me da para mucho más tiempo.&lt;br /&gt;&lt;br /&gt;Un saludo a todos.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-5331751313522814357?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/5331751313522814357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=5331751313522814357&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5331751313522814357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5331751313522814357'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/04/alternativa3d-y-efecto-mar-muerto.html' title='Alternativa3D y Efecto Mar Muerto'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-2780706021160622269</id><published>2008-01-21T10:08:00.001+01:00</published><updated>2008-11-26T23:24:17.832+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Nueva etapa</title><content type='html'>Casi tres años después vuelvo a dar un gran salto.&lt;br /&gt;En éste tiempo he conocido a grandes profesionales y a grandes personas. He aprendido tantísimas cosas tanto en el plano profesional como en el personal, que me resultaría imposible listarlas aquí. Y lo más importante para mí, me he dado cuenta que aún me queda un mundo por descubrir, aprender y explorar.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.gextech.com/"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_UXKUeU6z7xE/R5Rn9OuDSBI/AAAAAAAAAJA/IxV6-P7qj1o/s320/gextech_logo.bmp" alt="Gextech: The brain of the game" id="BLOGGER_PHOTO_ID_5157861774866991122" border="0" /&gt;&lt;/a&gt;Es por esto por lo que voy a dar un gran salto. Me traslado a Madrid, donde se me abren nuevos y distintos horizontes en todos los aspectos. Es una sensación muy rara la que siento, de estar ilusionado por el reto que me queda por delante, y de miedo a la vez. Y he de admitir que sin el apoyo de una persona, que considero imprescindible en mi vida, me costaría muchísimo el cambio.&lt;br /&gt;&lt;br /&gt;Pero pasteleo aparte, deseo lo mejor a mi ya antigua empresa, Gextech, con sus proyectos. Que cumplan sus objetivos y sueños tanto empresa como empleados. Los echaré de menos.&lt;br /&gt;&lt;br /&gt;Deseadme suerte. Planet Media, allá voy.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.planetmedia.es/"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_UXKUeU6z7xE/R5RogOuDSCI/AAAAAAAAAJI/jOetltZgFx8/s320/logo_b2b.gif" alt="Planet Media" id="BLOGGER_PHOTO_ID_5157862376162412578" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-2780706021160622269?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/2780706021160622269/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=2780706021160622269&amp;isPopup=true' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/2780706021160622269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/2780706021160622269'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2008/01/nueva-etapa.html' title='Nueva etapa'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_UXKUeU6z7xE/R5Rn9OuDSBI/AAAAAAAAAJA/IxV6-P7qj1o/s72-c/gextech_logo.bmp' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-6975176933137412728</id><published>2007-12-02T21:06:00.000+01:00</published><updated>2008-11-26T23:24:44.522+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='projects'/><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Fin de semana gravitacional</title><content type='html'>Sí, vaya título más raro, pero no sabía cómo describir éste fin de semana que me he tirado programando a saco.&lt;br /&gt;&lt;br /&gt;Después de una semana marcada por Super Mario Galaxy, juegazo que trajo un compañero para probarlo en la oficina, me dije: &lt;span style="font-style: italic;"&gt;"tiene que esta&lt;/span&gt;&lt;span style="font-style: italic;"&gt;r interesante programar algo así"&lt;/span&gt;.&lt;br /&gt;No voy a realizar ningún análisis del juego aquí, más que nada porque seguro que los hay mucho más profesionales por la web. Simplemente baste con decir que ha sido catalogado por muchos como el mejor juego de la historia. Mi opinión, me la guardo. ;)&lt;br /&gt;&lt;br /&gt;Pues sí, llegó el viernes por la tarde y resultaba que me pillaba solo en casa, así que, a la carga con el Visual Studio.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;1) Lo primero: Saber qué quiero hacer.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Un jueguecillo de plataformas de scroll lateral, pero con todo en 3D, y que el personaje pueda moverse en todas direcciones, ésto es, que pueda trepar por las paredes, o boca-abajo.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;2) Segundo: Cómo voy a hacer los niveles.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;Quiero tener plataformas que sean auténticas mallas de cualquier forma. Y luego hacer niveles sin tener que andar repitiendo patrones. Habrán plataformas, comportamientos, items y texturas comunes y que se vean entre niveles, pero también flexibilidad para realizar niveles de muy diversa índole. Así pues, aquí tengo un nivel de prueba, con el 3D Studio Max.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_UXKUeU6z7xE/R1MSjzpfKyI/AAAAAAAAAIQ/Tr4kPND03Ec/s1600-R/LevelInMax.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp3.blogger.com/_UXKUeU6z7xE/R1MSjzpfKyI/AAAAAAAAAIQ/mDkgnZGuf28/s320/LevelInMax.jpg" alt="" id="BLOGGER_PHOTO_ID_5139472006128806690" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;3) Tercero: Entorno de trabajo&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;Me lo pensé bastante. Estoy desarrollando, muy lentamente, un minimotor en C# sobre MDX (Managed DirectX), el cual es bastante interesante y potente a la hora de realizar herramientas como un editor para posicionar entidades en los niveles.&lt;br /&gt;También pensé en usar XNA, ya que estoy ahora tocándolo un poco y me resulta cuanto menos, útil para hacer juegos rapidos y prototipos.&lt;br /&gt;Pero al final me decanté por C++, sobre Ogre3D. Cogí el proyecto de &lt;a href="http://gyakoo.blogspot.com/2007/06/postmortem-soldiers-i.html"&gt;soldados&lt;/a&gt;, y reutilizé toda la parte común. Reusé el core, sistema de sonido, de script, de parser de tablas, factoría, patrón de game - actores - acciones, y otras rutinas en común.&lt;br /&gt;Una vez con ésto, me puse a escribir código dependiente de lo que quiero hacer.&lt;br /&gt;Más: Visual Studio 2005 + SP1, Ogre3D, Fmod, lua.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;4) Cuarto: Assets.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Comencé modelando simples cajas, y cilindros para las plataformas y player.&lt;br /&gt;Al final, hice el mapa que veis arriba y utilicé un modelo y animaciones gratuíto de la web. No me acuerdo del autor, pero lo pondré en cuanto lo encuentre. Es un modelo muy simple, pero tiene las animaciones que me interesan: Idle, Walk, Run, Jump y Fall. (hacer click para agrandar).&lt;br /&gt;&lt;br /&gt;El personaje, tuve que abrirlo con Max8, y exportarlo usando el genial plugin Lexi Export. Pero me daba un fallo, ya que habían vértices que estaban pesados por más de 4 bones. No se usar el Max todo lo que me gustaría, y no funcionaba, pero al final lo que hice (para propósito de pruebas) fue exportar las animaciones como lo denominan PoseAnimation, básicamente, haciendo morphing, con el consiguiente gasto de memoria y tal... no es la mejor opción, pero para tener un modelo que probar.... de lujo!.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_UXKUeU6z7xE/R1MVITpfK0I/AAAAAAAAAIg/2kWB90CNinU/s1600-R/02.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp1.blogger.com/_UXKUeU6z7xE/R1MVITpfK0I/AAAAAAAAAIg/IZoqR-vM-3E/s320/02.jpg" alt="" id="BLOGGER_PHOTO_ID_5139474832217287490" border="0" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_UXKUeU6z7xE/R1MVADpfKzI/AAAAAAAAAIY/9mVPlr4E15E/s1600-R/01.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp0.blogger.com/_UXKUeU6z7xE/R1MVADpfKzI/AAAAAAAAAIY/kh00_d0fEIc/s320/01.jpg" alt="" id="BLOGGER_PHOTO_ID_5139474690483366706" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;5) Quinto: Complicaciones.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Después de haber programado antes, el movimiento de entidades en 3D, de personajes, tener que hacerlo para personajes que se mueven únicamente en 2D al principio me desconcertó.&lt;br /&gt;&lt;br /&gt;Luego está el tema de las colisiones con las plataformas. No está del todo afinado, pero estoy usando trazado de rayos con las entidades, que son nuestras plataformas. Si detecta colisión a alto nivel (bounding volumes), calculo la colisión con con la maya (bajo nivel). En ésta colisión detecto el polígono, el punto de intersección y la normal al mismo, ya que me servirá para la orientación del player.&lt;br /&gt;&lt;br /&gt;El salto se compone de dos animaciones, jump y fall. Cuando el personaje salta, aplico la animación de jump, y muevo manualmente al personaje (lo elevo en su eje relativo Y ó up vector). Este salto tiene un máximo de altura y tiempo. Terminado, este tiempo, aplico el estado de fall, otra animación. Aún tengo que detectar las colisiones con la cabeza, al saltar, así como hacer que la elevación y caída del personaje no sea lineal, tal y como es ahora. La caída debe de seguir la fórmula de la gravedad y el salto he pensado en algo exponencial.&lt;br /&gt;&lt;br /&gt;Por último, la orientación del player cuando está activada la gravedad relativa a las plataformas. Esto lo que hace es, con la normal del polígono donde estoy, calculo el quaternion, y lo encolo para interpolar al nodo de la entidad (para hacer los cambios de orientación más suaves). Además no hay que presuponer ninguna orientación (up, right, zaxis) para los saltos y movimiento.&lt;br /&gt;&lt;br /&gt;Resultado: (hacer click para agrandar).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_UXKUeU6z7xE/R1MXizpfK1I/AAAAAAAAAIo/7yLt15ikcpY/s1600-R/03.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp3.blogger.com/_UXKUeU6z7xE/R1MXizpfK1I/AAAAAAAAAIo/ti2ohFnLV7Y/s320/03.jpg" alt="" id="BLOGGER_PHOTO_ID_5139477486507076434" border="0" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_UXKUeU6z7xE/R1MXrjpfK2I/AAAAAAAAAIw/hvSGJ49mGP8/s1600-R/04.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp2.blogger.com/_UXKUeU6z7xE/R1MXrjpfK2I/AAAAAAAAAIw/2XRJFDgy-Hk/s320/04.jpg" alt="" id="BLOGGER_PHOTO_ID_5139477636830931810" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;6) Sexto: Lo siguiente?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Pues queda mucho, mucho. Pero la base que yo quería ya está lista. El resultado final es bastante interesante y jugable, ya que puedo saltar en cualquier posición y el personaje va cayendo hacia la derecha, izquierda o hacia arriba !!. Esto da mucho juego ya que puedo poner plataformas que solamente sean accesibles si me pongo de lado y me dejo caer hacia la derecha por ejemplo.&lt;br /&gt;&lt;br /&gt;Tengo que hacer el sistema para programar el comportamiento de las plataformas por lua. Ya está casi listo.&lt;br /&gt;&lt;br /&gt;Queda programar los items, enemigos, más habilidades, interfaz, etc... O sea, un montonazo, pero ya va siendo interesante, ya que es código de juego puro y duro, y me encanta.&lt;br /&gt;&lt;br /&gt;La siguiente imagen muestra la pantalla del juego, con la cámara alejada para ver el nivel cargado. Si la agrandais vereis al personaje en el centro.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_UXKUeU6z7xE/R1MZqTpfK3I/AAAAAAAAAI4/0yAx6z8abks/s1600-R/06.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_UXKUeU6z7xE/R1MZqTpfK3I/AAAAAAAAAI4/zuZiAl748F0/s320/06.jpg" alt="" id="BLOGGER_PHOTO_ID_5139479814379350898" border="0" /&gt;&lt;/a&gt;Un fin de semana de frikazo total !! Saludos.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-6975176933137412728?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/6975176933137412728/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=6975176933137412728&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6975176933137412728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6975176933137412728'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/12/fin-de-semana-gravitacional.html' title='Fin de semana gravitacional'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_UXKUeU6z7xE/R1MSjzpfKyI/AAAAAAAAAIQ/mDkgnZGuf28/s72-c/LevelInMax.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-7803280155007805141</id><published>2007-11-27T14:17:00.000+01:00</published><updated>2008-11-26T23:38:46.946+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='media'/><title type='text'>Arquitectura multihilos para motores 3D</title><content type='html'>No podeis dejar de leer el siguiente artículo.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.pablo-zurita.com.ar/spanish/2007/07/26/arquitectura-multihilos-para-motores-3d/"&gt;Arquitectura multihilos para motores 3D.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Vía Min.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-7803280155007805141?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/7803280155007805141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=7803280155007805141&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7803280155007805141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7803280155007805141'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/11/arquitectura-multihilos-para-motores-3d.html' title='Arquitectura multihilos para motores 3D'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-307015213059404254</id><published>2007-11-27T12:31:00.000+01:00</published><updated>2008-11-26T23:25:36.971+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>10 tipos de programadores</title><content type='html'>Me ha resultado, cuanto menos interesante, una lista de diez tipos de programadores distintos.&lt;br /&gt;&lt;br /&gt;¿Qué tipo te consideras que eres? Conozco a algunos que encajan a la perfección en algunos tipos.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.techrepublic.com.com/10things/?p=262"&gt;http://blogs.techrepublic.com.com/10things/?p=262&lt;/a&gt; (inglés)&lt;br /&gt;&lt;br /&gt;Vía wisefox.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-307015213059404254?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/307015213059404254/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=307015213059404254&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/307015213059404254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/307015213059404254'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/11/10-tipos-de-programadores.html' title='10 tipos de programadores'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-7134747981666270080</id><published>2007-11-09T17:40:00.000+01:00</published><updated>2008-11-26T23:25:36.972+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Cuentas en Outlook 2007</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_UXKUeU6z7xE/RzSOQ6qU-iI/AAAAAAAAAII/-RmutDaBCEA/s1600-h/Outlook2007.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 199px; height: 186px;" src="http://bp1.blogger.com/_UXKUeU6z7xE/RzSOQ6qU-iI/AAAAAAAAAII/-RmutDaBCEA/s320/Outlook2007.jpg" alt="" id="BLOGGER_PHOTO_ID_5130882296757680674" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Me ha resultado curiosa una característica que trae el nuevo Outlook 2007.&lt;br /&gt;&lt;br /&gt;Posiblemente muchos de vosotros tendreis varias cuentas de correo web, como hotmail, gmail, yahoo, etc...&lt;br /&gt;&lt;br /&gt;Pues bien, si añadimos una nueva cuenta a Outlook, y simplemente le indicamos el nombre de correo electónico, nombre y contraseña, Outlook resuelve con el servidor y se configura automáticamente.&lt;br /&gt;&lt;br /&gt;Antes ésto tardaba unos diez minutos, aparte de tener que saber la configuración manual.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-7134747981666270080?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/7134747981666270080/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=7134747981666270080&amp;isPopup=true' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7134747981666270080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7134747981666270080'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/11/cuentas-en-outlook-2007.html' title='Cuentas en Outlook 2007'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_UXKUeU6z7xE/RzSOQ6qU-iI/AAAAAAAAAII/-RmutDaBCEA/s72-c/Outlook2007.jpg' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-4735639020816112323</id><published>2007-11-03T14:14:00.000+01:00</published><updated>2008-11-26T23:34:52.693+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='books'/><title type='text'>Los dos últimos</title><content type='html'>Mis dos últimas lecturas han sido:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bp3.blogger.com/_UXKUeU6z7xE/Ryx1UNPBgWI/AAAAAAAAAH4/nKjL77BVgEw/s1600-h/Elfindelaeternidad.jpg"&gt;&lt;strong&gt;&lt;img id="BLOGGER_PHOTO_ID_5128603065678659938" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" height="199" alt="" src="http://bp3.blogger.com/_UXKUeU6z7xE/Ryx1UNPBgWI/AAAAAAAAAH4/nKjL77BVgEw/s320/Elfindelaeternidad.jpg" width="136" border="0" /&gt;&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;El fin de la Eternindad - Isaac Asimov&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Solo pienso qué se fumó Asimov para tener la idea de éste libro. Es de nuevo original al máximo. La eternidad es una organización que viaja entre años y cambia las realidades para dirigir el transcurso de la humanidad y del tiempo.&lt;br /&gt;&lt;br /&gt;En la novela realmente tratan el tiempo como si fuera espacio. Y hasta aquí puedo leer... ;)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bp1.blogger.com/_UXKUeU6z7xE/Ryx35tPBgXI/AAAAAAAAAIA/9rbuNwlGeEE/s1600-h/el_pintor_de_batallas.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5128605908947009906" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 138px; CURSOR: hand; HEIGHT: 174px" height="216" alt="" src="http://bp1.blogger.com/_UXKUeU6z7xE/Ryx35tPBgXI/AAAAAAAAAIA/9rbuNwlGeEE/s320/el_pintor_de_batallas.jpg" width="120" border="0" /&gt;&lt;/a&gt;&lt;strong&gt;El pintor de las batallas - Arturo Pérez-Reverte&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Éste autor escribe como nadie. Realmente notas la calidad de sus palabras, cuando lees otros libros en inglés traducidos y lees ésto en español puro.&lt;br /&gt;&lt;br /&gt;Alavo cómo puede coger una historia tan pequeña, tan escueta, y realmente simple, y extraerle todo un mundo de sentimientos y realidad alrededor. Saca petróleo de cada una de sus expresiones. No hay ninguna palabra que sobre ni que falte. Me parece un genio. Cada párrafo es para leerlo muy tranquilo y disfrutarlo.&lt;br /&gt;&lt;br /&gt;Lo único: No me ha gustado el desenlace. Esperaba otra cosa, pero es artístico hasta el final.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-4735639020816112323?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/4735639020816112323/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=4735639020816112323&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4735639020816112323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4735639020816112323'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/11/los-dos-ltimos.html' title='Los dos últimos'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_UXKUeU6z7xE/Ryx1UNPBgWI/AAAAAAAAAH4/nKjL77BVgEw/s72-c/Elfindelaeternidad.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-5607828647515639040</id><published>2007-11-03T13:02:00.000+01:00</published><updated>2008-11-26T23:30:48.698+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Java : Mi gran desconocido I</title><content type='html'>Este post es otro de la &lt;a href="http://gyakoo.blogspot.com/2007/07/python-pygame-y-whakman.html"&gt;serie de post&lt;/a&gt; estoy haciendo sobre aventuras y desventuras de un programador cansino con C++, como yo era, descubriendo nuevos entornos, lenguajes y herramientas; y of course, todo relacionado con desarrollo 3D en general.&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Un día os contaré cosas relacionadas con C#, que me resultó mejor de lo que pensaba en un principio para escribir juegos, pero por ahora toco mi gran rival y enemigo. El lenguaje al que muchos programadores C tratan con la "punta del pie", pero creo que mayormente es por desconocimiento de sus capacidades (tanto del lenguaje como del programador en sí). Estoy hablando de Java.&lt;img id="BLOGGER_PHOTO_ID_5128585645291307330" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 141px; CURSOR: hand; HEIGHT: 133px; TEXT-ALIGN: center" height="103" alt="" src="http://bp3.blogger.com/_UXKUeU6z7xE/RyxleNPBgUI/AAAAAAAAAHo/1U_ED8kaWh4/s320/java.gif" width="139" border="0" /&gt;&lt;br /&gt;Voy a intentar explicar lo que me he encontrado a la hora de enfocar la utilización de Java con respecto al desarrollo de software de entretenimiento, gráfico, y sobre todo 3D. (como siempre, vaya).&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Evidentemente, muchos pensarán que: &lt;em&gt;"¿Cómo vas a hacer un juego 3D en un lenguaje ejecutado en una máquina virtual?"&lt;/em&gt;. Se nos viene a la cabeza que una aplicación 3D necesita de unos algoritmos mayormente costosos recursos como tiempo y espacio. Por lo tanto, necesitaríamos usar un lenguaje a bajo nivel como es C, ya que tenemos acceso a todos los recursos de la máquina (por ejemplo para un mejor control de la memoria), y como es compilado a lenguaje máquina directamente su ejecución no tiene que pasar por la máquina virtual y de esta forma es más rápido.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Bien, perfecto. Teneis razón, además de que no estoy diciendo nada nuevo. Pero también puedo argumentar lo siguiente:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;A día de hoy, las operaciones 3D se realizan mayormente (por no decir "todo lo gordo") en la tarjeta gráfica, la cual acelera por hardware éstas operaciones, ya sea usando la api gráfica con fixed pipeline, o usando un lenguaje de shader determinado.&lt;/li&gt;&lt;li&gt;Otro punto a tener en cuenta es que, para nuestro propósitos, no queremos, ni podemos, ni debemos hacer el Crysis 2. Normalmente hablo desde un punto de vista amateur de creación de juegos.&lt;/li&gt;&lt;li&gt;Además, si no eres muy experimentado en C/C++, puedes empezar a hacerte un lio con punteros, referencias, arquitectura de la aplicación ... lo que se traduce principalmente en fallos en runtime y en memory leaks a punta pala.&lt;/li&gt;&lt;li&gt;La independencia de la plataforma es algo que con el auge de entornos domésticos en Linux y Mac, es algo muy a tener en cuenta, y Java nos proporciona ésto mucho mejor que tener que desarrollar nuestras propias clases de abstracción.&lt;/li&gt;&lt;li&gt;Mediante &lt;a href="http://en.wikipedia.org/wiki/Java_Native_Interface"&gt;JNI&lt;/a&gt; en java, tenemos acceso a librerías escritas en cualquier lenguaje. A Dlls como la de DirectX o la de OGL. Aunque no tiene sentido acceder a DirectX si lo queremos mantener multiplataforma.&lt;/li&gt;&lt;li&gt;Y a través del nuevo compilador &lt;a href="http://es.wikipedia.org/wiki/Compilaci%C3%B3n_JIT"&gt;JIT&lt;/a&gt; (a partir de la 1.2), java permite traducir en tiempo de ejecución el bytecode a código nativo optimizado para la plataforma.&lt;/li&gt;&lt;li&gt;JMonkeyEngine.&lt;/li&gt;&lt;li&gt;Protocolo JNLP.&lt;/li&gt;&lt;li&gt;WebStart.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;De los tres últimos puntos hablaré más detalladamente.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Creo que por éstas cosas, y por algunas otras que se me escapan, podemos decir que java es un candidato interesante a la hora de programar algún jueguecillo. Parece que se está haciendo un gran esfuerzo por usar Java allá donde siempre ha mantenido C++ la hegemonía.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Pero, de nuevo es obvio, Java nunca podrá llegar a tener mejor rendimiento bruto que C++. Pero nos ofrece otra serie de ventajas, aparte de las ya enumeradas, que son muy buenas a la hora de decidir el lenguaje.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Es por ésto, que decidir qué lenguaje usar para hacer nuestro pequeño proyecto es muy importante. Creo, desde mi minúscula opinión, que decir algo como:&lt;/div&gt;&lt;div&gt;&lt;em&gt;"Vamos a hacer un juego. Ah, por supuesto C++". &lt;/em&gt;Es un gran error, pero que mucha gente lo comete. Y luego muchos proyectos terminan siendo inmanejables. Me explico:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Sé, a ciencia cierta, que cuando estamos diseñando o ya desarrollando un proyecto de un juego o una aplicación 3D, en C++, muchos recursos (económicos, temporales y humanos) son dedicados para diseñar un conjunto de librerías internas, clases u otras estructuras de ayuda, para facilitarnos la vida con el lenguaje, y facilitar la tarea a la hora de hacer extensible, leíble y manejable nuestro sistema C++.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Generalmente, estas ayudas que nos creamos, después de un gran esfuerzo, la agruparemos en módulos de un motor, que pensaremos reutilizar y tal... Esa es la idea. Pero con todo esto no estamos más que gastando nuestro tiempo en facilitarnos el uso del lenguaje, alejándonos del quiz de la cuestión, que es &lt;strong&gt;escribir código del juego&lt;/strong&gt;. Esto es como el dilema de escribir nuestro propio motor o usar uno existente (Ogre3D por ejemplo).&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Debemos pensar que lo que nos interesa es acabar y escribir código de juego. Aunque por supuestísimo depende de los intereses de cada uno (alguien puede querer hacerse fuerte en C++, o en gráficos).&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Como digo, gastamos tiempo programándonos nuestras estruturas auxiliares para hacer callbacks a través de punteros a función o a miembros, o a exportar variables a script, o a llevar la cuenta de las referencias a un objeto, o a muchas otras cosas, cuando lenguajes como C# o Java incorporan todo esto built-in en el lenguaje de por sí. &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;La reflexión que nos brinda C# o Java es genial. Los delegates de C#, las definiciones inline de Java, etc... Además, de que nos abstraen del manejo de memoria y ofrecen sus propios recolectores de basura. Y casi seguro que aunque tú mismo implementes estos "azucarillos" en el lenguaje C++, no conseguirás el mismo resultado, y habrás perdido un tiempo que puedes emplear en código de juego.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Luego está el tema de que todas estas ayudas no son gratis. Suelen consumir tiempo/memoria, pero realmente, si las usamos bien, la pérdida de rendimiento del lenguaje en sí, puede ser inapreciable &lt;em&gt;para nuestros propósitos.&lt;/em&gt; &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;strong&gt;En resumen&lt;/strong&gt;: Aunque C++ sea de las mejores opciones (por no decir la única) a la hora de programar un videojuego de última generación, como Crysis, Bioshock, etc... Cada vez más son los desarrollos independientes, y lenguajes que nos brindan más potencia, aunque sean managed como C# o basados en máquina virtual como Java. Y yo personalmente no veo tan claro la utilización de C++ para todo. C++ tiene mucho riesgo en desarrollo para un equipo amateur que lo que le interesa es sacar ese juego original, sin necesidad de ser puntero en tecnología. Un riesgo que es arreglado por esos otros lenguajes de manera nativa.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;En el siguiente post escribiré sobre cómo acceder a la tarjeta gráfica a través de OpenGL, usando Java. Qué motor open source buenecito hay disponible. Y la ventaja de usar el protocolo JNLP para distribuir nuestro juego.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-5607828647515639040?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/5607828647515639040/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=5607828647515639040&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5607828647515639040'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5607828647515639040'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/11/java-mi-gran-desconocido-i.html' title='Java : Mi gran desconocido I'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_UXKUeU6z7xE/RyxleNPBgUI/AAAAAAAAAHo/1U_ED8kaWh4/s72-c/java.gif' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-8812353179514796501</id><published>2007-11-01T13:03:00.000+01:00</published><updated>2008-11-26T23:30:48.699+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>De vuelta!</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" &gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp0.blogger.com/_UXKUeU6z7xE/RynDjNPBgTI/AAAAAAAAAHg/bO-pkyGAZPo/s320/zelda.jpg" alt="" id="BLOGGER_PHOTO_ID_5127844660353532210" border="0" /&gt;&lt;/a&gt;¡Al fin vuelvo al mundo real! ... o virtual mejor dicho.&lt;br /&gt;&lt;br /&gt;Tras casi tres meses de baja por enfermedad, vuelvo a la carga recuperado y con muchas ganas y fuerzas de darle fuerte a la programación y a todo lo que se precie.&lt;br /&gt;&lt;br /&gt;No hay peor cosa, al menos para mí, que te veas obligado a tomar reposo durante tanto tiempo, y sí, eso incluye no sentarme delante del ordenador con mis frikadas oportunas. Muy chungo. Y en el curro me han recibido con los brazos abiertos, y eso siempre te da ánimos y ganas de tirar para arriba, cuando vuelves a la carga.&lt;br /&gt;&lt;br /&gt;Pues nada, os deleito con una imagen fantástica del igualmente fantástico Zelda Phantom Hourglass. Juegazo donde los haya. Los de nintendo lo han vuelto a conseguir. Engancha desde el principio, y la jugabilidad / control es perfecta.&lt;br /&gt;&lt;br /&gt;Después de jugar con él, pienso que parece que ya queda poco que inventar en cuanto a jugabilidad en NDS. Me da la impresión de que han cubierto todo lo que se puede hacer con una Nintendo DS en un juego, y aunque si investigas un poco, ves que lo que ofrece, ya lo hacen otros juegos, también ves que ninguno agrupa tantas cosas, tan bien mezcladas y en una historia tan interesante. Sus joyitas de jugabilidad van desde soplar para apagar antorchas o mover molinos, gritarle a gente que no te oye para que se gire y te vea, trazar rutas para distintas armas e incluso el barco, escribir símbolos para viajar por los mares, tomar anotaciones en mapas y con ellas conclusiones de puntos donde debes de seguir, cerrar la tapa de la consola, sin apagar el juego, para unir dos mapas y poder continuar, tirar de una caña de pescar dibujando una línea, para luego dibujar rápidamente círculos y recoger el sedal, y un largo etcétera.&lt;br /&gt;Y todo esto sin contar con la historia principal y subhistorias secundarias, todas muy cuidadas y ralmente "bonitas".&lt;br /&gt;&lt;br /&gt;Para despedirme: Retomaré el blog, seguiré posteando esas cosillas que me gustan, completaré los borradores que tengo pendientes de subir, y nada, ¡a frikear se ha dicho!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-8812353179514796501?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/8812353179514796501/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=8812353179514796501&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8812353179514796501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8812353179514796501'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/11/de-vuelta.html' title='De vuelta!'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_UXKUeU6z7xE/RynDjNPBgTI/AAAAAAAAAHg/bO-pkyGAZPo/s72-c/zelda.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-7109378185604804645</id><published>2007-09-06T17:46:00.000+02:00</published><updated>2008-11-26T23:34:52.693+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='books'/><title type='text'>¿Quien se ha llevado mi queso?</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_UXKUeU6z7xE/RuAhrlisRhI/AAAAAAAAAHQ/Znac9w_GZR8/s1600-h/queso.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 109px; height: 174px;" src="http://bp0.blogger.com/_UXKUeU6z7xE/RuAhrlisRhI/AAAAAAAAAHQ/Znac9w_GZR8/s320/queso.jpg" alt="" id="BLOGGER_PHOTO_ID_5107119010133853714" border="0" /&gt;&lt;/a&gt;Al fin me leí éste libro de ayuda. Fue un regalo de la empresa hace más de un año, lo que pasa es que nunca ví el momento oportuno de leérmelo. Ahora que lo he hecho, realmente estoy pasando por el momento que nos plantea el relato. Y me siento completamente como Hem, uno de sus personajes. Aunque creo que no estoy haciendo bien, no puedo evitar actuar como él.&lt;br /&gt;&lt;br /&gt;Es altamente recomendable para intentar encontrar la felicidad en la vida. Lo único que pasa es que se vuelve pesado repitiendo lo mismo una y otra vez, como si estuviera dirigido lectores un poco "cortitos".&lt;br /&gt;&lt;br /&gt;Tiene pocas páginas (yo me lo leí en una hora y media o algo así), así que no hay excusas, como la que yo he estado poniendo durante éstos meses. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-7109378185604804645?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/7109378185604804645/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=7109378185604804645&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7109378185604804645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7109378185604804645'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/09/quien-se-ha-llevado-mi-queso.html' title='¿Quien se ha llevado mi queso?'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_UXKUeU6z7xE/RuAhrlisRhI/AAAAAAAAAHQ/Znac9w_GZR8/s72-c/queso.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-1451854827568033969</id><published>2007-09-06T17:36:00.000+02:00</published><updated>2008-11-26T23:34:52.694+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='books'/><title type='text'>El honor del samurai</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_UXKUeU6z7xE/RuAfLVisRgI/AAAAAAAAAHI/_2rkLpCJ5yE/s1600-h/honor+samurai.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 97px; height: 157px;" src="http://bp3.blogger.com/_UXKUeU6z7xE/RuAfLVisRgI/AAAAAAAAAHI/_2rkLpCJ5yE/s320/honor+samurai.jpg" alt="" id="BLOGGER_PHOTO_ID_5107116257059816962" border="0" /&gt;&lt;/a&gt;Sigo de baja con anemia. Con fuerzas para muy pocas cosas, asi que aún no he decidido volver a  ponerme al ordenador, para recuperar las fuerzas y volver al trabajo con más ganas.&lt;br /&gt;&lt;br /&gt;Sigo leyendo y lo último ha sido "&lt;a href="http://www.ciao.es/El_honor_del_samurai_Takashi_Matsuoka__493859"&gt;El honor del samurai&lt;/a&gt;". Me ha gustado mucho la forma de describir las emociones de los personajes y la historia. También me ha gustado que describe la violencia y crudeza de algunos actos de manera sencilla y directa. Y otra cosa buena es que aún siendo el autor japonés no ridiculiza de ninguna manera a los personajes norteamericanos, ni tampoco eleva la condición de los samurais, más bien lo contrario.&lt;br /&gt;&lt;br /&gt;No me ha gustado tanto el final, y será porque te lo tienes que imaginar según transcurre la novela, y deja cosas un poco en el aire. ¿o será que quería que la historia siguiera?.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-1451854827568033969?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/1451854827568033969/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=1451854827568033969&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/1451854827568033969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/1451854827568033969'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/09/el-honor-del-samurai.html' title='El honor del samurai'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_UXKUeU6z7xE/RuAfLVisRgI/AAAAAAAAAHI/_2rkLpCJ5yE/s72-c/honor+samurai.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-7611237165461777324</id><published>2007-08-24T13:07:00.000+02:00</published><updated>2008-11-26T23:34:52.695+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='books'/><title type='text'>Don't Panic</title><content type='html'>Solo comentar que aún estoy recuperándome de un episodio de hemorragia chunga, así que de ordenador nada (he escrito ésto después de casi 3 semanas sin teclear).&lt;br /&gt;&lt;br /&gt;Eso sí, he podido leerme dos novelillas, y uno de ellas me gustaría definirla como:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.amazon.com/Guia-Autoestopista-Galactico-Douglas-Adams/dp/843391247X/ref=sr_1_2/104-8964838-2483104?ie=UTF8&amp;s=books&amp;qid=1187954346&amp;sr=8-2"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 107px; height: 165px;" title='La guia del autoestopista galactico' src="http://bp2.blogger.com/_UXKUeU6z7xE/Rs69hlisReI/AAAAAAAAAG4/4yH4z5tXKQQ/s320/dontpanic.jpg" alt="" id="BLOGGER_PHOTO_ID_5102223812568303074" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"Fundamentalmente recomendada".&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Otro libro que considero que he tardado demasiados años en descubrir.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-7611237165461777324?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/7611237165461777324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=7611237165461777324&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7611237165461777324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7611237165461777324'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/08/dont-panic.html' title='Don&apos;t Panic'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_UXKUeU6z7xE/Rs69hlisReI/AAAAAAAAAG4/4yH4z5tXKQQ/s72-c/dontpanic.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-3454438578451552801</id><published>2007-08-03T07:00:00.000+02:00</published><updated>2008-11-26T23:30:48.699+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>(IA) Introducción: Agentes</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Necesidades&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.pyrostudios.com/ficha_comm2.asp?11"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 168px; height: 126px;" title="PyroStudios' Commandos" src="http://bp2.blogger.com/_UXKUeU6z7xE/RowZNqgKjCI/AAAAAAAAAE8/9a_1j8Gah1I/s320/Commandos.jpg" alt="" id="BLOGGER_PHOTO_ID_5083465801932639266" border="0" /&gt;&lt;/a&gt;Antes de todo necesitamos sentarnos, y ver cuales son las necesidades de nuestra IA. Qué necesitamos que hagan nuestros agentes, y qué no. Confeccionar una gran lista con todo lo que se nos ocurra, en sesiones de brainstorming, donde estaría bien contar con las ideas de hardcore gamers objetivos de nuestro juego. Incluso caben detallar ideas descabelladas. La idea es tener una lista que se irá refinando y ajustando a lo largo del proyecto. &lt;span style="font-size:85%;"&gt;(Bob Scott).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Para nuestro minijuego de trabajo, tendremos una serie de soldados que estarán patrullando, y que pasarán a buscarte o atacarte si te detectan de alguna manera, como visualmente o escuchando. Estarán por un terreno con obstáculos, y podrán dispararte o huir en caso desfavorable.&lt;br /&gt;&lt;br /&gt;Una vez especificado nuestro minijuego, el cual "parece" sencillo, podemos pasar a romperlo en piezas más manejables, y a diseñar la arquitectura más adecuada. Para éste caso, diseñaremos un sistema de agentes y unidades de "inteligencia". Usaremos ésta arquitectura conjunto máquinas de estados para animaciones y comportamiento, y una serie de reglas para representar las transiciones entre estados.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Agentes&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.aaai.org/AITopics/html/agents.html"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp3.blogger.com/_UXKUeU6z7xE/RouBPKgKi_I/AAAAAAAAAEk/ICeZVL-t5uM/s320/superagent.jpg" alt="" id="BLOGGER_PHOTO_ID_5083298701935021042" title="MIT Encyclopedia - Itelligent Agent" border="0" /&gt;&lt;/a&gt;Un &lt;a href="http://www.aaai.org/AITopics/html/agents.html"&gt;&lt;span&gt;agente&lt;/span&gt;&lt;/a&gt;, en términos generales y centrándonos en lo que nos concierne, no es más que una entidad o actor del mundo del juego, que se diferencia de otros,  objetos estáticos como cajas o algunos items, en que éste muestra un cierto comportamiento, que no es fijo, que depende de un entorno. O sea, que reacciona de una manera que pueda parecernos "inteligente".&lt;br /&gt;&lt;br /&gt;Entonces podemos ver que un agente, no es más que una &lt;a href="http://www.gamedev.net/dict/term.asp?TermID=1032"&gt;entidad&lt;/a&gt; más del sistema, con una cierta especialización que le hace poseer "inteligencia". Y podemos definir ésta "inteligencia" como unos algoritmos y/o datos.&lt;br /&gt;&lt;br /&gt;Vamos a modelar esta relación. Esto es solo una de las maneras posibles. Hay decenas de arquitecturas para agentes y comportamientos. Así como algunas &lt;a href="http://www.gameai.com/toolkits.html"&gt;soluciones&lt;/a&gt; middleware para lo mismo. Aquí mostraremos una manera natural, flexible y estructurada de hacerlo, pero no es la única ni la mejor:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_UXKUeU6z7xE/RowitKgKjDI/AAAAAAAAAFE/V-hU5PZGAac/s1600-h/Diag01.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_UXKUeU6z7xE/RowitKgKjDI/AAAAAAAAAFE/V-hU5PZGAac/s320/Diag01.jpg" alt="" id="BLOGGER_PHOTO_ID_5083476238703168562" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Hacemos que nuestro agente sea una entidad (o derivada), la cual puede representar información gráfica (para visualización), o física (para colisiones), o incluso de red. También podríamos ser agregado de la entidad.&lt;br /&gt;&lt;br /&gt;Un objeto &lt;code&gt;AIUnit&lt;/code&gt; es una unidad de pensamiento que se puede "enchufar/desenchufar" a/de un agente. La idea es que podemos tener varias de éstas unidades bajo un agente, idealmente auto-contenidas e independientes entre sí, sin tener que conocerse los interfaces unas de otras, y comunicándose mediante paso de mensajes.&lt;br /&gt;&lt;br /&gt;Los  métodos polimórficos "&lt;code&gt;on...&lt;/code&gt;" son callbacks que son invocados, automáticamente para representar determinados eventos.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;onSync()&lt;/code&gt; - Síncrono al frame, llamado una vez cada fotograma. Utilizado para interpolar y cálculos con delta de tiempo.&lt;/li&gt;&lt;li&gt;&lt;code&gt;onAsync()&lt;/code&gt; - Asíncrono, es llamado de manera fija, cada cierto tiempo, o cada cierto número de frames. Podría ser ejecutado en threads diferentes. Y ejecuta cálculos que no son necesitados en tiempo real al frame (por eso son asíncronos), como pathfinding, detección en rango visual, etc...&lt;/li&gt;&lt;li&gt;&lt;code&gt;onActivate()&lt;/code&gt; - Llamado cuando ésta unidad es activada, y comienza a ejecutarse. Por tanto podemos pensar que éstas unidades pueden ser desactivadas (o pausadas).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;onDeactivate()&lt;/code&gt; - Llamado cuando la únidad es desactivada o pausada.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;onMessage()&lt;/code&gt; - Aquí se responden a aquellos mensajes que son recibidos, y nos interesan. Cada mensaje tiene una información adicional, que varía según el tipo de mensaje que fuera.&lt;/li&gt;&lt;/ul&gt;Al menos ya tenemos definido así a grandes rasgos lo que un agente es. Un NPC o un enemigo, sería un agente en el sistema, de forma que tendremos varios de ellos navegando (o no) por el mundo del juego.&lt;br /&gt;&lt;br /&gt;Vemos como aquí no se está detallando nada sobre gráficos (modelos, animaciones, etc...), ni sobre colisiones, ni siquiera por ahora estamos diciendo nada de la representación del espacio de mundo. También vemos cómo la lógica de los agentes se mantiene separada. Aislamos el comportamiento de lo que es el agente en sí. Trataremos de diseñar comportamientos genéricos (siempre cuando se pueda) para poder ser asignados a diferentes agentes.&lt;br /&gt;&lt;br /&gt;En el siguiente post veremos como diseñar máquinas de estado basándonos en ésta arquitectura, para seleccionar distintas animaciones según el estado de nuestro personaje o agente.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-3454438578451552801?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/3454438578451552801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=3454438578451552801&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/3454438578451552801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/3454438578451552801'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/08/ia-introduccin-arquitectura-del-sistema.html' title='(IA) Introducción: Agentes'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_UXKUeU6z7xE/RowZNqgKjCI/AAAAAAAAAE8/9a_1j8Gah1I/s72-c/Commandos.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-622891612643231788</id><published>2007-08-01T14:09:00.001+02:00</published><updated>2007-08-01T14:09:45.163+02:00</updated><title type='text'>Antz Wars</title><content type='html'>Inauguramos un nuevo proyecto: &lt;span style="font-weight: bold;"&gt;Antz Wars&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Un minijuego 2D casual, propuesto a ser desarrollado en un mes o mes y medio. Mezcla entre estrategia y simulador de hormigas.&lt;br /&gt;&lt;br /&gt;Aquí podéis ver su diario de desarrollo, que iré rellenando durante el transcurso de su realización, desde mi punto de vista técnico.&lt;br /&gt;&lt;a href="http://antzwars.blogspot.com"&gt;http://antzwars.blogspot.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Y ésta es su página en Sourceforge:&lt;br /&gt;&lt;a href="http://sourceforge.net/projects/antzwars/"&gt;http://sourceforge.net/projects/antzwars/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;No es un juego ambicioso, ni grande, pero los tres desarrolladores esperamos que sea entretenido, rápido de jugar, y sobre todo que nos aporte algún tipo de experiencia en alguno de sus campos de desarrollo. ... Ah se me olvidaba ... por lo menos vamos a divertirnos haciéndolo.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_UXKUeU6z7xE/RrB1pgKePMI/AAAAAAAAAGo/ucrmGCX2KjY/s1600-h/worker_ant_01.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 138px; height: 180px;" src="http://bp2.blogger.com/_UXKUeU6z7xE/RrB1pgKePMI/AAAAAAAAAGo/ucrmGCX2KjY/s320/worker_ant_01.jpg" alt="" id="BLOGGER_PHOTO_ID_5093700534424976578" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-622891612643231788?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/622891612643231788/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=622891612643231788&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/622891612643231788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/622891612643231788'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/08/antz-wars.html' title='Antz Wars'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_UXKUeU6z7xE/RrB1pgKePMI/AAAAAAAAAGo/ucrmGCX2KjY/s72-c/worker_ant_01.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-4020030342364451611</id><published>2007-07-30T09:12:00.000+02:00</published><updated>2008-11-26T23:39:16.479+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='books'/><title type='text'>Los propios Dioses</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_UXKUeU6z7xE/Rq2XUgKePGI/AAAAAAAAAF8/MwooVDTmolg/s1600-h/Propios+Dioses.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 107px; height: 176px;" src="http://bp3.blogger.com/_UXKUeU6z7xE/Rq2XUgKePGI/AAAAAAAAAF8/MwooVDTmolg/s320/Propios+Dioses.jpg" alt="" id="BLOGGER_PHOTO_ID_5092893132112936034" border="0" /&gt;&lt;/a&gt;En éstos pocos días de playa, he tenido la ocasión de leerme el libro de Isaac Asimov, "Los propios Dioses". Aunque no es difícil de leer, sí que tiene partes que pueden llegar a aburrir o a desesperar, ya que pueden parecer bastantes complicadas. Pero todo va tendiendo a explicarse avanzado el libro.&lt;br /&gt;&lt;br /&gt;Sobre todo, me ha encantado la segunda parte, en la que comienza hablando de cuatro tipos de seres. Comienza a hablar de sus vidas, sus costumbres, sus formas de reproducirse, etc... cosas tan raras como &lt;span style="color: rgb(102, 102, 102); font-style: italic;"&gt;"...y su borde se puso duro para mostrar desaprobación..."&lt;/span&gt;, ó &lt;span style="font-style: italic; color: rgb(102, 102, 102);"&gt;"... nunca ninguna emocional admitía que le gustaba fusionarse con las rocas, pero lo hacían ..."&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Claro, te quedas extrañado, y no sabes qué estás leyendo, hasta que caes en la cuenta de que está hablando del universo paralelo, con leyes físicas distintas al nuestro, del que hablan en la primera parte de la novela. Primera parte, donde si entiendes algo de física, pues mejor.&lt;br /&gt;&lt;br /&gt;A mí me ha gustado bastante, porque es muy Asimov ... fuera de lo común.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-4020030342364451611?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/4020030342364451611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=4020030342364451611&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4020030342364451611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/4020030342364451611'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/07/los-propios-dioses.html' title='Los propios Dioses'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_UXKUeU6z7xE/Rq2XUgKePGI/AAAAAAAAAF8/MwooVDTmolg/s72-c/Propios+Dioses.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-7245707106773979843</id><published>2007-07-27T17:25:00.000+02:00</published><updated>2008-11-26T23:30:48.700+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Python, pygame y whakman</title><content type='html'>Primero comentar que he estado más de medio mes primero ocupado y segundo de playeo (no de la playstation), por eso, no he podido postear los artículos sobre IA que tengo en borrador, pero aunque se extienda más allá de Julio (como era de suponer), seguiré con ellos.&lt;br /&gt;&lt;br /&gt;Luego, exponer e invitar a todos aquellos que no han tenido la ocasión de trabajar con &lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt;, como yo hasta hace poco, que lo prueben y lo evalúen muy concienzudamente. Es object-oriented. Bastante rápido. Fácil de embeber en aplicaciones. Existen muchas librerías. Una gran comunidad detrás. ... Y google trabaja mayormente bajo python (incluso han contratado a su creador). Más pros y contras &lt;a href="http://articles.techrepublic.com.com/5100-22-1045768.html"&gt;aquí&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.python.org/" title="python.org"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp3.blogger.com/_UXKUeU6z7xE/RqoWlQKePBI/AAAAAAAAAFU/5Kg4RLOLAVo/s320/python.jpg" alt="" id="BLOGGER_PHOTO_ID_5091907157945629714" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Existe una libería para Python, llamada &lt;a href="http://www.pygame.org/news.html"&gt;pygame&lt;/a&gt;, que utiliza la SDL, la cual nos proporciona una serie de clases y funciones, (una especie de motor), para desarrollar jueguecitos 2D mayormente. Es fácil y rápida.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.pygame.org/news.html" title="pygame.org"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 173px; height: 48px;" src="http://bp2.blogger.com/_UXKUeU6z7xE/RqoWOAKePAI/AAAAAAAAAFM/xfmeqz0E3gU/s320/pygame.jpg" alt="" id="BLOGGER_PHOTO_ID_5091906758513671170" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;hr /&gt;Bien, resulta de que hace poco he tenido que realizar una prueba para una empresa de desarrollo de videojuegos.&lt;br /&gt;&lt;br /&gt;Parte de la prueba era programar un juego, usando únicamente python + pygame, y para el cual me suministraron una serie de sprites. Tenía que hacer un juego estilo pacman, o algo similar con dichos gráficos. Lo realizé en tres días, y algunos screenshots del juego son los siguientes:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_UXKUeU6z7xE/RqojbAKePCI/AAAAAAAAAFc/6XVgDS7LW5U/s1600-h/whakman01.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; cursor: pointer; width: 223px; height: 173px;" src="http://bp2.blogger.com/_UXKUeU6z7xE/RqojbAKePCI/AAAAAAAAAFc/6XVgDS7LW5U/s320/whakman01.jpg" alt="" id="BLOGGER_PHOTO_ID_5091921275503131682" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_UXKUeU6z7xE/RqojigKePDI/AAAAAAAAAFk/YCOEydS0KDA/s1600-h/whakman02.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; cursor: pointer; width: 223px; height: 173px;" src="http://bp0.blogger.com/_UXKUeU6z7xE/RqojigKePDI/AAAAAAAAAFk/YCOEydS0KDA/s320/whakman02.jpg" alt="" id="BLOGGER_PHOTO_ID_5091921404352150578" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_UXKUeU6z7xE/RqokFwKePEI/AAAAAAAAAFs/sP0JMYCvaV8/s1600-h/whakman03.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; cursor: pointer; width: 223px; height: 173px;" src="http://bp1.blogger.com/_UXKUeU6z7xE/RqokFwKePEI/AAAAAAAAAFs/sP0JMYCvaV8/s320/whakman03.jpg" alt="" id="BLOGGER_PHOTO_ID_5091922009942539330" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Es una serie de niveles laberínticos con scroll 2D, donde  tenemos que guiar a nuestro whakman a conseguir todas las monedas sin ser asesinado por fantasmas y calaveras. Podemos usar guantes de boxeo para golpearlos, un patín para acelerar el ritmo y un muelle para saltar enemigos y obstáculos. Los niveles se editan con un editor de texto.&lt;br /&gt;&lt;br /&gt;Lo subiré para que os lo podais descargar, junto con otras cosas que tengo que subir, un día de éstos.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-7245707106773979843?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/7245707106773979843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=7245707106773979843&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7245707106773979843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7245707106773979843'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/07/python-pygame-y-whakman.html' title='Python, pygame y whakman'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_UXKUeU6z7xE/RqoWlQKePBI/AAAAAAAAAFU/5Kg4RLOLAVo/s72-c/python.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-5788923296201444924</id><published>2007-07-03T13:59:00.000+02:00</published><updated>2008-11-26T23:30:48.700+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>(IA) Introducción: Unos párrafos sobre IA</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.ai-depot.com/"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 138px; height: 138px;" src="http://bp2.blogger.com/_UXKUeU6z7xE/RopyRKgKi6I/AAAAAAAAAD8/jmS-6vVHdAQ/s320/AI.png" alt="" id="BLOGGER_PHOTO_ID_5083000768643632034" title="AI-Depot.com" border="0" /&gt;&lt;/a&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Definiciones&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Definiciones de IA (Inteligencia Artificial) hay muchas. En las &lt;a href="http://www-formal.stanford.edu/jmc/whatisai/"&gt;asignaturas &lt;/a&gt;de universidad, en &lt;a href="http://www.amazon.com/s/ref=nb_ss_gw/103-6377973-7639810?url=search-alias%3Daps&amp;field-keywords=artificial+intelligence&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;Go.x=0&amp;Go.y=0&amp;amp;Go=Go"&gt;libros&lt;/a&gt;, o en &lt;a href="http://ai-depot.com/"&gt;sites&lt;/a&gt;. También &lt;a href="http://en.wikipedia.org/wiki/Artificial_intelligence"&gt;aquí&lt;/a&gt;, en la wikipedia.&lt;br /&gt;No creo que pueda definir IA mejor que las decenas de definiciones existentes, pero sí podría decir lo que parece que se entiende por IA, enfocada al desarrollo profesional de videojuegos.&lt;br /&gt;&lt;br /&gt;De manera muy básica, entendemos por IA enfocada a los videojuegos, &lt;span style="font-style: italic;"&gt;una serie de algoritmos y estructuras de datos que "simulan" el comportamiento de una determinada entidad del mundo, real o imaginario; que deben de llegar a un compromiso entre precisión y optimalidad; y que desde hace unos años conforma uno de los pilares básicos en el éxito o fracaso de un videojuego.&lt;/span&gt; &lt;span style="font-style: italic;"&gt;Se está intentando llegar al aprendizaje automático de dichos &lt;/span&gt;&lt;a style="font-style: italic;" href="http://en.wikipedia.org/wiki/Intelligent_agent"&gt;agentes&lt;/a&gt;&lt;span style="font-style: italic;"&gt; simulados, a su auto-adaptabilidad al entorno, y a la cooperación entre ellos.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;La IA implementada para juegos, no es, por regla general, tan avanzada como la utilizada en el campo académico, en cuanto a redes neuronales y algoritmos genéticos se refiere. Tampoco se pretende que sea así, ya que con máquinas de estados finitas o difusas, así como con sistemas basados en reglas, se cubren las necesidades de la mayoría de los videojuegos&lt;span style="font-size:85%;"&gt; (Steven Woodcock en la GDC'01)&lt;/span&gt;, aunque esto está tendiendo a cambiar.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Últimas tendencias&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;Desarrollos en la paralelización de operaciones gráficas (mediante GPU), ahora nos permiten disponer de más tiempo de CPU para las tareas de IA. Hace años, no podíamos ver el perfil de programador única y exclusivamente dedicado a IA; pero actualmente ésto está cambiando, y son predominantes las demandas de programadores de IA, por encima de las de programadores gráficos. De hecho, en la mayoría de los desarrollos de hoy, los recursos dedicados a IA son mayores que los de tecnología gráfica.&lt;br /&gt;&lt;br /&gt;Otros campos que se están explorando y comienzan a implementarse, es la &lt;a href="http://en.wikipedia.org/wiki/OpenMP"&gt;paralelización &lt;/a&gt;de la IA. Con los nuevos procesadores multinúcleo, multiprocesadores y las videoconsolas de nueva generación, es factible la realización de cálculos como raycasting, pathfinding y otros, en paralelo, cuidando siempre las dependencias y otros problemas comunes en &lt;a href="http://en.wikipedia.org/wiki/Concurrent_programming"&gt;programación concurrente&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Técnicas&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.lionhead.com/bw2/"&gt;&lt;img title="Lionhead's Black&amp;White 2" style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 157px; height: 115px;" src="http://bp3.blogger.com/_UXKUeU6z7xE/RopzBagKi7I/AAAAAAAAAEE/dCmjYGz8CL8/s320/bw.jpg" alt="" id="BLOGGER_PHOTO_ID_5083001597572320178" border="0" /&gt;&lt;/a&gt;Existen una diversidad de técnicas que podemos emplear, y dependen del tipo de objetivo que queramos conseguir, algunas vendrán mejor que otras, e incluso otras ni vienen al cuento. Cito algunas: Sistemas expertos, razonamiento automático, máquinas de estado finitas, árboles de decisión, métodos de búsqueda, planificadores, sistemas multiagente, vida artificial y flocking, algoritmos genéticos, redes neuronales, comportamiento emergente, dead reckoning, mapeado de influencia, evasión de obstáculos, análisis de terreno,  lógica difusa, visión artificial, y algunas más, e incluso híbridos entre éstas técnicas (AIWisdom).&lt;br /&gt;&lt;br /&gt;Es muy importante, como todo, tener bien claro qué queremos conseguir. Qué agentes queremos representar y hasta qué grado de precisión. Cómo influye al gameplay, y al flujo de juego (&lt;a href="http://www.cs.cmu.edu/afs/cs/user/michaelm/www/nidocs/Dautenhahn.pdf"&gt;ai story-telling&lt;/a&gt;). Como hacerla configurable y qué sistema de reflexión o scripting es el más adecuado. Hasta qué punto un diseñador (de nivel o de personaje), puede modificar la IA, mediante parámetros o incluso código script ejecutable.&lt;br /&gt;&lt;br /&gt;Cosas que también son importantes es mantener simple el código de IA y bien estructurado en capas, de manera que sea más sencillo su depuración. Por ejemplo, uno de los consejos de un AI Wisdom es que distribuyas la inteligencia en los distintos agentes del mundo, no solo en el player. Así es como lo explota "Los Sims". De esta forma, además de simplificar la depuración, ayuda a extender el mundo, pudiendo incrementar la inteligencia de algunos agentes, como humanos, ya que añadiendo una lavadora, descargada desde web, por ejemplo, tiene información de animaciones y reacciones, que pasa mediante mensajes o similar al humano que interactúa con ella.&lt;br /&gt;&lt;br /&gt;Distintos géneros de juegos, usarán distintas aproximaciones para simular "inteligencia" en sus personajes. E incluso, hay juegos que basan su gameplay únicamente en la IA, como la serie Sim o Black&amp;White.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Desarrollo&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Con esta serie de artículos solamente se pretende dar un paso en éste mundo del análisis y programación de IA para aplicaciones de entretenimiento.&lt;br /&gt;&lt;br /&gt;Vamos a ver una serie de técnicas e implementaciones &lt;u&gt;muy básicas&lt;/u&gt;, para representar y simular IA en personajes. Al final de todo tendremos un escenario, donde nos podremos mover, y disparar; y habrán enemigos, patrullando y respondiendo a diferentes eventos, que te perseguirán, huirán y trabajarán un poco en equipo. Algo así como un Commandos o un MGS más básico. Podremos modificar el comportamiento de los enemigos sin necesidad de cambiar código interno; y mostraremos objetos visuales de depuración, para ver qué está haciendo la IA en cada momento. Así que ¡al lío!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-5788923296201444924?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/5788923296201444924/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=5788923296201444924&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5788923296201444924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5788923296201444924'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/07/ia-introduccin-unos-prrafos-sobre-ia.html' title='(IA) Introducción: Unos párrafos sobre IA'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_UXKUeU6z7xE/RopyRKgKi6I/AAAAAAAAAD8/jmS-6vVHdAQ/s72-c/AI.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-5333129579289827124</id><published>2007-07-02T21:29:00.000+02:00</published><updated>2008-11-26T23:30:48.701+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Julio: IA</title><content type='html'>Voy a escribir una serie de artículos&lt;s&gt;, por mes,&lt;/s&gt; relacionados a un tema en particular. Inauguro con &lt;s&gt; éste mes,&lt;/s&gt; algunos post relacionados con investigación en el campo de la IA para juegos en particular.&lt;br /&gt;&lt;br /&gt;Esto me va a servir para ir investigando más en éste fascinante campo. Me iré documentando, y afianzando conocimientos, así como citando las fuentes. Intentaré implementar a mi manera todos aquellos algoritmos y estructuras interesantes, sobre un framework (minijuego) que me estoy preparando.&lt;br /&gt;&lt;br /&gt;Estos son los temas que tengo planeado ir desarrollando. July Roadmap.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;u&gt;Introducción&lt;/u&gt;: Qué se entiende por IA para juegos. Arquitectura para agentes y acciones. Conceptos básicos. Implementación del framework de trabajo. Scripting.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;Máquinas de estado&lt;/u&gt;: Simples, jerárquicas y basadas en pila. Uso por niveles de las FSM.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;Máquinas de estado a bajo nivel&lt;/u&gt;: Animaciones.&lt;/li&gt;&lt;li&gt;&lt;u&gt;Máquinas de estado a alto nivel&lt;/u&gt;: Comportamiento.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;Sistema básico basado en reglas&lt;/u&gt;: Transiciones para las FSM. Cambio entre estados. Scripting de las reglas. Raycasting.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;Representación del espacio de búsqueda&lt;/u&gt;: Tipos de representación para los algoritmos de pathfinding. Generación automática. Estructuras. Representación para juegos de carrera.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;Algoritmos de posicionamiento&lt;/u&gt;: Pesos y parámetros de los nodos. Como lo hace Killzone.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;Pathfinding&lt;/u&gt;: Distintos algoritmos. A* y mejoras, teniendo en cuenta pesos.&lt;/li&gt;&lt;li&gt;&lt;u&gt;Tácticas&lt;/u&gt;: Algoritmos de IA en equipo.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;u&gt;Learning&lt;/u&gt;: Conceptos.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;La bibliografía que voy a utilizar va a ser principalmente, la serie &lt;a href="http://www.aiwisdom.com/"&gt;AI Wisdom&lt;/a&gt;, algo de los &lt;a href="http://www.gameprogramminggems.com/"&gt;Game Programming Gems&lt;/a&gt;, artículos en la red de los que iré detallando sus enlaces, algunos conocimientos adquiridos y otros que iré desarrollando.&lt;br /&gt;&lt;br /&gt;&lt;s&gt;Julio&lt;/s&gt; movidito, eh!.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-5333129579289827124?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/5333129579289827124/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=5333129579289827124&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5333129579289827124'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5333129579289827124'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/07/julio-ia.html' title='&lt;s&gt;Julio:&lt;/s&gt; IA'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-3439134548240429282</id><published>2007-07-02T15:55:00.000+02:00</published><updated>2008-11-26T23:42:24.124+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>More on Endian</title><content type='html'>Un test para ver si estamos en una máquina little-endian:&lt;br /&gt;&lt;table style="width: 640px; height: 115px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;inline bool &lt;span style="color: rgb(0, 0, 153);"&gt;isLittleEndian&lt;/span&gt;()&lt;br /&gt;{&lt;br /&gt;static unsigned short s = 0x0001;&lt;br /&gt;return *( (char*)&amp;s ) == 0x01;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Conceptos básicos, funciones de swap y endianness en networking:&lt;br /&gt;&lt;a href="http://www.codeproject.com/cpp/endianness.asp"&gt;http://www.codeproject.com/cpp/endianness.asp&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Más sobre endian, y como escribir código endian-neutral:&lt;br /&gt;&lt;a href="http://www.gamedev.net/reference/articles/article2091.asp"&gt;http://www.gamedev.net/reference/articles/article2091.asp&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Intel White paper sobre endianness y guías para escribir código endian-neutral:&lt;br /&gt;&lt;a href="http://download.intel.com/design/intarch/papers/endian.pdf"&gt;http://download.intel.com/design/intarch/papers/endian.pdf&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-3439134548240429282?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/3439134548240429282/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=3439134548240429282&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/3439134548240429282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/3439134548240429282'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/07/more-on-endian.html' title='More on Endian'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-8085460400999907566</id><published>2007-07-02T14:12:00.000+02:00</published><updated>2008-11-26T23:42:24.124+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Endian</title><content type='html'>Wisefox me hizo recordar, una cosa que debí poner antes, y es que los ejemplos de código que expongo en los posts de éste blog, están probados y compilados bajo Visual Studio 2005, con su compilador, bajo la arquitectura PC Intel x86.&lt;br /&gt;Esto afecta, entre otras cosas al "&lt;a href="http://en.wikipedia.org/wiki/Endianness"&gt;Endianness&lt;/a&gt;". Así por ejemplo, habría que tener cuidado con las clases xcc/fourcc, al tratar directamente con bytes y tal, ya que la mayoría de videoconsolas utilizan un endian cambiado (big endian), en lugar del de Intel (little endian). Aunque como bien me comenta, algunas arquitecturas tienen un endian configurable.&lt;br /&gt;&lt;br /&gt;La siguiente función me invierte de una manera rápida el endian de una palabra de 32 bits. He cogido y he calculado los desplazamientos que al final requieren cada byte, realmente, ya que algunas implementaciones que he visto por ahí, primero aislan los bytes para luego ponerlos en su sitio. Ésta lo hace de manera más óptima:&lt;br /&gt;&lt;table style="width: 640px; height: 147px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;inline unsigned long &lt;span style="color: rgb(0, 0, 153);"&gt;inv_endian&lt;/span&gt;( const unsigned long _n )&lt;br /&gt;{&lt;br /&gt;return unsigned long( ( _n &amp; 0x000000ff ) &amp;lt;&amp;lt; 24 ) |&lt;br /&gt;       ( _n &amp; 0x0000ff00 ) &amp;lt;&amp;lt; 8  |&lt;br /&gt;       ( _n &amp; 0x00ff0000 ) &amp;gt;&amp;gt; 8  |&lt;br /&gt;       ( _n &amp; 0xff000000 ) &amp;gt;&amp;gt; 24 ;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-8085460400999907566?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/8085460400999907566/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=8085460400999907566&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8085460400999907566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8085460400999907566'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/07/endian.html' title='Endian'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-2412911311243253996</id><published>2007-06-29T08:46:00.000+02:00</published><updated>2008-11-26T23:42:24.125+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Precode Macro</title><content type='html'>Como hemos visto en el &lt;a href="http://gyakoo.blogspot.com/2007/06/namespaces-e-inicializacin-automtica.html"&gt;post anterior&lt;/a&gt;, hemos definido una macro para realizar un Registro semi-automático en un vector. Esta macro no es más que la definición de un namespace determinado, una estructura y un objeto global estático, cuya construcción nos permite ejecutar el código que queramos.&lt;br /&gt;&lt;br /&gt;Las siguiente macros, generalizan un poco más éste concepto, y nos permite definir zonas de código que se ejecutan de la misma manera que antes.&lt;br /&gt;&lt;table style="width: 640px; height: 67px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;#define &lt;span style="color: rgb(0, 0, 153);"&gt;BEGIN_PRECODE&lt;/span&gt;(UNIT) namespace { struct temp##UNIT{ temp##UNIT(){&lt;br /&gt;#define &lt;span style="color: rgb(0, 0, 153);"&gt;END_PRECODE&lt;/span&gt;(UNIT) } }; static temp##UNIT temp##UNIT##Ins; };&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Y ahora podemos definir código dentro de estas dos macros, que deben de ir siempre en pareja y en un modulo cpp.&lt;br /&gt;&lt;table style="width: 640px; height: 227px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;---- SomeTest.cpp ----&lt;br /&gt;#include "SomeTest.h"&lt;br /&gt;...&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;BEGIN_PRECODE&lt;/span&gt;(SomeTest);&lt;br /&gt; OutputDebugStringA( "This code is executed on initial constructor calls\n" );&lt;br /&gt; ClassManager::registerClass( "Zerg", new ZergAllocator() );&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;END_PRECODE&lt;/span&gt;(SomeTest);&lt;br /&gt;...&lt;br /&gt;int main( int, const char* [] )&lt;br /&gt;{&lt;br /&gt; // Application begins.&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;El nombre pasado a las macros debe de ser un identificador válido, sin comillas, y único en el sistema, ya que lo utilizamos para construir una estructura y una instancia en tiempo de preprocesado, bajo el namespace anónimo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-2412911311243253996?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/2412911311243253996/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=2412911311243253996&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/2412911311243253996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/2412911311243253996'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/06/precode-macro.html' title='Precode Macro'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-6723625583906670609</id><published>2007-06-28T18:28:00.000+02:00</published><updated>2008-11-26T23:42:24.126+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Namespaces e inicialización automática.</title><content type='html'>Algunas veces, es necesario registrar una serie de objetos al comienzo de una aplicación; como podría ser tener un array de nombres de tipos.&lt;br /&gt;Por ejemplo, tenemos la siguiente clase global estática, que contendrá un vector con cadenas de texto. Cada entrada del vector es un nombre de un tipo.&lt;br /&gt;&lt;table style="width: 640px; height: 131px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;struct ClassManager&lt;br /&gt;{&lt;br /&gt; static vector&amp;lt;string&amp;gt;   gClasses;&lt;br /&gt;}&lt;br /&gt;vector&amp;lt;string&amp;gt; ClassManager::gClasses;&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Bien, ahora imaginemos que empezamos a diseñar e implementar clases, en distintos puntos del proyecto, como por ejemplo:&lt;br /&gt;&lt;table style="width: 640px; height: 163px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;class BaseEnemy&lt;br /&gt;{&lt;br /&gt; ...&lt;br /&gt;};&lt;br /&gt;class BaseItem&lt;br /&gt;{&lt;br /&gt; ...&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Y ahora queremos tener en nuestro array global &lt;code&gt;ClassManager::gClasses&lt;/code&gt;, registrados los nombres de éstas clases (para éste ejemplo resulta de poco uso almacenar ésto, pero al final del post pondré un ejemplo más interesante).&lt;br /&gt;Habría varias formas de hacer ésto.&lt;br /&gt;&lt;br /&gt;Por ejemplo podemos tener en un código principal, que sepamos que se ejecuta una única vez y al comienzo del programa, algo tal que así:&lt;br /&gt;&lt;table style="width: 640px; height: 211px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;int main ( int , const char*[] )&lt;br /&gt;{&lt;br /&gt; // Init del ClassManager&lt;br /&gt; {&lt;br /&gt;    ClassManager::gClasses.push_back( "BaseEnemey" );&lt;br /&gt;    ClassManager::gClasses.push_back( "BaseItem" );&lt;br /&gt;    ...&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; // Empieza app.&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Cada vez que definimos un nuevo tipo, tendremos que venir a éste código y añadir una entrada.&lt;br /&gt;Otra cosa que podemos hacer es registrarlo en el constructor del objeto, lo que pasa que entonces tendremos que mirar si está previamente registrado. Y también pasa que puede que queramos acceder a la lista de clases, antes de haberse registrado alguna.&lt;br /&gt;&lt;br /&gt;Una cosa mejor que ésto, es haciendo uso de namespaces y construcción de objetos globales. Si definimos, en un namespace anónimo, una clase como la que sigue:&lt;br /&gt;&lt;table style="width: 640px; height: 147px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;struct Register_BaseEnemy&lt;br /&gt;{          &lt;br /&gt; Register_BaseEnemy( const char* _n )&lt;br /&gt; {&lt;br /&gt;    ClassManager::gClasses.push_back( _n );&lt;br /&gt; }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Entonces podemos declarar, por ejemplo en el cpp de &lt;code&gt;BaseEnemy&lt;/code&gt;, una instancia global de ésta clase, y su constructor se invocará justo antes de tan siquiera entrar en el código &lt;code&gt;main&lt;/code&gt;. Con lo que tenemos un registro semi-automático.&lt;br /&gt;&lt;table style="width: 640px; height: 51px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;static Register_BaseEnemy ___BaseEnemy( "BaseEnemy" );&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Pero aún sigue siendo ésto, cuanto menos, pesado y engorroso. Tener que definir una estructura auxiliar para cada clase que queramos registrar en nuestro &lt;code&gt;ClassManager&lt;/code&gt;. Y luego instanciarla globalmente en algún módulo cpp.&lt;br /&gt;Podemos simplificar algo, haciendo uso de &lt;code&gt;macros&lt;/code&gt;, de la siguiente manera:&lt;br /&gt;&lt;table style="width: 640px; height: 243px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;#define &lt;span style="color: rgb(0, 0, 153);"&gt;REGISTER_IN_MANAGER&lt;/span&gt;( C ) \&lt;br /&gt;namespace ns_Register_##C     \&lt;br /&gt;{                             \&lt;br /&gt; struct Register_##C         \&lt;br /&gt; {                           \&lt;br /&gt;    Register_##C( const char* _name ) \&lt;br /&gt;    {                        \&lt;br /&gt;       ClassManager::gClasses.push_back( _name ); \&lt;br /&gt;    }                        \&lt;br /&gt; };                          \&lt;br /&gt;                             \&lt;br /&gt; static Register_##C ___##C( #C );\&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Los tokens &lt;code&gt;#&lt;/code&gt; y &lt;code&gt;##&lt;/code&gt; son operadores para el preprocesador, para convertir a constante de cadena y concatenar nombres respectivamente.&lt;br /&gt;Ahora, de esta forma, cuando definimos una clase, en su cpp correspondiente, o en algún cpp que sea linkado, podemos dejar el código como sigue:&lt;br /&gt;&lt;table style="width: 640px; height: 163px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;---- BaseEnemy.cpp ----&lt;br /&gt;#include "BaseEnemy.h"&lt;br /&gt;REGISTER_IN_MANAGER( BaseEnemy );&lt;br /&gt;...&lt;br /&gt;---- BaseItem.cpp ----&lt;br /&gt;#include "BaseItem.h"&lt;br /&gt;REGISTER_IN_MANAGER( BaseItem );&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Esto es interesante. Quizás el ejemplo no sea acertado, pero imaginemos que en lugar de tener un &lt;code&gt;vector&lt;/code&gt; para registrar &lt;code&gt;string's&lt;/code&gt;, tenemos un mapa que aplica &lt;code&gt;string&lt;/code&gt; a un &lt;code&gt;functor&lt;/code&gt;, por ejemplo, el cual crea una instancia en memoria dinámica de ese tipo que define la cadena. Esto que cuento es una de las implementaciones del patron &lt;code&gt;factory&lt;/code&gt;, de la forma que podemos crear instancias según el identificador de cadena de texto con el que la hallamos definido.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-6723625583906670609?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/6723625583906670609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=6723625583906670609&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6723625583906670609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6723625583906670609'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/06/namespaces-e-inicializacin-automtica.html' title='Namespaces e inicialización automática.'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-5615001766764290304</id><published>2007-06-28T08:48:00.000+02:00</published><updated>2008-11-26T23:42:24.127+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Static methods y this == NULL</title><content type='html'>Supongamos que tenemos una clase que sigue un patrón determinado como la siguiente:&lt;br /&gt;&lt;table style="width: 640px; height: 291px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;struct ClassA&lt;br /&gt;{&lt;br /&gt;  ClassA ( float field ): mField( field ){}&lt;br /&gt;&lt;br /&gt;  float avg( int a, int b )&lt;br /&gt;  {&lt;br /&gt;     return (a + b) / 2.0f;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  float mul ( int a )&lt;br /&gt;  {&lt;br /&gt;     return mField * a;&lt;br /&gt;  }&lt;br /&gt;private:&lt;br /&gt;  float mField;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Si hacemos uso de ésta de la siguiente manera:&lt;br /&gt;&lt;table style="width: 640px; height: 83px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;ClassA* pA = NULL;&lt;br /&gt;float a = pA-&gt;avg( 3, 5 );  // no falla&lt;br /&gt;float b = pA-&gt;mul( 4 );     // sí falla&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;La primera línea no falla. Y ¿por qué?, si tenemos un puntero nulo a ClassA. Pues en principio, el primer método no hace uso de ningún campo de la clase. El segundo sí que lo hace, por lo que, cuando intente leer de la memoria reservada para la clase, en el offset de &lt;code&gt;mField&lt;/code&gt;, daría un error, al no tener acceso, en este caso, a la posición de memoria 0x0.&lt;br /&gt;&lt;br /&gt;Podemos plantearnos, en métodos como éstos, si realmente dependen de la instancia de la clase, o tienen más sentido ser estáticos a la misma:&lt;br /&gt;&lt;table style="width: 640px; height: 147px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;...&lt;br /&gt;static float avg( int a , int b )&lt;br /&gt;{&lt;br /&gt;  return ( a + b ) / 2.0f;&lt;br /&gt;}&lt;br /&gt;...&lt;br /&gt;float a = ClassA::avg( 3, 5 );&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;También vemos que tiene un método como &lt;code&gt;mul&lt;/code&gt;, el cual accede a &lt;code&gt;mField&lt;/code&gt;. Suficiente para dejarlo como método de la instancia, ya que depende del estado de la misma, para &lt;code&gt;mField&lt;/code&gt;. Pero si analizamos el código de la clase, vemos que &lt;code&gt;mField&lt;/code&gt; únicamente se inicializa en construcción del objeto. Y no se vuelve a cambiar. Ni siquiera tiene métodos que lo cambien. Podríamos poner estático igualmente éste método.&lt;br /&gt;&lt;table style="width: 640px; height: 147px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;...&lt;br /&gt;static float mul( int a, float field )&lt;br /&gt;{&lt;br /&gt;  return field * a;&lt;br /&gt;}&lt;br /&gt;...&lt;br /&gt;float b = ClassA::mul( a, 4.5f );&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;A veces me ha pasado que, en algunos códigos necesitando de una cierta funcionalidad,  tenía que crear un objeto, para asignarle un cierto estado, luego llamar al método necesitado y eliminar el objeto. Si podemos sacar patrones como éste, y funcionalidad independiente del estado de la instancia, pues podríamos plantearnos métodos estáticos de clase.&lt;br /&gt;&lt;br /&gt;Por último, podemos ver que los parámetros de entrada en ambos métodos, &lt;code&gt;a, b, field&lt;/code&gt;, no son modificados, solo leídos. Ayudemos al compilador a optimizar, metiéndolos en registros oportunos, hagamos &lt;code&gt;const&lt;/code&gt;:&lt;br /&gt;&lt;table style="width: 640px; height: 227px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;struct ClassA&lt;br /&gt;{&lt;br /&gt;  inline float avg( const int a, const int b )&lt;br /&gt;  {&lt;br /&gt;     return (a + b) / 2.0f;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  inline float mul ( const int a, const float field )&lt;br /&gt;  {&lt;br /&gt;     return field * a;&lt;br /&gt;  }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-5615001766764290304?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/5615001766764290304/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=5615001766764290304&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5615001766764290304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5615001766764290304'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/06/static-methods-y-this-null.html' title='Static methods y this == NULL'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-5727684724414864759</id><published>2007-06-28T00:01:00.000+02:00</published><updated>2008-11-26T23:30:48.701+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Postmortem Soldiers II</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_UXKUeU6z7xE/RoLnnqgKi3I/AAAAAAAAADk/DkrePVHUQIo/s1600-h/Surcos_03.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 213px; height: 158px;" src="http://bp0.blogger.com/_UXKUeU6z7xE/RoLnnqgKi3I/AAAAAAAAADk/DkrePVHUQIo/s320/Surcos_03.jpg" alt="" id="BLOGGER_PHOTO_ID_5080877998237453170" border="0" /&gt;&lt;/a&gt;En esta segunda y última entrega del postmortem del juego de soldados que he programado, voy a explicar algunos detalles interesantes de la implementación.&lt;br /&gt;&lt;br /&gt;Quiero recordar que este juego fue una prueba que me propuse terminar empezar y acabar en dos meses. Tuve que forzarme a ser pragmático y realista con el tiempo y recursos; por lo que algunas técnicas, aunque fueron pensadas y planteadas, no llegaron a ser llevadas a cabo.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;u&gt;Detalles técnicos.&lt;/u&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;El plugin BSP de Ogre&lt;/span&gt;, carecía de un sistema para devolverme información de material del plano de colisión de un rayo. Lo modifiqué para cuando le lanzara una query de test de rayo, me devolviera el nombre del material utilizado por dicho plano. Aunque los bsp (q3) definen materiales con metadata (datos extra aparte del material propiamente dicho), el sistema de materiales de Ogre no. Y al cargar el nivel se creaban los materiales tipo Ogre, a partir de los del tipo Q3, perdiéndose la posible metadata. Es pues por lo que tenía aparte una tabla mapeando el nombre del material a información extra, en éste caso, el nombre del recurso de sonido. En definitiva, lo usaba para saber qué sonido reproducir cuando caminaba por distintos materiales.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;El sistema de colisiones, sliding y subidas de desniveles&lt;/span&gt;. Todas las colisiones están realizadas a través de lanzar queries de rayos al manager. Tuve que lanzar rayos extras a los lados de la esfera del player para que no atravesara las esquinas, dando la sensación de colisión esfera-plano. Tuve que detectar la colisión en bucle para cuando llegaba a esquinas con otras paredes. Las subidas a desniveles se hizo calculando la altura del siguiente punto a donde caminar, e interpolando hacia el mismo, para la suavidad. La altura del siguiente punto es ajustable, para evitar subir grandes obstáculos. Aún así existe un bug por el cual, los soldados se quedan atrapados en ciertos puntos, colisionando con paredes.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;El sistema de partículas&lt;/span&gt;, para la explosión de la granada, me dio algún que otro quebradero de cabeza. Éste sistema de partículas utiliza texturas animadas para cada una de las partículas. El control del frame actual de la animación de textura no estaba fino en ogre, de hecho es un bug aún sin resolver, y la forma de hacerlo era la de clonar la textura para cada explosión simultánea en pantalla, eliminándola cuando acababa, de esta forma cada vez que explotaba, empezaba en frame 0.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;El sistema de física de la granada,&lt;/span&gt; fue implementado utilizando ODE, con un proxy de cápsula. A veces, en algunos planos, la cápsula lo atravesaba. Puse un delta, en el código del ogre del interface con ode, cuando calculaba la distancia al plano, y las colisiones fueron bien.&lt;/li&gt;&lt;li&gt;Para especificar los &lt;span style="font-style: italic;"&gt;puntos de la malla&lt;/span&gt; navegación para la IA, hice una pequeña clase que me permitía añadir, modificar y borrar puntos del mapa, a modo de editor. Luego podía serializar dichos puntos a un fichero de puntos de navegación. Supongo que podría hacer un algoritmo para rellenar automáticamente el mapa, pero prefería editarlos a mano para seguir con otras cosas.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;El sistema de partículas para los &lt;span style="font-style: italic;"&gt;disparos de las balas&lt;/span&gt;, para los soldados manejados por cpu son distintos que el del avatar. No podían ser iguales porque la impresión que daba  visto desde el hombro del avatar, era que no iban en la misma dirección del punto de mira en pantalla.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Cuando el avatar dispara,&lt;/span&gt; el arma se mueve arriba y abajo, dando la sensación de que el retroceso de la misma hace al soldado moverse. Este movimiento es aleatorio arriba y abajo. Pero para los soldados manejados por cpu evité ponerlo así, ya que al rato de disparar podía acabar apuntando muy arriba o muy abajo. Aunque podía haberle puesto un código que le hiciera apuntar al frente cuando dejara de disparar.&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;La cámara debía tener sistema de colisión&lt;/span&gt;, ya que cuando acercaba un soldado a una pared y giraba, la cámara acababa apuntando a otra habitación (clipping), y ésto hacía cambiar el conjunto de visibilidad (pvs), con lo cual desparecían algunas cosas. En lugar de tener la cámara como una esfera, se trazaba un rayo desde el punto a donde mirar hasta el punto donde debía estar. Se quedaba en el primer punto donde había colisión. Aunque no le puse interpolación, con lo que a veces podía dar saltos.&lt;/li&gt;&lt;li&gt;Las entidades del sistema tienen un sistema de acciones, que son trozos de código autodependientes, que cuelgan de la entidad. Podemos asignarle / quitarle éstas acciones a las entidades, en runtime, sin problemas. Por ejemplo, tenemos una acción que representa el comportamiento de IA, que puede ser asignado a cualquier soldado. Estas acciones no conocen de otras acciones hermanas, y se comunican mediante el paso de mensajes a través de su padre entidad.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Aunque Lua proporciona una definición y uso de datos en forma de tablas, muy potente, preferí utilizar mi propio formato, a su vez muy similar, para definir ficheros de configuración. Solo utilizo Lua para bind de funciones de código a script. Tengo un parser y un manager de variables que me permiten definir configuraciones como la siguiente. Son tablas, que pueden ser jerárquicas, tantos niveles como se deseen.&lt;/li&gt;&lt;/ul&gt;&lt;table style="width: 640px; height: 245px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;soldier&lt;br /&gt;{&lt;br /&gt;  type   "Soldier"&lt;br /&gt;  name   "Avatar"&lt;br /&gt;  mesh   "Soldier.mesh"&lt;br /&gt;  weap   "M4.mesh"&lt;br /&gt;  life&lt;br /&gt;  {&lt;br /&gt;     type   "Life"&lt;br /&gt;     tick   5.0&lt;br /&gt;     def    100&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td style="vertical-align: top;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;ul&gt;&lt;li&gt;El comportamiento de los soldados enemigos es muy básico. Es una máquina de estados con tres estados: { IDLE, ATTACKING, ALERTED }. En el primer estado, el soldado va patrullando, mirando a sitios aleatorios. Cuando escucha una granada, o recibe un impacto o ve a un soldado enemigo, pasa al segundo estado. Atacando, el soldado se mueve entre los puntos de un entorno, mientras dispara al soldado. Cuando deja de ver a ningún soldado pasa a Alerted, estado en el cual se queda mirando un tiempo hacia el último punto donde vió al enemigo. Si pasado un tiempo no lo ve, vuelve a Idle.&lt;/li&gt;&lt;li&gt;Existe un módulo para el soldado, aparte del comportamiento, que es el de movimiento (animaciones). Máquina de estado a bajo nivel. Éste tiene una función que le hace ir desde el punto actual a un punto especificado. Durante éste movimiento, según al punto donde esté mirando, y la dirección a donde se dirige, se selecciona una animación u otra. Haciendo strafe, diagonal, backward, ...&lt;/li&gt;&lt;li&gt;Los soldados enemigos tienen un factor de precisión, que influye en una cierta aleatoriedad en el vector de di sparo.&lt;/li&gt;&lt;li&gt;En último momento, quise implementar un sistema de reseteo, para re-arrancar el juego, sin tener que reiniciar la aplicación. Aqui me di cuenta lo importante que fue tener una de init() / reset(), para volver al estado inicial de los objetos. Pero aún así me costó algunos quebraderos.&lt;/li&gt;&lt;li&gt;El arma tiene configuración de distinto daño según la distancia de impacto. Lo mismo pasa  con la granada.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;u&gt;Refinamiento, bugs.&lt;br /&gt;&lt;br /&gt;&lt;/u&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_UXKUeU6z7xE/RoLoiagKi4I/AAAAAAAAADs/JBAvih7FpLE/s1600-h/Surcos_01.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 212px; height: 158px;" src="http://bp3.blogger.com/_UXKUeU6z7xE/RoLoiagKi4I/AAAAAAAAADs/JBAvih7FpLE/s320/Surcos_01.jpg" alt="" id="BLOGGER_PHOTO_ID_5080879007554767746" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;&lt;u&gt;&lt;/u&gt;&lt;/span&gt;La mayoría de los bugs fueron ocasionados por no saber exáctamente el orden de liberación de ciertos recursos de Ogre . Objetos "atachados" a nodos por ejemplo.&lt;br /&gt;&lt;br /&gt;También a la hora de crear entidades y nodos, los cuales deben de tener nombres únicos.&lt;br /&gt;&lt;br /&gt;En cuanto a la jugabilidad y al testeo, pues el juego lo han probado varias personas, y la mayoría de feedback han podido ser solucionado mediante el ajuste de parámetros.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;u&gt;Futura versión.&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;Se está trabajando sobre las texturas y animaciones de los modelos.&lt;br /&gt;El algoritmo de IA debe de ser mejorado, y permitir tácticas en grupo, y funciones de posicionamiento según pesos.&lt;br /&gt;Añadir pathfinding, ya que ésta versión carece de él. Por ahora se está viajando entre puntos visibles de la malla de navegación.&lt;br /&gt;Hardware skinning y normalmapping para modelos.&lt;br /&gt;... etc ...&lt;br /&gt;Un wish-list que a ver hasta que punto tengo tiempo de ir completando.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-5727684724414864759?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/5727684724414864759/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=5727684724414864759&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5727684724414864759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5727684724414864759'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/06/postmortem-soldiers-ii.html' title='Postmortem Soldiers II'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_UXKUeU6z7xE/RoLnnqgKi3I/AAAAAAAAADk/DkrePVHUQIo/s72-c/Surcos_03.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-5996057930281322176</id><published>2007-06-27T09:03:00.000+02:00</published><updated>2008-11-26T23:38:46.947+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='media'/><title type='text'>CryEngine2 Level Editor</title><content type='html'>Estos videos tienen un tiempo, pero no deja de ser impresionante el editor que tienen.&lt;br /&gt;&lt;b&gt;Parte I&lt;/b&gt;&lt;br /&gt;&lt;object width="425" height="350"&gt;&lt;param name="movie" value="http://www.youtube.com/v/OTj_I-iCzqY"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/OTj_I-iCzqY" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Parte II&lt;/b&gt;&lt;br /&gt;&lt;object width="425" height="350"&gt;&lt;param name="movie" value="http://www.youtube.com/v/w9JV7Bszonk"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/w9JV7Bszonk" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-5996057930281322176?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/5996057930281322176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=5996057930281322176&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5996057930281322176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5996057930281322176'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/06/cryengine2-level-editor.html' title='CryEngine2 Level Editor'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-3911442978658973441</id><published>2007-06-27T09:01:00.000+02:00</published><updated>2008-11-26T23:42:24.128+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Especialización parcial</title><content type='html'>Cuando tenemos una función templatizada de la forma:&lt;br /&gt;&lt;table style="width: 640px; height: 115px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;template&amp;lt; typename T, typename U &amp;gt;&lt;br /&gt;T* create( const U&amp; _v )&lt;br /&gt;{&lt;br /&gt; return new T( _v );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Podemos usarla para hacer llamadas como las siguientes:&lt;br /&gt;&lt;table style="width: 640px; height: 99px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt; Protoss* p0 = create&amp;lt;Protoss&gt;( AmmoPack(5000) );&lt;br /&gt; Protoss* p1 = create&amp;lt;Protoss&amp;gt;( LifePack(200) );&lt;br /&gt; Zerg* z0    = create&amp;lt;Zerg&amp;gt;( LifePack(100) );&lt;br /&gt; Terran* t0  = create&amp;lt;Terran&amp;gt;( LifePack(150) );&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Nota: Mientras que no introduzcan los nuevos tipos &lt;code&gt;decltype&lt;/code&gt; y/o &lt;code&gt;auto&lt;/code&gt; en el estandard de C++, tendremos que seguir llamando con &lt;code&gt;create&amp;lt;Type&amp;gt;&lt;/code&gt;, ya que el compilador no puede deducir el tipo del argumento &lt;code&gt;T&lt;/code&gt; devuelto.&lt;br /&gt;&lt;br /&gt;Ahora bien, si deseamos sobreescribir el comportamiento de &lt;code&gt;create()&lt;/code&gt; para cuando es de tipo, por ejemplo, &lt;code&gt;Terran&lt;/code&gt; podemos hacer varias cosas.&lt;br /&gt;La primera, que se nos viene es una &lt;code&gt;sobrecarga&lt;/code&gt;. Puede quedar de la forma siguiente:&lt;br /&gt;&lt;table style="width: 640px; height: 115px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;template&amp;lt; typename U &amp;gt;&lt;br /&gt;Terran* create( const U&amp; _v )&lt;br /&gt;{&lt;br /&gt; return new Terran( _v );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Y otra cosa que podemos hacer es una especialización del template. Pero solamente queremos especializar para el tipo &lt;code&gt;T&lt;/code&gt;, que es el de &lt;code&gt;Terran&lt;/code&gt;. El tipo &lt;code&gt;U&lt;/code&gt; queremos dejarlo genérico.&lt;br /&gt;Aquí viene el problema. El compilador no nos permite especialización parcial del template.&lt;br /&gt;&lt;table style="width: 640px; height: 131px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;// Error en compilación.&lt;br /&gt;template&amp;lt; typename U &amp;gt;&lt;br /&gt;Terran* create&amp;lt;Terran, U&amp;gt;( const U&amp; _v )&lt;br /&gt;{&lt;br /&gt; return new Terran( _v );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Aunque sí que nos permite especializaciones parciales para las clases, no lo hace para las funciones a nivel de namespace ni para los métodos. Tendríamos que hacer algo así, para cada uno de los &lt;code&gt;U&lt;/code&gt; que pueda permitir con &lt;code&gt;T=Terran&lt;/code&gt;:&lt;br /&gt;&lt;table style="width: 640px; height: 227px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;template&amp;lt; &amp;gt;&lt;br /&gt;Terran* create&amp;lt;Terran, AmmoPack&amp;gt;( const AmmoPack&amp; _v )&lt;br /&gt;{&lt;br /&gt; // Hacer algo con T = Terran, U = AmmoPack&lt;br /&gt; return new Terran( _v );&lt;br /&gt;}&lt;br /&gt;template&amp;lt; &amp;gt;&lt;br /&gt;Terran* create&amp;lt;Terran, LifePack &amp;gt;( const LifePack&amp; _v )&lt;br /&gt;{&lt;br /&gt; // Hacer algo con T = Terran, U = LifePack&lt;br /&gt; return new Terran( _v );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Pero ésto no es lo que queremos. Queremos dejar &lt;code&gt;U&lt;/code&gt; genérico, o sea, una especialización parcial.&lt;br /&gt;&lt;br /&gt;Pues bien, el &lt;a href="http://gyakoo.blogspot.com/2007/06/modern-c-design.html"&gt;Modern C++&lt;/a&gt; nos da una idea, con su patrón &lt;code&gt;Type2Type&lt;/code&gt;, definido como sigue:&lt;br /&gt;&lt;table style="width: 640px; height: 115px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;template&amp;lt; typename T &amp;gt;&lt;br /&gt;struct Type2Type&lt;br /&gt;{&lt;br /&gt; typedef T Tipo;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Con ésto, podemos hacer especializaciones parciales de métodos y funciones, de la siguiente manera:&lt;br /&gt;&lt;table style="width: 640px; height: 243px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;template&amp;lt; typename T, typename U &amp;gt;&lt;br /&gt;T* create ( const U&amp; _val, Type2Type&amp;lt;T&amp;gt; )&lt;br /&gt;{&lt;br /&gt; printf ( "Creating element\n" );&lt;br /&gt; return new T( _val );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;template&lt; typename U &amp;gt;&lt;br /&gt;Terran* create( const U&amp; _val, Type2Type&amp;lt;Terran&amp;gt; )&lt;br /&gt;{  &lt;br /&gt;  printf ( "Creating specifically Terran\n" );  &lt;br /&gt;  return new Terran( _val );&lt;br /&gt;} &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Hemos consegido tener una especialización para &lt;code&gt;T=Terran&lt;/code&gt;, y &lt;code&gt;U&lt;/code&gt; genérico. Nuestro código de llamada queda de la siguiente manera:&lt;br /&gt;&lt;table style="width: 640px; height: 195px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt; Zerg* z     = create( AmmoPack(1000),  Type2Type&amp;lt;Zerg&amp;gt;() );&lt;br /&gt; Protoss* p0 = create( LifePack(200),   Type2Type&amp;lt;Protoss&amp;gt;() );&lt;br /&gt; Protoss* p1 = create( AmmoPack(3000),  Type2Type&amp;lt;Protoss&amp;gt;() );&lt;br /&gt; Terran* t0  = create( AmmoPack(5000),  Type2Type&amp;lt;Terran&amp;gt;() );&lt;br /&gt; Terran* t1  = create( LifePack(100),   Type2Type&amp;lt;Terran&amp;gt;() );&lt;br /&gt; Terran* t2  = create( SimpleHuman("Pepe"),Type2Type&amp;lt;Terran&amp;gt;() );&lt;br /&gt;&lt;br /&gt; // La siguiente línea no compila, ya que el tipo Protoss no tiene&lt;br /&gt; // constructor a partir de un objeto SimpleHuman.&lt;br /&gt; // Protoss* p2 = create( SimpleHuman("John"),Type2Type&amp;lt;Protoss&amp;gt;() );&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;El resultado es:&lt;br /&gt;&lt;table style="width: 640px; height: 147px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;---- Output ----&lt;br /&gt;Creating element.&lt;br /&gt;Creating element.&lt;br /&gt;Creating element.&lt;br /&gt;Creating specifically Terran.&lt;br /&gt;Creating specifically Terran.&lt;br /&gt;Creating specifically Terran.&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Ya os comenté que el Modern C++ tiene tela ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-3911442978658973441?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/3911442978658973441/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=3911442978658973441&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/3911442978658973441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/3911442978658973441'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/06/especializacin-parcial.html' title='Especialización parcial'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-2223832957131789992</id><published>2007-06-27T08:29:00.001+02:00</published><updated>2008-11-26T23:42:24.131+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><title type='text'>Modern C++ Design</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_UXKUeU6z7xE/RoID_KgKi2I/AAAAAAAAADc/5LJTPI3o3Zc/s1600-h/modern-c%2B%2B-design.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 119px; height: 150px;" src="http://bp2.blogger.com/_UXKUeU6z7xE/RoID_KgKi2I/AAAAAAAAADc/5LJTPI3o3Zc/s320/modern-c%2B%2B-design.png" alt="" id="BLOGGER_PHOTO_ID_5080627713313246050" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://books.google.com/books?id=aJ1av7UFBPwC&amp;dq=modern+c%2B%2B+design&amp;amp;pg=PP1&amp;ots=YPiF3qWh5_&amp;amp;sig=Mlah22ZU_2iOr7UKo-MZIFO--vM&amp;prev=http://www.google.com/search%3Fq%3Dmodern%2Bc%252B%252B%2Bdesign%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dorg.mozilla:es-ES:official%26client%3Dfirefox-a&amp;amp;sa=X&amp;oi=print&amp;amp;ct=title"&gt;Libro &lt;/a&gt;que recomiendo encarecidamente a todo aquél interesado en la programación genérica usando templates.&lt;br /&gt;&lt;br /&gt;Aunque lo había visto varias veces, nunca me dio por abrirlo, pensando que era otro libro más de aprender a programar en C++ donde únicamente son interesantes los dos o tres últimos capítulos. Wisefox me lo pasó y me di cuenta de que no es así.&lt;br /&gt;&lt;br /&gt;Este no. Este desde el comienzo se enfoca a los templates, a un nivel avanzado, haciendo un uso magristral de ellos. Te explica el porqué utilizarlos y muchas técnicas útiles haciendo uso de ellos. Además te explica como implementar algunos patrones de diseño, usando templates.&lt;br /&gt;&lt;br /&gt;Curioso el capítulo dedicado a los que llaman &lt;code&gt;TypeList&lt;/code&gt;. Y ahora me doy cuenta de que la clase &lt;code&gt;List&lt;/code&gt; que implementé en &lt;a href="http://gyakoo.blogspot.com/2007/06/templates-recursivos.html"&gt;otro post&lt;/a&gt;, no es más que ésto. Me hubiera ahorrado algún que otro quebradero de cabeza, aunque por otro lado, pensar nunca puede ser malo, no?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-2223832957131789992?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/2223832957131789992/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=2223832957131789992&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/2223832957131789992'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/2223832957131789992'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/06/modern-c-design.html' title='Modern C++ Design'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_UXKUeU6z7xE/RoID_KgKi2I/AAAAAAAAADc/5LJTPI3o3Zc/s72-c/modern-c%2B%2B-design.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-6957865252181848273</id><published>2007-06-26T18:15:00.000+02:00</published><updated>2008-11-26T23:42:24.132+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Argument list</title><content type='html'>Sabemos que la forma nativa y directa de poner una lista de argumentos variable, en lenguaje C es mediante el operador la ellipsis (...), y haciendo uso de unas macros, llamadas &lt;code&gt;va_star(), va_end(), y va_arg()&lt;/code&gt;.&lt;br /&gt;Esto tiene numerosos inconvenientes, además de que no se yo hasta que punto está recomendado su uso bajo C++. &lt;a href="http://www.codeproject.com/cpp/argfunctions.asp"&gt;Aquí&lt;/a&gt; podeis ver más del tema.&lt;br /&gt;&lt;table style="width: 640px; height: 179px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;void func( int _a, ... )&lt;br /&gt;{&lt;br /&gt;  va_list   marker;&lt;br /&gt;  va_start( marker, _a );&lt;br /&gt;  // bucle&lt;br /&gt;     int a = (int)va_arg( marker, int );&lt;br /&gt;  // fin bucle&lt;br /&gt;  va_end( marker );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Existen múltiples alternativas a ésto.&lt;br /&gt;Por ejemplo, una es utilizando la clase &lt;a href="http://gyakoo.blogspot.com/2007/06/variant-type.html"&gt;Variant&lt;/a&gt;, previamente definida en otro post. Podemos hacer una pequeña clase contenedora. Soportando únicamente los tipos que soporte dicho Variant, como parámetros.&lt;br /&gt;Ahora, nuestra función con lista de argumentos variable:&lt;br /&gt;&lt;table style="width: 640px; height: 179px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;template&amp;lt; typename T &amp;gt;&lt;br /&gt;void func ( const T&amp; _params )&lt;br /&gt;{&lt;br /&gt;  for ( int i = 0; i &amp;lt; _params.size(); ++i )&lt;br /&gt;  {&lt;br /&gt;     Var v = _params[i];&lt;br /&gt;     // Hacer algo con v.&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;El código de llamada a ésta función quedaría así:&lt;br /&gt;&lt;table style="width: 640px; height: 51px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;func ( VArray&amp;lt;4&amp;gt;().push(5).push(3.5f).push("hola").push('a') );&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Y finalmente nuestra clase &lt;code&gt;VArray&lt;/code&gt; queda así:&lt;br /&gt;&lt;table style="width: 640px; height: 387px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;template&amp;lt; int N &amp;gt;&lt;br /&gt;struct VArray&lt;br /&gt;{&lt;br /&gt;  VArray ():ndx(0){}&lt;br /&gt;&lt;br /&gt;  inline VArray&amp; push( const Var&amp;amp; _v )&lt;br /&gt;  {&lt;br /&gt;     array[ndx] = _v;&lt;br /&gt;     ndx++;&lt;br /&gt;     return *this;&lt;br /&gt;  }&lt;br /&gt;  inline Var  pop  ( )  { return array[--ndx]; }&lt;br /&gt;  inline bool empty( ) const { return ndx == 0; }&lt;br /&gt;  inline int  size ( ) const { return SIZE; }&lt;br /&gt;  inline Var  get  ( const int _ndx ) const { return array[_ndx]; }&lt;br /&gt;  inline Var  operator[]( const int _ndx ) const { return get(_ndx); }&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;  enum { SIZE = N };&lt;br /&gt;  int  ndx;&lt;br /&gt;  Var  array[N];&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Debo decir que éste código de arriba no hace test de índices ni de rangos. Puede provocar un fallo en runtime si accedemos fuera de &lt;code&gt;array&lt;/code&gt;, es solo demostrativo, y debe de mejorarse.&lt;br /&gt;Este &lt;code&gt;VArray&lt;/code&gt; tiene tamaño estático en compilación, pero podemos quitar los templates y usar un &lt;code&gt;std::vector&lt;/code&gt; para tener un VArray con tamaño dinámico.&lt;br /&gt;&lt;br /&gt;Por otra parte, usando la clase &lt;a href="http://gyakoo.blogspot.com/2007/06/templates-recursivos.html"&gt;&lt;code&gt;List&lt;/code&gt;&lt;/a&gt; podemos hacer algo similar, y nos permitiría más tipos aparte de los nativos. Unicamente que sería todo resuelto en compilación, con lo que, además de otros contras, no podríamos recorrer nuestro &lt;code&gt;VArray&lt;/code&gt; con un bucle, como lo hacemos arriba.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-6957865252181848273?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/6957865252181848273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=6957865252181848273&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6957865252181848273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6957865252181848273'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/06/argument-list.html' title='Argument list'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-5874454919665775883</id><published>2007-06-26T00:22:00.000+02:00</published><updated>2008-11-26T23:42:24.133+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Templates recursivos</title><content type='html'>El otro día se me apeteció jugar un poco con los &lt;code&gt;templates&lt;/code&gt; de C++, para coger más soltura con ellos. Estuve probando con los templates recursivos, similar al típico ejemplo de factorial. Me puse a implementar una clase template que representara una lista de distintos tipos, estática (tamaño solo resuelto en compilación).&lt;br /&gt;Un ejemplo de código que utiliza ésta clase lista podría ser el siguiente:&lt;br /&gt;&lt;table style="width: 640px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;// -- Definimos nuestra lista (o tupla), e inicializamos --&lt;br /&gt;List&amp;lt; Player , &lt;br /&gt;List&amp;lt; Computer , &lt;br /&gt;List&amp;lt; Door , &lt;br /&gt;List&amp;lt; Monitor &amp;gt; &amp;gt; &amp;gt; &amp;gt; MyTuple ( Player ( "Juan", 32 ),&lt;br /&gt;    Computer( "Dell", 512, 2 ),&lt;br /&gt;    Door ( 3.0f ),&lt;br /&gt;    Monitor ( "Sony" ) );&lt;br /&gt;&lt;br /&gt;// -- Obtenemos referencia al segundo elemento, y lo modificamos --&lt;br /&gt;Computer&amp; c = MyTuple.get&amp;lt;1,Computer&amp;gt;();&lt;br /&gt;c.mem = 1024;&lt;br /&gt;&lt;br /&gt;// -- Cambiamos directamente el elemento 2 --&lt;br /&gt;MyTuple.set&amp;lt;2&amp;gt;( Door(5.0f) );&lt;br /&gt;&lt;br /&gt;// -- Obtenemos el nº elementos --&lt;br /&gt;printf ( "Size = %d\n", MyTuple.SIZE );&lt;br /&gt;&lt;br /&gt;// -- Recorremos lista imprimiendo sus datos --&lt;br /&gt;MyTuple.print( );&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Y el resultado sería el siguiente:&lt;br /&gt;&lt;table style="width: 640px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;---- Output ----&lt;br /&gt;Size = 4&lt;br /&gt;Player "Juan" (32)&lt;br /&gt;Computer "Dell" (1024,2)&lt;br /&gt;Door 5.0&lt;br /&gt;Monitor "Sony"&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Al final, acabé con algo similar a la &lt;a href="http://www.boost.org/libs/tuple/doc/tuple_users_guide.html#constructing_tuples"&gt;&lt;code&gt;boost::tuple&lt;/code&gt;&lt;/a&gt;.&lt;br /&gt;El código de mi pseudo-tuple es el siguiente.&lt;br /&gt;&lt;table style="width: 640px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;// -- Tipo base ( caso base ) para finalizar lista --&lt;br /&gt;struct ListEnd&lt;br /&gt;{ &lt;br /&gt;   // -- Nº elementos de esta lista vacía --&lt;br /&gt;   enum { SIZE = 0 };&lt;br /&gt;&lt;br /&gt;   // -- Casos base en recursión --&lt;br /&gt;   template&amp;lt; int NDX, typename VT &amp;gt; VT&amp; get(){ static VT v; return v; }&lt;br /&gt;   template&amp;lt; int NDX, typename VT &amp;gt; void set( const VT&amp; _v ){ }&lt;br /&gt;   void print(){}&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;code&gt;ListEnd&lt;/code&gt; sirve para especificar el tipo del caso base en recursión del template. Contiene aquellos métodos base, que no realizan nada, y son para hacer que el compilador no proteste.&lt;br /&gt;&lt;table style="width: 640px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;template&lt; typename T, typename L = ListEnd &amp;gt;&lt;br /&gt;struct List &lt;br /&gt;{&lt;br /&gt;   // -- Numero de elementos para la lista -- &lt;br /&gt;   enum{ SIZE = L::SIZE + 1 }; &lt;br /&gt; &lt;br /&gt;   // -- Constructors --&lt;br /&gt;   List ( ){}&lt;br /&gt; &lt;br /&gt;   template&amp;lt; class T0 &amp;gt; &lt;br /&gt;   List( const T0&amp; _v0 ) { set&amp;lt;0&amp;gt;( _v0 ); }&lt;br /&gt; &lt;br /&gt;   template&amp;lt; class T0, class T1 &amp;gt;&lt;br /&gt;   List( const T0&amp; _v0, const T1&amp; _v1 ) &lt;br /&gt;   { set&amp;lt;0&amp;gt;( _v0 ); set&amp;lt;1&amp;gt;( _v1 ); }&lt;br /&gt; &lt;br /&gt;   template&amp;lt; class T0, class T1, class T2 &amp;gt;&lt;br /&gt;   List( const T0&amp; _v0, const T1&amp; _v1, const T2&amp; _v2 ) &lt;br /&gt;   { set&amp;lt;0&amp;gt;( _v0 ); set&amp;lt;1&amp;gt;( _v1 ); set&amp;lt;2&amp;gt;( _v2 ); } &lt;br /&gt;&lt;br /&gt;   // ... Sucesivas sobrecargas del constructor aquí ... &lt;br /&gt;&lt;br /&gt;   // -- Accessors --&lt;br /&gt;   template&amp;lt; int NDX, typename VT &amp;gt; &lt;br /&gt;   VT&amp; get( ){ return mList.get&amp;lt; NDX - 1, VT &amp;gt;(); }&lt;br /&gt;   template&amp;lt;&amp;gt; T&amp; get&amp;lt;0,T&amp;gt;( ){ return mElm; }&lt;br /&gt;&lt;br /&gt;   // -- Mutators --&lt;br /&gt;   template&amp;lt; int NDX, typename VT &amp;gt;&lt;br /&gt;   void set( const VT&amp; _v ){ mList.set&amp;lt; NDX - 1, VT &amp;gt;( _v ); } &lt;br /&gt;   template&amp;lt;&amp;gt; void set&amp;lt;0,T&amp;gt;( const T&amp; _v ){ mElm = _v; }&lt;br /&gt; &lt;br /&gt;   // -- Recursive print --&lt;br /&gt;   void print ( )&lt;br /&gt;   {&lt;br /&gt;      mElm.print( );&lt;br /&gt;      mList.print( ); &lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   // -- Data --&lt;br /&gt;   T   mElm;  // Elemento&lt;br /&gt;   L   mList; // Resto de la lista&lt;br /&gt; &lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Notas:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Los tipos de datos de la tupla deben de tener el método print() definido.&lt;/li&gt;&lt;li&gt;Para acceder al tamaño (&lt;code&gt;SIZE&lt;/code&gt;) de la tupla, se accede mediante la instancia y con el operador punto (.), aunque sea un elemento de una enumeración.&lt;/li&gt;&lt;li&gt;Intenté no utilizar sobrecargas del constructor para permitir lista de inicialización variable. Usando la ellipsis (...) y con &lt;code&gt;va_list&lt;/code&gt;, pero no me convenció la transformación de tipos, así como que no me funcionaba &lt;code&gt;va_arg()&lt;/code&gt; en algunos casos.&lt;/li&gt;&lt;li&gt;Notad las especializaciones de los métodos templatizados &lt;code&gt;get()&lt;/code&gt; y &lt;/code&gt;set()&lt;/code&gt;. Para cuando &lt;code&gt;NDX&lt;/code&gt; vale 0. De esta forma, cubrimos sus casos base en la recursividad en compilación; pero aún así necesitaba definirlos para el tipo ListEnd, porque el compilador me protestaba. A ver si averiguo porqué.&lt;/li&gt;&lt;li&gt;Notad también el tipo por defecto, para el argumento &lt;code&gt;L&lt;/code&gt; de la estructura &lt;code&gt;List&lt;/code&gt;, definiendo como por defecto &lt;code&gt;ListEnd&lt;/code&gt;, el cual marca el final de la lista.&lt;/li&gt;&lt;li&gt;No he podido probar a mantener subtipos &lt;code&gt;List&lt;/code&gt; dentro de los tipos de &lt;code&gt;List&lt;/code&gt;...(si alguien se anima).&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-5874454919665775883?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/5874454919665775883/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=5874454919665775883&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5874454919665775883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/5874454919665775883'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/06/templates-recursivos.html' title='Templates recursivos'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-6262555340411054320</id><published>2007-06-25T08:40:00.001+02:00</published><updated>2008-11-26T23:30:48.702+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>Postmortem Soldiers I</title><content type='html'>Hace poco he terminado un proyecto de un "juego" de soldados.&lt;br /&gt;&lt;br /&gt;Manejas a un soldado que tiene que tomar un edificio, donde se esconden otros, como si fueran terroristas.&lt;br /&gt;&lt;br /&gt;Para ello dispones de un fusil automático, de unas cuantas granadas y del control de tus compañeros que te siguen y actúan a unas órdenes básicas. Tanto enemigos como compañeros están manejados por la CPU con una IA muy básica.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;u&gt;Tecnologías utilizadas.&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_UXKUeU6z7xE/Rn9jo1Kp0QI/AAAAAAAAAC8/k6JamNfyvnY/s1600-h/Surcos_02.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 210px; height: 155px;" src="http://bp1.blogger.com/_UXKUeU6z7xE/Rn9jo1Kp0QI/AAAAAAAAAC8/k6JamNfyvnY/s320/Surcos_02.jpg" alt="" id="BLOGGER_PHOTO_ID_5079888457814888706" border="0" /&gt;&lt;/a&gt;Me propuse acabar este juego en dos meses. Para ello, tenía que partir de algún desarrollo previo, o alguna librería. Y aunque estoy diseñando un motor, aún está muy verde para ser usado así que me decanté por las siguientes third-parties:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ogre3d.org/"&gt;Ogre3D&lt;/a&gt; como motor gráfico. Plugin BSP para Ogre, modificado, como manager de escena. &lt;a href="http://www.fmod.org/"&gt;Fmodex &lt;/a&gt;como sistema de sonido. &lt;a href="http://www.lua.org/"&gt;Lua &lt;/a&gt;como sistema de script.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Luego, como aplicaciones utilizadas, caben destacar, Visual Studio 2005 + SP1 para código, SVN como source control, gtk Radiant para diseñar el mapa, 3DStudio Max 8.0 + LexiExporter para los modelos 3D, doxygen para documentación, y alguna que otra herramienta más.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;u&gt;Assets.&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_UXKUeU6z7xE/Rn904lKp0TI/AAAAAAAAADU/fQIPw_eax0k/s1600-h/Surcos_00.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 216px; height: 162px;" src="http://bp0.blogger.com/_UXKUeU6z7xE/Rn904lKp0TI/AAAAAAAAADU/fQIPw_eax0k/s320/Surcos_00.jpg" alt="" id="BLOGGER_PHOTO_ID_5079907420095500594" border="0" /&gt;&lt;/a&gt;Las texturas para el mapa son extraídas de aquí y allá. Del quake3, del rtcw, y del q3ut. Luego, algunas otras me las pasó un compañero, obtenidas fotografiando un edificio.&lt;br /&gt;&lt;br /&gt;El modelo del carro de combate está sacado de una librería de modelos. Y los sonidos igualmente de la librería sound ideas 6000, gracias &lt;a href="http://electrofobia.wordpress.com/"&gt;norky&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;El skinning del soldado y su geometría están limpiados por dvicente. El modelo de granada y su textura por asaborido. Luego, tanto las animaciones, como el modelo del soldado base, como el diseño del mapa e iluminación, está realizado por mí. (he ahí la precariedad de los mismos). Pero para tirar me valían.&lt;br /&gt;&lt;br /&gt;El mapa está realizado bajo gtkRadiant. El modelado bajo 3dsmax 8 y exportado con LexiExporter, a formato mesh de ogre. Solamente está diseñada la planta baja del edificio, y aunque podemos subir a otras plantas, ni la IA lo soporta, ni tampoco vas a ver nada, por que solo se ilumina la planta baja.&lt;br /&gt;&lt;br /&gt;En sucesivos posts iré describiendo un poco lo que fue bien y lo que fue mal. Algunas características internas del código, así como muchos pequeños detalles y bugs que fueron consumiendo el tiempo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-6262555340411054320?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/6262555340411054320/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=6262555340411054320&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6262555340411054320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/6262555340411054320'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/06/postmortem-soldiers-i.html' title='Postmortem Soldiers I'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_UXKUeU6z7xE/Rn9jo1Kp0QI/AAAAAAAAAC8/k6JamNfyvnY/s72-c/Surcos_02.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-7828929140383987067</id><published>2007-06-25T08:00:00.000+02:00</published><updated>2008-11-26T23:30:48.702+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><title type='text'>DirectX9 SDK, June 2007</title><content type='html'>Nueva versión del SDK &lt;a href="http://msdn2.microsoft.com/es-es/xna/aa937788(en-us).aspx"&gt;aquí&lt;/a&gt;.&lt;br /&gt;Pulsar &lt;a href="http://msdn2.microsoft.com/es-es/xna/aa937789(en-us).aspx"&gt;Release Notes&lt;/a&gt; para ver los cambios y problemas conocidos.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-7828929140383987067?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/7828929140383987067/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=7828929140383987067&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7828929140383987067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7828929140383987067'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/06/directx9-sdk-june-2007.html' title='DirectX9 SDK, June 2007'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-7118403976381391610</id><published>2007-06-24T22:32:00.000+02:00</published><updated>2008-11-26T23:42:24.134+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Inlining printf format</title><content type='html'>Supongamos que tenemos la siguiente función:&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;void log( const char* _msg )&lt;br /&gt;{&lt;br /&gt;   ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Muchas veces es necesario llamar a funciones como ésta, con una cadena de carácteres descriptiva, formada por varios campos. A veces se utiliza el siguiente código para componer la cadena y llamar:&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;{&lt;br /&gt;   char  str[64];&lt;br /&gt;   sprintf ( str, "Player position = %.2f, %.2f, %.2f\n", player-&gt;x, player-&gt;y, player-&gt;z );&lt;br /&gt;   log ( str );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Este patron de declarar una cadena, rellenarla y usarla podemos encapsularlo en una función tal que así:&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#ccccee"&gt;&lt;pre&gt;&lt;br /&gt;template&amp;lt; unsigned long T &amp;gt;&lt;br /&gt;const char *str( const char *_format, ... )&lt;br /&gt;{&lt;br /&gt;   __declspec( thread ) static char g_str[ T ];&lt;br /&gt;&lt;br /&gt;   va_list   marker;&lt;br /&gt;   va_start ( marker, _format );&lt;br /&gt;   vsprintf ( g_str, _format, marker );&lt;br /&gt;   return g_str;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Y el código quedaría así:&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;log ( str&lt;64&gt;("Player position = %.2f, %.2f, %.2f\n", player-&gt;x, player-&gt;y, player-&gt;z) );&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Esto crea una cadena estática por cada tamaño que especifiquemos, y por cada thread &lt;code&gt;(__declspec(thread))&lt;/code&gt;. La cadena que devuelve debe de ser copiada al momento, y no quedarse con el puntero a char, ya que otras llamadas a &lt;code&gt;str&lt;/code&gt; pueden modificarla, al ser &lt;code&gt;static&lt;/code&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-7118403976381391610?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/7118403976381391610/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=7118403976381391610&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7118403976381391610'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7118403976381391610'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/06/inlining-printf-format.html' title='Inlining printf format'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-7515999175277026882</id><published>2007-06-24T17:28:00.000+02:00</published><updated>2008-11-26T23:42:24.134+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Win32 Debug CRT Heap Internals</title><content type='html'>Interesante y útil artículo en el cual podemos ver los valores que se asignan a la memoria, por el Visual Studio. Cuando ejecutamos una aplicación en debug, desde el IDE, éste inicializa y maneja la memoria dinámica, asignándole patrones de valores que pueden ser luego reconocibles cuando depuramos al encontrar un bug, por ejemplo.&lt;br /&gt;Aquí teneis el enlace.&lt;br /&gt;&lt;a href="http://www.nobugs.org/developer/win32/debug_crt_heap.html"&gt;Win32 Debug CRT Heap Internals&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-7515999175277026882?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/7515999175277026882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=7515999175277026882&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7515999175277026882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/7515999175277026882'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/06/win32-debug-crt-heap-internals.html' title='Win32 Debug CRT Heap Internals'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-2662780747603059902</id><published>2007-06-24T16:21:00.000+02:00</published><updated>2008-11-26T23:38:46.948+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comments'/><category scheme='http://www.blogger.com/atom/ns#' term='media'/><title type='text'>Id's Tech 5</title><content type='html'>&lt;a href="http://www.armadilloaerospace.com/n.x/johnc/Recent%20Updates"&gt;John Carmack&lt;/a&gt; ha presentado en la &lt;a href="http://developer.apple.com/wwdc/"&gt;Apple Worldwide Developers Conference de 2007&lt;/a&gt;, su nueva tecnología, disponible también ahora para los Macs, llamada &lt;b&gt;Tech 5&lt;/b&gt;.&lt;br /&gt;&lt;object width="425" height="350"&gt;&lt;param name="movie" value="http://www.youtube.com/v/HvuTtrkVtns"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/HvuTtrkVtns" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-2662780747603059902?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/2662780747603059902/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=2662780747603059902&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/2662780747603059902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/2662780747603059902'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/06/tech-5.html' title='Id&apos;s Tech 5'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-3585165740435632436</id><published>2007-06-24T15:41:00.000+02:00</published><updated>2008-11-26T23:42:24.135+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Memory leak detection code snippet</title><content type='html'>El siguiente código muestra cómo activar las funciones de depuración del heap, para que muestren un informe de posibles memory leaks. Más información &lt;a href="http://msdn2.microsoft.com/en-us/library/x98tx3cf%28VS.80%29.aspx"&gt;aquí&lt;/a&gt;.&lt;br /&gt;He añadido el re-define del operador new, ya que, a mi parecer, faltaba en el enlace anterior, y no me salía la información del fichero donde se produce el leak.&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Nota: Solo bajo el depurador de Visual Studio. Compilar en DEBUG (directiva de preprocesador _DEBUG).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#ccccee"&gt;&lt;pre&gt;&lt;br /&gt;// Las 4 siguiente lineas activan la detección de leaks.&lt;br /&gt;#define _CRTDBG_MAP_ALLOC&lt;br /&gt;#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#include &amp;lt;crtdbg.h&amp;gt;&lt;br /&gt;int main(int argc, char* argv[])&lt;br /&gt;{&lt;br /&gt;  _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );&lt;br /&gt;  int*  pInt = new int(0);&lt;br /&gt;  char* pStr = new char[256];&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Y el resultado en la ventana de output es:&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;---- Output ----&lt;br /&gt;Detected memory leaks!&lt;br /&gt;Dumping objects -&amp;gt;&lt;br /&gt;main.cpp(70) : {127} normal block at 0x003A6740, 256 bytes long.&lt;br /&gt;Data: &amp;lt;                &amp;gt; CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD&lt;br /&gt;main.cpp(69) : {126} normal block at 0x003A6700, 4 bytes long.&lt;br /&gt;Data: &amp;lt;    &amp;gt; 03 00 00 00&lt;br /&gt;Object dump complete.&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Nos muestra dos bloques sin liberar, de 256 y 4 bytes respectivamente. Si hacemos doble click en la línea del fichero main.cpp, ya sea de uno u otro bloque, nos lleva exactamente al código que reservó dicha memoria dinámica, y del cual deberemos partir para averiguar el porqué no se está liberando.&lt;br /&gt;&lt;br /&gt;El código de arriba saca el report de leaks cuando se acaba la aplicación, en cualquier punto. Si queremos específicamente sacar el report en un punto especificado podemos usar la función &lt;code&gt;_CrtDumpMemoryLeaks()&lt;/code&gt;, y también podemos cambiar la salida del report, por si la queremos en un fichero o en una ventana de diálogo, con la función &lt;code&gt;_CrtSetReportMode()&lt;/code&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-3585165740435632436?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/3585165740435632436/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=3585165740435632436&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/3585165740435632436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/3585165740435632436'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/06/memory-leak-detection-code-snippet.html' title='Memory leak detection code snippet'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-27518612.post-8903308043756580719</id><published>2007-06-23T12:00:00.000+02:00</published><updated>2008-11-26T23:42:24.136+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='c++'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Variant type</title><content type='html'>Un tipo de datos &lt;a href="http://en.wikipedia.org/wiki/Variant_type"&gt;Variant&lt;/a&gt; brevemente, es aquel que puede representar varios tipos de datos (enteros, flotantes, doubles, fechas). E incluso en runtime se puede cambiar su valor y representación. &lt;br /&gt;&lt;br /&gt;C++ estándar no define variant como uno de sus tipos nativos. Aunque Microsoft tiene una implementación del mismo para soporte de objetos COM. C# tiene su tipo &lt;code&gt;object&lt;/code&gt; que es como un variant. VB sí lo soporta. Algunos sistemas de script como lua también lo soportan.&lt;br /&gt;&lt;br /&gt;En el trabajo usamos actualmente un Variant polimórfico. Es útil para poder extenderlo y hacer que soporte nuevos tipos nativos. Además no obliga a tener memoria reservada para representar un double, si solo estamos representando un byte, por ejemplo. Pero hay que tratar demasiadas veces con memoria dinámica, así como con polimorfismo, con la consecuente penalización de resolver la dirección en las tablas virtuales.&lt;br /&gt;&lt;br /&gt;Para casa, utilizaba una idea similar, pero el otro día, tras analizar varios miniproyectos donde los utilizaba llegué a la conclusión que solamente lo estaba utilizando para tipos nativos, y que no me hacía falta la posibilidad de extensión que me ofrecía. Pensé pues en definir un variant más específico, pero intentando ser un poco más óptimo en espacio y tiempo. He visto el &lt;code&gt;boost::variant&lt;/code&gt; y &lt;code&gt;boost::any&lt;/code&gt;, además, &lt;a href="http://www.ddj.com/dept/cpp/184402027"&gt;aquí&lt;/a&gt;, Christopher Diggins explica algunas desventajas de éstas y expone su propia implementación. Y luego, nada más que hay que &lt;a href="http://www.google.es/search?source=ig&amp;hl=es&amp;q=variant+c%2B%2B&amp;btnG=Buscar+con+Google&amp;meta="&gt;buscar&lt;/a&gt; un poco para ver otras implementaciones.&lt;br /&gt;Pero me decidí a reinventar la rueda e implementé la siguiente clase. Es sencilla, y no es más que la abstracción de uso de una unión:&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#ccccee"&gt;&lt;pre&gt;&lt;br /&gt;struct Var&lt;br /&gt;{&lt;br /&gt;   enum{ V_NONE = 0, V_INT, V_BYTE, V_FLOAT, V_BOOL, V_HANDLE, V_STRING, V_TABLE };&lt;br /&gt;&lt;br /&gt;   // -- Constructors&lt;br /&gt;   Var ( )  : type(V_NONE){ asInt = 0; }&lt;br /&gt;   Var ( int _i ) : type(V_NONE){ setI (_i); }&lt;br /&gt;   Var ( char _c ) : type(V_NONE){ setBy( _c ); }&lt;br /&gt;   Var ( float _f) : type(V_NONE){ setF ( _f ); }&lt;br /&gt;   Var ( bool _b ) : type(V_NONE){ setB ( _b ); }&lt;br /&gt;   Var ( void* _h )     : type(V_NONE){ setH ( _h); }&lt;br /&gt;   Var ( const char* _s ): type(V_NONE){ setS ( _s ); }  &lt;br /&gt;   Var ( const Var&amp; _r ): type(V_NONE){ *this = _r; }&lt;br /&gt;&lt;br /&gt;   // -- Destructor&lt;br /&gt;   ~Var( )&lt;br /&gt;   {&lt;br /&gt; destroy(); &lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   /// -- Accessors&lt;br /&gt;   inline char  getType( ) const { return type; }&lt;br /&gt;   inline int  asI( )  const { return asInt;}&lt;br /&gt;   inline char  asBy( ) const { return asByte;}&lt;br /&gt;   inline float asF( )  const { return asFloat;}&lt;br /&gt;   inline bool  asB( )  const { return asBool; }&lt;br /&gt;   inline void* asH( )  const { return asHandle; }&lt;br /&gt;   inline const char* asS( ) const { return asString; }&lt;br /&gt;   &lt;br /&gt;   // -- Type conversion operators&lt;br /&gt;   operator int()  const { return asI(); }&lt;br /&gt;   operator char() const { return asBy(); }&lt;br /&gt;   operator float()const { return asF(); }&lt;br /&gt;   operator bool() const { return asB(); }&lt;br /&gt;   operator void*()const { return asH(); }&lt;br /&gt;   operator const char*() const{ return asS(); }&lt;br /&gt;&lt;br /&gt;   // -- Mutators&lt;br /&gt;   inline void setI ( int _i ) { destroy(); type = V_INT; asInt = _i; }&lt;br /&gt;   inline void setBy( char _c ){ destroy(); type = V_BYTE; asByte = _c; }&lt;br /&gt;   inline void setF ( float _f){ destroy(); type = V_FLOAT; asFloat = _f; }&lt;br /&gt;   inline void setB ( bool _b) { destroy(); type = V_BOOL; asBool = _b; }&lt;br /&gt;   inline void setH ( void* _h){ destroy(); type = V_HANDLE; asHandle = _h; }&lt;br /&gt;   inline void setS ( const char* _s) &lt;br /&gt;   { &lt;br /&gt;       destroy(); &lt;br /&gt;       type = V_STRING; &lt;br /&gt;       const int strLen = (int)strlen(_s); &lt;br /&gt;       asString = new char[ strLen+1 ];  &lt;br /&gt;       memcpy( (void*)asString, _s, strLen );&lt;br /&gt;       asString[strLen] = 0;&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   // -- Assignment operators&lt;br /&gt;   inline const Var&amp; operator =( const int _i ){ setI(_i); return *this; }&lt;br /&gt;   inline const Var&amp; operator =( const char _c){ setBy(_c); return *this;}&lt;br /&gt;   inline const Var&amp; operator =( const float _f){ setF (_f ); return *this;}&lt;br /&gt;   inline const Var&amp; operator =( const bool _b ){ setB( _b); return *this;}&lt;br /&gt;   inline const Var&amp; operator =( void* _h){ setH(_h); return *this;}&lt;br /&gt;   inline const Var&amp; operator =( const char* _s){ setS(_s); return *this;}&lt;br /&gt;   inline const Var&amp; operator =( const Var&amp; _r )&lt;br /&gt;   {&lt;br /&gt;      destroy();&lt;br /&gt;      type = _r.type;&lt;br /&gt;      if ( _r.type == V_STRING )&lt;br /&gt;      {&lt;br /&gt;         asInt = 0;&lt;br /&gt;         setS( _r.asS() );&lt;br /&gt;      }else&lt;br /&gt;      {&lt;br /&gt;         asInt = _r.asInt; &lt;br /&gt;      }&lt;br /&gt;      return *this;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;   // Invalidate current.&lt;br /&gt;   inline void destroy( )&lt;br /&gt;   {&lt;br /&gt;      if ( type == V_STRING &amp;&amp; asString != 0 )&lt;br /&gt;      {&lt;br /&gt;         delete [] asString;&lt;br /&gt;      }&lt;br /&gt;      type = V_NONE;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;   // Distinct representations of var.&lt;br /&gt;   union&lt;br /&gt;   {&lt;br /&gt;      int     asInt;&lt;br /&gt;      char    asByte;&lt;br /&gt;      float   asFloat;&lt;br /&gt;      bool    asBool;&lt;br /&gt;      void*   asHandle; &lt;br /&gt;      char*   asString; &lt;br /&gt;   };&lt;br /&gt;&lt;br /&gt;   // Type of var, only support 256 types!&lt;br /&gt;   char type; &lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Esta implementación tiene algunos inconvenientes. &lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;No es segura. Si representamos un &lt;code&gt;int&lt;/code&gt; y aún así queremos obtener un &lt;code&gt;asS()&lt;/code&gt; para tratarlo como una cadena, podemos tener errores en runtime. La compilación no protesta.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Conjunto reducidos de tipos que puede representar. Un double no puede ser representado. Se puede añadir como tipo soportado, aun así.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Byte alignment. La unión ocupa el valor máximo, 4 bytes. Pero tenemos que mantener un campo más, &lt;code&gt;type&lt;/code&gt; para indicar el tipo. Este campo, podría ocupar 1, 2 o incluso 4 bytes, da igual, la estructura se alineará a 8 bytes. Pero bueno, entonces con un &lt;code&gt;type&lt;/code&gt; de 1 byte como está, podemos usar 3 bytes extras para otra información adicional.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Almacenamos 8 bytes independientemente de si representamos un dato de menor longitud&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Aunque también tiene algunas ventajas.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;No trata con memoria dinámica. Todo se queda en stack, exceptuando si estamos representando cadenas.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;No necesario polimorfismo, para estos tipos básicos. No necesaria tabla virtual.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Poco espacio, 8 bytes.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Facilidad de uso, al sobrecargar operadores y constructores&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Pongamos un ejemplo de código de uso:&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td bgcolor="#cccccc"&gt;&lt;pre&gt;&lt;br /&gt;Var v0 = "hola mundo!";&lt;br /&gt;Var v1 = 5+3;&lt;br /&gt;&lt;br /&gt;printf ( "v0 = %s\n", v0 );&lt;br /&gt;printf ( "v1 = %d\n", v1 );&lt;br /&gt;&lt;br /&gt;v1 = "my string";&lt;br /&gt;printf ( "v1 = %s\n", v1 );&lt;br /&gt;&lt;br /&gt;-------- Resultado ----------&lt;br /&gt;v0 = hola mundo!&lt;br /&gt;v1 = 8&lt;br /&gt;v1 = my string&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Bueno, como os comenté, para mis propósitos me viene bien. Aun así habrá que seguir investigando, como siempre.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/27518612-8903308043756580719?l=gyakoo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gyakoo.blogspot.com/feeds/8903308043756580719/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=27518612&amp;postID=8903308043756580719&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8903308043756580719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/27518612/posts/default/8903308043756580719'/><link rel='alternate' type='text/html' href='http://gyakoo.blogspot.com/2007/06/variant-type.html' title='Variant type'/><author><name>gyakoo</name><uri>http://www.blogger.com/profile/13800797986180829939</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_UXKUeU6z7xE/StBh3qVWlvI/AAAAAAAAAZE/MiRTs9COrII/S220/photo.jpg'/></author><thr:total>0</thr:total></entry></feed>
