Sunday, January 10, 2010

My Vista OGRE, Part III

It has been awhile since I have had time to update my blog. Life has a funny way of getting in the way of best laid plans. :-)

In any event, I figured I would update (finalize, for now), my comments on using OGRE. The real bottom line on this project is that the requirements changing drastically coupled with only ~10 weeks to do this (in addition to work, my other graduate class, family, Michigan Football, and sleep) really was not enough time to do this properly. I guess I should add that trying to just "dive-in" into this was definitely the wrong approach. With this in mind, my summary here may be updated as I "remember" more of what I did to finish this project. It might be pertinent to add that I did finish the class with an "A," although I don't know my project grade. However, with the weight it carried, it had to have been at least a "B." :-)

If anyone is actually reading this blog and is interested, I did produce a write-up on the project, design decisions, and thoughts on how to make it better. Plus, I have the source code still. Can't ever seem to delete source code. :-)

In the submitted prototype, I ended up using two different data structures (standard Linked List and standard deque) and a couple of algorithms used during each frame updates.

Entry, Exit, and Curve Vectors were all stored in a standard linked list (as IntersectionNodes). While I believe that there are other methods to account for these coordinates, and the actions that need to happen at each one in a scripted world of traffic, I decided that a linked list would be the easiest to maintain and use for these vectors.

The IntersectionNodes themselves stored not only the Vector3 types, but also Ints and Chars to indicate:
- The implicit direction of travel that a car must be facing.
- for example, Intersection 1 is a four-way stop. An entry Vector3 facing North would indicate a stopping point for the car facing North and an corresponding exit Vector3 with the car facing South.
- The number of the intersection.

The deque was used for scripting individual car routes (I have 5 vehicles that are mix of cars, trucks, and a school bus). Initially, it was a simple matter of adding each entry and exit point to the route deque's. During each frame update, the current position (Vector3) is compared to the list of Entry Vectors, which indicates a stopping point for the vehicle (curves were seperated from Entry and Exit Vector lists) and an algorithm for slowing the car was used (below). The hard part of the deque's (made hard by my own inability to just do some research first), and something I think I mentioned already, was calculating the turns through intersections and curves. The algorithms I attempted based on some math (sin, cosine, etc), never "quite" worked right. I ended up calculating manually a minumum number of points of a turn and adjusting the Vector3's x and z values. I added no less than seven Vector3's to between each Entry and Exit point on the deque's.

The stopping and restarting of the vehicles was fairly simple to transform into an algorithm to use during each frame update (I did not seperate this out into another class as I think it would have added more coupling than neccessary). Basically, what I did at each frame update was take the precent of change in distance to the stopping point (<=30 from Entry Vector3), and slowed the car by the same delta. To prevent any negative values in direction (makes the car go backwards), I tested for any distance <= 0.5. If distance was <= 0.5, the algorithm automatically set the wait timer to 30, distance to 0.0, and current position = destination (Entry Vector). This basically "snapped" a car to the stopping point and initiated the stop wait timer.

The Camera views, and toggling them, was a little difficult and time did not allow me to finish this aspect. The current prototype has one camera (movable) that overlooks the "city" I created.

Futre Plans/Increments:
As time permits, I would like to do more with this project, if only for myself. There is an OGRE physics engine that I have seen used for car movements and I would like to incoporate this. I also plan to revisit not only the multiple (toggling) cameras, but a more dynamic way to script out the movements of the cars that are not being "driven" by the user.

OGRE provides support for peripherals suchs as joysticks and I may be interested enough in the future to play with this for the driving simulator. However, right now, the actual "driving" of the car will actually be "camera view."

I also want to look at how storing Vector3's for a turn compares to a more dynamic approach of using a turning algorithm/function. I am curious as to the comparison of:
- storing and popping a turn algorithm as compared to a method that calculates the Vector3 of a set number of points on a turn. It is the memory used versus the processor time used that I am curious about.

The bottom line is that I really want to find some extra time to create the next increment on this prototype. I realized too late that there are some definite improvements I could implement to make this simulator: more realistic, more efficient, and more fun. The OGRE API, and the additional physics engine, definitely provide all the means to transform this prototype into what I want it to be. My middle daughter is only 8 years old, so I have at least seven years to perfect this program. :-)