Skip navigation

Category Archives: misc

There’s this point in Woo’s paper that confused me before, and it just confused me again now.

The paper says to always pick the largest t.

So the situations in red and pink confused me. It would seem at first glance that “further t” (in the pink diagram, the one intersecting min.y) would be the “greater t” but the _wrong one_ to pick.

But it turns out when you cull the back faces _based on ray direction_, the smaller t would be at the max.y plane, even though the ray starts AFTER the max.y plane.

Note Woo’s method as presented _doesn’t work for when the ray starts totally inside the box_.

If the ray starts inside the box, if you only need the boolean result then RETURN TRUE immediately. But if you need the intersection point, you need to turn around some of the rules of the test:


From “Geometric Tools for Computer Graphics”, the definition of convex given on pg 265 sec 7.7 is:

A set S is convex if given any two points P and Q in S,the line segment ( 1 − t ) P + t Q for t ∈ [0, 1] is also in S.

Said more plainly, if every line you can draw that connects two vertices a shape is completely contained inside the shape (tracing edges is allowed), then that shape is convex.

Basic program showing how to use GLSL and GLUT together

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <map>
using namespace std ;

#include <math.h>

//     #defining GLEW_STATIC means to compile the glew library as a static lib.
//     This means your prog WILL NOT require the glew32.dll file to accompany your executable.
#include <GL/glew.h>
#pragma comment( lib, "glew32s.lib" )   // the 's' is for 'static'

//#include <GL/glew.h>
//#pragma comment( lib, "glew32.lib" )

// I'm using the STATIC LIB way above, because I prefer it.

#include <GL/glut.h>

GLuint glslProgId ;     // GLSL shader PROGRAM identifier
GLuint vshId, pshId ;   // GLSL vertex shader id, pixel shader id

// These 2 are "handles" that connect the POSITION attribute in
// the GLSL shader with __AN ACTUAL SET OF VERTICES__ from the C++ source code.
// In this program each VERTEX has a position and a color (only).
GLuint positionAttribute, colorAttribute;

// This is the connector between the uniform variable modelViewMatrix,
// used in the glsl shader code.  We need this variable to LOAD
// a specific modelview matrix INTO the GLSL shader before rendering the verts.
GLuint uniformModelViewMatrix;

// The vertex array object identifier.  This single number
// identifies EVERYTHING about the vertex buffer we are 
// about to create and render, from its attribute set (positions, colors)
// to where to fetch the data from when it's time to draw.
GLuint vao ;

// window width and height.
float w=512.f, h=512.f;

struct VertexPC
  float x,y,z, r,g,b,a ;
  VertexPC( float ix, float iy, float iz, float ir, float ig, float ib, float ia ):
    x(ix),y(iy),z(iz), r(ir),g(ig),b(ib),a(ia)
} ;

// The data for the vertex and index buffers.
// I'm just using index buffers to show how they are used.
static VertexPC verts[] = { 
  VertexPC(0,0,0, 1,0,0,1),
  VertexPC(1,0,0, 0,1,0,1),
  VertexPC(0,1,0, 0,0,1,1)
} ;
static int indices[] = {0,1,2};

map<int,const char*> glErrName ;
map<int,const char*> createErrMap()
  map<int,const char*> errmap ;
  errmap.insert( make_pair( 0x0000, "GL_NO_ERROR" ) ) ;
  errmap.insert( make_pair( 0x0500, "GL_INVALID_ENUM" ) ) ;
  errmap.insert( make_pair( 0x0501, "GL_INVALID_VALUE" ) ) ;
  errmap.insert( make_pair( 0x0502, "GL_INVALID_OPERATION" ) ) ;
  errmap.insert( make_pair( 0x0503, "GL_STACKOVERFLOW" ) ) ;
  errmap.insert( make_pair( 0x0504, "GL_STACK_UNDERFLOW" ) ) ;
  errmap.insert( make_pair( 0x0505, "GL_OUTOFMEMORY" ) ) ;
  errmap.insert( make_pair( 0x8CD5, "GL_FRAMEBUFFER_COMPLETE" ) ) ;
  errmap.insert( make_pair( 0x8CD6, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT" ) ) ;
  errmap.insert( make_pair( 0x8CD7, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT" ) ) ;
  errmap.insert( make_pair( 0x8CD9, "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS" ) ) ;
  errmap.insert( make_pair( 0x8CDD, "GL_FRAMEBUFFER_UNSUPPORTED" ) ) ;                    
  return errmap ;

inline bool GL_OK()
  GLenum err = glGetError() ;
  if( err != GL_NO_ERROR )
    printf( "GLERROR %d %s\n", err, glErrName[ err ] ) ;
  return err == GL_NO_ERROR ;

inline bool GL_OK( int line, const char* file )
  GLenum err = glGetError() ;
  if( err != GL_NO_ERROR )
    printf( "GLERROR %d %s, line=%d of file=%s\n", err, glErrName[ err ], line, file ) ;
  return err == GL_NO_ERROR ;

inline bool CHECK( bool cond, const char* errMsg )
  if( !cond )  puts( errMsg ) ;
  return cond ;

#define CHECK_GL GL_OK( __LINE__, __FILE__ ) 

//#define CHECK_GL GL_OK()

void printShaderInfoLog(GLuint obj)
  int infologLength = 0;
  glGetShaderiv( obj, GL_INFO_LOG_LENGTH, &infologLength ) ;
  if( infologLength )
    char *infoLog = (char *)malloc(infologLength);
    int charsWritten ;
    glGetShaderInfoLog( obj, infologLength, &charsWritten, infoLog ) ;
    puts( infoLog ) ;
    free( infoLog ) ;

void printProgramInfoLog( GLuint obj )
  int infologLength = 0;
  glGetProgramiv( obj, GL_INFO_LOG_LENGTH, &infologLength ) ;
  if( infologLength )
    char *infoLog = (char *)malloc( infologLength ) ;
    int charsWritten ;
    glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog);
    puts( infoLog ) ;
    free( infoLog ) ;

void setupShaders()
  // The text of the shaders.  I put it as an inline string
  // just so I could post this easily w/o external files,
  // but you could easily load the shader from an external file.
  // The point is, you must pass your shader to OpenGL as
  // just a NULL terminated string.
  const char *vs = 
    "uniform mat4 modelViewMatrix ;                         "
    "                                                       "
    "attribute vec3 position;                               "
    "attribute vec4 color;                                  "
    "                                                       "
    "varying vec4 Color;                                    "
    "                                                       "
    "void main()                                            "
    "{                                                      "
    "  Color = color;                                       "
    "  gl_Position = modelViewMatrix * vec4(position,1.0) ; "
    "}                                                      " ;

  const char *fs =
    "in vec4 Color;            "
    "                          "
    "void main()               "
    "{                         "
    "  gl_FragColor = Color ;  "
    "}                         " ;
  vshId = glCreateShader(GL_VERTEX_SHADER) ;  CHECK_GL ;
  glShaderSource( vshId, 1, &vs, NULL ) ;  CHECK_GL ;
  glCompileShader( vshId ) ;  CHECK_GL ;
  printShaderInfoLog( vshId );
  pshId = glCreateShader(GL_FRAGMENT_SHADER) ;  CHECK_GL ;
  glShaderSource( pshId, 1, &fs, NULL ) ;  CHECK_GL ;
  glCompileShader( pshId ) ;  CHECK_GL ;
  printShaderInfoLog( pshId );

  glslProgId = glCreateProgram();
  glAttachShader( glslProgId, vshId );
  glAttachShader( glslProgId, pshId );

  glLinkProgram( glslProgId );
  printProgramInfoLog( glslProgId );

  positionAttribute = glGetAttribLocation( glslProgId, "position" ) ;
  colorAttribute = glGetAttribLocation( glslProgId, "color" ) ; 

  uniformModelViewMatrix = glGetUniformLocation( glslProgId, "modelViewMatrix" ) ;

  // Make a "vertex buffer"
  GLuint vertexBuffer ;
  glGenBuffers( 1, &vertexBuffer ) ;

  glBindBuffer( GL_ARRAY_BUFFER, vertexBuffer ) ;
  glBufferData( GL_ARRAY_BUFFER, sizeof( verts ), verts, GL_STATIC_DRAW ) ;

  // Make an "index buffer"
  GLuint indexBuffer ;
  glGenBuffers( 1, &indexBuffer ) ;
  glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indexBuffer ) ;
  glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( indices ), indices, GL_STATIC_DRAW ) ;

  // You know, this is weird, but a VERTEX ARRAY OBJECT
  // Vertex BUFFERS store the data.
  // A VAO stores the SETUP of how a group of
  // vertices is to be rendered.
  // That is, it stores:
  // 1)  The DATA (in vertex BUFFERS) to be drawn
  // 2)  THE SEMANTICS of that data (vertex format)

  // So you can see, it's all very intermingled and messy.
  // TO draw vertex data with GLSL, you have to:
  //   1) Load the raw vertex data into a vertex buffer
  //   2) set up vertex attributes (via glVertexAttribPointer)
  //      WHICH does 2 things:
  //      a)  It tells OpenGL the VERTEX FORMAT (floats? 3 elements? 4 elements? stride?)
  //   3) Call glDrawArrays or glDrawElements( ..., 0 ) 
  // INIT THE VERTEX ARRAY (stuff to draw)
  // The vertex array OBJECT remembers info about
  // indices, and the actual vertex buffer object
  // from which to pull data when rendering.
  glGenVertexArrays( 1, &vao ) ;
  glBindVertexArray( vao ) ;

  glBindBuffer( GL_ARRAY_BUFFER, vertexBuffer ) ;
  glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indexBuffer ) ;
  glEnableVertexAttribArray( positionAttribute ) ;
    positionAttribute,  // index. NOTE THIS HAS BEEN CONNECTED UP EARLIER
    // IN THE LINE:
    //   > positionAttribute = glGetAttribLocation( glslProgId, "position" ) ; // C++ code line
    // and "position" is used in the GLSL vertex shader as:
    //   > attribute vec3 position; // GLSL shader line
    // SO. Don't be confused, the `positionAttribute` variable is simply connected up
    // to the vertex shader's INCOMING "position" attribute.  Naked girls.
    3,          // size. 3 floats/vertex
    GL_FLOAT,   // type. floats!
    0,          // normalized? No.
    sizeof(VertexPC),          // stride
    0           // pointer.  0 says to use the CURRENTLY BOUND
    // If you want to draw from CLIENT MEMORY you would pass AN ACTUAL ADDRESS
  ) ;

  glEnableVertexAttribArray( colorAttribute ) ;

  int offset = 3*sizeof(float) ;
  glVertexAttribPointer( colorAttribute, 4, GL_FLOAT, 0, sizeof( VertexPC ),
    (void*)offset  // RE: THE LAST PARAMETER: I know it looks ridiculous!! to pass a NUMBER as cast to VOID* here,
    // but that's C api's for you.  "Wait! Shouldn't it be &offset?"
    // NO. Your eyes kid you not.  You take the INTEGER NUMBER (which amounts to 12 here)
    // AND JUST PASS THAT AS IF IT WERE A "VOID*" POINTER. Even though you and I know it is not.
  ) ;


void keyboard(unsigned char key, int x, int y)
    case 27: //esc
      glDeleteVertexArrays( 1,&vao ) ;
      glDeleteProgram( glslProgId );
      glDeleteShader( vshId );
      glDeleteShader( pshId );
      break ;

void resizeWindow(int width, int height)

void draw()
  glViewport( 0, 0, w, h ) ;
  glClearColor( 0.1f, 0.1f, 0.1f, 0.1f ) ;

  // Bind the shader I created earlier
  glUseProgram( glslProgId );
  // Update the uniform variable.  YOU CAN
  // IE glUniformMatrix4fv must be called AFTER glUseProgram
  float m[16] = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 } ;
  glUniformMatrix4fv(uniformModelViewMatrix, 1, false, m);

  // Here we bind the vertex array "object".  This is EQUIVALENT
  // to "replaying" 
  glBindVertexArray( vao );

  // Now we could draw in one of 2 ways:

  //glDrawArrays( GL_TRIANGLES, 0, 3 ) ; // draw as vertex buffer (with no index buffer)

    3, //# INDICES in the index buffer
    GL_UNSIGNED_INT, // I used 4-byte ints. Some other people use shorts, but I never do.
    0  // 0 means, use the index buffer bound
  ) ;


int main(int argc, char **argv)
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
  glutInitWindowSize( w,h ) ;
  glutCreateWindow("GLSL with GLUT");


  //if( glewIsSupported("GL_VERSION_3_0") )


  setupShaders() ;

  glutMainLoop() ;

  return 0 ; 

If you’re using numerical indexing to access the xyz components of a vector, (with 0=x, 1=y, 2=z) a good tip is to remember that

axis = 0 ; // for example.
otherAxis1 = ( axis + 1 ) % 3 ; // =1
otherAxis2 = ( axis + 2 ) % 3 ; // =2

This works for all values of axis to get you “the other 2” axes

The description on Wikipedia is ok, but here’s more.

Marching cubes is all about filling the space with cubes, and “cutting the cubes” by triangles if the isosurface cuts through the cube.

This talk by Shewchuk is great to help understand what an isosurface is, etc.

Now, there’s all this talk about 256 possible cube configurations. What’s that about.

Well the cube has 8 vertices. Pretend being inside the isosurface means the vertex is “wet”. Assuming the cube could dip in and out of the isosurface on any of those 8 vertices, means there are 2^8=256 possible configurations for the vertices to be “wet” (inside the isosurface).

The case where the cube is “completely dry” is when no vertices are inside the isosurface. If I put one corner in the isosurface, then one vertex is “wet”. But wait! There are 8 ways that “one corner” can be wet, because there are 8 corners on a cube. So each of the 8 corners can be in one of 2 states (“wet” or “dry”), means there are 2^8 possible configurations for the corners to be wet and dry. This actually boils down to just 14 cases if you exploit symmetry (ie consider the case of “one vertex being wet” as one case, not 8 cases).

