This project is read-only.

Wheels vs TriangleMesh?

Feb 10, 2009 at 8:16 PM
Hi,

I'm just wondering if someone is successfully using the demo car with TriangleMeshes?
Whenever I drive the car onto a static mesh, the car starts spinning and flying. It seems like the wheel collision code gives the body of the car a rather big up force, which puts the car into a spin.

I saw that ProxiProdigy had the same issue over at the wiki but I thought I would post a question here as well...
Feb 10, 2009 at 10:23 PM
Yep. I'm having the same problem. I'm actually looking into it right now. I'll post my findings on here. If you come up with anything first, please share it as this is a big hurdle for a lot of people apparently.
Feb 11, 2009 at 8:01 PM
I am using cars on very large triangle meshes (one such mesh is entire game level). There are some pitfalls :(
But in your case it seems, that something is wrong with car setup.
Feb 11, 2009 at 9:19 PM
How is your car setup? I'm using the same parameters as in JiggleGame and the TriangleMesh is the same too,
Feb 13, 2009 at 9:21 PM
Edited Feb 13, 2009 at 9:37 PM

    <PhysicalProperties>
      <Mass>150</Mass>
      <FWDrive>false</FWDrive>
      <RWDrive>true</RWDrive>
      <maxSteerAngle>45</maxSteerAngle>
      <steerRate>5</steerRate>
      <wheelFwdFriction>6</wheelFwdFriction>
      <wheelSideFriction>7</wheelSideFriction>
      <wheelTravel>0.15</wheelTravel>
      <wheelRadius>0.41</wheelRadius>
      <wheelXOffset>1.05</wheelXOffset>
      <wheelYOffset>1.75</wheelYOffset>
      <wheelZOffset>0.05</wheelZOffset>
      <wheelRestingFrac>0.65</wheelRestingFrac>
      <wheelDampingFrac>0.4</wheelDampingFrac>
      <driveTorque>330</driveTorque>
      <GearSpeedLimit>15 35 70 120 200</GearSpeedLimit>
    </PhysicalProperties>

Also make sure, that integration step ('dt' parameter of 'Integrate(...)' function) doesn't vary too much and stays in a physics stability range. My experiments show, that this range is approximately [4 -:- 0.5] ms (what corresponds to 25 - 200 fps).

Feb 14, 2009 at 1:07 AM
I tried everything you mentioned and none of it worked for me. I tried it with the standard car from the JiggleGame and with my own 3-wheeled bot seen at http://www.everydayxna.com/images/screenshots/brawlbots/8.jpg. Oh well. Back to the drawing board.
Feb 14, 2009 at 2:22 PM
Carmageddon forever? ;)
Are you using 3-wheeled physics model for your car, or standard 4-wheeled?
I am planning to implement 6-wheeled physics model for a heavy truck.

Use fixed integration step (0.02f for example) to diagnose the problem. I encountered the car behavior you describe here. In my case it was caused either by wrong car setup or incorrect integration step.
Feb 14, 2009 at 2:56 PM
I'm actually using 4-wheel, but I'm moving the 2 back tires into the middle to form the one single wheel in the back so that I didn't have to make a new wheel with textures on both sides. This is just for testing. I'll eventually make a really nice looking 3-wheeled bot with it's own 3-wheel physics model, better textures, more parts, etc... Right now, I'm working on destructable objects. For instance, if I had 2 of these 3-wheeled vehicles battling it out and one cut the wheel off of the other, I want the wheel to stay where it is and have the missing wheel affect steering, speed, etc... I want it to drag along the frame on the side of the missing wheel. I also want to be able to cut the blade off of the other bot as well as other parts. I'm also working on other kinds of bots to choose from. I have a basic wedge shaped bot that can drive up under other bots (such as the 3-wheeled bot) and flip them over. I've started on a bot with a flipper too. My goal is to create a bunch of bots to choose from and customize. Depending on armor, weapons, motor, battery, etc... will affect how your bot maneuvers. Once I get the basic models down, I'm going to create an in-game model editor so that you can create and customize your own bots.

http://www.everydayxna.com
Feb 15, 2009 at 5:47 AM
Edited Feb 15, 2009 at 5:55 AM
I'm just fishing here, but is it possible that the GetMassProperties method of TriangleMesh is missing some code? It only has 3 lines in it:

public override void GetMassProperties(PrimitiveProperties primitiveProperties, out float mass, out Vector3 centerOfMass, out Matrix inertiaTensor)
{
            mass = 0.0f;
            centerOfMass = Vector3.Zero;
            inertiaTensor = Matrix.Identity;

}

where as the other primitives have a lot more. I'm going on almost 44 hours of no sleep. So, there's a good chance that I'm wrong. But, with sleep deprivation kicking in, I can't look into it too much right now. I just finished some stuff for work that was suppose to be done last week for a co-worker and thought I'd take a gander at this problem again. After a good night's rest, I'll look into a little more and see exactly what's going on there. But, I'm thinking that the inertia is throwing it off some how.
Coordinator
Feb 15, 2009 at 7:07 PM
>I'm just fishing here, but is it possible that the GetMassProperties method of TriangleMesh is missing some code?

No.

