Ever had to link in an external library for your iPhone project?
Did you receive a big headache having to switch between the simulator version and the iphone version of the library?
Yes?
Well, this is for you, run the lipo command, and it'll magically embed both versions into one FAT library.
And fear not, the linker will only link in the required version.
So I've been working on and off on a Syndicate style birds eye view shooter, just as an excuse to mess around with AI again.
When going on to creating the actual game map, usually I'd hard-coding everything (I see things easier in code). However, this time since I had an actual artist (non-programmer artist) create the base ground texture. Placing buildings to conform to an artists texture would be a pain, especially because maths and uniformity doesn't mesh with art. So yesterday I decided to quickly mock up a level editor using everyone's favourite new buzz word 'HTML5'.
All it does is simply draw the ground texture on a webpage using the canvas tag, then allows you to draw rectangles over the image. These rectangles are then exported out as an xml file. The xml file is then read by the game, and buildings are placed in position and to proportion of the rectangles created.
It's simple, it works, and since the level editor is web based, it should be relatively easy to release it alongside the game (if it ever gets done) for gamers to produce and play maps of their own.. I'll keep you updated.
After a week of dev, the first release of iGrapher 3D has just been submitted.
It's been developed to work on the iPad and iPhone 3GS. It does run on the older iPhones, but not smooth enough for my liking.
The first release will feature panning, rotating, zooming, raining (yes there's rain), and price scanning through the ftse 100 and dow jones indices in glorious 3D.
So I was trying to launch a YouTube video from my game, without the game switching to the YouTube app. To do this, I ran into a few issues.
Here I'll describe how to set up the playing of a YouTube video and how to tackle the issues you will encounter.
So first you must create a UIWebView and add it to your main view.
In the following I create a webview pointing to http://technolojia.com/NahBruv/trailer.htm where I have embedding the YouTube clip I want to play, I set it hidden because I'll later want to launch the video full screen.
Once it's loaded it'll call the delegate function which you music implement in your class. Notice I set htmlView.delgate = self. I do this because I want to launch the video once the page is loaded, because by default YouTube video's need to have the play button clicked before they launch in the MPMoviePlayerController object.
So here I scan through all the buttons in the webview and select the first button found using the sendActionsForControlEvents function.
Great so far huh? But on return if you're using OpenAL, the sound no longer works. Eek. So what you have to do is, before launching the video you must make sure you call AudioSessionSetActive( NO ) and then AudioSessionSetActive( YES ) once the video has finished. I also found I had to destroy and recreate my OpenAL context and samples loaded, but I haven't looked too much into it, so if you find a way to reuse your OpenAL context and device, let me know.
Just managed to submit make my first submission to the app store. Getting a distribution profile was a pain.. I'll post more details after I've got some sleep..
Just implemented a new feature called Graph Normalization as suggested by Jeff from Forex Fundamental Analysis. The problem previously was when you chart stocks with extreme differences in price levels, it's impossible to visualize the graph shapes together.
But now with the Graph Normalization feature, you can normalize the graphs to see the pattern by clicking on the graph you wish to normalize the rest by..
Then selecting Normalize Graph..
Now all the graphs will be normalized to the chosen scale..
You can denormalize the charts using the same option.
If anyone has any requests/suggestions, feel free to drop me a line.
I recently switched from rendering texture strings to font pages. The difference between the two is for texture strings you'd render the string into a bitmap and assign the image to an openGL handle. For a font page, you'd create all the characters of the font required and then when rendering a string, you'd fetch the characters required individually from the created page to render one by one.
The reason for switching was to display a more dynamic text such as an OSD counter. With the old system I'd have to have to constantly create and release different images representing the numbers required, which would be impractical.
So here's how rendering text using a font page works.
First we initialize our class, where we create a bitmap with all the characters from the font required, and paste them one by one onto the page, incrementing the width and height as we paste along..
Just managed to re-use my male character model to create a female. It's still work in progress, but it was enough to inspired me to put together this quick concept cover art.
Octrees are a data structure to represent spartially dividing up a scene. The way they work is to divide up a scene into eight leafs, with each leaf further dividing up if they contained more objects than the set threashold.
You could then use this divided up scene for optimisations. Such as to only process rendering for the objects in the visible octrees, or to only process collisions for the objects in the same octree as the current object.
Here's a video of the octrees in action, notice how when a leaf becomes dense, it breaks down into a further eight leafs.
So let's start.
First we create our octree structure. With each octree will containing a pointer to it's parent tree, it's eight leafs, a set of objects and it's world position.
Now we'd need to handle adding an object to the tree, this is done by use of recursive function calls, that drill down into the leaf nodes to add the object to all the leafs it resides in. Once it's found a leaf if we have space for the object we add it into it's object list, if we don't have space we'll need to split the tree down to a further eight leafs and re-attempt adding the object.
void OctreeAddObject(Octree *tree, ObjectCollideable *collideable)
{
// Ensure the object is within the octree's limits
if( tree->parent == nil )
{
UpdateCollisions( collideable );
Vector3 *objectMin = &collideable->min;
Vector3 *objectMax = &collideable->max;
if( objectMax->x < tree->min.x ||
objectMax->y < tree->min.y ||
objectMax->z < tree->min.z ||
objectMin->x > tree->max.x ||
objectMin->y > tree->max.y ||
objectMin->z > tree->max.z )
{
return;
}
}
// Insert in an approperate leaf node
if( tree->leafs != nil )
{
UpdateCollisions( collideable );
for( uint i=0; i<8; ++i )
{
Octree *leaf = tree->leafs[i];
if( OctreeIsInLeaf( leaf, &collideable->min, &collideable->max ) )
{
OctreeAddObject( leaf, collideable );
}
}
}
// Unless we don't have any
else if( tree->numberOfObjects < MAX_TREE_OBJECTS )
{
tree->objects[tree->numberOfObjects++] = collideable;
assert( collideable->numberOfOctrees < MAX_OBJECT_TREES );
collideable->octrees[collideable->numberOfOctrees++] = tree;
}
// If we have too many objects split the octree
else
{
OctreeSplit( tree );
// Try again
OctreeAddObject( tree, collideable );
}
}
To check if the object resides in a leaf's space we simply use our min max vectors which we're set in OctreeNew.
Now comes the fun part, splitting our octree into a further eight octrees.
To do so, we first create the eight leaf nodes from our parent's min max vectors and hSize variables.
We then parse through the current leaf's objects, remove them from the object list and re-add them into the appropriate new leafs we've just created.
// Now we need to sort our objects into our new leafs
while( tree->numberOfObjects > 0 )
{
ObjectCollideable *collideable = tree->objects[0];
removeFromList( collideable, (void**)tree->objects, &tree->numberOfObjects );
removeFromList( tree, (void**)collideable->octrees, &collideable->numberOfOctrees );
UpdateCollisions( collideable );
for( uint i=0; i<8; ++i )
{
Octree *leaf = tree->leafs[i];
if( OctreeIsInLeaf( leaf, &collideable->min, &collideable->max ) )
{
// Place this object in this leaf
leaf->objects[leaf->numberOfObjects++] = collideable;
assert( leaf->numberOfObjects <= MAX_TREE_OBJECTS );
collideable->octrees[collideable->numberOfOctrees++] = leaf;
assert( collideable->numberOfOctrees < MAX_OBJECT_TREES );
}
}
}
}
Now for removing an object from the tree, we simply check through all the leafs the object resides in and one by one remove the object from the trees list. We then set a call to prune the tree, so that if the leafs are no longer needed they'll be deleted.
Above I set a timer to 1.0f which would count down elsewhere to call the prune tree function. With the prune tree function recursively calling itself on all it's leafs, and if the set of leafs have no objects in them they get deleted.
That's it! Simply add in all your static objects, then whenever you move an object, just re-add it to the root tree, so it can put itself into the appropriate leafs.
I'm currently working through the setting screens, so I needed to make a few widget classes. Basically I have a bunch of widgets which contain their position, size and some functions to determine how input is handled. Now comes the fun bit, re-using the class for different options. I wanted one widget to handle starting a new game, one for toggling collision boxes, etc.
To get this done, I used function pointers. I'd let the scene handle the interactions with the widgets and when one was invoked, it's set callback was fired.
So in the header file, I have two members, the first being the function to call, and second being the parameter to pass into the function.
So in the case of toggling a bool on or off, in the main scene I'd create a widget and pass in the function pointer for toggling bools with the variable active.
Alright, just added in support for selecting 3d objects using 2d coordinates. So you can select an object in a 3d scene using your finger. The idea to do this is to unproject the 2d coordinates passed in at 0 and 1 range to get the direction of the ray, then simply use that ray to find which objects collide.
Step one was to find the source for glu unProject function. There's loads of sources online for OpenGL, so all you need to do is port it over to OpenGL ES (just replace GLdouble with GLfloat).
Step two take in a 2d coordinate and feed it into the collision detection system. My collision system scans through all base objects of ObjectCollideable and returns the one which is closest to the start of the ray. The viewport and projection matrices are calculated on OpenGL initialisation with the following calls.