This is easier to understand if you look at a square.

So there, we have 4 vertices, so 2^4=16 cases. case 0 is “dry”. case 1 has 1 vertex wet, and there are 4 symmetric cases. Case 2 has 2 adjacent corners.. etc. Just look at the diagram.

I can’t count the number of times extremely difficult mathematese was made understandable via a quick diagram.

All academics should take COMIC DRAWING as a course in university. The reason is, to be able to express themselves via diagrams and symbols, actors and examples, rather than just relying on words and the jargon of their field.

Well, a surprising result, never use your extern variables inside a function that runs before main.

Here’s an example:

In the header:

//extern test.  the externs are giving 0's.
struct Vector4f
  float x,y,z,w;
  Vector4f( float ix, float iy, float iz, float iw ) :x(ix),y(iy),z(iz),w(iw){}
} ;

extern Vector4f Red ; // This is the weird variable..

In the main.cpp file:

static map<char, Vector4f> initMapping()
  map<char, Vector4f> mp ;
  mp.insert( make_pair( 'r', Red ) ) ;
  for( auto &p : mp )
    printf( "%c: %f %f %f %f\n", p.first, p.second.x, p.second.y, p.second.z, p.second.w );
  return mp ;

//Vector4f Red(1,0,0,1) ; // if this is here, Red has (1,0,0,1)
map<char, Vector4f> colorMapping = initMapping() ;
Vector4f Red(1,0,0,1) ; // if Red is only given its value HERE, when the static ctor runs, Red will be (0,0,0,0)

int main(int argc, const char * argv[])
  for( auto &p : colorMapping )
    printf( "%c: %f %f %f %f\n", p.first, p.second.x, p.second.y, p.second.z, p.second.w );

So those 2 declarations of Vector4f Red (without extern qualifier) in the cpp are the issue here. If the compiler runs into the Vector4f Red(1,0,0,1) ; BEFORE running SomeStruct::initMapping(), then the mapping has the correct value for Red in it. If the compiler first runs into Vector4f Red(1,0,0,1) only __after__ running SomeStruct::initMapping(), then the value of Red inside the map would be all 0’s.

I was browsing my spam and I came across this “spammer template”: use it to develop spam protection software!

{I have|I’ve} been {surfing|browsing} online more than {three|3|2|4} hours today, yet I never found any interesting article like yours. {It’s|It
is} pretty worth enough for me. {In my opinion|Personally|In my view}, if all {webmasters|site
owners|website owners|web owners} and bloggers made good content as you did, the
{internet|net|web} will be {much more|a lot more} useful than ever before.
I {couldn’t|could not} {resist|refrain from} commenting. {Very well|Perfectly|Well|Exceptionally well} written!|
{I will|I’ll} {right away|immediately} {take hold of|grab|clutch|grasp|seize|snatch} your {rss|rss feed} as I {can not|can’t} {in finding|find|to find} your {email|e-mail} subscription {link|hyperlink} or {newsletter|e-newsletter} service. Do {you have|you’ve} any?

{Please|Kindly} {allow|permit|let} me {realize|recognize|understand|recognise|know} {so that|in order that} I
{may just|may|could} subscribe. Thanks.|
{It is|It’s} {appropriate|perfect|the best} time to make some plans for the future and {it is|it’s} time to be happy.
{I have|I’ve} read this post and if I could I {want to|wish to|desire to} suggest you {few|some} interesting things or {advice|suggestions|tips}. {Perhaps|Maybe} you {could|can} write next articles referring to this article. I {want to|wish to|desire to} read {more|even more} things about it!|
{It is|It’s} {appropriate|perfect|the best} time to make {a few|some} plans for {the future|the longer term|the long run}
and {it is|it’s} time to be happy. {I have|I’ve} {read|learn} this {post|submit|publish|put up} and if I
{may just|may|could} I {want to|wish to|desire to} {suggest|recommend|counsel} you
{few|some} {interesting|fascinating|attention-grabbing} {things|issues}
or {advice|suggestions|tips}. {Perhaps|Maybe} you {could|can} write {next|subsequent} articles {relating to|referring to|regarding}
this article. I {want to|wish to|desire to} {read|learn} {more|even more} {things|issues} {approximately|about}
{I have|I’ve} been {surfing|browsing} {online|on-line} {more than|greater than} {three|3} hours {these days|nowadays|today|lately|as of late}, {yet|but} I {never|by no means} {found|discovered} any {interesting|fascinating|attention-grabbing} article like yours. {It’s|It is} {lovely|pretty|beautiful}
{worth|value|price} {enough|sufficient} for me.
{In my opinion|Personally|In my view}, if all {webmasters|site owners|website
owners|web owners} and bloggers made {just right|good|excellent} {content|content material} as
{you did|you probably did}, the {internet|net|web} {will be|shall be|might be|will probably be|can be|will
likely be} {much more|a lot more} {useful|helpful} than ever before.
Ahaa, its {nice|pleasant|good|fastidious} {discussion|conversation|dialogue} {regarding|concerning|about|on the topic of} this {article|post|piece of writing|paragraph} {here|at this place} at this {blog|weblog|webpage|website|web
site}, I have read all that, so {now|at this time} me also commenting {here|at this place}.

I am sure this {article|post|piece of writing|paragraph} has touched
all the internet {users|people|viewers|visitors}, its really really
{nice|pleasant|good|fastidious} {article|post|piece
of writing|paragraph} on building up new {blog|weblog|webpage|website|web site}.

Wow, this {article|post|piece of writing|paragraph} is {nice|pleasant|good|fastidious}, my {sister|younger sister} is
analyzing {such|these|these kinds of} things, {so|thus|therefore} I am going to {tell|inform|let know|convey} her.
{Saved as a favorite|bookmarked!!}, {I really like|I like|I love}
{your blog|your site|your web site|your website}!
Way cool! Some {very|extremely} valid points!
I appreciate you {writing this|penning this} {article|post|write-up}
{and the|and also the|plus the} rest of the {site is|website is} {also very|extremely|very|also really|really} good.
Hi, {I do believe|I do think} {this is an excellent|this is a great} {blog|website|web
site|site}. I stumbledupon it ;) {I will|I am going to|I’m going to|I may} {come back|return|revisit} {once again|yet again} {since I|since i have} {bookmarked|book marked|book-marked|saved as a favorite} it. Money and freedom {is the best|is the greatest} way to change, may you be rich and continue to {help|guide} {other people|others}.|
Woah! I’m really {loving|enjoying|digging} the template/theme of this {site|website|blog}.
It’s simple, yet effective. A lot of times it’s {very hard|very difficult|challenging|tough|difficult|hard}
to get that “perfect balance” between {superb usability|user friendliness|usability} and {visual appearance|visual appeal|appearance}.
I must say {that you’ve|you have|you’ve} done a {awesome|amazing|very good|superb|fantastic|excellent|great} job with this.
{In addition|Additionally|Also}, the blog loads {very|extremely|super} {fast|quick}
for me on {Safari|Internet explorer|Chrome|Opera|Firefox}.
{Superb|Exceptional|Outstanding|Excellent} Blog!|
These are {really|actually|in fact|truly|genuinely} {great|enormous|impressive|wonderful|fantastic} ideas in {regarding|concerning|about|on the topic of} blogging.
You have touched some {nice|pleasant|good|fastidious} {points|factors|things} here.
Any way keep up wrinting.|
{I love|I really like|I enjoy|I like|Everyone loves} what you guys
{are|are usually|tend to be} up too. {This sort of|This type of|Such|This kind of} clever work
and {exposure|coverage|reporting}! Keep up the {superb|terrific|very good|great|good|awesome|fantastic|excellent|amazing|wonderful} works guys I’ve {incorporated||added|included} you guys to {|my|our||my personal|my own} blogroll.|
{Howdy|Hi there|Hey there|Hi|Hello|Hey}! Someone in my {Myspace|Facebook} group shared this {site|website} with us so I came to {give it a look|look it over|take a look|check it out}. I’m definitely
{enjoying|loving} the information. I’m {book-marking|bookmarking} and will be tweeting this to my followers! {Terrific|Wonderful|Great|Fantastic|Outstanding|Exceptional|Superb|Excellent} blog and {wonderful|terrific|brilliant|amazing|great|excellent|fantastic|outstanding|superb} {style and design|design and style|design}.|
{I love|I really like|I enjoy|I like|Everyone loves} what you guys {are|are usually|tend to be} up too. {This sort of|This type of|Such|This kind of} clever work and {exposure|coverage|reporting}! Keep up the {superb|terrific|very good|great|good|awesome|fantastic|excellent|amazing|wonderful} works guys I’ve {incorporated|added|included} you guys to {|my|our|my
personal|my own} blogroll.|
{Howdy|Hi there|Hey there|Hi|Hello|Hey} would you
mind {stating|sharing} which blog platform you’re {working with|using}? I’m {looking|planning|going}
to start my own blog {in the near future|soon} but
I’m having a {tough|difficult|hard} time {making a decision|selecting|choosing|deciding} between BlogEngine/Wordpress/B2evolution and Drupal. The reason I ask is because your {design and style|design|layout} seems different then most blogs and I’m looking for something {completely unique|unique}.
P.S {My apologies|Apologies|Sorry} for {getting|being} off-topic but I
had to ask!|
{Howdy|Hi there|Hi|Hey there|Hello|Hey} would you mind letting me know which {webhost|hosting company|web host} you’re {utilizing|working with|using}? I’ve
loaded your blog in 3 {completely different|different} {internet browsers|web browsers|browsers} and I must say
this blog loads a lot {quicker|faster} then most. Can you {suggest|recommend} a good {internet
hosting|web hosting|hosting} provider at a {honest|reasonable|fair} price?
{Thanks a lot|Kudos|Cheers|Thank you|Many thanks|Thanks}, I appreciate it!
{I love|I really like|I like|Everyone loves} it {when
people|when individuals|when folks|whenever people} {come together|get together} and share {opinions|thoughts|views|ideas}.

Great {blog|website|site}, {keep it up|continue the good work|stick with it}!
Thank you for the {auspicious|good} writeup. It in fact
was a amusement account it. Look advanced to {far|more} added
agreeable from you! {By the way|However}, how {can|could} we communicate?
{Howdy|Hi there|Hey there|Hello|Hey} just wanted to give you
a quick heads up. The {text|words} in your {content|post|article} seem to be running off the
screen in {Ie|Internet explorer|Chrome|Firefox|Safari|Opera}.
I’m not sure if this is a {format|formatting} issue or something to do with {web browser|internet browser|browser} compatibility but I {thought|figured} I’d post to let you know.
The {style and design|design and style|layout|design} look great though!
Hope you get the {problem|issue} {solved|resolved|fixed} soon.
{Kudos|Cheers|Many thanks|Thanks}|
This is a topic {that is|that’s|which is} {close to|near to} my heart… {Cheers|Many thanks|Best wishes|Take care|Thank you}! {Where|Exactly where} are your contact details though?|
It’s very {easy|simple|trouble-free|straightforward|effortless} to find out any {topic|matter} on {net|web} as compared to {books|textbooks}, as I found this {article|post|piece of writing|paragraph} at this {website|web site|site|web page}.
Does your {site|website|blog} have a contact page?

I’m having {a tough time|problems|trouble} locating it but, I’d like to {send|shoot} you an {e-mail|email}.
I’ve got some {creative ideas|recommendations|suggestions|ideas} for your blog you might be interested in hearing. Either way, great {site|website|blog} and I look forward to seeing it {develop|improve|expand|grow} over time.|
{Hola|Hey there|Hi|Hello|Greetings}! I’ve been {following|reading} your {site|web site|website|weblog|blog} for {a long time|a while|some time}
now and finally got the {bravery|courage} to go ahead and give you a shout out from {New Caney|Kingwood|Huffman|Porter|Houston|Dallas|Austin|Lubbock|Humble|Atascocita} {Tx|Texas}!
Just wanted to {tell you|mention|say} keep up the {fantastic|excellent|great|good} {job|work}!
Greetings from {Idaho|Carolina|Ohio|Colorado|Florida|Los angeles|California}!
I’m {bored to tears|bored to death|bored} at work so I decided to {check out|browse} your {site|website|blog} on my iphone during lunch break. I {enjoy|really like|love} the {knowledge|info|information} you {present|provide} here and can’t wait to take a look when
I get home. I’m {shocked|amazed|surprised} at how {quick|fast} your blog loaded on my {mobile|cell phone|phone} .. I’m not even using WIFI, just
3G .. {Anyhow|Anyways}, {awesome|amazing|very good|superb|good|wonderful|fantastic|excellent|great} {site|blog}!
Its {like you|such as you} {read|learn} my {mind|thoughts}!

