Copyright 1999-2013 (c) Synthetic Reality Co

Synthetic Reality:
Company Store
Contact Us

Well of Souls
Warpath 97
Warpath Classic
MIX Game Server

Rocket Club
Galaxy Simulator

About Us

Another in a series of programming experiments. This program is FREE, not shareware. Just enjoy it.

What Is synVertigo?

This is another of those ideas which came to me while driving along I5 from Oregon to California (well, technically I should say being driven, since my lovely wife does all the driving. This leaves me with plenty of time to stare at the passing scenery).

Basically the justification for the program was to see if I could get a reasonably high frame rate of 3D rendering using Microsoft Foundation Classes. But along the way I thought it might be interesting to see if it was possible to have a program generate the same level of vertigo-induced fear that I find myself feeling in certain high altitude circumstances. Partially, I reasoned, such a program might be useful in desensitizing someone against that panic (hopefully not so desensitized that they then freely jump off the next high building!)

I got distracted during development and ended up just focusing on the frame rate issue. Perhaps I will return to this project and do something more interesting with it. As it is, you have no control whatever. It just does a lissajous flyover a city, looking straight down. On a Pentium 2 300Mhz the frame rate hits my target of 25 frames per second with 100 buildings. Not very spectacular compared to 3D hardware accelerated programs, but this is a simple MFC app using GDI calls for the drawing

Running the Program

Well, just download the executable and run it.

synVertigo version 1.0 synVertigo.exe

It is a SDI-based MFC app written in VC++ 4.2b

While it appears that there are some controls, these are just the fluff which VC++ generates automatically for you and that I was too lazy to even remove. (My justification being that I would eventually add a parachute/hangglider simulation and then I would need some of those controls - but really I was just too lazy, I only had a budget of 3 hours to write this program, and I ended up spending 2 of those on the fractal city builder again.)

If you left-click in the window, it will generate a new city.

Along the top of the window is a line of text indicating:

  • FPS: Frames Per Second (25 is the max possible)
  • #visible: How many of the 100 buildings have NOT been clipped
  • #polys: How many polygons were drawn this frame
  • #collisions: How many buildings are we actually INSIDE of at this moment

The Math

The basic 3D math is the same as in synVista, so I won't go into that here. The vaguely interesting bits are:

  • I have been generally unsatisfied with the jerkiness of frame rates in an MFC application when using the standard or multimedia timers (WM_TIMER message). Also, I find that it is only too easy to perform operations within the WM_TIMER handler which are not safe. What I did in this program was override the ::Run method of the CWinApp class and basically stick a call to a new method "DoTick()" in the middle of the idle loop of the ::Run method. You have to be a little tricky to prevent windows from lowering your priority, but it isn't all that hard to get it right. This would then basically call DoTick() as fast as possible (whenever not handling other messages). However, that would create a situation where the program would be unpleasant to look at in 20 years when processors are all running at 30 terahertz. So I put in an explicit check and will not call DoTick() within 40 msec of the last time I started it. This creates the upper limit on frame rate of 25 hertz. DoTick is the number cruncher which moves the viewpoint and rebuilds the polygon display list. Then it invalidates the window rectangle and the OnPaint handler paints the polygons.
  • The city is an array of building objects where each building is defined by the x,y of the center of its shado on the ground, a Z value which is its altitude and a few extra values for future cleverness. The first thing DoTick() does after calculating the new view location (moving the camera, I mean), is to sort the list of buildings by their distance to the viewer. At this time any buildings whose shadows are completely outside the 'view pyramid' are discarded. The result is a sorted list of buildings inside the viewing pyramid. We then generate a list of polygons (3 4-sided polygons per building) starting with the most remote building and working towards the closest one (this provides the hidden surface elimination).
  • For each building we need to determine which of the 3 surfaces we can see, and which order they should be drawn in. This is done by determining which 'octant' the center of the building is in relative to our position (the more clever way to do this would be to compute the dot-product between a 'normal vector' sticking out of the polygon and a vector from the center of the polygon to the camera. Based on the sign of the dot-product we would know if the polygon was visible or not. BUt I was able to use this cheat since I knew I wasn't going to be viwing the buildings from all possible angles.
  • For each possible octant relative to camera position, I computed a list of the polygons in the order they should be drawn. Again, a simple cheat. At the last possible second, the actual 3D coordinates of the 8 points which comprise the building's corners are computed and transformed into 2D screen coordinates using the normal linear algebra described in synVista. The 2D polygon is then added to the end of the polygon list and the next building is processed. When done, the polygn list is perfectly sorted by distance (furthest away polygon is first in list). If the camera stops moving, this polygon list can be kept around indefinitely with no additional computation required.
  • The OnPaint handler does no thinking at all and just renders the polygon list as fast as it can (in this case I just use calls to CDC::Polygon)
  • The fractal city planner is similar to the fractal world builder used in synVista, only instead of breaking the world into 4 equal squares per recursion, I just cut it in half, either horizontally or vertically (random selection made at each level of recursion). The recursion proceeds by cutting the area into smaller and smaller pieces, withthe probabilty at any level that a building will be emitted filling the current piece instead of further recursion. This results in buildings coming in 3 basic shapes: square, horiz. rect, and vert. rect.
  • The tricky bit is that the probability of a particular piece becoming a building has to DECREASE the smaller the piece becomes. Otherwise all the bits get stuck in one corner of the available space since the recursion is NOT done as a parallel process.

synVertigo is the property of Synthetic Reality and all rights are reserved. If we can figure out a way to convince people to pay for this, you can be sure we'll give it a try. But for now it is expressly intended to provide a moment of joy for the math geeks in the audience, looking for number-crunching programs to show off their power computers!

Thanks for your feedback in advance!

Dan Samuel
Synthetic Reality Co.