Author Archives: Taylor Petrick

It’s been a while…

It’s been a while since I’ve posted here, and ironically this will likely be my last post on this blog. Aside from being busy with university, I’ve also been working on setting up a small software company with some like-minded individuals. We’re starting off with some smaller scale app development to get the ball rolling, and will hopefully be moving on to larger projects in a few months time. Ion Engine may be involved. ūüėČ

The main site for our company, Orange Bytes, can be found at orangebytes.net. My new blog can be found at taylorpetrick.com

Taylor


C-A-Day

One of the suggestions my C programming professor gave us was to try to use a command line editor to do as many assignments as possible if we weren’t already familiar with one. Given that I fall in the “never used one” category, I decided to take it a bit further and do a sort of “c program a day” using Vim via the OS X terminal. The purpose is actually two-fold; I’m also using it to learn new algorithms as each program deals with an algorithm I’ve never tried writing before.

I started on the 16th by¬†implementing¬†Newton’s Method for finding the roots of the function x^2 = 916; in other words, the square root of 916. Yesterday I wrote a prime number sieve, and today I wrote a MergeSort implementation. I’m getting to know Vim pretty well too, and although I still prefer using an IDE I could probably survive with command line if I had to.

With regards to Ion Engine, I’ve done a bit of work on some small items over the last few days. I haven’t had time to sit down and work for a solid block of time so progress has been rather limited. Hopefully during this week I’ll be able to work on some other larger features on my list (terrain engine in particular).

Taylor


Mesh loader

I’ve started to work on fleshing out a proper set of mesh classes for handling mesh instancing, animation and whatnot. I scrapped my old .obj loader and wrote a new one that’s more compliant with current codebase. Here are a few shots of the space scene running with different meshes:

Given that I do my modeling in Blender 3D, I felt obligated to include Susanne, a.k.a the “Blender monkey” as one of my test objects. I haven’t setup trimesh collisions for Bullet yet, so Susanne is stuck with (rather poorly sized) bounding box. The tori use a cylinder. I’m really happy with how the lighting is working on smoother objects though, and with the scene’s performance in general.

T


Math and Campus Maps

It’s been a few days since I’ve posted as I’ve been pretty busy with frosh week events here at Waterloo. Since I’m going into software engineering, I’m¬†technically¬†part of both the engineering faculty and math faculty and therefore participate in events from both faculties. At this point, all “softies” have earned their engineering hard hats and pink math ties:

The other night, one of the Comp Sci guys on my floor came to my room with a pretty cool math problem that would have fit well on Project Euler. It basically wanted to know how many downward-pointing triangles were present in a pyramid made of triangles. Of course, these downward-pointing triangles could be built from multiple triangles; for 4 layers of pyramid the answer is 7 because of one bigger multi-triangle:

Arriving at a computer-friendly answer is very easy, and requires a simple nested for-loop. I also found a slightly more elegant solution with only a single for-loop, but again this solution was fairly easy to come by. The hard part began when a few more CS/Eng students arrived and asked if we could find a single equation that would work for all cases that was “calculator-friendly”, i.e. without any looping. This was tougher.

We worked for several hours that night and didn’t really produce any solid results. I decided to try again earlier this morning and I’ve finally come up with an extremely ugly solution for cases were the number of layers (n) is greater than 4:

I’m still not satisfied, but I’m putting it away because I’ve already put way too much time into it.

¬†The second item I mentioned in my title is an idea for an app I’ve started working on. I used my iPhone + Google Maps to get around campus for the first few days, but this required some looking back/forth between the phone and the actual campus map. I think it would be handy to have a campus map super imposed onto Google Maps. In addition this map could take building names as start/end locations and plot the optimal route. I’m hoping to have this done by the time class starts on Monday. ūüėõ

T


Move-In!

Well, it’s official, I’m a University of Waterloo student! Well not quite, classes don’t start until next week. The move was straightforward enough and I’m already starting to feel at home on campus.

Believe it or not, I still need to go buy several more textbooks. Many of the ones on my shelf are from previous courses I’ve taken that I thought might be handy for reference at some point.

Unfortunately¬†today also marks a shift in gears as far as my own personal projects go. I’m still going to be working on my game engine, iPhone programming, RakNet, etc but will be unable to devote the same amount of time to them as I had over this past summer. It’s tough for me to judge how much free time I’ll have at this point in time, but I do know the program I’m in is supposed to require a significant weekly hour¬†commitment. I guess I’ll just have to see how things go.

