Monthly Archive for September, 2009

OpenGTA2 segment tracing

I’m using point vs level collision for OpenGTA2 maps, and it is implemented by tracing few rays to where pedestrian may go, as I said in previous post. In this post I will try to describe how this ray tracing is actually implemented – it’s a very simple algorithm, really.

First, we will need this illustration (this is the situation we’re having, with our segment we’re tracing against that triangle):
seg_trace

Before even attempting to check if this line collides with the triangle, let’s just compute our triangle parameters (two vectors that define it, and triangles normal):
V1 = p2 - p1;
V2 = p3 - p2;
triNormal = Vector3f::Cross(V1,V2); //cross product: V1 x V2

Also we should compute vector for our line (let’s not normalize it… you’ll see why later):
lineVector = (lineEnd - lineStart);

Now, there’s instantly first thing we can do – let’s check if our segment (line) is parallel to our triangle. This would mean 90 degree angle between triangle normal and line vector (they are perpendicular). If this happens, then their dot product (Vector3f::Dot(triNormal,lineVector) in OpenGTA2) will return value of zero. If that is so, we return false, because there is no collision for sure.

Also, if their dot product is higher than zero, they are facing different direction (cosine of angle is higher than zero, that means angle between them is less than 90). That means we return false as well.

Now, if triangle normal and line vector are facing different directions, the triangles plane and the line collide for sure – let’s find the collision point. Now through some math we can solve equation for point position on the plane. Warning vector math ahead.

  1. Any point on line can be written as lineStart + lineDirection * t, where t is some scalar constant. lineDirection vector must have length of 1. t is the distance from lineStart to this point.
  2. For our case lineVector = lineDirection * |lineStart - lineEnd|, because its direction is same as our line direction, and its length matches length of entire segment.
  3. This means we can write collision point position as lineStart + lineVector * distance, where distance is equal to T / |lineStart - lineEnd|.
  4. This means that distance will be 0 in lineStart, it will be 1 in lineEnd. It will be over 1 if collision point is beyond this segment, and under 0 if this collision point is before this segment (but we will never occur the latter).
  5. Now let’s find vector from P1 to our collision point (basically it’s location of this point on our plane, sort of): lineStart + lineVector * distance - P1
  6. Now we use simple equation that tells us whether point lies on triangle – if the point lies on triangle, angle between the vector to the point we found in earlier step, and triangle normal will be 90 degrees. Cosine will be zero, so we can use dot product to find this out: triNormal . (lineStart + lineVector * distance - P1) = 0

Now let’s just perform a series of transforms on it:
triNormal . (lineStart + lineVector * distance – P1) = 0
triNormal . (lineStart – P1) + triNormal . (lineVector * distance) = 0 (we opened the parentheses)
triNormal . (lineStart – P1) + distance * triNormal . lineVector = 0 (got the distance out of the dot product, it’s a scalar, we can do it)
distance * triNormal . lineVector = -triNormal . (lineStart – P1) (just moving some junk to the right…)
distance = -(triNormal . (lineStart – P1))/(triNormal . lineVector) (it’s a scalar, so we divide by it… oh wait, that’s an answer! yay!)

This is the result of our mathematical ramblings:
float distance = -Vector3f::Dot(triNormal,lineStart-p1)/Vector3f::Dot(triNormal,lineVector);

Okay, so as I said before, to check if our segment collides we just need to check if this distance is in range of 0 to 1.

But wait! There’s more! You noticed we didn’t check if our point actually lies inside the triangle. To perform that we will do what they call a clockness test. This test tells you if three vectors are listed clockwise, or counter-clockwise (if you start with vector 1, then you move on to vector 2, and then you move on to vector 3).

Clockness test for a triangle is this:

  1. Compute normal for triangle that is defined by P1, P2 and our collision point.
  2. Check if normal is same direction as triNormal (this means ((P2 - P1) x (CollisionPoint - P1)) . triNormal is larger than zero)
  3. Also repeat for these pairs: P2, P3, and P3, P1. If clockness on all of these is same, then our point lies within our triangle.

Okay, well, if you don’t understand that, don’t worry, I’ll just give you the function that performs clockness test (look below).

Well, all this should suffice for a ray/segment collision check. To summarize: check if ray is parallel (note: don’t forget to actually check if ray lies within triangle, I forgot to do this, I’ll fix this and will post a new post later), check if ray aims at triangle plane, check if collision point lies within triangle.

Continue reading ‘OpenGTA2 segment tracing’

uZASM compiler

This is something I’ve wanted to do for entire previous day – I wanted to write ZASM compiler in ZASM. So I did write it, and now you can compile ZASM code while running ZASM code on ZCPU. Really, it’s a bit cut down version from it’s bigger brother, but it’s sufficient to create simple programs.

zasm_output

Yes I know about the obvious joke that I’m obligated to make. Yes, we put ZASM in your ZASM so you can code while you code. Also there’s both standalone frontend (to use it in your own applications), and frontend for Fizyk AlcyoneOS. You can use it with OS’s notepad application to write programs right there, on console screen, and then compile it on very same computer.

