Jump to content

  • Log In with Google      Sign In   
  • Create Account

- - - - -

Building An Isometric Game Using Horde3D (Part 2)

Posted by JTippetts, 01 August 2011 · 3,208 views

Constructing Geometry Using Anti-Aliased Sprites
As a jumping off point for trying to use pre-existing anti-aliased rendered sprites, I want to create a few geometry primitives using some pre-rendered assets. For the first tests, I'll set up a set with a basic floor tile, a floor decal for decoration, a left wall, a right wall, a roof, and a basic wall decal for decoration. This will give me a good set to test with and, hopefully, help me to see where I'm going to have issues.

To begin, I'll just go ahead and grab the assets I made for the SFML isometric post.

Then I'll fire up Blender and map those sprites to some geometry. The way I do this for a 3D-based game is to create the geometry to match the shape and orientation of the sprite. I do need to construct the wall geometry to be of the proper height, in pixels, on the screen. This means taking into account the fore-shortening introduced by the camera angle.

With a 2:1 tile-ratio dimetric projection, the camera angle above the horizon is 30 degrees, the angle around the Z axis is 45. Now, going with the above assets which are 64 pixels wide, this means that the total cell on-screen size is 128 pixels wide. Ignoring the 30 degree azimuth angle for a moment, we can calculate the length of the cube edges using the Pythagorean theorem, a^2+b^2=c^2. The hypotenuse is 128 pixels long, and the cube sides are the same length, so 2*a^2=128^2. Solving for a we get a=sqrt((128*128)/2) or a~90.5. So if the cube edges are approximately 90.5 in pixel units, then we now take into account the foreshortening of the vertical axis by the 30 degree azimuth angle, by multiplying the edge length by cos(30), to get approximately 78.384. Thus, taking the 64 pixel width of the isometric wall sprites, a unit cube on-screen will be approximately 78.384 pixels tall. We can prove this by firing up Blender and rendering a unit cube from the dimetric viewpoint to an image of the appropriate size:

Attached Image

If you open that image in an image editor and put the cursor at the apex of the near corner of the cube, you will see that it is approximately 78 pixels above the bottom of the image, so our math works. Now, the wall assets I created for the SFML isometric post are 256 pixels tall, and 64 pixels wide. The vertical axis represented is 224 pixels. Dividing 224 by 78.384 we get 2.8577. This is the amount we need to scale the unit cube by, vertically, in order to obtain geometry that matches the 64x256 size of the assets.

This stuff can get confusing, I know. One of these days I might try to write a more comprehensive guide, but for now I'm not too concerned about it. If we go back to Blender and apply the vertical scale to the unit cube, then re-adjust the output image dimensions to 128x256 (showing both the right wall and the left wall) and render, we'll get something like this:

Attached Image

You can see that this is the right size to get the full left and right walls. Now, since at this stage we are just trying to build geometry for the wall planes, we can go ahead and delete the "back" vertices of the cube:

Attached Image

This removes extraneous geometry and leaves us with just the wall planes. Now, we need to separate the planes into separate objects. We do this by entering edit mode, selecting the 4 vertices that form a wall plane, and hitting p to separate the selected pieces. This leaves us with 2 wall planes. The only thing left to do now is UV map them. Select a wall plane, enter edit mode and select all vertices, switch view to Camera view, press u to Unwrap, and select Project From View (Bounds). This will map the UVs from the camera view, and the result is something like this:

Attached Image

Do the same with the other wall piece. From here, it's a simple matter of applying materials to the wall pieces and exporting them to Collada for conversion, then loading them into the game framework to see the results. Here is a test run with the left wall piece:

Attached Image

The image is scaled down so you can't really see it, but there are filtering artifacts due to small math imprecisions. I'm still using the default shaders. I'll be replacing them with more appropriate ones that will disable filtering to avoid those artifacts soon.

The floors, roofs, and floor/roof decal geometry setups are similar, though much easier to do. For those, I simply use a 1x1 plane oriented on X/Z.

Next up, I'm going to figure out a drawing order and re-write the basic shaders I'll be using.

Attached Thumbnails

  • Attached Image
  • Attached Image
  • Attached Image
  • Attached Image

Great post :) Everyone hates assholes!

I've decided to sort blended objects in my project and only have blended objects when its really needed (windows, fires etc.). Though my sorting algorithm is rather crapy. I'll look forward to future posts.

The sorting problem has been... uh.... sorted. I'll detail it further in the next post, but basically it has to do with the way I did the isometric camera. Turns out, the sort in the h3d engine uses the fabs() of the distance, so nodes that fell behind the camera eye point weren't sorted correctly. The fix is to offset the camera upward on Y, then correct the position on X and Z in SetPosition accordingly.

Hi O-san! How's Medieval Story coming along?
Tiny steps - a week at a time, difficult to keep it going when you got a full-time job. Other ways its going okay :)