You {seem|appear} {to understand|to know|to grasp} {so much|a lot} {approximately|about} this, {like you|such as you}
wrote the {book|e-book|guide|ebook|e book} in it or something.
{I think|I feel|I believe} {that you|that you
simply|that you just} {could|can} do with {some|a few} {%|p.
c.|percent} to {force|pressure|drive|power} the message {house|home} {a
bit|a little bit}, {however|but} {other than|instead of} that, {this
is|that is} {great|wonderful|fantastic|magnificent|excellent} blog.
{A great|An excellent|A fantastic} read. {I’ll|I will} {definitely|certainly} be back.|
I visited {multiple|many|several|various} {websites|sites|web sites|web pages|blogs} {but|except|however} the audio {quality|feature} for audio songs {current|present|existing} at this {website|web site|site|web page} is {really|actually|in fact|truly|genuinely} {marvelous|wonderful|excellent|fabulous|superb}.|
{Howdy|Hi there|Hi|Hello}, i read your blog {occasionally|from time to time} and i own a similar one and i was just {wondering|curious} if you get a lot of spam {comments|responses|feedback|remarks}? If so how do you {prevent|reduce|stop|protect against} it, any plugin or anything you can {advise|suggest|recommend}? I get so much lately it’s driving me {mad|insane|crazy} so any {assistance|help|support} is very much appreciated.
Greetings! {Very helpful|Very useful} advice {within this|in this particular} {article|post}!
{It is the|It’s the} little changes {that make|which will make|that produce|that will make} {the biggest|the largest|the greatest|the most important|the most significant} changes. {Thanks a lot|Thanks|Many thanks} for sharing!|
{I really|I truly|I seriously|I absolutely} love {your blog|your site|your website}.. {Very nice|Excellent|Pleasant|Great} colors & theme. Did you {create|develop|make|build} {this website|this site|this web site|this amazing site} yourself? Please reply back as I’m {looking to|trying
to|planning to|wanting to|hoping to|attempting to} create {my own|my very own|my own personal} {blog|website|site} and {would like to|want
to|would love to} {know|learn|find out} where you got
this from or {what the|exactly what the|just what the} theme {is called|is
named}. {Thanks|Many thanks|Thank you|Cheers|Appreciate
{Hi there|Hello there|Howdy}! This {post|article|blog post} {couldn’t|could not} be written {any better|much better}! {Reading through|Looking at|Going through|Looking through} this {post|article} reminds me of my previous roommate! He {always|constantly|continually} kept {talking about|preaching about} this. {I will|I’ll|I am going to|I most certainly will} {forward|send} {this article|this information|this post} to him.
{Pretty sure|Fairly certain} {he will|he’ll|he’s
going to} {have a good|have a very good|have a great} read.
{Thank you for|Thanks for|Many thanks for|I appreciate you for} sharing!
{Wow|Whoa|Incredible|Amazing}! This blog looks {exactly|just} like my old one!
It’s on a {completely|entirely|totally} different {topic|subject} but it has pretty much the same {layout|page layout} and design. {Excellent|Wonderful|Great|Outstanding|Superb} choice of colors!|
{There is|There’s} {definately|certainly} {a lot to|a great deal to} {know about|learn about|find
out about} this {subject|topic|issue}. {I like|I love|I really like} {all the|all
of the} points {you made|you’ve made|you have made}.|
{You made|You’ve made|You have made} some {decent|good|really
good} points there. I {looked|checked} {on the internet|on
the web|on the net} {for more info|for more information|to find out more|to learn more|for additional information} about the issue
and found {most individuals|most people} will go along with your views on
{this website|this site|this web site}.|
{Hi|Hello|Hi there|What’s up}, I {log on to|check|read} your {new stuff|blogs|blog} {regularly|like every week|daily|on a regular basis}. Your {story-telling|writing|humoristic} style is {awesome|witty}, keep {doing what you’re doing|up
the good work|it up}!|
I {simply|just} {could not|couldn’t} {leave|depart|go away} your {site|web site|website} {prior to|before} suggesting that I {really|extremely|actually} {enjoyed|loved} {the standard|the usual} {information|info} {a person|an individual} {supply|provide} {for your|on your|in your|to your} {visitors|guests}? Is {going to|gonna} be {back|again} {frequently|regularly|incessantly|steadily|ceaselessly|often|continuously} {in order to|to} {check up on|check out|inspect|investigate cross-check} new posts|
{I wanted|I needed|I want to|I need to} to thank you for this {great|excellent|fantastic|wonderful|good|very good} read!! I {definitely|certainly|absolutely} {enjoyed|loved} every {little bit of|bit of} it. {I have|I’ve got|I have got} you {bookmarked|book marked|book-marked|saved as
a favorite} {to check out|to look at} new {stuff you|things you}
{Hi|Hello|Hi there|What’s up}, just wanted to {mention|say|tell you}, I {enjoyed|liked|loved} this {article|post|blog post}. It was {inspiring|funny|practical|helpful}. Keep on posting!|
I {{leave|drop|{write|create}} a {comment|leave a response}|drop a {comment|leave a response}|{comment|leave a response}} {each time|when|whenever} I {appreciate|like|especially enjoy} a {post|article} on a {site|{blog|website}|site|website} or {I have|if I have} something to {add|contribute|valuable to contribute} {to the discussion|to the conversation}. {It is|Usually it is|Usually it’s|It’s} {a result of|triggered by|caused by} the {passion|fire|sincerness} {communicated|displayed} in the {post|article} I {read|looked at|browsed}. And {on|after} this {post|article} Bobobobo’s Weblog | technology and the internets.

I {{was|was actually} moved|{was|was actually} excited} enough to
{drop|{leave|drop|{write|create}}|post} a {thought|{comment|{comment|leave a response}a
response}} {:-P|:)|;)|;-)|:-)} I {do have|actually do have} {{some|a few} questions|a couple of questions|2 questions} for
you {if you {don’t|do not|usually do not|tend not to} mind|if it’s
{allright|okay}}. {Is it|Could it be} {just|only|simply} me or {do|does
it {seem|appear|give the impression|look|look as if|look
like} like} {some|a few} of {the|these} {comments|responses|remarks} {look|appear|come across} {like they are|as if
they are|like} {coming from|written by|left by} brain
dead {people|visitors|folks|individuals}? :-P
And, if you are {posting|writing} {on|at} {other|additional} {sites|social sites|online sites|online
social sites|places}, {I’d|I would} like to {follow|keep up with} {you|{anything|everything} {new|fresh} you have to post}. {Could|Would} you {list|make a list} {all|every one|the complete urls} of {your|all your} {social|communal|community|public|shared} {pages|sites} like your {twitter feed, Facebook page or linkedin profile|linkedin profile, Facebook page or twitter feed|Facebook page, twitter feed, or linkedin profile}?|
{Hi there|Hello}, I enjoy reading {all of|through} your {article|post|article post}. I {like|wanted} to write a little comment to support you.|
I {always|constantly|every time} spent my half an hour to read this {blog|weblog|webpage|website|web site}’s
{articles|posts|articles or reviews|content} {everyday|daily|every day|all the time} along with a {cup|mug} of coffee.
I {always|for all time|all the time|constantly|every time} emailed this {blog|weblog|webpage|website|web site}
post page to all my {friends|associates|contacts}, {because|since|as|for the reason that} if like to read it {then|after that|next|afterward} my {friends|links|contacts} will too.
My {coder|programmer|developer} is trying to {persuade|convince} me to
move to .net from PHP. I have always disliked the idea because of the {expenses|costs}.
But he’s tryiong none the less. I’ve been using {Movable-type|WordPress} on {a number of|a variety of|numerous|several|various} websites for about a year and am {nervous|anxious|worried|concerned} about switching to
another platform. I have heard {fantastic|very good|excellent|great|good} things about blogengine.
net. Is there a way I can {transfer|import} all my wordpress {content|posts}
into it? {Any kind of|Any} help would be {really|greatly} appreciated!
{Hello|Hi|Hello there|Hi there|Howdy|Good day}! I could
have sworn I’ve {been to|visited} {this blog|this web site|this website|this site|your blog} before but after {browsing through|going through|looking at} {some of the|a few of the|many of the} {posts|articles} I realized it’s new to me.
{Anyways|Anyhow|Nonetheless|Regardless}, I’m {definitely|certainly} {happy|pleased|delighted} {I found|I discovered|I came across|I stumbled upon} it and I’ll
be {bookmarking|book-marking} it and checking back {frequently|regularly|often}!
{Terrific|Great|Wonderful} {article|work}! {This is|That is} {the type of|the kind of} {information|info} {that are
meant to|that are supposed to|that should} be shared {around the|across the} {web|internet|net}.
{Disgrace|Shame} on {the {seek|search} engines|Google} for {now not|not|no longer} positioning this {post|submit|publish|put up} {upper|higher}!
Come on over and {talk over with|discuss with|seek advice from|visit|consult with} my {site|web site|website} .
{Thank you|Thanks} =)|
Heya {i’m|i am} for the first time here. I {came across|found} this board and I find It {truly|really} useful & it helped me out {a lot|much}. I hope to give something back and {help|aid} others like you {helped|aided} me.|
{Hi|Hello|Hi there|Hello there|Howdy|Greetings}, {I think|I believe|I do believe|I do think|There’s no
doubt that} {your site|your website|your web site|your
blog} {might be|may be|could be|could possibly be} having {browser|internet browser|web
browser} compatibility {issues|problems}. {When I|Whenever I}
{look at your|take a look at your} {website|web site|site|blog} in
Safari, it looks fine {but when|however when|however, if|however,
when} opening in {Internet Explorer|IE|I.E.}, {it has|it’s got} some overlapping issues. {I just|I simply|I merely} wanted to {give you a|provide you with a} quick heads up! {Other than that|Apart from that|Besides that|Aside from that}, {fantastic|wonderful|great|excellent} {blog|website|site}!|
{A person|Someone|Somebody} {necessarily|essentially} {lend a hand|help|assist} to make {seriously|critically|significantly|severely} {articles|posts} {I would|I might|I’d} state.
{This is|That is} the {first|very first} time I frequented your {web page|website page} and
{to this point|so far|thus far|up to now}? I {amazed|surprised} with the {research|analysis} you made to {create|make} {this
actual|this particular} {post|submit|publish|put up} {incredible|amazing|extraordinary}.
{Great|Wonderful|Fantastic|Magnificent|Excellent} {task|process|activity|job}!
Heya {i’m|i am} for {the primary|the first} time here. I {came across|found} this board and I {in finding|find|to find} It {truly|really} {useful|helpful} & it helped me out {a lot|much}. {I am hoping|I hope|I’m hoping} {to give|to
offer|to provide|to present} {something|one thing} {back|again} and {help|aid} others {like you|such as you} {helped|aided} me.
{Hello|Hi|Hello there|Hi there|Howdy|Good day|Hey there}!
{I just|I simply} {would like to|want to|wish to} {give you a|offer you a} {huge|big} thumbs up {for the|for
your} {great|excellent} {info|information} {you have|you’ve got|you have got} {here|right here} on this post. {I will be|I’ll be|I am} {coming back to|returning to} {your blog|your site|your website|your web site} for more soon.
I {always|all the time|every time} used to {read|study} {article|post|piece of writing|paragraph}
in news papers but now as I am a user of {internet|web|net} {so|thus|therefore} from
now I am using net for {articles|posts|articles or reviews|content}, thanks to web.
Your {way|method|means|mode} of {describing|explaining|telling} {everything|all|the whole
thing} in this {article|post|piece of writing|paragraph} is
{really|actually|in fact|truly|genuinely} {nice|pleasant|good|fastidious}, {all|every
one} {can|be able to|be capable of} {easily|without difficulty|effortlessly|simply}
{understand|know|be aware of} it, Thanks a lot.
{Hi|Hello} there, {I found|I discovered} your {blog|website|web site|site} {by means of|via|by the use of|by way of} Google {at the same time as|whilst|even as|while} {searching for|looking for} a {similar|comparable|related} {topic|matter|subject}, your {site|web site|website} {got here|came} up, it {looks|appears|seems|seems to
be|appears to be like} {good|great}. {I have|I’ve} bookmarked it in my google bookmarks.
{Hello|Hi} there, {simply|just} {turned into|became|was|become|changed into} {aware of|alert to} your {blog|weblog} {thru|through|via} Google, {and found|and located} that {it is|it’s}
{really|truly} informative. {I’m|I am} {gonna|going to} {watch out|be careful} for brussels. {I will|I’ll} {appreciate|be grateful}
{if you|should you|when you|in the event you|in case
you|for those who|if you happen to} {continue|proceed} this {in future}.
{A lot of|Lots of|Many|Numerous} {other folks|folks|other people|people} {will be|shall be|might be|will probably be|can be|will likely
be} benefited {from your|out of your} writing.

{I am|I’m} curious to find out what blog {system|platform} {you have been|you happen to be|you are|you’re} {working with|utilizing|using}?

I’m {experiencing|having} some {minor|small} security {problems|issues} with my latest {site|website|blog} and {I would|I’d} like to find something more {safe|risk-free|safeguarded|secure}.
Do you have any {solutions|suggestions|recommendations}?|
{I am|I’m} {extremely|really} impressed with your writing skills {and also|as well as} with the layout on your {blog|weblog}. Is this a paid theme or did you {customize|modify} it yourself? {Either way|Anyway} keep up the {nice|excellent} quality writing, {it’s|it is} rare
to see a {nice|great} blog like this one {these days|nowadays|today}.
{I am|I’m} {extremely|really} {inspired|impressed} {with your|together with your|along with your} writing {talents|skills|abilities} {and also|as {smartly|well|neatly} as} with the {layout|format|structure} {for your|on your|in your|to your} {blog|weblog}. {Is this|Is that this} a paid {subject|topic|subject matter|theme} or did you {customize|modify} it {yourself|your self}? {Either way|Anyway} {stay|keep} up the {nice|excellent} {quality|high quality} writing, {it’s|it is}
{rare|uncommon} {to peer|to see|to look} a {nice|great} {blog|weblog} like this
one {these days|nowadays|today}..|
{Hi|Hello}, Neat post. {There is|There’s} {a problem|an issue} {with your|together with your|along with your} {site|web site|website} in {internet|web} explorer, {may|might|could|would} {check|test} this? IE {still|nonetheless} is the {marketplace|market} {leader|chief} and {a large|a good|a big|a huge} {part of|section of|component to|portion of|component of|element of} {other folks|folks|other people|people} will {leave out|omit|miss|pass over} your {great|wonderful|fantastic|magnificent|excellent} writing {due to|because of} this problem.|
{I’m|I am} not sure where {you are|you’re} getting your {info|information}, but {good|great} topic. I needs to spend some time learning {more|much more} or understanding more. Thanks for {great|wonderful|fantastic|magnificent|excellent} {information|info} I was looking for this {information|info} for my mission.|
{Hi|Hello}, i think that i saw you visited my {blog|weblog|website|web site|site} {so|thus} i came to “return the favor”.{I am|I’m}
{trying to|attempting to} find things to {improve|enhance} my {website|site|web site}!
I suppose its ok to use {some of|a few of} your ideas!