gm_bigcity0048
gm_bigcity0045

OS filesystem allows you to store your program and sourcecode! Also, yes, this how it works: you’re compiling a computer program inside an OS, inside virtual machine inside virtual machine inside game, inside OS inside computer. It only took 1.5 hours to write the compiler, and then I just fixed some bugs and added support for labels (although limited, see below).

These are the features:

  • Support for all ZCPU opcodes
  • 128 preset labels you can use (named @0 through @127)
  • Support for reg, #reg, 123, #123 operands
  • Can output files in COM file format for AlcyoneOS
  • Very quick (in ZCPU terms), and can run own code after compiling

You can see source code for the compiler core here, in GWCD SVN. (username: anonsvn, password: anonsvn)

OpenGTA2 collision system update

I’ve been working on OpenGTA2 again! I’ve fixed a lot of bugs, and found a lot more (I organized them into a neat text file listing all known bugs…).

First of all, I’ve finished pedestrian collision detection. Pedestrians are simulated as a point, whose collision is tested against the map. To do this, I trace three rays – on each axis of movement (X ray, Y ray, and Z ray). I’m tracing them slightly above pedestrian (the height depends on how steep slopes can be for pedestrian to climb on them) – and then just blocking pedestrian from moving on certain axis if ray hits the surface (ray length is equal to pedestrian movement within one frame).

To illustrate this let me show you screenshot from the collision debug mode:
opengta2_collisions

You can see how rays hit obstacles. That information is used to block pedestrian movement (or let him move) – and this works for any map geometry (even I make block shapes much more complex than it is right now). The trace is also very cheap, and fast – so is the pedestrian physics simulation (I hope it will allow us to have a giant amount of pedestrians!).

I’ll write about the actual math behind this tomorrow – it’s late today, I’ve had a great birthday, and I’m lazy to draw all the math illustrations at the moment. Not even talking about writing text to accompany them here….

X-Plane wind tunnel

I’m working on a script for X-Plane – a wind tunnel. What it does: it allows you to put your aircraft into any windstream you desire, and automatically gather specific data (for example angular accelerations based on control surface deflections). It’s also really useful when designing aircraft shape, as it can tell you if your center of mass (CG) is off, or how you should ballance it.

In fact even more, later it will show you how your CG should be changed as your aircraft looses weight (fuel burns away), and as you get higher (less density), and faster (higher speed). Ideally this should be a constant, but it may vary in planes.

This system will help one to build perfect autopilot system (which can instantly compensate any angular acceleration, it contains a matrix of angular rates vs current airspeed, which is used to compute perfect control surface deflection for given angular acceleration). These are simple graphs that it produces, I’ve put my X-30 Venture into airstream under different angle of attack (AOA):
graph_drag_lift
(SASL, the plugin I’m using to run Lua inside X-Plane doesn’t properly render fonts on my machine, so I painted those over. The graph spans AOA from -90 to +90 degrees).

This is how it looks inside simulator (yes, you can move your control surfaces, change wind speed, change aircraft attitude in realtime, and it draws you a graph. Later this will all get a GUI where you can configure everything):
screenshot_50

More about the perfect autopilot: some real autopilots use a table of values – and they use a function that interpolates data in that table. This function is F(KIAS, A) = DEFLECTION, where KIAS is aircraft indicated airspeed (basically windstream that blows on it), A is current angular acceleration (the one we want to compensate), DEFLECTION is the resulting control surface deflection we want to apply. F is our function which interpolates between known values for KIAS, A, DEFLECTION measured in wind tunnel and during flight testing.

The set of variables may vary, but the general concept is the same. In reality, this function/matrix of values is computed mathematically, then enhanced using wind tunnel models, and then enhanced once more during aircraft flight testing.

XS8

I’ve completed XS8 space mission in X-Plane! This one was first really serious space mission. Just look at this: it’s 25 hours long (including 24 hours clear on orbit), it uses most advanced spacecraft I have in possesion (X-30 Venture with all of it’s detailed systems), at least four people worked to make it happen (me as pilot, Wraith as mission support, Hunter NL for voice transmission support, Mick as local ATC and air dispatching service upon return to Edwards AFB).

The launch and return were performed live online on X-Plane.org’s flight server. The return was coincidental (although this was done on purpose) with a general fly-in to Edwards Air Force Base (X-Plane.org server people organize weekly fly-ins to a certain location). Of course there were many people waiting for the spacecraft to return! I won’t really hide it from you, the mission was successful.

The mission spans time interval of 16:00 UTC, September 5th to 17:00 UTC, September 6th