I loaded a complete triangle mesh into the demo and drove arround with the car - no problems. You must do something wrong.
Feb 15, 2009 at 8:55 PM
Edited Feb 15, 2009 at 8:56 PM
Are you driving the car on the TriangleMesh? The demo works great for me. This only happens when the car drives over the TriangleMeshObject. I didn't think to try it in the demo. I'll try it there and see what happens.
Feb 15, 2009 at 9:08 PM
Edited Feb 15, 2009 at 9:13 PM
You're right. I just loaded the same ramp model into the demo and everything worked perfectly. I can't figure out what I'm doing wrong though. I have the same exact code in my game as you have in your demo.
Feb 15, 2009 at 9:46 PM
After playing around some more, I don't think it has anything to do with the TriangleMesh. I believe it's all in the car just like And4 said. But, I still can't find the problem there either. The reason I believe it's the car and not the TMO, is because I loaded several cars into my world and started crashing into them. Whenever I manage to slam one into another causing it to come up off the ground, it begins spinning just like the single car does when it leaves the ramp. However, even by gently driving up to the ramp, once my front tires touch it, it begins going crazy. So, I'm still searching for answers and will post anything I find on here.
Feb 16, 2009 at 2:01 AM
After even more digging and testing, I've found that my car does in fact do the same thing in the demo as it does in my game.
Coordinator
Feb 16, 2009 at 11:26 AM
Carmageddon :) Could it be that you changed the inertia to some strange values?
Feb 16, 2009 at 12:14 PM
Edited Feb 16, 2009 at 12:17 PM
No sir. I haven't changed a thing in your demo. I've left it as-is so that I can use it as a reference. Well, I did make one change. The only thing I did do was I added body.moveTo() in the TriangleMeshObject to utilize the incoming parameter. Otherwise, it stayed at Vector3.Zero.
Coordinator
Feb 16, 2009 at 12:20 PM
Can you make a video? I can't reproduce this here :(
Feb 16, 2009 at 5:02 PM
Edited Feb 16, 2009 at 5:26 PM
I made a video of both the car in the demo and the bot in my game. The videos are a little choppy, but you'll get the idea. The car doesn't spin as fast in this video as the bot does in my game. But, I have seen it do the same at other times. I'm at home for lunch right now and don't have time to do too much with it right now. But, when I get home from work tonight, I'll change the heightmap to a plane and duplicate the problem more accurately so that you can see that it does it the same in the demo as it does in my game.

Car in demo:
http://www.yourmercials.com/video/460/

Bot in my game: http://www.yourmercials.com/video/461/


Coordinator
Feb 16, 2009 at 6:50 PM
okay, you won ;)  and found the problem. The ray-intersection doesn't work correctly with transformed trianglemeshs (your moveto). I have no time this week to fix it. But here is a short workaround:

            for (int i = 0; i < vertexList.Count; i++)
            {
                vertexList[i] = Vector3.Transform(vertexList[i], translation);
            }

Just translate the vertices yourself after extractiing and before creating the mesh.
Coordinator
Feb 16, 2009 at 7:02 PM
okay, wasn't that hard...

change the segmentintersect code of your triangle mesh to this:

        public override bool SegmentIntersect(out float frac, out Vector3 pos, out Vector3 normal, Segment seg)
        {
            // move segment into octree space
            seg.Origin = Vector3.Transform(seg.Origin, invTransform);
            seg.Delta = Vector3.TransformNormal(seg.Delta, invTransform);


            BoundingBox segBox = BoundingBoxHelper.InitialBox;
            BoundingBoxHelper.AddSegment(seg, ref segBox);

            unsafe
            {
#if USE_STACKALLOC
                int* potentialTriangles = stackalloc int[MaxLocalStackTris];
                {
#else
                int[] potTriArray = DetectFunctor.IntStackAlloc();
                fixed (int* potentialTriangles = potTriArray)
                {
#endif
                    int numTriangles = GetTrianglesIntersectingtAABox(potentialTriangles, DetectFunctor.MaxLocalStackSCPI, ref segBox);

                    float tv1, tv2;

                    pos = Vector3.Zero;
                    normal = Vector3.Zero;

                    float bestFrac = float.MaxValue;
                    for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
                    {
                        IndexedTriangle meshTriangle = GetTriangle(potentialTriangles[iTriangle]);
                        float thisFrac;
                        Triangle tri = new Triangle(GetVertex(meshTriangle.GetVertexIndex(0)),
                          GetVertex(meshTriangle.GetVertexIndex(1)),
                          GetVertex(meshTriangle.GetVertexIndex(2)));

                        if (Intersection.SegmentTriangleIntersection(out thisFrac, out tv1, out tv2, seg, tri))
                        {
                            if (thisFrac < bestFrac)
                            {
                                bestFrac = thisFrac;
                                // re-project
                                pos = Vector3.Transform(seg.GetPoint(thisFrac), transformMatrix);
                                normal = Vector3.TransformNormal(meshTriangle.Plane.Normal,transformMatrix);
                            }
                        }
                    }

                    frac = bestFrac;
                    if (bestFrac < float.MaxValue)
                    {
                        DetectFunctor.FreeStackAlloc(potTriArray);
                        return true;
                    }
                    else
                    {
                        DetectFunctor.FreeStackAlloc(potTriArray);
                        return false;
                    }
#if USE_STACKALLOC
                }
#else
                }
#endif
            }
        }
Feb 16, 2009 at 7:54 PM
Extreme coolness!
It works like a charm :)
Thanks!!!
Feb 16, 2009 at 10:42 PM
Friggin awesome!!! You are the man!