GKMatch is weird. You don’t ever instantiate GKMatch directly. Instead you use GKMatchMaker as a type of “factory” to instantiate GKMatch objects.

There are basically 2 ways to get a GKMatch up and running.

1) BOOTY CALLS: I call out people I want to have sex with have a match with BY NAME.

2) RANDOM ENCOUNTER: All players initiated THEIR OWN random partner search, and GameCenter “hooked them up” with a random partner.

First we’ll cover booty calls, then random encounters.

1. Booty call

BOOTY CALL works as follows. ONE OF THE PLAYERS (the “horny dude”) INVITES ALL THE OTHER PLAYERS BY NAME. He can invite as many players as he wishes (mm hmm). ALL PLAYERS WHO WANT TO ACCEPT INVITES BY NAME __MUST__ HAVE REGISTERED TO RECEIVE “BOOTY CALLS” BY SETTING [GKMatchmaker sharedMatchmaker].inviteHandler. We’ll call those players “the booty”.

[GKMatchmaker sharedMatchmaker].inviteHandler = ^( GKInvite *acceptedInvite, NSArray *playersToInvite )
  printf( "You got an invitation to join a match started by `%s`\n", [acceptedInvite.inviter UTF8String] );
  [ [GKMatchmaker sharedMatchmaker] matchForInvite:acceptedInvite completionHandler:^( GKMatch *theMatch, NSError *nsError ) {
    if( nsError ) {
      error( nsError, "matchForInvite:acceptedInvite" ) ; // prints the error (using my `error` function)
      return ;

    Game->match = theMatch ; /////////////// YOU MUST DO THIS.
    // ATTACH YOUR GKMatchDelegate.  __YOU MUST DO THIS__
    // otherwise you have no chance in hell of making a GKMatch work.
    // I instantiated myGameMatchDelegate OUTSIDE this function.
    // instantiating it here gives an ARC error. 
    theMatch.delegate = myGameMatchDelegate ; // myGameMatchDelegate implements GKMatchDelegate protocol

    // Now after this, your GKMatchDelegate match:player:didChangeState: event will trigger
    // automatically.  You can continue to do network setup there.  From that point forward
    // the machines are "having sex" (network connected).
 } ] ;
} ;

The “horny dude” who initiates the booty call does so like this:

GKMatchRequest *request = [[GKMatchRequest alloc] init] ; 
request.minPlayers = 2 ; // INCLUDES YOU.  "The minimum number of players must be at least 2."
request.maxPlayers = 2 ;
request.defaultNumberOfPlayers = 2 ;
request.playerAttributes = 0 ; // NO SPECIAL ATTRIBS
request.playerGroup = 0 ;

// Only for when you have another user to play with BYNAME.
request.playersToInvite = [[NSArray alloc] initWithObjects:@"G:1928347891235", nil] ; //G:1928347891235 is
// the ID of the player I want to booty call.

// A block to be called when a response from an invited BY NAME player is returned to your game.
request.inviteeResponseHandler = ^( NSString *playerID, GKInviteeResponse response )
  printf( "\n*** `%s` RESPONDED TO YOUR INVITE WITH `%s`\n", 
  [playerID UTF8String], GKInviteeResponseName[response] ) ;
} ;

