Still at it after five years, I see.
I think what you're doing is pretty cool. I've been doing this professionally now for about 14 years including an AI system or two, and must say that it's pretty rare to see somebody doing what you're doing. I've written an AI system too, and you probably could not have picked a more difficult challenge. AI is hard and judging by your video you're doing a great job so far.
I haven't read the whole thread, but seem to remember when you were starting out on this. I'm looking through post 316 from last Wednesday and it looks like you're using trig to solve everything instead of using rotation matrices and vectors. Using those you can solve everything in 3D and a lot of the stuff it looks like you're trying to do may become a lot easier. Have you looked much into these yet?
There are few basic operations that can help. Forgive me if you know this already, but with all the sines and cosines I see in post 316 I'm thinking maybe this might be new for you?
If you want to compute the angle between two 3D vectors, you can just compute the dot product of it like this:
dotProduct = Vector1.x * Vector2.x + Vector1.y * Vector2.y + Vector1.z * Vector2.z
This gives you the cosine of the angle between the two vectors. For your purposes this may be enough if you're doing steering and so on based on the angles. The actual angle in degrees or radians may not be important to you. If it is, you can just do an arc cosine operation to get it in radians:
angleRadians = arcCos(dotProduct)
Not sure what language you're using, but it will probably have an arc-cosine function to do this somewhere if it's doing trig. If not, you can compute the arc-cosing using other trig functions. Will leave that up to you to Google.
What I would probably end up doing in your case is build a 3x3 rotation matrix for the car if you aren't able to pull that matrix directly from LFS. A 3x3 rotation matrix is really just 3 vectors grouped together that are always perpendicular to each other. The driver's forward vector you describe is one of them and points forward. Another vector points up, and another vector points either to the right or left depending on your coordinate system.
You need a forward direction vector (normalized to length 1) to start with which it looks like you already have (driver or car forward vector, I'll just call it "car forward vector"). To build the rest of the matrix I bet you can cheat a little bit since the tracks are pretty flat and just assign an "up" vector that's always 0,1,0 (or whatever it is in your coordinate system).
Next, you construct a new vector that's perpendicular to that "up vector" and the car's forward vector. You do that with a cross product operation. A cross product of two 3D vectors works like this:
Result.x = Vector1.y * Vector2.z - Vector2.y * Vector1.z
Result.y = Vector1.z * Vector2.x - Vector2.z * Vector1.x
Result.z = Vector1.x * Vector2.y - Vector2.x * Vector1.y
"Result" is a 3D vector just like you're car's forward vector is, but this one is perpendicular to the other two. Since your other vectors were "forward" and "up," this one points to the right or left side. For now I'm going to call "result" the "right" vector.
To keep things simple and see if this is at all interesting to you, I'm going to skip something here. Really what you'll want to do at this step is create another vector or two. This will allow your driver to see in actual 3D and remove the simplification that I made where we assume "up" is the same in the car's space as it is in the world's space. It would replace that first 0,1,0 vector we made with a new "up" vector that points up relative to the car instead of the world. With this, if the car is rolled at a 52 degree angle or going around a banked turn or down a steep hill or something, the reference points you describe will move up and down and spiral all correctly from the driver's perspective. You won't scratch your head anymore over the directions and relative orientations of any of this anymore, and you won't ever use another sine or cosine unless you really care how many degrees are in an angle for some reason. Maybe you use it as an input into your steering controller, but you could probably use the dot product instead. Anyway, I'll save this for later in case this all interests you. It's just a couple more quick steps that would go right here. The important part here is that you create 2 more vectors in addition to the forward vector you're already using. For now we'll just move along to the next bit.
Now you can just stuff those into a 3x3 matrix by stacking them into a structure something like this:
carRotationMatrix.x.x = ForwardVector.x
carRotationMatrix.x.y = ForwardVector.y
carRotationMatrix.x.z = ForwardVector.z
carRotationMatrix.y.x = UpVector.x
carRotationMatrix.y.y = UpVector.y
carRotationMatrix.y.z = UpVector.z
carRotationMatrix.z.x = RightVector.x
carRotationMatrix.z.y = RightVector.y
carRotationMatrix.z.z = RightVector.z
This is cool because now you not only know what direction is forward, you also know just as accurately what direction is up and what direction is right! You could have your AI controller react to something above or below you, or even tell if the car crashed and flipped upside down or something. It also may come in handy if you want to make a flight simulator some day and have your aircraft do stuff in 3D.
When you want to rotate some point into the car's coordinate frame, you just multiply whatever point you want to rotate by the transpose of this carRotationMatrix. For example, if you knew reference point A in world coordinates, but you really wanted it in the car's coordinate frame since that's where the driver is seeing everything, you multiply point A by the transpose of carRotationMatrix. Probably what you'll want is a function something like this:
referencePointRelativeToCar = Transpose(carRotationMatrix) * referencePoint
I do it a little differently than this, but you could do it this way probably if you wanted to.
What's the Transpose()? I used to just write out the entire computation in my code over and over every time I used it so it would get burned into my brain. I use a function or a function macro that looks like this:
Transpose:
Result.x = InitialVector.x * Matrix.x.x +_
InitialVector.y * Matrix.x.y +_
InitialVector.z * Matrix.x.z
Result.y = InitialVector.x * Matrix.y.x +_
InitialVector.y * Matrix.y.y +_
InitialVector.z * Matrix.y.z
Result.z = InitialVector.x * Matrix.z.x +_
InitialVector.y * Matrix.z.y +_
InitialVector.z * Matrix.z.z
That's the math for it. This looks like a lot but it's actually very fast. What is somewhat slow computationally are the sine and cosine operations, so I try to avoid those whenever I can. Note that right now we have an angle and have computed two other direction vectors that are all perpendicular to each other without using sine or cosine at all. So much easier. I still use sine/cosine in some places where there isn't really any other choice though, so don't worry about it too much.
Anyway, at the end of this you have referencePointRelativeToCar. This is sweet because now a coordinate like (1,0,0) tells you that the reference point is 1 unit left of the driver relative to the car regardless of what direction the car is pointing in the world. It could have crashed into a wall and flipped up on its front bumper, rotated 87.254 degrees around the roll axis and you would know that point is 1 unit left relative to the driver's point of view. Just imagine the possibilities...
This matrix and vector stuff is incredibly powerful. I used to do everything with sines and cosines too, and once I started learning this stuff things got a lot easier and I never went back. Beginning 3D graphics books and web sites will cover the big important ones that you use all the time: Rotation matrices, cross products (to get perpendicular vectors), and dot products. Dot products are especially cool. They're used to get angles and do lots of other cool stuff like finding out how far something is from something else in ANY direction from ANY point of view. So it wouldn't even need to be something that's forward/up/right relative to the car anymore. You could have a gun pointed at a 30 degree angle off the hood, twisted to the right 10 degrees, and figure out how much further it would have to rotate to point to the bad guy.
Or if you wanted to get even fancier with your AI, you could have the AI compute things based on the orientation of the driver's head inside the car rather than basing it on the orientation of the car. Maybe he's looking to the left at the car next to him so he doesn't see that Schumacher just slammed his brakes in front of him, and POW! Fortunately the AI next to him was looking forward, so he swerves out of the way of both of them. Maybe the next guy sees that and pees himself, so he looks down at his shorts for a couple seconds and misses his next braking point.
Anyway!
These two operations (dot products and cross products) are used extensively in my simulation's suspension system in VRC Pro which has 76 individually animated parts on every car. Everything has a rotation matrix just like the one we computed earlier. These are all used to compute the physics of the vehicle and resulting motion, and because I hardly use sines or cosines anywhere at all, it runs really fast on the CPU. Those 76 matrices get passed to the renderer and presto, this happens:
http://www.youtube.com/watch?v=NSfoGDWMzgo
You can really do a lot with this vector stuff once you get the basic math behind it. It's not really that hard, and when you're coding it all you really have to do is write a MatrixMultiply() function and maybe a Transpose() function, things like that. Then you just start multiplying matrices and doing all that heavy math with a single line of code here and there. Next thing you know you're talking about multiplying this vector by that dot product rotating it by the thingamabob in the doohickey's coordinate system and transforming it back into whazoo-land. It gets to be kind of fun.
Anyway, if you have any questions about any of this, I'd be happy to help guide you a little bit. I haven't read the whole thread so I'm not totally sure where your understanding is. I'm just going off what I read in parts of post 316. So if you know this all already I apologize in advance.
Great stuff. I'll read some more and perhaps post again if you haven't replied in the meantime. It's neat to see that you've stuck to it all these years, let's just see if we can help speed things up a bit.