Archive for February, 2012


Raytracing!

So I’m taking CS500 this semester with Dr. Gary Herron and he mentioned one of the sample images we work with reminded his daughter of fractals.  Well, back in the 90’s I remember fractals being super cool, so of course I instantly decided I should learn how to raytrace them!  Raytrace is probably the wrong word – although I’m working with my raytracer, these shapes are using raymarching and some of the coolest things ever, distance estimators!

Anyhow, just in case anyone else is as interested in this as I am, I recommend starting here.
Here are some pictures I’ve generated so far:

Advertisements

More Dreaming

Thought up a new way to handle cube-based construction in a game – potentially really cool, hopefully I’ll either have time to try it someday, document it or someone else will beat me to the punch.  It isn’t voxel based (unless your voxels are teeny-tiny.)  Just posting here so I won’t forget, chonestly.

Dream Game

I just had a dream I was working on the following game:

It’s like Pokemon, where you train monsters to fight other trainers, except instead of a turn-based battle the combat takes place in real time in an arena.  The monsters are controlled by AI, leaving you to control your trainer – who actually fights (with boxing gloves.)  Other trainers are typically horrified to see you fighting their monsters.

The story is that you were a master of these battles back when the monsters made sense and there was a human component, but many years have passed since then and you think the new monsters the kids have found are dumb and this makes you very angry.  So you’re basically one of those 151-elitists…

Oh, and the first monster you start with is Meat Boy.

Then I woke up, I think Ivy jumped on me.

Invent words

Words which mean opposite things should have the first letters reflected across the center of the alphabet with the bigger/better version being on the right side…  so instead of min and max, you’d have min and nax.  Endothermic and exothermic?  Which is which, I can’t tell, but call them endothermic and vxothermic and all is clear.  Good and bad?  Yood and bad (or vood and evil, ymmv.)  This is a treat idea.

Roadmap

GDC is quickly approaching and Voxel Chronicles isn’t yet where I want it to be.

Here is the roadmap, though – in case you’re curious as to what I’m working on or how long something took.

His bed.

An integral part of the very short plot/tutorial level. Obviously our hero would have a Dwarf Fortress themed bedroom, pfft.

Link to video
Link to code

Weapons point in (0,0,-1) in model space with the tip of the handle located at (0,0,0). startingOffset and endingOffset are two vectors controlling the direction of the swing – for the mace above, they’re set to (0,1,-1) and (0,-1,-1) and then normalized (before we hit the code below.) The code is longer than it needs to be mainly for debugging/clarity, as I’m trying to isolate the problem. Any help is much appreciated!

The code looks like:

// this will be the player's transform
Transform* parentTransform = (Transform*)parent->GetComponent( CT_Transform );