request.inviteMessage = @"COME PLAY WITH ME" ; // This appears in a game center notification notice.
// This is like a GKMatch constructor for the caller.
// It usually completes almost IMMEDIATELY.
[ [GKMatchmaker sharedMatchmaker] findMatchForRequest:request
   withCompletionHandler:^( GKMatch *newMatch, NSError *nsError )
    if( nsError ) {
      error( nsError, "[MM findMatchForRequest] failed" ) ;
      return ;
    // This is the chance to finish setting up the GKMatch object.
    newMatch.delegate = myGameDelegate ; // YOU HAVE TO SET THE DELEGATE.
    Game->match = newMatch ; // YOU MUST DO THIS.
] ;

So after the booty call goes out, OTHER PLAYERS RECEIVE THE INVITATIONS AND ACCEPT IT (Note: requires VIA GC OVERLAY).


BOTH PLAYERS ARE LOOKING FOR “RANDOM ENCOUNTERS”. They put on makeup/shave as appropriate. They then EACH INVOKE findMatchForRequest, BUT WITHOUT SPECIFYING OTHER PLAYER NAMES TO HOOK UP WITH. In other words, they’re looking to hook up with just anybody. GAMECENTER WILL “HOOK THEM UP” WITH RANDOM PARTNERS (TO HAVE SEX WITH).

The code that both players call then, to say to GameCenter they are DTF with just about anyone, is very similar to the code used “make a booty call” above. You just don’t fill out the playerIDs field (leave it nil).

GKMatchRequest *request = [[GKMatchRequest alloc] init] ; 
request.minPlayers = 2 ; // INCLUDES YOU.  "The minimum number of players must be at least 2."
request.maxPlayers = 2 ;
request.defaultNumberOfPlayers = 2 ;
request.playerAttributes = 0 ; // NO SPECIAL ATTRIBS
request.playerGroup = 0 ;

request.playersToInvite = nil ; // NIL THAT
// This is like a GKMatch constructor for the caller.
// It completes IMMEDIATELY.
[ [GKMatchmaker sharedMatchmaker] findMatchForRequest:request
   withCompletionHandler:^( GKMatch *newMatch, NSError *nsError )
    if( nsError ) {
      error( nsError, "[MM findMatchForRequest] failed" ) ;
      return ;
    // This is the chance to finish setting up the GKMatch object.
    newMatch.delegate = myGameDelegate ; // YOU HAVE TO SET THE DELEGATE.
    Game->match = newMatch ; // YOU MUST DO THIS.
] ;

I don’t have any real technical reason for hating exceptions. I simply hate exceptions in a stylistic sense.

Exceptions are a retroactive way of handling error conditions. They kind of say “Yeah try this, if that doesn’t work, then do that.”

  to parse the value out of the string
catch( ValueParsingException ex )
  not a valid value..?

Seems like a manager with a bad attitude. Like “Yeah try it, whatever, and if that doesn’t work, then do this other thing”. Sure, technically it’s very clear what the code is doing. But to me, (mostly because I’ve seen too many 200 line try/catch blocks), try/catch will always be a code structure very readily abused.

I generally hate people that say they will do one thing, then partway through they say “No, go back” and start doing something else. But that is exactly the language of a try/catch block.

Exceptions are like walking across the street without looking:

  to cross the street
catch( BusHitException busException )
  go to hospital?

I much prefer a series of rigorous if statements to try/catch blocks where possible. I’d much rather have code like this:

if( the string is valid )
  parse the value out of the string
  not a valid value.

So in other words, look before crossing:

if( there are no cars )
  cross the street

That would be more like a while loop, but you get the idea.

If statements say “I’m watching what is going on, this code knows what its doing.”

Sure, you can achieve the exact same ends with try/catch as with if/else. But try/catch all too often is used as sloppy code. I hate when exceptions are used in the generic “If something goes wrong then just throw that general error “Uh there was an exception” and printstacktrace.”

Have you ever seen one of those 200 line try blocks? Disgusting. People use them because they don’t know/they don’t care what is going wrong.

Try/catch can too easily be abused. That’s why I hate it as a programming construct.

Funky Inheritance

Or functor-based inheritance

Funky inheritance is my name for when you allow attachment of functors to specify behavior instead of always just subclassing.

This came up recently in some UI event handling code that I was writing. Buttons come and go, dialogs appear and get dismissed. Each dialog dismissal button (okButton) needs something specific to happen, but that same functionality is extremely unlikely to be reused in another dialog.

Normally, to write an object type that has customizable behavior (by a subclass), you would write a base class like this:

class Dialog
  virtual void onDismiss() = 0 ;

So, when you subclass Dialog, you override onDismiss to provide custom behavior that occurs when the dialog is dismissed (assume onDismiss would be invoked by a window manager).

class FileOpenDialog : public Dialog
  virtual void onDismiss()
    // stuff to do when the FileOpenDialog is dismissed..

So, that’s the regular (classical) inheritance pattern. Every time you want different functionality onDismiss(), you’d write a new subclass of Dialog. Another way to get custom code to run onDismiss is to allow onDismiss() to accept a functor that can be invoked …

class FileOpenDialog : public Dialog
  virtual void onDismiss( function <void ()> runThisAfter )
    // stuff to do when the FileOpenDialog is dismissed..
    // then..
    runThisAfter() ;


You could write onDismiss as a functor in base class Dialog instead of using classical inheritance here:

class Dialog
  function< void (Dialog* that) > onDismiss ;

Now onDismiss is a functor (that may or may not be set).

So then customized behavior is by instance, not by class. Creating a FileOpenDialog object would then be like:

Dialog fileOpenDialog ;
fileOpenDialog.onDismiss = [](Dialog* that) {
  // Do something with `that`, which acts as `this`
  // if this were a member function ;)
} ;

When the window object handler finds out a dialog has been dismissed, it invokes the onDismiss handler if it has been set.

// It is detected that fileOpenDialog needs to be closed:
if( fileOpenDialog.onDismiss )
  fileOpenDialog.onDismiss( fileOpenDialog ) ;

// Above line manually passes `this`.
// If I am not mistaken, this is considered "Pythonic" (just kidding,
// but Python does require passing of self in a similarly visible fashion)

This may come across to you as very JavaScripty- or follow a prototypal inheritance pattern. But it actually isn’t prototypal inheritance, because objects do not inherit from other objects. Each instance of Dialog has its own behavior, that is not repeated by any other instance of Dialog.

Of course, this would need some more detail and fleshing out to really work. But this is the jist of funky inheritance. Regular inheritance is class-wide customization. Funky inheritance is instance-wide customization. Funky inheritance is great for when you need to define custom behavior (often one-off, for a button or a widget) without having to define an entire subclass.

Drawbacks of Funky Inheritance

Functors are unable to persist their own internal running state except as static variables. However statics inside a functor are inaccessible from outside the functor. This means modification of a functor’s internal values is difficult/impossible from outside the functor. So, that kind of sucks sometimes.

One way you can modify a functor’s internal state variables is to capture a pointer before entering the functor:

Object * someObject = new Object() ;
functor = [ someObject ]() {
  // now if someObject is modified outside the functor,
  // I will use "the most up to date" version of someObject.
} ;

Functors seem to be best used to send global state messages or somehow modify global state. For example, if a FileOpenDialog is modal, it may flip off the `modal` flag inside your window manager when it is dismissed. Functors are also useful to modify the object running the functor’s state as well.

GameCenter isn’t easy to work with. For one it’s networking, and networking errors are hard to debug because there’s no natural UI. debug print messages is all you’ve got. It doesn’t help that GC is none too detailed on what you did wrong, and sometimes weird errors can occur if you use the API incorrectly.

1. A match request by name can take up to 2 minutes to reach the remote device. Unprepared for this I’d just sit there trying the request again and again, wondering why it wasn’t working.

2. The iOS simulator doesn’t seem to work for GKMatchmaker requests. I don’t know why this is, but the iOS simulator cannot even startBrowsingForNearbyPlayersWithReachableHandler.


I created an xml file with my newest XCode C++ theme.

It looks like this:

So, gray background, white text, all numeric constants and defines are kinda blue, classes are purple, and C preprocessor macros are red.

The factory pattern is most useful when an object type cannot and should not be used independently of some master managing class.

An analogy would be if you have a Theater as the "Master class" (factory) and the objects that are created in the factory are Tickets. So you have to ask the Master Theater class for a new Ticket() whenever you want one. The Master class can now remember that it has sold you a Ticket and that there is one additional Ticket in the system. Tickets aren’t useful at all if the ticket issuer disappeared. Notice this is much better than having a system where Tickets are created with no reference to a Theater, but then are registered to a theater after creation. That would be like "counterfeit your ticket, then call us and tell us you have a ticket to our Theater".

And so the factory pattern makes perfect sense here.

Objects make the most sense in the context of encapsulating code that:

  • Has some mandatory startup that must run (constructors), otherwise the related functions won’t work
  • Has a family of related functions, but not all of them should be called by the class user (private)
  • Has some cleanup routines that should be called when the user is done (destructor)

An example of this is my SecKeyHelper.h file I wrote today. That file is just C functions, but there is some code that must be called before any of the related functions work. On top of that, only 2 functions should really be called by the class user.

Public key loading, private key loading, it’s all very easy with OpenSSL on Linux. You must link the libcrypto.dylib library in XCode for this to work.

XCode 4.6 project download here

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <openssl/rsa.h>
#include <openssl/engine.h>
#include <openssl/pem.h>
// I'm not using BIO for base64 encoding/decoding.  It is difficult to use.
// Using superwills' Nibble And A Half instead 
#include "base64.h"
// The PADDING parameter means RSA will pad your data for you
// if it is not exactly the right size
RSA* loadPUBLICKeyFromString( const char* publicKeyStr )
  // A BIO is an I/O abstraction (Byte I/O?)
  // BIO_new_mem_buf: Create a read-only bio buf with data
  // in string passed. -1 means string is null terminated,
  // so BIO_new_mem_buf can find the dataLen itself.
  // Since BIO_new_mem_buf will be READ ONLY, it's fine that publicKeyStr is const.
  BIO* bio = BIO_new_mem_buf( (void*)publicKeyStr, -1 ) ; // -1: assume string is null terminated
  BIO_set_flags( bio, BIO_FLAGS_BASE64_NO_NL ) ; // NO NL
  // Load the RSA key from the BIO
  RSA* rsaPubKey = PEM_read_bio_RSA_PUBKEY( bio, NULL, NULL, NULL ) ;
  if( !rsaPubKey )
    printf( "ERROR: Could not load PUBLIC KEY!  PEM_read_bio_RSA_PUBKEY FAILED: %s\n", ERR_error_string( ERR_get_error(), NULL ) ) ;
  BIO_free( bio ) ;
  return rsaPubKey ;
RSA* loadPRIVATEKeyFromString( const char* privateKeyStr )
  BIO *bio = BIO_new_mem_buf( (void*)privateKeyStr, -1 );
  //BIO_set_flags( bio, BIO_FLAGS_BASE64_NO_NL ) ; // NO NL
  RSA* rsaPrivKey = PEM_read_bio_RSAPrivateKey( bio, NULL, NULL, NULL ) ;
  if ( !rsaPrivKey )
    printf("ERROR: Could not load PRIVATE KEY!  PEM_read_bio_RSAPrivateKey FAILED: %s\n", ERR_error_string(ERR_get_error(), NULL));
  BIO_free( bio ) ;
  return rsaPrivKey ;
unsigned char* rsaEncrypt( RSA *pubKey, const unsigned char* str, int dataSize, int *resultLen )
  int rsaLen = RSA_size( pubKey ) ;
  unsigned char* ed = (unsigned char*)malloc( rsaLen ) ;
  // RSA_public_encrypt() returns the size of the encrypted data
  // (i.e., RSA_size(rsa)). RSA_private_decrypt() 
  // returns the size of the recovered plaintext.
  *resultLen = RSA_public_encrypt( dataSize, (const unsigned char*)str, ed, pubKey, PADDING ) ; 
  if( *resultLen == -1 )
    printf("ERROR: RSA_public_encrypt: %s\n", ERR_error_string(ERR_get_error(), NULL));
  return ed ;
unsigned char* rsaDecrypt( RSA *privKey, const unsigned char* encryptedData, int *resultLen )
  int rsaLen = RSA_size( privKey ) ; // That's how many bytes the decrypted data would be
  unsigned char *decryptedBin = (unsigned char*)malloc( rsaLen ) ;
  *resultLen = RSA_private_decrypt( RSA_size(privKey), encryptedData, decryptedBin, privKey, PADDING ) ;
  if( *resultLen == -1 )
    printf( "ERROR: RSA_private_decrypt: %s\n", ERR_error_string(ERR_get_error(), NULL) ) ;
  return decryptedBin ;
unsigned char* makeAlphaString( int dataSize )
  unsigned char* s = (unsigned char*) malloc( dataSize ) ;
  int i;
  for( i = 0 ; i < dataSize ; i++ )
    s[i] = 65 + i ;
  s[i-1]=0;//NULL TERMINATOR ;)
  return s ;
// You may need to encrypt several blocks of binary data (each has a maximum size
// limited by pubKey).  You shoudn't try to encrypt more than
// RSA_LEN( pubKey ) bytes into some packet.
// returns base64( rsa encrypt( <<binary data>> ) )
// base64OfRsaEncrypted()
// base64StringOfRSAEncrypted
// rsaEncryptThenBase64
char* rsaEncryptThenBase64( RSA *pubKey, unsigned char* binaryData, int binaryDataLen, int *outLen )
  int encryptedDataLen ;
  // RSA encryption with public key
  unsigned char* encrypted = rsaEncrypt( pubKey, binaryData, binaryDataLen, &encryptedDataLen ) ;
  // To base 64
  int asciiBase64EncLen ;
  char* asciiBase64Enc = base64( encrypted, encryptedDataLen, &asciiBase64EncLen ) ;
  // Destroy the encrypted data (we are using the base64 version of it)
  free( encrypted ) ;
  // Return the base64 version of the encrypted data
  return asciiBase64Enc ;
// rsaDecryptOfUnbase64()
// rsaDecryptBase64String()
// unbase64ThenRSADecrypt()
// rsaDecryptThisBase64()
unsigned char* rsaDecryptThisBase64( RSA *privKey, char* base64String, int *outLen )
  int encBinLen ;
  unsigned char* encBin = unbase64( base64String, (int)strlen( base64String ), &encBinLen ) ;
  // rsaDecrypt assumes length of encBin based on privKey
  unsigned char *decryptedBin = rsaDecrypt( privKey, encBin, outLen ) ;
  free( encBin ) ;
  return decryptedBin ;
int main( int argc, const char* argv[] )
  puts( "We are going to: rsa_decrypt( unbase64( base64( rsa_encrypt( <<binary data>> ) ) ) )" );
  // public key
  //1. The file must contain:
  //on a separate line (i.e. it must be terminated with a newline).
  //2. Each line of "gibberish" must be 64 characters wide.
  //3. The file must end with:
  //-----END CERTIFICATE-----
  // YOUR PUBLIC KEY MUST CONTAIN NEWLINES.  If it doesn't (ie if you generated it with
  // something like
  // ssh-keygen -t rsa -C ""
  // ) THEN YOU MUST INSERT NEWLINES EVERY 64 CHRS (just line it up with how I have it here
  // or with how the ssh-keygen private key is formatted by default)
  const char *b64_pKey = "-----BEGIN PUBLIC KEY-----\n"
  "-----END PUBLIC KEY-----\n";
  // private key
  const char *b64priv_key = "-----BEGIN RSA PRIVATE KEY-----\n"
  "-----END RSA PRIVATE KEY-----\n";
  // String to encrypt, INCLUDING NULL TERMINATOR:
  int dataSize=37 ; // 128 for NO PADDING, __ANY SIZE UNDER 128 B__ for RSA_PKCS1_PADDING
  unsigned char *str = makeAlphaString( dataSize ) ;
  printf( "\nThe original data is:\n%s\n\n", (char*)str ) ;
  RSA *pubKey = loadPUBLICKeyFromString( b64_pKey ) ;
  int asciiB64ELen ;
  char* asciiB64E = rsaEncryptThenBase64( pubKey, str, dataSize, &asciiB64ELen ) ;
  RSA_free( pubKey ) ; // free the public key when you are done all your encryption
  printf( "Sending base64_encoded ( rsa_encrypted ( <<binary data>> ) ):\n%s\n", asciiB64E ) ;
  puts( "<<----------------  SENDING DATA ACROSS INTERWEBS  ---------------->>" ) ;
  char* rxOverHTTP = asciiB64E ; // Simulate Internet connection by a pointer reference
  printf( "\nRECEIVED some base64 string:\n%s\n", rxOverHTTP ) ;
  puts( "\n * * * What could it be?" ) ;
  // Now decrypt this very string with the private key
  RSA *privKey = loadPRIVATEKeyFromString( b64priv_key ) ;
  // Now we got the data at the server.  Time to decrypt it.
  int rBinLen ;
  unsigned char* rBin = rsaDecryptThisBase64( privKey, rxOverHTTP, &rBinLen ) ;
  printf("Decrypted %d bytes, the recovered data is:\n%.*s\n\n", rBinLen, rBinLen, rBin ) ; // rBin is not necessarily NULL
  // terminated, so we only print rBinLen chrs
  RSA_free(privKey) ;
  bool allEq = true ;
  for( int i = 0 ; i < dataSize ; i++ )
    allEq &= (str[i] == rBin[i]) ;
  if( allEq ) puts( "DATA TRANSFERRED INTACT!" ) ;
  else puts( "ERROR, recovered binary does not match sent binary" ) ;
  free( str ) ; 
  free( asciiB64E ) ; // rxOverHTTP  
  free( rBin ) ;

Rae Johnston posts about an experience in a Starbucks’ involving a Bioshock Infinite t-shirt.

I am not sticking up for that guy. He sounds like a loser. But I want to explain what I think is behind that behavior.

First of all reading her top tweets you can see she gets a lot of flack for being a girl gamer. That brings us to the first point:

Any guys that give girl gamers flack for being a girl are sexist guys period. They’re losers. The girl is on “their turf” so they subject her to bad treatment. Only losers do that and there’s no excuse for it.

Second is the encounter with that guy that got almost 10k retweets. The thing there is, there is already a bunch of internet memes about gamer girls who pretend to like games, only to get guys’ attention.

Also you have to keep in mind the shock value of hot girl gamers. Although this might not be true nerdy guys immediately think they have a shot at the nerdy hot girl. Because! Finally! A hot chick who digs the things I do. We’re on the same page! Blah blah blah.

He did a stupid thing calling you out rudely for the shirt. He was a moron. But these are just thoughts on what is going through nerds’ heads.

I can never find this when I’m looking for it, so I dedicated a whole blog post to it.


The easiest way I’ve found to generate a random alphanumeric string involves RAND(), SHA(), and TO_BASE64()

select LEFT( TO_BASE64( SHA(rand()) ), 6 ) ;

You need MySQL 5.6 to execute.

Alternatively some MYSQL Procedures magic


drop function if exists randChr //
create function randChr()
returns char
  IF RAND() <= 0.5 THEN -- Lowercase
	return CHAR( 97 + 25*rand() ) ;
  ELSE -- uc
    return CHAR( 65 + 25*rand() ) ;
END //

drop function if exists randString //
create function randString( len int )
returns varchar(255)
  SET @n = 0;
  SET @res = '' ;
    SET @res = concat( @res, randChr() ) ;
    set @n = @n + 1 ;
  UNTIL @n >= len END REPEAT;
  return @res ;
END //


select randString( 5 );

Starting from my previous program (Windows), connecting in Mac OS X is even EASIER, only there are a couple’a gotchas.

To code with MYSQL in Mac OS X, just install MySQL normally. In fact it comes with the `/include` and `/lib` folders when you installed it. They are in `/usr/local/mysql` (which is a link to the specific version you have).

Ok, now that’s done, here’s your C++ program:

#include <stdio.h>
#include <stdlib.h>
#include "/usr/local/mysql/include/mysql.h"

MYSQL mysql;    // MYSQL global
MYSQL * conn ;  // represents connection to database

int main()
  mysql_init( &mysql ) ;
  conn = mysql_real_connect(  &mysql,
                              "localhost",// synonymous with
                              "root",     // connect as user="root".  Uh, bad security here..
                              "",         // my root password is blank.  REALLY bad security :)
                              "mysql",    // connect to the 'mysql' _database_ within MySQL itself.
                               0, 0, 0 ) ;
  // Check if connection succeeded.
  if( !conn )
    printf( "Couldn't connect to MySQL database server!\n" ) ;
    printf( "Error: %s\n", mysql_error( &mysql ) ) ;
    return 1 ;
  //else  puts( "Connect success" ) ;
  // Here, we are connected.
  // form a sql string to execute.
  if( mysql_query( conn, "select * from user" ) )
    printf("Whoops!  The query failed.  Error:  %s\n", mysql_error( conn ) );
    return 1 ;

  // here, query succeeded, so we can proceed to pull out results.
  MYSQL_RES * resultset ;
  MYSQL_ROW row;  // MYSQL_ROW is #defined as (char **)
  // Data ALWAYS comes back from MySQL as
  // an array of strings.  To convert it
  // to ints or whatever is YOUR JOB as the programmer.

  // mysql_store_result basically fetches
  // the entire array of results and dumps them
  // into our local program memory space (all
  // in the resultset variable.
  resultset = mysql_store_result( conn );

  // How many rows will there be?
  my_ulonglong numRows = mysql_num_rows( resultset ) ;
  printf( "There are %llu ROWS (records) of data\n", numRows ) ;
  // Now tell me what columns there are
  // in the result set.
  int numFields = mysql_num_fields( resultset ) ;
  printf( "There are %d FIELDS (columns) of data\n", numFields ) ;

  // Print all those column by name
  MYSQL_FIELD * fields = mysql_fetch_fields( resultset ) ;
  for( int i = 0 ; i < numFields ; i++ )
    printf( "%25s", fields[i].name ) ;

  printf( "\n" ) ;
  // print all results
  while( (row = mysql_fetch_row( resultset )) )
    // row is 2d array of char
    // underlying type is char **
    for ( int i = 0; i < numFields ; i++ )
      printf( "%5s", row[ i ] ) ;
    puts( "" ) ;    // next row
  mysql_free_result( resultset );  // Now free the result
  mysql_close( conn ) ;  // And close down.
  return 0;

GOTCHA #1: An easy one, but you need to link up your TARGET with the libmysqlclient.a library file. So goto your TARGETS / BUILD PHASES tab, under “Link Binary With Libraries” go select “libmysqlclient.a” from /usr/local/mysql/lib.
GOTCHA #2: This is the stupid one, COPY /usr/local/mysql/lib/libmysqlclient.18.dylib to /usr/lib/. ISN’T THAT DUMB??? Well it’s the eq of copying a DLL to C:\Windows\System32 on Windows. Just something you have to do.

If you don’t copy the .dylib you’ll get Library not loaded: libmysqlclient.16.dylib reason: image not found.

The easiest.

1. Mac OS X

sudo apachectl start

Make sure cgi is enabled in your Apache settings

sudo vi /etc/apache2/httpd.conf

Create and build the following:

#include <stdio.h>

int main(int argc, const char * argv[])
  //puts( "HTTP/1.1 200 OK" ) ;
  puts( "Content-Type: text/plain; charset=UTF-8" ) ;
  puts( "Status: 200 OK" ) ;
  puts( "" ) ;
  puts( "HELLO INTERNET" ) ;

The default folder Xcode 4.6 dumps the exec in is


Take the exec (called PROJECTNAME) and drop it into:


hit http://localhost/cgi-bin/YOUREXECNAME

It should say HELLO INTERNET.

You are on your way to C++ internet freedom

I simulated some game results. In the sim, Player 2 was so bad, he was 0 for 680. The ranking algorithm ranked him first though, because he sucked so bad, he kept on losing increasingly large quantities of negative points for each match he lost.

It is possible! This table shows it as a sort of nested table.

All you have to do to achieve glow in pixelmator:

1) Take an image

2) Duplicate the layer (Make sure View/Show Layers is on, then Right click/Duplicate)

3) View / Show Effects must be on. From the little Effects window, choose Gaussian Blur. Make it something like 10-15px of blur radius. Your duplicate layer should look like that:

4) Under Blending in your Layers dialog select LINEAR DODGE, then drag the opacity to get your desired level of glow. Make sure the blurred texture appears ON TOP of the original.

5) The result should look something like that

You could compute them using factorials, but this is far more efficient.