T


Tutorial : RakNet Replica3 on the iPhone

Sorry this took a while getting out, it took a bit longer than expected to finish.

One of the more useful features of RakNet,¬†particularly¬†for games, is the ReplicaManager plugin. This piece of code handles “replication” of objects, ensuring that all clients have the same state as the server. For example, in some of my previous posts I demonstrated the feature by running a physics simulation on a server and viewing the scene on several connecting clients. Replica is very scaleable and allows for fine-grained control over what aspects of an object are transmitted over the network, how reliable the arrival order is, etc. This tutorial will only cover a basic client-side iPhone integration based on the Replica sample provided with RakNet; more details on the specifics of using the system can be found in the RakNet forums and documentation section.

I’m going to assume that you’ve looked at the previous tutorials using RakNet, and have at least compiled an iOS RakNet library. We’ll need to use that to compile the application in this tutorial.

The first step is to create a new “View-based Application” project for the iPhone. You can name it whatever you want, but I’m using RaknetReplicaSample and this name may appear in some screenshots.

The original RakNet sample was contained in a single .cpp file that would run both ¬†a client server, making things a bit confusing to work with. I’ve split the example into several files and added a logger class that will print to a UITextView, which makes things a bit easier on the iOS platform. These files, along with a compiled version of the RakNet sample for OS X, can be downloaded here.

Import these files into your newly created Xcode project and add them to the Classes folder. There are still some hooks to add to the ViewController and AppDelegate files. These are similar to the ones made for the previous tutorial on setting up a RakNet chat client on the iPhone, but there are a few key differences in the ViewController.

We’ll start off with the AppDelegate though. Like last time, we need to setup an NSTimer to run our network loop. Add a new NSTimer to the AppDelegate.h file at the end of the @interface declaration:

NSTimer * mTimer;

And a new method to actually call the network update function:

-(void) networkUpdate: (NSTimer *) pTimer;

The interface should look something like this:

In the corresponding implementation file, <ProjectName>AppDelegate.m, add the following line at the end of the application:didFinishLaunching: method:

mTimer = [NSTimer scheduledTimerWithTimeInterval: 0.1 target:self selector:@selector(networkUpdate:) userInfo:nil repeats: YES];

Then, add an implementation for the networkUpdate method:

-(void) networkUpdate: (NSTimer *) pTimer
{
	[self.viewController tickClient];
}

That’s all that needs to be done in AppDelegate. In theViewController.h, add the following includes to the top of the file, directly after UIKit.h. Please keep them in this order as well:

#include "SampleReplica.h"
#include "SampleConnection.h"
#include "SampleReplicaManager.h"
#include "Logger.h"

Then add the following items to the @interface declaration:

	NetworkIDManager networkIdManager;
	RakPeerInterface *rakPeer;
	ReplicaManager3Sample replicaManager;
	SocketDescriptor sd;
	Packet *packet;

	UITextView* mTextView;

This is similar to the chat tutorial, but now we had a new “ReplicaManager” instance. This class and its super class handle much of the work behind the object replication process.

We’ll also need to add the following lines after the closing brace on the @interface¬†declaration:

-(void)tickClient;

@property (nonatomic,retain) IBOutlet UITextView* mTextView;

In the implementation file for the ViewController, we first need to @synthesize  the UITextView by adding the following line after the @implementation declaration:

@synthesize mTextView;

In the viewDidLoad method, add the following block of code after the call to the super class:

	Logger::getLogger()->setTextView(mTextView);

	sd.socketFamily=AF_INET;
	sd.port=0;

	rakPeer = RakNet::RakPeerInterface::GetInstance();
	rakPeer->Startup(32,&sd,1);
	rakPeer->AttachPlugin(&replicaManager);
	replicaManager.SetNetworkIDManager(&networkIdManager);
	rakPeer->SetMaximumIncomingConnections(32);	

	rakPeer->Connect("192.168.2.17",12345,0,0,0);

Just like the chat client example, the IP address can and should be changed to suit the environment you’re using. The port needs to remain as it is, since the RakNetReplicaSample server is hardcoded to use this port. The port shouldn’t be a problem for anyone.

Next, add the tickClient method. This method is called by our NSTimer once every 10th of a second and updates the network:

