Racing_Sim Stage 2 Help

 

Banking

Banking a track segment involves rotating the right vector about the forward vector by the bank angle;

        public TrackSegment(Vector3 start,Vector3 end, TerrainPlane terrain, float angle){



            forward = end - start;
            forward.Normalize();

            right = Vector3.Cross(forward,Vector3.Up);
            right.Normalize();



            Matrix bank = Matrix.CreateFromAxisAngle(forward,angle);

            // bank right vector
            right = Vector3.Transform(right, bank);


            up = Vector3.Cross(right, forward);
            up.Normalize();


            position = start;

        

            back_left = position + right * -width;
            back_right = position + right * +width;

            
			float adj =5; // minimum height off the ground
            // adjust height to at least above the ground
            float min = MathHelper.Min(back_right.Y-(terrain.GetHeight(back_right)+adj), back_left.Y-(terrain.GetHeight(back_left)+adj));

            
            if (min < 0)  // are either point underground?
            {
                adj = Math.Abs(min);
                // shift everything above ground
                back_left.Y += adj;
                position.Y += adj;
                back_right.Y +=adj; 
            }
            

 
        } 

 

Calculate the bank Angle

We can use the code above to give a constant bank angle to the track, but this would end up banking the straight sections and give negative banking to right hand corners .

Assume that bank angle depends on degree of curvature. The degree of curvature can be measured locally by looking at the angle between the forward vector of the current segment and the forward vector of the next segment. The dot product can be used to get the magnitude, but will not give us the direction of curvature. Instead we will get the dot product of the forward vector and the right vector of the next segment. This will give the degree an direction of banking.

        void BuildTrack()
        {
            Vector3 start,end, next;
            Vector3 a,b;
            float bank = 0;
            for (int i = 0; i < points.Count; i++)
            {
                start = points[i];
                end = points[(i+1) % points.Count];
                next = points[(i + 2) % points.Count];

                if((i > points.Count *1.0/ 4.0) && i < (points.Count * 3.0 / 4.0))// turn on banking only for middle portion of track
                {
                    a=end-start;
                    b = Vector3.Cross(Vector3.Up, next - end);
                    a.Normalize();
                    b.Normalize();
                    
                    bank = 5.0f  *(MathHelper.Pi ) * Vector3.Dot(a,b); //Dot will be zero for straight sections
                    bank = MathHelper.Clamp(bank, -MathHelper.PiOver4, +MathHelper.PiOver4);
                }
                else { bank = 0; }

               
            	TrackSegment s=new TrackSegment(start, end, up,trackWidth, terrain, bank);
segments.Add(s); } // other stuff... // pass thru list of segments to generate planes // generate vertex lists, // generate crash barriers }