// Computes n CHOOSE k
// ( n )
// ( k )
int binomial( int n, int k )
  // must accumulate nums/dens separately
  // to avoid roundoff error
  int nums = 1;
  int dens = 1;
  for( int i = 1 ; i <= k ; i++ )
    nums *= ( n - k + i ) ;
    dens *= i ;
  return nums/dens ;

int p=7;
for( int i = 0  ; i <= p ; i++ )
  printf( "%dx^%d +", binomial(p, i), p-i ) ;

Delegate: A person sent or authorized to represent others

First, DELEGATE is problematic. It’s not a common word, and most people don’t know what it means, and beyond that it’s NOT CLEAR what it means in a software context. It’s a bad metaphor.

The use of the word DELEGATE is different than in C#. A delegate in C# is just a function pointer. A DELEGATE in Objective-C is an OBJECT that implements a bunch of functions (very similar to overriding methods in inheritance), BUT THESE FUNCTIONS AREN’T OVERRIDING FUNCTIONS IN A BASE CLASS. Instead, they are implementing A “PROTOCOL” (not a C++ programming concept, its an objective-c concept). OC PROTOCOLS are like C++ INTERFACES (abstract base classes), only weirder. Delegate classes contain just a bunch of stubs of functionality that would get called by the default Apple UIApplication object, if that object respondsToSelector, for example.

Some Foundation Framework classes are like big assholes, like UIApplication for example. They go about their business in a VERY routine way, and WHEN THEY FEEL LIKE IT, they “delegate” little tasks out to YOUR DELEGATE OBJECT. When you program with Foundation classes, you provide that itty-bitty, gopher-boy, go-do-what-I-said, shoe-shine, lackey-boy, I-have-no-money-please-help-me-sir object (called a DELEGATE). The big king UIApplication Foundation class WILL CALL YOUR DELEGATE WHEN THE TIME COMES.

So your little shitty delegate just implements willDoStep3 here, and arguments may be passed by Framework object. UIApplication has a bunch of points at which it “needs” a delegate to call: applicationDidFinishLaunching, applicationWillResignActive, etc.

So app delegation is like fake inheritance. In normal inheritance, you would OVERRIDE applicationDidFinishLaunching, and provide your own method stub. In Objective C, you “provide a delegate object that implements a protocol”. It is conceptually almost the same thing.

I don’t understand why Apple decided to invent this new language and concepts of protocols and delegates, when C++’s concepts of interfaces and inheritance do just fine.

As an example of implementing a delegate protocol, let’s implement GKMatchDelegate. All the information you need is in the documentation there.

// SFMatchDelegate : inherits from NSObject< Implements GKMatchDelegate protocol >
@interface SFMatchDelegate : NSObject< GKMatchDelegate >

// any @property here


// Usually in another file:
@implementation SFMatchDelegate

//any @synthesize statements

// "override"/implement protocol "Tasks"

//Receiving Data from Other Players
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID

//Receiving State Notifications About Other Players
- (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state

//Handling Errors
- (void)match:(GKMatch *)match didFailWithError:(NSError *)error

//Reinviting a Player
- (BOOL)match:(GKMatch *)match shouldReinvitePlayer:(NSString *)playerID
  return YES ;


They play a game of odds.  “If we sell lots of shitty product at a cheap price, with 1/5 dead, then we make money b/c 1/5 will buy the dead product and customers won’t want to pay $15 to return a $20 item.”



Here is my ray sphere intersection code. Pay special attention to the __6__ possible results for the ray’s situation wrt the sphere.

bool Sphere::intersectExact( const Ray& ray, Intersection* intn )
  // an important override

  //If E is the starting point of the ray,
  //.. and L is the end point of the ray,
  //.. and C is the center of sphere you're testing against
  //.. and r is the radius of that sphere

  // Compute:
  //    d = L - E ; // Direction vector of ray, from start to end
  //    f = E - C ; // Vector from center sphere to ray start
  const Vector &d = ray.direction ;
  Vector f = ray.startPos - this->pos ;

  real a = d • d ;  // a is nonnegative, this is actually always 1.0
  real b = 2*(f • d) ;
  real c = f • f - radius*radius ;

  real discriminant = b*b-4*a*c;
  if( discriminant < 0 )
    return false ;  // no intersections.
    // the geometric meaning of this is
    // the ray totally misses the sphere.
    // ray didn't totally miss sphere,
    // so there is a solution to
    // the equation.

    discriminant = sqrt( discriminant );
    // just t1 here implies t1 VALID (ie 0 ≤ t1 ≤ len)
    // 3x HIT cases:
    //       -o->       --|-->  |            |  --|->
    // Impale(t1,t2), Poke(t1,t2>len), ExitWound(t1<0, t2), 
    // 3x MISS cases:
    //       ->  o                     o ->              
    // FallShort (t1>len,t2>len), Past (t1<0,t2<0)
    // | -> |
    // CompletelyInside(t1<0, t2>len)

    // You might consider CompletelyInside a HIT, but I consider it a miss here.
    // t1 is always the smaller value, because BOTH discriminant and
    // a are nonnegative.
    real t1 = (-b - discriminant)/(2*a);
    real t2 = (-b + discriminant)/(2*a);

    // Just purely sphere info
    if( BetweenIn(t1,0,ray.length) )
      // t1 is the intersection, and its closer
      // Impale, Poke
      Vector p = t1 ) ;
      if( intn )  *intn = Intersection( p, getNormalAt( p ), this ) ;
      return true ;

    // here t1 didn't intersect so we are either started
    // inside the sphere or too 
    if( BetweenIn( t2,0,ray.length ) )
      // ExitWound
      Vector p = t2 ) ;

      // We invert the normal because you are inside the sphere.
      if( intn )  *intn = Intersection( p, -getNormalAt( p ), this ) ;
      return true ;

    return false ; // no intn: FallShort, Past, CompletelyInside

There is this misleading marketing tactic used by coffee vendors, to sell you _dark_ roasted coffee as “stronger” coffee. Dark coffee is often labelled “robust”. The truth about “dark coffee”, which I’ll admit I didn’t know before:

1) DARK is a reference to HOW COOKED it is. Very dark coffee is very, very burnt.

(image from here)

2) There are tons of varieties of beans, but you can make dark and light coffee from the same original bag of beans. “Dark” coffee does not come from a “darker bean”. (In fact original coffee beans are always green).
3) You need higher quality beans to make and sell a light roast.

Companies like kicking horse coffee, seem to market dark roast as “more hardcore”. “454 horse power”, “Grizzly Claw”, “Hoodoo Jo”, and yes, even “KICK ASS!”, are all dark roasted coffees sold by them. More apt names would be names like “Volcanic”, “Pumice”, “Supernova”, and “Total Destruction”.

In fact, dark roasting burns away some of the caffeine (so there’s less caffeine in dark roasts, NOT more as “KICK ASS!” or “454 horse power” might have you think at first).

So the point is, there’s this misleading notion everywhere (with respect it’s not all coffee vendor’s faults.. but most people just don’t know)

Yes, in my opinion, dark roasting all but destroys the bean. I have started to believe coffee companies just want to sell more bean by selling off the crappy dark roast. Also DARK ROAST MAKES ME TIRED. I drink a lot of coffee and if I have 2 cups of dark roast, I won’t have nearly the same energy I will have if I drink 2 same “strength” cups of light roast.

So you wanna MEL script, do you?

But you don’t want to learn MEL scripting? And you don’t want to read about it??

Fortunately, MAYA is very cleverly built. It turns out that EVERY UI action you do with the mouse, turns into a MEL script command, which MAYA then executes.

So here’s how you can generate your own MEL script for your own tedious task.

1) Open the script editor

Now try something. Select an object with your mouse. You should see pop into that “script editing” dialog a line like:

select -r pSolid1 ;

That, sir, is the MEL script command to “select” an object. Namely, the object that you just clicked on with your mouse.

So, carefully click through ALL the actions that you need to do your tedious task. Copy and paste each MEL script action into your own MEL script.

You may need to tweak it a bit to get it to work in the end, but it is a quick and easy way to LEARN MEL scripting, as well as generate the correct MEL script for the task you want.

The basic steps are:

1) set up your model and textures / scene for baking
2) right click the object to bake, choose baking/assign new bake set…
3) set up the parameters for baking as you like. to re-edit them, right click the object, then select baking/edit attributes/texture…

Baking a texture out WITH alpha is hard. Even though maya lets you select HDR, TIF, and TGA as bake texture formats.. when you go to open the texture in photoshop, the alpha channel is black, not 0 alpha. Even though your resultant texture will have an alpha.. I think there is a flaw in the maya export process. Anyway, so to KEEP the alpha, you go RENDERING (menu) / Lighting/Shading / Batch Bake (mental ray).

The file will be output in whatever format you chose in the Baking Set options in C:\Users\YOURUSERNAME\Documents\maya\projects\default\renderData\mentalray\lightMap, but THAT file will have 0 alpha pixels as BLACK, not 0 alpha. So ignore that file, it is useless. Go to Hypershade/Textures tab, and find the texture starting with baked_.. That is your baked texture. RIGHT CLICK IT AND SELECT TEST TEXTURE. SAVE THAT as PNG.

And that is the only way I found to save the alpha channel in a Maya baked texture.

Just a link to this, probably the best one I’ve seen

This is a makeString() function that works like printf(). Gives you a std::string from a printf()’d one, so you can stop using sprintf() all the time and NEVER use ostringstream!

string makeString( const char *fmt, ... )
  va_list args ;
  va_start( args, fmt ) ;
  char msgBuffer[ 4096 ] ; // max len.  Can also use a strlen call to avoid over alloc
  vsprintf( msgBuffer, fmt, args ) ;
  return string( msgBuffer ) ;

I want to believe iteration style doesn’t make a difference as much as the next guy, but the fact is, it does.

In order, performance goes

For std::vector:
integer indexing FASTER THAN range based for FASTER THAN traditional iterators

For std::list:
range based for FASTER THAN traditional iterators

You can quote me on that. A test below proves it with a simple example.

#include <stdio.h>
#include <vector>
#include <list>
using namespace std ;

/////#include "Timer.h" // TIMER.h pasted below
#include <sys/time.h>