Now, short overview of the mission (full original description here):

  • X-30 Venture internal systems were tested – and they all worked nominally (although one of two RGA, the rotational gyro assemblies, was lost at roughly 6 AM UTC, September 6th). Not all systems were properly simulated on this flight, but these ones were: hydraulic system, electric system, on-board computer system, rotational hand controller & input, panels and switches, partially reaction control system, partially engine system, and rotational gyro assembly (the gyroscopes)
  • XNAV system worked great. Many people connected using their terminals, and received live telemetry stream from ships computers, exactly what the on-board computers decided to output!
  • I’ve gathered telemetry from the flight, although I accidently erased over 100 megabytes of it (which was recording of all on-orbit time… too bad!). Although I’ve received very detailed telemetry of the ships return to Earth
  • My orbital engine firings (or possibly the X-Plane itself) resulted in inclination changing from 57 degrees to 61 degrees, and I successfully changed inclination to 63 degrees, which allowed me to reentry right over Edwards AFB. Although I overshot by 200 miles, it was my own stupid mistake, cause I started de-orbit burn 200 miles later than expected
  • Both orbits were visited (although I’ve used 700km instead of 600km, and inclination different by 1 degree)

Everything went smooth. The autopilot software wasn’t yet complete, so I have been flying all this in a fully manual mode. Including launch, reentry and landing! I’m afraid I didn’t analyze the reentry data yet (I’m lazy, really), but I can show you approximate graph of reentry profile for this X-30:
reentry2_text

I’ve counted 24 hours on orbit, and 13 circles around Earth on two different orbits. This was the maiden space flight for the X-30 vehicle, right now it counts 1560 minutes of flight time, with 1440 minutes in space. During this time I’ve had to restart the X-Plane 4 times (although preserving all state, I’ve wrote separate application for it).

Over indian ocean at about 2000km:
screenshot_29

Somewhere over China:
screenshot_23

Guess where:
screenshot_35

Performing burn to change from 2600-700km orbit to 135-700km orbit (and prepare for pre-deorbit orbit):
screenshot_40

Final look at the Earth after deorbit has been complete (the X-Plane Earth by default doesn’t have atmospheric halo… it’s a bug/lack of feature). This looks completly badass in a video, I’ll show you whenever I can (it’s not easy, I will have to downgrade to 9.31 from 9.40, because replay format changed…):
screenshot_47

Continue reading ‘XS8′

Rocket forces museum

I’ve been to museum of rocket forces of Ukraine this summer! It’s based on Soviet Union times missle silo, which is now not functional (the missle silo itself was filled with concrete, and communication cables with Moscow were cut off. But apart from that, everything else pretty much works).

We’ve been over ground, and also went down into the actual command center. It is a 45-meter high 3-meters in diameter cylinder, divided into 12 levels. It is supported by several legs, which damp any earthquake, and there are containers that store 30 tonnes of ice for coolant. It can survive completly isolated for 45 days – and it survives several direct nuclear strikes. It is the safest place in Ukraine.

I actually got stuck for some time on lowest level of the command center! The elevator broke, and it didn’t want to go up from 12th level (so we had to climb up to 11th level, and elevator worked from there).

I’ve brought you some photos too! There’s just too much to describe, but I’ll try to accompany each photo with some description.

SS-18 Satan rocket (one of these wipes out 1/3rd of Ukraine):
IMG_0316

Rocket engine for the PC-18 rocket:
IMG_0284

Same rocket engine, those small nozzles are RCS (reaction control system) of a sort, they are used to rotate the stage around while it’s in space, and correct it’s flight.
IMG_0288

Continue reading ‘Rocket forces museum’

Antonov Intl.

Antonov international cargo airport is only 6km away from my grandparents house – where I always stay during summers. So once in a while I’m taking a bike trip there, and I’ve brought you some photos from there (and I kind of tresspassed to get them, but nothing really serious. Although once someone noticed me and shouted “hey boy!”, so I ducked and they thought I ran away).

Distant view (you can see tail of some old soviet aircraft there):
IMG_0438

Near the base of runway, and near the approach/landing lights (at least I think they are called like that, they are rows of bright strobes mounted on yellow supports):
IMG_0429

The bigger hangar in distance, which never really got completed (it was like that for at least 8 years):
IMG_0490

Antonov An-225 Mriya in the distance. In it’s new paintjob!
IMG_0496

X-30 cockpit panels

There is a real lot of panels in X-30 cockpit now – because every system is simulated in great detail, you can control many aspects of your spacecraft, and like real spacecraft there are actually hundreds of switches that unprepared person would simply ignore (there is a great chance that by touching them you’ll shut down something really important to your flight).

Well, not all panels are done yet (I didn’t actually draw the backgrounds for them), but here is the collage of some that are ready:
panels

Also I’ve been working with fonts rendering in SASL, I’ve created a glowing LED font – and used that to make a really nice MET (mission elapsed time) counter. It actually glows, and you can notice how it’s brightness goes down with greater electric load, just like on real LED screens of this kind:
met

Here is caution/warning panel in better detail (most of those lights are wired to control lines coming from central computers, but some of them are hardwired logic. For example “DC BUS OVERLOAD” will light up even if computers are disabled):
alert_cw

Caution/warning (annunciator) panel can be controlled using fuses A1 (turns off power to lights), A6 (turns on all lights, for testing) and A5 (disables hardwired lights from being lit up).