maandag 4 april 2011

Creating a simple race track

In this blogpost I'm going to show you how to build a simple racetrack using two splines and a texture using loft in 3d studio max. With this method you can build and texture a track in no time and have a lot of options to adjust and edit your track without messing up the mesh or the UVW coordinates.
First we need to create the shape of the track using a spline, next we need to determine the profile of the road also using a spline. In this example I've made a shape that resembles the profile of the road and the sidewalk.
Now we are going to create the track using loft. First select the track spline, go to the Create tab and select "Compound Objects" in the drop down menu. Now press the Loft button and change Instance to Copy in the Creation Method menu. Now press the Get Shape button and select road profile spline. The result can be seen in the image below.
Turn off automatic banking in the Skin Parameters menu, we'll add the banking manually
Note: Sometimes its necessary to flip the objects normals. There is a flip normals option in the Skin Parameters menu.

A big advantage of the loft is that it automatically creates usable UVW coordinates. Now create a road texture and apply it to the track mesh. You can set the tiling of the texture in the Surface Parameters menu, now tile the texture until it looks ok.
And what if you have done all this and you're just not happy with your track shape? No worries it can easily be adjusted without messing things up. To edit the spline expand the Loft menu by clicking on the Plus icon in front of the Loft text (see image below). Now hilight Path, as you can see Editable Spline appears below, now click Editable Spline and start editing you shape. In this example I've raised some of the vertexes to give the track some higher parts. When you're done exit the Editable Spline menu and go back to the Loft.
Now we'll add some banking to the corners, this can be done using the Twist option in the Deformations menu. Here you can determine the banking of each part of the track.
Fiddle around with all the options in the Loft menu to see what they do. Here's a close up image of the end result.
That's it for this post,
Cheers Matt

vrijdag 18 maart 2011

Test Day

Dear readers,

Today is the test day for one of our games. Luckily it's not my game being tested as it always provides some stress. As a tester you have to try to find bugs by trying many actions. If at a certain point you encounter a bug you have to remember what actions you did that led you to the bug. Then you try to reproduce the bug. If you can't reproduce it then you either forgot to do an action or the bug is very subtile or time-related. We also tag our bugs with priority. Naturally a bug that prevents game progress is a bug of high priority. Bugs like "this button has the wrong text" should be fixed but are of lower priority. Other bugs like the one shown in the screenshot below (where an explosion decal is partly in air) are not very useful to commit as they won't be fixed due to it being too hard to fix. Removing it all together however would cause lack of detail (you'd miss it).



An explosion decal is partly in air.

Luckily I didn't find many bugs in the part I was testing or perhaps I didn't test well enough (there are endless combinations) :P

-- Stijn

donderdag 17 maart 2011

Happy face....sad face.

It has been a while but here's finally another blogpost by Matthew. After some nagging, begging and harassing programmer Stijn approved one of my "feature requests" (probably just to get me off his back). The feature that got approved was some relatively simple face animation for the player character of Rhino Rush. The Rhino only needed some basic expressions like smile, fear, hurt etc. Here's how we set it up.


Stijn finally added some code to dynamically switch between the expression meshes. Even these few expressions give the rhino much, much more character. Looking at the end results gave us both a happy face expression. :)

Matthew

woensdag 16 maart 2011

Something new

Hello readers!

 As you might know modern console games use a lot of pixel and vertex shaders to draw their 3D worlds and characters. Slowly we also want to go in this direction with our own games. But this comes with a lot of technical difficulties, also seen the platform we're developing on.

Today I made a 3d model for Pieter to do some tests with. It has 'next-gen' specs (although you could call it 'current gen' these days). It uses a diffuse, normal and specular map.

First I made a rough highpoly version of the fusebox. Which I used later to get the basic normals information from. I made the main shape out of some 'plate' like elements, as it would have been constructed in real life. I kept the rest of the highpoly simple and added all of the smaller normalmap details during the texturing stage.

It was nice to be working on something new, something we don't usually do. Normalmaps are always some kind of magic to me, makes everything pop so much more :)!

-Joep

maandag 14 maart 2011

Still alive!

Hi all,

A short, but important update. We’re still alive! J
As Stijn told you in his previous post it has been very busy for all of us in the last few weeks. I it is not likely that this will change any time soon,  but this also means that we’ll have some cool stuff coming up/out quite soon!

Rhino Rush will be released soon on a portal near you and we got a nifty first person shooter thingy planned. Definitely keep an eye out on this one as it will push Shockwave to its limits. There will not be a cooler and visually more impressive online first person shooter on the webZ!