struct Timer
  timeval start ;
  Timer() { reset(); }
  void reset() {
    gettimeofday( &start, NULL ) ;
  double getTime() const {
    timeval end ;
    gettimeofday( &end, NULL ) ;
    return end.tv_sec - start.tv_sec + (end.tv_usec - start.tv_usec)/1e6 ;
} ;

struct O{
  int a ;
  float b;
  O( int ia, float ib ):a(ia),b(ib){}
  void print()
    printf( "%d %f\n", a,b ) ;
  void doIt()
} ;

int TESTS = 10000000 ;

int main(int argc, const char * argv[])
  vector os ;
  os.push_back( O(2, 2.2 ) ) ;
  os.push_back( O(3, 3.3 ) ) ;
  os.push_back( O(4, 4.4 ) ) ;
  Timer t ;
  t.reset() ;
  for( int i = 0 ; i < TESTS ; i++ )
    for( vector::iterator iter = os.begin() ; iter != os.end(); ++iter )
  printf( "TRADITIONAL ITERATOR : %f\n", t.getTime() ) ; // 0.755 sec
  t.reset() ;
  for( int i = 0 ; i < TESTS ; i++ )
    for( O& entry : os ) // note: if you pass by value, it's even faster
  printf( "NEWFANGLED RANGE BASED for : style Time %f\n", t.getTime() ) ; // 0.493 sec
  for( int i = 0 ; i < TESTS ; i++ )
    for( int j = 0 ; j < os.size() ; j++ )
  printf( "INTEGER INDEXING Time %f\n", t.getTime() ) ; // 0.243 sec
  return 0;

Edit Mesh / Add Divisions .. will cut a polygonal mesh into uniform squares.

Exponential tessellates by triangular divisions. For example, I’ve tessellated this icosahedral sphere into a round version of the same by going to Edit Mesh / Add Divisions ..

After that, you can triangulate, using Edit Mesh / Add Divisions ..

You can experiment with the settings, but Exponential is the setting you need to add divisions to this type of mesh.

See also Mesh / Smooth.

Here’s a C++ function:

// Little endian (little end/lsb first)
inline UInt32 RGBA( Byte R, Byte G, Byte B, Byte A )
  return A<<(3*8) + B<<(2*8) + G<<(8) + R ; //LE
  //return R<<(3*8) + G<<(2*8) + B<<(8) + A ; //BE

What’s wrong with it?. Why doesn’t it return the correct value? Try and guess! No cheating!

Is it the bitshifting being wrong? No, that’s right

Is it that R, G, B, and A are Byte type, and Byte overflows? Nope, they are automatically promoted to int.

So guess what it is? GUESS!


Bitshift has a precedence lower than +. So the shifting is off (and by WAY too much in most cases!)

// Little endian (little end/lsb first)
inline UInt32 RGBA( Byte R, Byte G, Byte B, Byte A )
  return (A<<(3*8)) + (B<<(2*8)) + (G<<(8)) + R ; //LE // works
  // You could also change to bitwise OR, which has lower prec than +
  return A<<(3*8) | B<<(2*8) | G<<(8) | R ; //LE // works

So you dug out your old webcam. Want to take some pictures of food.

Well guess what. You can’t.

Even if you find the old Dynex CD and install it, Creative Live! center shows you that. (It is plugged in, BTW).

Just buy a new camera. 1.3MP wasn’t that good anyway.

What a stupid dialog.

View / pixel aspect ratio correction should be __unchecked__

You can, but it doesn’t work exactly as you’d expect.

To make the “rotate axis” _keyable_, you do this:

Once it’s keyable, it appears in your channel box

Sure you can now key the rotate axis.. but like I said it doesn’t work as you’d expect. The value I have entered there is 260.. but if you increase it to 300, it automatically changes to -60! How annoying.

there is the hard way, or you can use illustrator format.

Note that if you use too new a version of Illustrator, it doesn’t work. You get:

// Error: Command illustratorCurves failed. Open Script Editor for details.

Just save it as ILLUSTRATOR 3 and it will definitely work. FILE / SAVE AS .. (pick a name), THEN another dialog appears with a dropdown.

In Maya 2009, you can use up to ILLUSTRATOR 8 format, but ILLUSTRATOR 9 doesn’t work (for me anyway).

Well it turns out when you create a Newton field, and try to click the object you want it to affect, then “Fields/Affect selected object(s)” , that didn’t work, for me.

I get:

// Error: Please select the particle objects to be connected for emission or collision, or the particle objects/rigid bodies to be connected to fields.


So I solved this by selecting the fluid first, then creating the force via Fields/Newton.  Delete those other bad forces that don’t want to affect selected.

I had this fun problem this morning.  In the Render View:  Options / Test Resolution / Render Settings (and not that “Camera Panel” poison)

Orange lines in Maya mean you have “soft select” on.

Before this happened, you probably remember clicking on something like this:

To get to that dialog go here

Soft select is like “area of effect” select and manipulation. For example, with the curve I have there, scaling a face affects an _area_ of faces around it:

But you probably just want to turn it off! (Click the checkbox beside “Soft select” off)

So easy!

Just follow the instructions here.

All I did was Create / Polygon Primitives / Platonic Solids,

Then select at the right side in the channel box “Icosahedron”

Then Mesh / Smooth to add more polygons

I had this seemingly inane threading bug:

this was a multithreading bug that appeared when the cubemap object got destroyed (early) by another thread.

by the time this thread entered the if statement, the cubeMap variable was gone (set to 0 by another thread in the same object)

If you have 3 vectors, right, up, and forward, you can write a ROW MAJOR change of basis matrix as follows:

  [       right.x     right.y     right.z   ]
  [          up.x        up.y        up.z   ]
  [    -forward.x  -forward.y  -forward.z   ]

The new basis in terms of the original basis are the ROWS of this change-of-basis matrix.

This matrix takes any vector with (1,0,0), (0,1,0), (0,0,1) as its OLD basis vectors, and rotates it so that its new basis vectors ARE right,up,forward as given.

A viewing matrix is the transpose of the change of basis matrix, because a viewing matrix “pushes the world away” from a stationary camera. (The viewing matrix isn’t going to _move the camera_, instead it moves the whole world so that the portion you want to see sits in the canonical viewing volume).

To make this column major

Just transpose it.

Arbitrary axis angle rotation C++ code, ROW MAJOR

/// Arbitrary axis angle rotation
Matrix Matrix::Rotation( const Vector & u, real radians )
  real c = cos( radians ) ;
  real l_c = 1 - c ;

  real s = sin( radians ) ;
  return Matrix(
    u.x*u.x + (1 - u.x*u.x)*c,      u.x*u.y*l_c + u.z*s,        u.x*u.z*l_c - u.y*s,  0,
          u.x*u.y*l_c - u.z*s,  u.y*u.y+(1 - u.y*u.y)*c,        u.y*u.z*l_c + u.x*s,  0,
          u.x*u.z*l_c + u.y*s,      u.y*u.z*l_c - u.x*s,  u.z*u.z + (1 - u.z*u.z)*c,  0,
                            0,                        0,                          0,  1
  ) ;

Arbitrary axis angle rotation C++ code, __COLUMN__ MAJOR

/// Arbitrary axis angle rotation
Matrix Matrix::Rotation( const Vector & u, real radians )
  real c = cos( radians ) ;
  real l_c = 1 - c ;

  real s = sin( radians ) ;
  return Matrix(
    u.x*u.x + (1 - u.x*u.x)*c,      u.x*u.y*l_c - u.z*s,        u.x*u.z*l_c + u.y*s,  0,
          u.x*u.y*l_c + u.z*s,  u.y*u.y+(1 - u.y*u.y)*c,        u.y*u.z*l_c - u.x*s,  0,
          u.x*u.z*l_c - u.y*s,      u.y*u.z*l_c + u.x*s,  u.z*u.z + (1 - u.z*u.z)*c,  0,
                            0,                        0,                          0,  1
  ) ;

GPU style: do both, then throw away the one you don’t want.

Overarchitecting is overplanning for things you don’t know the system will need or planning for things you don’t understand that you think the system needs.

When will programmers realize that the over-emphasis (Java-style) on the use of classes, with every variable as a class-level variable, is just moar globals!! ?

* A class is just a mini program
* class-members in a large program with many classes are equivalent to globals in a smaller program (with a single class)
* you still have to use locals correctly
* just because it’s a class doesn’t mean overusing class members is ok

Being a programmer today is like being a diamond in a sea of diamonds. There are so many of us out there.
But finding a good programmer is like finding an IF diamond, where most of us are at least SI-2.

Image from here

Don’t forget to key a std::map, you must overload operator< Maps use binary search and insertion defaults to being in-order!

Friend classes in C++: In C++ a friend is allowed to touch your privates.

C++: public inheritance: everybody knows who your parents are. private inheritance: You are ashamed of your parents so nobody knows that you even have a parent class.

Oct 11 2012 12:49pm

Experimenting is the only way you know your assumptions are wrong.

Oct 15 2012 1:47pm

.push_back() into an STL vector is not necessarily slower than .push_back() into an STL list. Even though you would think it should be ;).

Oct 16 2012 7:26pm

C preprocessor is the original duck typing

static is C’s private

Jan 4 2013

NEVER return references to entries (ie &theAddressOf) in a <vector> of value-types. return &vec[2] and storing that value as a pointer is a no no. If you push_back into the vector, all the references you took earlier may become invalidated. Always use simple integer indices into a <vector>, or better yet use a vector of pointer types (where that makes sense to do).

Jan 26 2013

Overloading is overrated. (Not always, but sometimes). Is having 4 methods named intersects in your mesh class easier to read, or is naming them intersectsSphere, intersectsBounds, intersectsTri better?

Jan 26 2013

Marking a member function const is for when that member function call should have no change on the state of the object, neither now nor further down the line. If a const member function wants to return a pointer to a member inside the object, then that member function should not be labelled const, because that pointer is a key to making changes to the object further down the line.

constify member functions only when the member function being called is a prostitute and the code calling the “prostitute” is a married politician. Neither the caller nor the callee want the rest of society to know what went down in that function, so no record is kept. The prostitute agrees that the politician will have no lasting impact on her internal state (ie she will not talk about the affair). const on a member function means “this call never happened, and nothing changed inside the prostitute, nor will anything _ever_ change inside the prostitute anywhere down the line as a result of the politician’s call”

A bit of a long one, but hey, it involved prostitutes.

Feb 7 2013

If you delete the front node of a <list> while reverse iterating, list.rend() changes. list.rend() is not “one past the end” as list.end() would be.

Mar 3 2013

If I had a dollar every time I realized this. There are 6 cases to consider when doing ray sphere intersections: 1) Fall short 2) Entry 3) Impale 4) COMPLETE CONTAINMENT (which usually is mistakenly counted as a miss) 5) Exit wound 6) Past. Usually ppl only check for Entry,Impale and Exit, but CONTAINMENT must also be considered a “hit” (short ray inside large sphere))

Mar 21 2013

Never use M_2_PI from <math.h>. It is 2/PI, NOT 2*PI like you’d expect.

Mar 21 2013 11:28p

Crazy numbers like 8589934592 are almost certainly OOB problems.
Can you spot the potential OOB problem in the line below?

for( int i = 0 ; i < pts.size(); i++ )
  nextPts.push_back( pts[i+i].pos + Matrix3f::rotation( alongLine, angle )*perpLine*r ) ;

The i+i was supposed to be i+1! Oops!

Mar 26 2013 11:58a

The ternary operator precedence level is VERY low!

int a = 5 + 1 ? 2 : 3 ;

The result for a is always 2. Why? because evaluation is happening as:

int a = (5 + 1) ? 2 : 3 ;

5+1=6 turns into TRUE, then the result is 2.

To make it evaluate properly, you would need

int a = 5 + (1 ? 2 : 3) ;

Mar 30 2013 11:32p

The Common Part Last rule

When naming multiple variables that have to do with the same thing, with similar names, such as playerVel for the player’s velocity and enemyVel for the enemy’s velocity, always put the different part first, not last. So never use a naming convention like velPlayer and velEnemy. It makes it far too easy to interchange the variables, especially when the similar string is long (for example, rollAccel and rollAccelRadar. I know of this rule and I just mistakenly used rollAccel where I wanted to use rollAccelRadar).

Another example: you’re more likely not to notice IconDashBaseship should be IconDashFighter than you would notice BaseshipIconDash is wrong and FighterIconDash should be there instead.

Apr 1 2013 3:26p

acos and asin on Mac are different than on PC.
acos( 1.0 + 1e-38 ) is nan on Mac because the arg is OOB strict domain of acos [-1,1]
This is not an April Fool’s joke.

Apr 10 2013 1:19a

Never use Google App Engine. Always use Amazon EC2 + RDS AWS instead.

Apr 24 2013 11:41p

Why encapsulate? It’s IMPOSSIBLE to remember all the implementation details of how a cohesive bunch of code works — even if you wrote it 3 weeks ago. THAT’S the reason for encapsulation. It says “Don’t fuck with this, it’s self managing”.

Apr 25 2013 1:19a

The factory pattern is most useful when an object type cannot and should not be used independently of some master managing class.

Fri May 3 2013 9:27p

Avoid remove_if for std::vector. It is rat poison, not syntactic sugar.

Use the following idiom for removal from a std::vector instead

for( vector<TYPE>::iterator iter = vec.begin() ; iter != vec.end() ; )
if( iter->shouldRemove )
  iter = vec.erase( iter ) ; // advances iter
  ++iter ; // don't remove

UI is 90% of a game.

Fri May 24 2013 11:30a

The best way to fast debugging is error checking and log messages for even the most outlandish cases. The condition that “shouldn’t happen” will always happen, at some point or another (usually do to programmer error!)

Great code has just the right amount of debug checks. No debug checks should be logically redundant or impossible (ie don’t set a flag=TRUE then immediately after check if that flag is still TRUE).

Mon May 27 2013 6:13

Exceptions are a retroactive way of handling error conditions. They kind of say “Yeah try this, if that doesn’t work, then do that.” Exceptions are too easily abused.

Sat Jun 1 2013 12:05p

Never use your extern variables inside a function that runs before main.

Tues Jun 4 2013 6:06a

I think I like writing stored procedures because the tables are like working with a couple of GB of global variables. Nothing better.

Fri Jun 7 2013 7:57p

There is a difference between brittle code and fragile code. Robust code survives all kinds of fail cases, at the extra overhead cost it takes to code that in. Brittle code breaks if something changes (for example, code that uses fixed value integer indexing for array access), but it might break in a safe way (check bounds before accessing). Fragile code is brittle code without the error checking.

Wed Jun 12 2013 3:14p

Betas are for suckers.

Thurs June 20 2013 5:31p

In good code, the author’s intentions clear.

If your intentions aren’t clear, use comments.

Sun June 30 2013 5:26p

The key to removing low area triangles (slivers AND small tris) is collapsing edges, not deleting triangles.

Tues July 1 2013 12:43p

Always clean up your mess in the kitchen before going to bed.
There is nothing, nothing worse than having to come back to your own mess.
Clean up your dirty code immediately (and by immediately I usually mean once the primary task the code is for is working correctly, clean it up).

Sun July 7 2013 6:32p

Calls to glVertexAttribPointer() MUST BE AFTER glBindBuffer().

Sun July 7 2013 6:33p

OpenGL is stupid.

Sun July 7 2013 6:33p

OpenGL is like a baby with OCD that cries inconsolably if you do something wrong. The biggest problem with OpenGL (unlike Direct3D’s detailed albeit hidden debug information) is that it doesn’t tell you what exactly you did wrong — just that it was an INVALID OPERATION. The order doesn’t always have logical reasoning — some state changes must be done just that way.

Thurs July 11 2013 3:16p

If you’re going to frustum cull, use SAT, but use a square based pyramid instead of a true frustum.

Sun July 14 2013 11:27a

The best way to develop is to “unit test” your code immediately as you produce it.
A “unit test” can be as simple as some specialized code that allows you to make sure your code is working by testing a wide variety of test cases all at once. For code such as raycasting, a good unit test is just draw a ray from the player’s forward vector and walk around the world, visually displaying the results.

Sun July 14 2013 7:56p

Use (int) for mathematical floor operation only if you’ve never heard of negative numbers.

Otherwise use floorf().

Sat July 27 2013 12:58p

Journals are my answer to dead code.

Mon July 29 2013 11:19p

Don’t consider writing good or efficient code off the bat as just a “premature optimization”. To gracefully birth an efficient, well written program, you have to make good choices about the code you write at every step.

Fri Aug 2 2013 1:28p

Never let your program crash-fail on purpose, even for situations that should “never happen”. Emit an error message and fail gracefully.

Fri Aug 16 2013 12:42p

I hate NaN.
If you change your compiler optimization settings, be prepared for NaN bugs that didn’t appear before, to suddenly fuck everything up now. For this reason, whenever dividing floating point numbers don’t check for NaN; but Prevent NaN from ever occurring instead.

Tues Aug 27 2013 10:47p

Long live Globals.
(Tongue in cheek)

Wed Aug 28 2013 12:56p

If you can’t avoid having hardcoded constants in your program, at least confine them to a single loader or initialization function and put them in an array as soon as possible.

Sat Aug 31 2013 4:05p

Using a boolean variable to a constructor to indicate whether something is switched on or off isn’t very good. Use a 2-number enumeration instead. What I mean is, the code MakeLine( EndCapStyle::Flat ) is much more readable than MakeLine( 0 ).

Sat Aug 31 2013 4:12p

1 is much more readable than true, TRUE, and YES.

Thurs Sept 5 2013 6:15p

Initializer lists: they will bite you in the ass.

Fri Sept 6 2013 7:00p

Every bug is an OPPORTUNITY to uncover a mistake in the engine. A CLUE. If you paste over it and bury it, then that is the opposite of what you should be doing, and you will end up with a mudball.