if( parentTransform )
{
Body* weaponBody = (Body*)owner->GetComponent( CT_Body );

// The location of the wielder
btVector3 parentPosition = btVector3( parentTransform->position.x, parentTransform->position.y, parentTransform->position.z );

// The rotation of the wielder
btQuaternion parentRotation = btQuaternion( parentTransform->rotation.x, parentTransform->rotation.y, parentTransform->rotation.z, parentTransform->rotation.w );

// The weapon is offset from the parent position (to a point corresponding to the player's hand)
// TODO: Pass this in from the character controller
btVector3 handOffset = btVector3( -4, 1, -4 );

// this was to handle weapons with widths that are even
if( weaponBody && weaponBody->offset.x > 0 )
{
handOffset.setX( handOffset.getX() + weaponBody->offset.x );
}

// currentVector is some portion of the way between starting and ending offset
float progress = currentSwingDuration / totalSwingDuration;

btVector3 parentAxis = parentRotation.getAxis();
float parentAngle = parentRotation.getAngle();

// Rotate starting/ending to align with player, interpolate based on progress to get current
btVector3 rotatedStart = startingOffset.rotate( parentAxis, parentAngle );
btVector3 rotatedEnd = endingOffset.rotate( parentAxis, parentAngle );
btVector3 currentVector = rotatedStart.lerp( rotatedEnd, progress );

// get axis/angle to rotate starting vector to current
btVector3 planeThatRotatesStartToCurrent = rotatedStart.cross( currentVector );
float angleThatRotatesStartToCurrent = rotatedStart.angle( currentVector );

// get axis/angle to rotate weapon to start
btVector3 planeThatRotatesWepToStart = btVector3( 0, 0, -1 ).cross( rotatedStart );
float angleThatRotatesWepToStart = btVector3( 0, 0, -1 ).angle( rotatedStart );

// Rotate the handOffset
handOffset = handOffset.rotate( parentRotation.getAxis(), parentRotation.getAngle() );

//DebugDraw::instance.drawLine( parentPosition + handOffset, parentPosition + handOffset + ( currentVector * 30.0f ), btVector3( 0, 1, 0 ) );

// get a quaternion to rotate the weapon from it's default direction (0, 0, -1) to current...
btQuaternion weaponRotation = btQuaternion( planeThatRotatesStartToCurrent, angleThatRotatesStartToCurrent ) * btQuaternion( planeThatRotatesWepToStart, angleThatRotatesWepToStart );

// Push currentVector out based on the length of the weapon (we want the handle of the weapon located at the origin)
if( weaponBody )
{
currentVector *= abs( weaponBody->offset.z );
}

currentVector = currentVector + handOffset + parentPosition;

// Communicate the new position + rotation to our parent composition
owner->ReceiveMessage( &DataMessage( MSG_SetRotation, XMFLOAT4( weaponRotation.getX(), weaponRotation.getY(), weaponRotation.getZ(), weaponRotation.getW() ) ) );
owner->ReceiveMessage( &DataMessage( MSG_SetPosition, XMFLOAT3( currentVector.getX(), currentVector.getY(), currentVector.getZ() ) ) );

In mathematics, the quaternions are a number system that extend complex numbers.  A complex number is a number which can be put in the form a+bi, where a and b are real numbers and i is called the imaginary horror, a source of constant anxiety for mathematicians at a subconscious level, which when squared equals -1.

In January of 1843 the Irish explorer Sir William Rowan Hamilton discovered the tomb of Euler and, within it, a mural depicting the deceased mathematician crying a mixture of alphanumeric characters while vomiting into a four-dimensional box.  Slumped in front of this mural was the corpse of Euler himself.  As Hamilton would later write:

“I did not expect to find Leonhard Euler in Peru – his death in Russia a century ago is common knowledge.  If this was truly his final opus, perhaps his countrymen banished him for madness and then claimed him dead to save face?  My peers in academia refute my findings and my guides in the jungle refused transport for the corpse.  I’ve been dreaming of that day ever since – the smell, the heat, the symbols.  My dreams are becoming stranger still – last night Fourier was there with us, furiously peddling a child’s tricycle in tight circles, mumbling rhythmically in cacophonous tones while Euler stalked the four corners of the room.”

Later that year, while walking along the towpath of the Royal Canal with his wife, Hamilton began muttering and carving into the stone of Brougham Bridge.  His wife, concerned he was becoming unstable, transcribed his muttering as “Iejays’k jaykays’i  kayeye’sjay Cthulhu R’lyeh wgah’nagl fhtagn.”  His carving simply read: i2=j2=k2=ijk=-1.

On the following day, Hamilton wrote a letter to his friend and mathematician, John T. Graves.

“And here there dawned on me the notion that we must admit, in some sense, a fourth dimension of reality for the purpose of communing with triples… An electric circuit seemed to close, and a spark flashed forth in the darkness.”

Hamilton called a quadruple with these rules of multiplication a quaternion, and he devoted most of the remainder of his life to studying and teaching them. He founded a cult of “quaternionists” and authored several grimoires, the last and most powerful of which was titled Elements of Quaternions.

Although incomprehensible, Hamilton’s followers digitized and distributed his work in the late 20th Century, where it was rapidly adapted due to a preternatural ability to compactly describe spatial rotations without being susceptible to gimbal lock.  As of 2012, quaternionists have successfully infiltrated the following fields: computer graphics, computer vision, robotics, control theory, signal processing, altitude control, physics, bioinformatics, molecular dynamics, computer simulations and orbital mechanics.

Surviving quaternionists conduct an annual pilgrimage from Dunsink Observatory to the Royal Canal bridge where, fortunately, no trace of Hamilton’s carving remains.

It’s training, dummy!

A* + JPS

Finally got my A*+JPS implementation from last semester’s AI course into the game! Agents aren’t following the generated waypoints yet but the paths are coming in quickly and optimally, just the way we like them.