Currently I am finishing up an update of one of our hit games which needs to be tested internally at the end of this week. Not really looking forward to it as it’ll mean everybody will be shouting and screaming at me about things that aren’t working/unclear or are, simply put, ‘stupid’. Sigh…  anyways…

To end on a positive note. Diederik, Matthew and myself were at the GDC at San Francisco and we had a great time, met a lot of cool people and drank some beers J
It was a good visit and based on this we have some cool things to look out for this year. From now on we’ll update the development blog more regularly again so, if somebody is out there, keep checking for updates!



Cheers,
Pieter

vrijdag 11 maart 2011

Rhino Rush Wrap Up

Dear readers,

It's been a while since any of us has written anything (and I for one am deeply ashamed for all of us (and especially for Matthew! ;D)) but don't worry Xform is still alive!
The past few weeks have been busy for all of us, but I'll let the others inform you about that ;)
The platform game I've been working is now pretty much ready for release and to this end I'd like to treat our dear readers to an exclusive shot which is my personal favorite.

This animated image is a APNG-file, internet explorer might not play it.

So I've been working on the last few fixes and cleaning the code up a little here and there (removing code/comments that got obsolete during development and small optimizations). There are some things that in hindsight I would do differently but you really shouldn't make too much changes to the game when you're close to a release as it might have more side-effects/bugs than you originally think. And then you'll have to fix those and you lose a lot of time. There are still some things that bother me and Matthew but we don't have time to change them. Expect a post on the official release of the game soon!

-- Stijn

vrijdag 4 februari 2011

Shoot the crate

Dear readers,

Let's talk about something different than the platform game I'm working on. Last week one of our interns had a problem with the physics engine. The scenario was as follows: We're playing a character in first person style and we're holding a gun. We can walk around in the world and there are some non-static crates: if you bump into these they will move. This is all handled by the physics engine itself, there is no effort required by us to set forces or anything. Nice. But now we want that when we aim our gun at the crate and shoot, that the crate receives an impact and moves and spins realistically.

One solution here is to actually create a bullet and make it follow the path along our crosshair. As to whether this is a good solution I'm not too sure: bullets have to travel at high velocities which is something that could 'bug' the physics engine and unrealistic events might occur. I'm not sure this would occur as we haven't tried this solution. Additionally you'll need to create and delete the bullet (on impact) as well as keeping track of it: what happens when we fire the bullet into the sky (i.e. there is no impact, the bullet flies)? The bullet wouldn't get removed. Although you'd probably have to shoot a lot of bullets into the air before you'll notice a performance drop, it's sloppy. So you'd either have to give each bullet a lifetime as well and update it and remove it when its lifetime runs out or seal the world so bullets will always impact. This could all be done, but it's a bit of a hassle and as I said you might get unexpected results. Let's explore another solution.

Solution two is to immediately apply an impulse ourselves. So we cast a ray along our crosshair and get the first intersection. If this intersection is with a crate then we'll apply a force on it. But to apply a force on the crate the physics engine requires us to give a point on the crate and an impulse. Our impulse is whatever we like: for a small caliber gun we could give small impulse and the crate will move just a little. The problem here is that the physics engine requires us to give a point on the crate in it's local coordinates, whereas our intersection point is a point of world coordinates (see image below).

Here W is the center of world (0,0,0), while C is the center of crate (0,0,0) in its local coordinates. Ray r is the ray along our crosshair and I is the point of intersection.

As said, intersection I is returned to us in world coordinates, while we need it in the crate's local coordinates. You might think "Ok, so just take I and substract C (in world coordinates) from it", but this is only correct when the crate isn't rotated. Rotation needs to be taken into account as well because if we take the same crate and rotate it 90 degrees, you'll still have the same intersection point, but a different local coordinate. To get the correct local coordinate of the intersection we need to look at the transform of the crate. The transform is a matrix M which determines the model's position, rotation and scale with respect to its parent (in this case the world). When the model is drawn to the screen all of its vertices are multiplied by the matrix M to get to the world position. So what we need is the opposite: the inverse of matrix M. The inverse of matrix M is a matrix M' that satisfies: M * M' = ID where ID is the identity matrix (that matrix with 0's everywhere except on its diagonal it has 1's). Multiplying the identity matrix by a vector will result in the same vector: there's no change. Multiplying the inverse matrix M' of the crate by C (in world coordinates) will give us the local coordinates of the crate. Hence if we multiply the inverse matrix M' by the intersection I given to us in world coordinates we obtain the intersection in the crate's local coordinates, which is exactly what we want. We pass it to the physics engine and it works perfectly :)


Multiplying M by the Ilocal position brings us to the Iworld position. Multiplying M' by the Iworld position brings us back to the Ilocal position.

-- Stijn