Tues Sept 10 2013 2:40p

Every concept has a “burn-in” period. That is, anything you work on / paradigm you work in will seem foreign and strange and difficult for the first day, two days, month, whatever the burn in period is. After the burn in period, where you intensively work on a thing, then things start to become familiar things start to make sense. So you can’t get things right the first time for a new concept, because of the burn in period. Plan to iterate, or be happy with whatever the first result looks like.

Tues Sept 10 2013 2:41p

The correct abbreviation for Tuesday is Tues. Not Tue.

Wed Sept 18 2013 4:14p

Floating point subtractions in a squareroot where the values can be close together in value is just asking for the enemy nanemesis to appear. sqrtf( 1.f - valuePossiblyCloseTo_1 ) should have CLAMPED valuePossiblyCloseTo_1 above by 1.f.

Wed Sept 18 2013 4:17p

nan is my enemy.

Mon Sept 23 2013 7:01p

Large amounts of boilerplate code mean something needs a redesign. Often, the API you’re working with is too primitive (doesn’t do enough with little code — e.g. WinAPI via C) or is just old and crufty (browsers ~ early 2000’s).

Large boilerplate means you should refactor the underlying API to do more with less code. Or, if you can’t do that, you should write an API on top of the base API so that the user can do more with less code.

Thurs Oct 3 2013 7:05p

Polling a datastructure for state is usually easier to maintain than changing state.

For example, say you have a UI element that displays the “mode” of a program, call it displayMode. Instead of having code that goes and updates the mode that will be displayed by displayMode, you should have displayMode look up the system mode when it needs to display. The reason this is easier to maintain is, if you don’t poll, then every place the system mode is changed, displayMode must also be updated.

This difficult to follow piece of advice brought to you by bobobobo

Thurs Oct 3 2013 11:31p

I think in computer programming you are continually learning about logic. When debugging, you are often finding a mistake in your logic. A bug is basically: there was a problem in your logic, or you forgot to take care of something.

Sun Oct 6 2013 12:13p

The fastest way to find a class or struct declaration is Xcode is not to cmd+click the class, rather do cmd+shift+F, then type ss classname or ct firstfewlettersofstructname, which will probably only turn up the correct class or struct declaration in search results.

Wed Oct 9 2013 2:55p

Developers or actual active software tech lead not being present at the interview is a red flag.

Thurs Oct 10 2013 8:28a

In software development, paranoia can save you a lot of time*.

* paranoid if statement and error checking means catching bugs early, as soon as they appear. Or, you could use unit tests.

Thurs Oct 10 2013 11:33a

ASSERT is bad. If your assert condition dissolves in release mode, you may have hidden bugs which only appear in release mode (usually uninitialized variable-type bugs).

Tues Oct 15 2013 2:21p

In polled environments (such as games) messages do not have to be passed via function calls. A message can be passed by setting a variable.

As long as the recipient of the message reads the variable frequently (and you have taken care of any threading issues), you can “send a message” by directly setting a variable that the recipient reads every frame.

Tues Oct 15 2013 6:11p

When writing a walkthrough or a tutorial, if you get stuck or end up not liking the progression, starting over, but drawing from the previous attempt, is a powerful way to do it. It clears your mind and relieves you of tension, but you can also draw from your previous work.

Sun Oct 20 2013 1:27p

Clean math==clean code

Tues Oct 22 2013 12:20p

Recruiters are like shoe sales-people, but they try to stuff random customers into random shoes. So you have to tell the recruiter if the shoe doesn’t fit. Otherwise, they’ll keep jamming away.

Tues Oct 22 2013 12:44p

Functors are a great way to customize object behavior per instance, where there isn’t a need to derive a custom class. onMove, onDie are two useful examples.

Fri Oct 25 2013 3:51p

Successful people have a grudge against unsuccessful people, where the successful try to keep the unsuccessful unsuccessful, believing success to only lie with the previously successful. Just a trend.

Fri Oct 25 2013 7:07p

Getting an inheritance hierarchy is a bitch to start out with, but it makes things unbelievably easy to extend and maintain later on if done right.

Sat Oct 26 2013 4:57p

Achievements are kind of like documentation for a game’s special features or hidden capabilities.

I think achievements done right, are like a list of “special” things you might not have known you could do in the gameworld. About discovering hidden things, or doing a task in a special but somehow preferred way (eg 50 x headshots). They shouldn’t be lame like the infamous Avatar 5x achievements you can get in one single place, and they shouldn’t feel like mind numbing work (e.g. “10 million kills”). They should just be like little tasks, akin to Quests from WOW or something similar.

Wed Nov 6 2013 9:09p

Using integer indices into a std::vector over iterators/std::list whenever reasonable (small array, not a lot of insertion into the middle).

Sat Nov 9 2013 12:03p

Meaningless loop counter names such as i, j, k are fine, as long as you are consistent with usage (eg I always use i as the outermost, j for inner loops, and k for triple-nested loops).

Don’t take the “variable names must be meaningful” bit of wisdom overboard. If you have a list of names and use i simply as the loop variable, then i is meaningless and doesn’t need a more meaningful name.

The context of the loop makes it completely clear that i will be the name-number in the list. Don’t use an extra long name like nameNo because you “think” you should.

Sat Nov 23 2013 3:49p

Say you had some branching code in a for loop

for( each checkersquare )
if( isRed ) color=Red ;
else color = Yellow ;

There are a number of ways to do this branchlessly.

The basic way to write branchless code is to write something like:

for( each checkersquare )
color = isRed * Red + (1-isRed) * Yellow

Or, for the specific case of red/yellow alternating patterns,

for( each checkersquare )
color = (1,0,0) + (1,1-isRed,0)

friend functions are just an admission by C++ that public members are sometimes desirable. Java will forever remain in denial.

Bobobobo’s links to non-bobobobo boboboboisms

8 things web designers should keep in mind

Jonathan Blow’s talk on How To Program Independent Games

Wacom replacement nibs are actually hard to find at reasonable prices in Canada.

For one, most of the dealers are in the US, so there’s really high shipping costs.

Anyway, I’ve found one of the best places to buy wacom tablet nibs is DIRECTCANADA. The secret to buying there is BUY OVER $50 OF GOODS AND YOU GET FREE SHIPPING.

So for example, here I’ve filled my cart with $50.09 of nibs. Magically, the shipping cost goes down from $20 to $0.00.

The best nibs for the 12WX and 21UX (the pens that come with both of those devices use the same nibs) are:

I learned this from this guy, but this is just a super short, clean simple bare class that loads a single file (called “explode1.caf”). Adapt it to your needs.

// SoundMan.h
@interface SoundMan : NSObject

- (void) loadSound: (NSString*) name ;
- (void) genTestSound ;
- (void) playSound ;


@implementation SoundMan

  ALCcontext *alC ;
  ALCdevice *alD ;
  NSUInteger sourceId ;
  NSUInteger soundBufferId ;
  - (id) init
    if( self = [super init] )
      // initializes openal
      alD = alcOpenDevice(NULL);
      if( alD )
        alC = alcCreateContext( alD, NULL ) ;
        alcMakeContextCurrent( alC ) ;
        // Generate a test sound
        [self genTestSound] ;
    return self ;
  - (void) genTestSound
    alGenSources( 1, &sourceId );
    // Load explode1.caf
    NSString *path = [[NSBundle mainBundle] pathForResource:@"explode1" ofType:@"caf" ];

    AudioFileID fileID ;
    NSURL *afUrl = [NSURL fileURLWithPath:path];
    // NON zero means err
    if( AudioFileOpenURL((__bridge CFURLRef)afUrl, kAudioFileReadPermission, 0, &fileID) )
      printf( "cannot open file: %s", [path UTF8String] ) ;
    UInt32 fileSize = [self audioDataSize:fileID];
    unsigned char *outData = (unsigned char*)malloc(fileSize);
    if( AudioFileReadBytes(fileID, FALSE, 0, &fileSize, outData) )
      printf( "Cannot load sound %s", [path UTF8String] );
    alGenBuffers(1, &soundBufferId);
    alBufferData( soundBufferId, AL_FORMAT_STEREO16, outData, fileSize, 44100 );
    free( outData ) ;
  - (void) playSound
    // set source
    alSourcei( sourceId, AL_BUFFER, soundBufferId ) ;
    alSourcef( sourceId, AL_PITCH, 1 ) ;
    alSourcef( sourceId, AL_GAIN, 1 ) ;
    alSourcei( sourceId, AL_LOOPING, AL_FALSE ) ;
    ALenum err = alGetError();
    if( err ) // 0 means no error
      printf( "ERROR SoundManager: %d", err ) ;
      alSourcePlay( sourceId );
  - (UInt32) audioDataSize:(AudioFileID)fileId {
    UInt64 dataSize = 0;  // dataSize
    UInt32 ps = sizeof(UInt64); // property size
    if( AudioFileGetProperty(fileId, 
        kAudioFilePropertyAudioDataByteCount, &ps, &dataSize) )
      puts( "error retriving data chunk size" );
    return dataSize ;


Here is how you draw in latex in 3d using tikz


\section{3d picture}

% style of faces
\tikzset{facestyle/.style={fill=lightgray,draw=red,very thin,line join=round}}
% how to draw a polygon
\draw[fill=green,draw=orange,opacity=1.0,thin,line join=round]
 (0,0,0) -- 
 (1,0,0) --
 (1,1,0) --
 (0,1,0) -- cycle ;

\draw[fill=blue,draw=orange,opacity=1.0,thin,line join=round]
 (0,0,0) -- 
 (0,0,1) --
 (0,1,1) --
 (0,1,0) -- cycle ;

\draw[fill=red,draw=orange,opacity=1.0,thin,line join=round]
 (0,0,0) -- 
 (1,0,0) --
 (1,0,1) --
 (0,0,1) -- cycle ;

\draw[fill=purple,draw=orange,opacity=1.0,thin,line join=round]
 (1,0,0) -- 
 (1,0,1) --
 (0,1,1) --
 (0,1,0) -- cycle ;


You must not insert additional returns. Extra newlines will ruin the table. If you need a space use


on the line (so it becomes a comment, not just a newline)


\ctable[cap = {TABLE CAPTION},caption = {ninny},label={idiottable},]{cc}
  % You specify table footnotes here.
  \tnote[$\ast$]{DA FOOTNOTE 1}
  \tnote[$\dagger$]{dat other footnote}
  \tnote[b]{mistakes are possible (you must match these up yourself)}
\FL % FLORIDA (just kidding, means "first line")
COL 1\tmark[a] & COL 2\tmark[$\ast$]
\ML % middle line
6.920e+00\tmark[$\dagger$]     &   0.09781\\
97     &   2000
\LL % last line

These are things that I tend to forget between times I use

3ds max

– To rotate the view, ALT+Middle Mouse. If it isn’t working as you expect, your camera pivot is probably too far
– Move tool: W, Rotate Tool: E, Scale Tool: R, if they aren’t working as you expect (manipulator looks wrong), PRESS X to fix it.
– To zoom in and out use []

– To select an object, RIGHT click
– Middle mouse rotates view, Ctrl+Middle Mouse zooms
– Z toggles wireframe

– CTRL+A shows the attribute editor

So, this post talks about cosine weighted hemisphere sampling.

Really its simple.

There are 2 ways to do this, both are outlined in Philip Dutre’s “Total Compedium”

Way #1
– generate points on the disk
– project points upward

Way #2
– Use these explicit formulae.

//generate 2 random floats, each between 0 and 1
RANDOM_NUMBER_1 = randFloat() ; 
RANDOM_NUMBER_2 = randFloat() ; 

PHI(aziumthal angle) = 2*PI*RANDOM_NUMBER_1 ;
THETA (elevation angle) = acos( sqrt( RANDOM_NUMBER_2 ) ) ;

That’s it! This is what you get:

I didn’t initialize the filename member:

GetOpenFileName fails if you do _not_ write a blank string to ofn.lpstrFile

Be sure to


sprintf( ofn.lpstrFile, “” ) ;


before calling OpenFileName

A simple template, to find the minimum of 3 numbers.

Can you find the bug in this code?

  template<typename T> inline T min3( const T& a, const T& b, const T& c )
    if( a < b && a < c )  return a ;
    else if( b < a && b < c ) return b ;
    else return c ;

Hint: Actually I’m not going to give you any hints. But it is possible for the above function to return the incorrect value.

Sibernik Cathedral

(Download links dead), now available on web archive: .max | 3ds | lp


I got an AMD FX-8150 chip in a new PC build.

_It sucks._ It’s no better than the AMD 1090T, which incidentally was taken _off_ the market by AMD. Now I know why. The 1090T performs very similarly (with no overclocking at all, either chip) to the “new” AMD 8 core.

I was already using an AMD 1090T to do parallel raytraces. I thought I’d get a second machine as a workhorse. Built one for $500. Shoulda gone with Intel. I’m running the same raytrace in parallel, one on this machine (which I’m also using to write this post) and I’m leaving the FX 8150 alone. The FX 8150 spawned 8 threads to raytrace on (7 for raytracing and 1 for the UI) because 8 cores were detected, here on the 1090T only 5 raytracing threads are running, +1 for the UI thread.

So far they are neck and neck, even though I am using this machine to write this post. The FX 8150 machine has completed 119/300 jobs (each “job” is 2 800 pixel long rows), this machine 117/300 jobs. Totally terrible. I expected _some sort_ of improvement, with a 400 MHz faster clock speed and 2 extra cores, but you get absolutely nothing.

It’s the SAME core as the 1090T, far as I’m concerned.

Further proof

So, there’s always this question of “what’s the difference between rotate THEN translate VS translate THEN rotate”?



If you do ROTATE THEN TRANSLATE, the effect is __spinning in place__, because ROTATE about axis first (we are still @ origin), then translate OUT to some point in space.


If you do TRANSLATE THEN ROTATE, the effect is __ORBITING__ around an axis, because it translates you OUT FIRST, away from the origin, then you rotate that new further point about the origin: