The Hobbit Hole

In a hole there lived a hobbit. Not a nasty, dirty, wet hole, filled with the ends of worms and an oozy smell, nor yet a dry, bare, sandy hole with nothing in it to sit down on or to eat: it was a hobbit-hole, and that means comfort.

5/26/2006

Hobbit and Elven Names

Filed under: General — bilbo @ 1:22 pm

I like these little tidbits from around the internet. Find out your hobbit name and elven name. Also, does the picture on the hobbit name generator look familiar? :)

My hobbit name is Pimpernel Smallburrows of Sandydowns.

My elven name is Olwë Oronrá.

Pretty funky.

5/17/2006

Fristrom’s Law

Filed under: Programming — bilbo @ 12:06 pm

Interesting take on how to estimate labor costs for game development.

Fristom’s Law: if there are n people on your team, expect (n ^ .75) people’s worth of work out of them.

This leads to an interesting corollary.

As the industry trends towards larger projects, demand for talent goes up, because of the reduced efficiency. So although these big budget projects may be bad for the industry, they’re good for the individual. As our companies flounder and our projects get canceled, we’ll all still be able to land well-paying jobs.

Namely, by the fact that projects are getting bigger and therefore more inefficient, this creates demand for the game developer. So even though there are more cancellations and fewer games brought to market, it makes a better labor market. Interesting theory. Time will tell if it holds up.

I think this will hold until someone invents a new efficiency. Already we are seeing many games attempt to go “procedural” for many of their art needs. It might reach a point where this is viable, thereby reducing the inefficiencies and putting many people out of work. :(

Still, for estimating game development manpower, it’s as good as anything else I’ve seen. And maybe, just maybe, we’ll call the magic constant (1 / .75) George. :)

5/10/2006

Visits for Operations

Filed under: Programming — bilbo @ 7:00 am

No, I’m not talking about hospital procedures. I’m talking about visitors, as in the visitor design pattern.

So, the GMTL is coming along nicely. I’m doing specialized functions now, meaning that I’ve completed the generic algorithms for arbitrary size matrices, vectors, and square matrices. Specialized means that they only work for certain size matrices, such as from_euler which produces a 3×3 matrix.

Which brings me to this post’s point. See, I really, really like functional programming. One of the main points of the GMTL is to create a matrix library with a purely functional notation. No operations are to be performed on the matrices themselves, so m.setIdentity or m.fromEulerAngles are not allowed. Also, no temporaries are to be created intermittently.

So, how do you write

m = from_euler( x, y, z );

without using a temporary? An expression template.

First, we define an operation class that will contain an expression or computation. We’ll call it op_matrix.

template <typename Operation>
struct op_matrix {

    Operation _op;

    op_matrix( Operation& op ) : _op( op )
    {
    }

    template 
    void apply( Matrix& m )
    {
        _op.apply( m );
    }
};

The class is a template so that we can put in custom operations, but make them all members of a family of classes we use later on.

Next, we define an assignment operator in our matrix class that takes a parameter of type op_matrix.

template <typename Operation>
matrix& operator=( op_matrix<Operation>& op )
{
    op.apply( *this );
    return *this;
}

As you can see, the assignment operator simply calls apply on op_matrix, which in turn calls apply on the Operation, using the matrix as the parameter. Hence, the operation is visited by the matrix in the same manner as using the Visitor pattern.

As an example, let’s take a rotation matrix around the x axis for an operation.

template <typename Element>
struct op_from_euler_x {

    Element _x;

    op_from_euler_x( Element x )
        : _x( x )
    {
    }

#if defined(_DEBUG)
    ~op_from_euler_x( void )
    {
    }
#endif

    void apply( Matrix3& m )
    {
        Element cx = cosf(_x);
        Element sx = sinf(_x);

        m = 1.0f, 0.0f, 0.0f,
            0.0f, cx, -sx,
            0.0f, sx, cx;
    }
};

To make this clean, we wrap it in a function that contains the operation we are performing.

op_matrix< op_from_euler_x<float> > rot_x( float x )
{
    return op_matrix<op_from_euler_x<float> >( op_from_euler_x<float>( (float) x ));
}

The downside to such usage is the inflexibility of expressions using this technique. The only real possible statement using this is

Matrix m;
m = my_operation();

There are undoubtedly ways to extend this to make full expressions possible, but for now it works and gives us the functional notation we crave with the efficiency of a passed parameter.