-(void)tickClient
{
	for (packet = rakPeer->Receive(); packet; rakPeer->DeallocatePacket(packet), packet = rakPeer->Receive())
	{
		switch (packet->data[0])
		{
			case ID_CONNECTION_ATTEMPT_FAILED:
				Logger::getLogger()->appendLine(@"Connection failed\n");
				break;
			case ID_NO_FREE_INCOMING_CONNECTIONS:
				Logger::getLogger()->appendLine(@"Connection failed - No free incoming connections\n");
				break;
			case ID_CONNECTION_REQUEST_ACCEPTED:
				Logger::getLogger()->appendLine(@"Connection request accepeted\n");
				break;
			case ID_DISCONNECTION_NOTIFICATION:
				Logger::getLogger()->appendLine(@"Disconnecting\n");
				break;
			case ID_CONNECTION_LOST:
				Logger::getLogger()->appendLine(@"Connection lost\n");
				break;
			case ID_SND_RECEIPT_LOSS:
			case ID_SND_RECEIPT_ACKED:
			{
				uint32_t msgNumber;
				memcpy(&msgNumber, packet->data+1, 4);

				DataStructures::Multilist replicaListOut;
				replicaManager.GetReplicasCreatedByMe(replicaListOut);
				DataStructures::DefaultIndexType idx;
				for (idx=0; idx < replicaListOut.GetSize(); idx++) 
				{ 					
                                      ((SampleReplica*)replicaListOut[idx])->NotifyReplicaOfMessageDeliveryStatus(packet->guid,msgNumber, packet->data[0]==ID_SND_RECEIPT_ACKED);
				}
			}
				break;
		}
	}
}

Finally, add two lines of clean-up to the viewDidUnload method to disconnect from the network:

	rakPeer->Shutdown(100,0);
	RakNet::RakPeerInterface::DestroyInstance(rakPeer);

Like last time, we also need to tell the compiler that this project will contain some C++ code. This means that all the .m files need to be renamed to .mm, or set to compile as Objective-C++ by right clicking them, going to Get Info, and changing the File Type field to Objective-C++:

That should cover all of the code changes needed. You’ll also need to add a new UITextView to the interface builder and link it to the UITextView created in the ViewController class. This will be used to display output from the server and any connect/disconnect messages.

Like last time, you’ll need to include your RakNet library and add the RakNet source directory to your header search path. At this point, everything should be ready to compile.

To test the app, first start the provided OS X Replica application. Since this application is taken straight from RakNet, it can run as a client, server or peer-to-peer instance. Start it as a server by entering ‘s’ into the console. You can create new objects by pressing ‘c’, and assign them random values with ‘r’. Delete all created objects with the ‘d’ key. All three of these actions will be replicated on the client, and can be verified by checking the output UITextView on the iPhone app.

As always, I’m happy to help sort out any issues that come up with the tutorial. Let me know in the comments if you need anything, or if there are any other specific RakNet samples that you want to see ported to the iPhone.

T


New Light Manager and Deferred Rendering

I haven’t had as much time to work on Ion over the last few days, however I put in a few solid hours of coding today and finished the first version of my light manager. It’s only hooked into the deferred renderer at the moment, since I still need to finish the code that’ll allow the forward render to pull a limited number of lights based on some input factors. At the moment lights can have custom position, color, intensity and a variety of different fall-off equations. I’d like to add support for lens flares and cubemap masks later on, to add some extra visuals.

For the deferred renderer, the light values are stored in a pixel buffer which is passed into the final deferred shader.¬†Unfortunately¬†I’m doing something wrong with¬†glTexSubImage2D¬†and isn’t working properly, so I haven’t been able to add light animation to the system quite yet.

The scene setup I’m using to test things out has 7 lights in it; a white light at the center, four colored lights at the four sides of the cube stack, and then two small, bright lights (pink and cyan) directly next to the stack. I setup the scene to be in a 0-gravity space environment as well, so the effects of the lighting were more obvious. Here are a handful of screenshots of the test scene:

I also recorded a video, however QuickTime dropped the FPS down a bit. In the video each click adds another 6x6x6 group of physics cubes; at the end of the recording there are several thousand floating around. At one point there’s a bit of visual lag since I added several groups in quick succession, and the physics and render loop are tied together. Anyways, here’s the video:¬†http://vimeo.com/28528048.

That’s it!

T


%d bloggers like this: