Example #1
0
        // Methods
        public void Run(float deltaTime)
        {
            if (this.vehicleIndex < 0)
            {
                return;
            }
            if (AIRegionsDS == null)
            {
                if (AIRegions == null)
                {
                    return;
                }
                AIRegionsDS = AIRegions.GetDrawingSurface();
            }
            float angleSum = 0f;
            int   agscolor = AIRegionsDS.GetPixel(FloatToInt(Cars[this.vehicleIndex].position.x, eRoundNearest), FloatToInt(Cars[this.vehicleIndex].position.y, eRoundNearest));
            int   i        = 0;

            for (i = 0; i < 16; i += 1)
            {
                if (RegionAngles[i].color == agscolor)
                {
                    angleSum = RegionAngles[i].angle;
                    break;
                }
            }
            this.targetAngle = angleSum;
            float dirAngle     = Cars[this.vehicleIndex].direction.angle();
            float angleBetween = Maths.AnglePiFast(this.targetAngle - Maths.Angle2Pi(dirAngle));
            float steeringDT   = UISteeringAngle * deltaTime * 1.1f;

            if (Maths.AbsF(angleBetween) <= Maths.AbsF(steeringDT))
            {
                Cars[this.vehicleIndex].steeringWheelAngle = 0.0f;
                Cars[this.vehicleIndex].direction.set2(1.0f, 0.0f);
                Cars[this.vehicleIndex].direction.rotate(this.targetAngle);
            }
            else if (angleBetween > 0.0f)
            {
                Cars[this.vehicleIndex].steeringWheelAngle = UISteeringAngle;
            }
            else if (angleBetween < 0.0f)
            {
                Cars[this.vehicleIndex].steeringWheelAngle = -UISteeringAngle;
            }
            else
            {
                Cars[this.vehicleIndex].steeringWheelAngle = 0.0f;
            }
            Cars[this.vehicleIndex].Accelerator = 1.0f;
            Cars[this.vehicleIndex].Brakes      = 0.0f;
        }
        public void processInteraction(float deltaTime)
        {
            int i = 0;

            float[] friction     = new float[NUM_COLLISION_POINTS];
            float   avg_friction = 0.0f;

            bool[] hit_area = new bool[NUM_COLLISION_POINTS];
            for (i = 0; i < NUM_COLLISION_POINTS; i += 1)
            {
                VectorF colpoint = this.collPointOff[i].clone();
                colpoint.rotate(this.direction.angle());
                colpoint.add(this.position);
                this.collPoint[i] = colpoint;
                int room_x   = FloatToInt(colpoint.x, eRoundNearest);
                int room_y   = FloatToInt(colpoint.y, eRoundNearest);
                int screen_x = room_x - GetViewportX();
                int screen_y = room_y - GetViewportY();
                int area     = GetWalkableAreaAt(screen_x, screen_y);
                if (area == 0)
                {
                    hit_area[i] = true;
                }
                else
                {
                    friction[i]           = Track.TerraSlideFriction[area];
                    avg_friction         += friction[i];
                    this.terrafriction[i] = friction[i];
                }
                this.colpt[i].x = FloatToInt(colpoint.x, eRoundNearest);
                this.colpt[i].y = FloatToInt(colpoint.y, eRoundNearest);
            }
            avg_friction /= IntToFloat(NUM_COLLISION_POINTS);
            this.friction = avg_friction;
            for (i = 0; i < NUM_COLLISION_POINTS; i += 1)
            {
                if (!hit_area[i])
                {
                    continue;
                }
                VectorF impact = VectorF.subtract(this.position, this.collPoint[i]);
                impact.normalize();
                impact.scale(Maths.AbsF(this.driveVelocityValue));
                this.impactVelocity.add(impact);
                float projection = VectorF.projection(impact, this.driveVelocity);
                if (this.driveVelocityValue < 0.0f)
                {
                    projection = -projection;
                }
                this.driveVelocityValue += projection;
            }
        }
        public void run(float deltaTime)
        {
            this.position.addScaled(this.velocity, deltaTime);
            float rot_angle = 0f;

            if (this.driveVelocityValue >= 0.0f)
            {
                rot_angle = this.steering * deltaTime;
            }
            else
            {
                rot_angle = -this.steering * deltaTime;
            }
            this.directionAngle = Maths.Angle2Pi(this.directionAngle + rot_angle);
            this.direction.rotate(rot_angle);
            this.processInteraction(deltaTime);
            float absVelocity      = Maths.AbsF(this.driveVelocityValue);
            float thrustResistance = this.friction * absVelocity + this.brakes;
            float thrustForce      = this.engine * deltaTime;
            float brakeForce       = Maths.MinF(thrustResistance * deltaTime, absVelocity);

            if (this.driveVelocityValue < 0.0f)
            {
                brakeForce = -brakeForce;
            }
            this.driveVelocityValue += thrustForce - brakeForce;
            this.driveVelocity.set(this.direction);
            this.driveVelocity.scale(this.driveVelocityValue);
            this.thrustForceValue = thrustForce;
            this.brakeForceValue  = brakeForce;
            float impactValue = this.impactVelocity.length();

            if (impactValue > 0.0f)
            {
                impactValue = Maths.MaxF(0.0f, impactValue - (this.friction * impactValue * 10.0f + this.brakes) * deltaTime);
                this.impactVelocity.truncate(impactValue);
            }
            this.velocity.set(this.driveVelocity);
            this.velocity.add(this.impactVelocity);
            this.syncCharacter();
        }
Example #4
0
        public int TryInsertNode(int refNode, int x, int y)
        {
            if (FreePathSlot < 0)
            {
                return(0);
            }
            int nodep = Paths[refNode].prev;
            int noden = Paths[refNode].next;

            if (nodep < 0 && noden < 0)
            {
                return(PutNewNode(x, y));
            }
            int nodeopp = 0;

            if (nodep < 0)
            {
                nodeopp = noden;
            }
            else if (noden < 0)
            {
                nodeopp = nodep;
            }
            else
            {
                VectorF hit     = VectorF.create(x, y);
                VectorF hitDir  = VectorF.subtract(hit, Paths[refNode].pt);
                VectorF nextDir = VectorF.subtract(Paths[noden].pt, Paths[refNode].pt);
                VectorF prevDir = VectorF.subtract(Paths[nodep].pt, Paths[refNode].pt);
                if (Maths.AbsF(VectorF.angleBetween(hitDir, nextDir)) <= Maths.AbsF(VectorF.angleBetween(hitDir, prevDir)))
                {
                    nodeopp = noden;
                }
                else
                {
                    nodeopp = nodep;
                }
            }
            VectorF newpt = Paths[refNode].pt.clone();

            newpt.add(Paths[nodeopp].pt);
            newpt.scale(0.5f);
            int insertPrev = 0;
            int insertNext = 0;

            if (nodeopp == noden)
            {
                insertPrev = refNode;
                insertNext = noden;
            }
            else
            {
                insertPrev = nodep;
                insertNext = refNode;
            }
            int newnode = FreePathSlot;

            Paths[newnode].Reset();
            Paths[newnode].pt = newpt;
            OnNewNode(newnode, insertPrev, insertNext);
            PathNodeCount += 1;
            FindFirstFreeNode();
            return(newnode);
        }
Example #5
0
        public int TryInsertNode(int refNode, int x, int y)
        {
            if (FreeCheckptSlot < 0)
            {
                return(0);
            }
            int nodep = Checkpoints[refNode].prev;
            int noden = Checkpoints[refNode].next;

            if (nodep < 0 && noden < 0)
            {
                return(PutNewNode(x, y));
            }
            int nodeopp = 0;

            if (nodep < 0)
            {
                nodeopp = noden;
            }
            else if (noden < 0)
            {
                nodeopp = nodep;
            }
            else
            {
                VectorF hit     = VectorF.create(x, y);
                VectorF hitDir  = VectorF.subtract(hit, Checkpoints[refNode].pt);
                VectorF nextDir = VectorF.subtract(Checkpoints[noden].pt, Checkpoints[refNode].pt);
                VectorF prevDir = VectorF.subtract(Checkpoints[nodep].pt, Checkpoints[refNode].pt);
                if (Maths.AbsF(VectorF.angleBetween(hitDir, nextDir)) <= Maths.AbsF(VectorF.angleBetween(hitDir, prevDir)))
                {
                    nodeopp = noden;
                }
                else
                {
                    nodeopp = nodep;
                }
            }
            VectorF newpt = Checkpoints[refNode].pt.clone();

            newpt.add(Checkpoints[nodeopp].pt);
            newpt.scale(0.5f);
            int insertPrev = 0;
            int insertNext = 0;

            if (nodeopp == noden)
            {
                insertPrev = refNode;
                insertNext = noden;
            }
            else
            {
                insertPrev = nodep;
                insertNext = refNode;
            }
            int newnode = FreeCheckptSlot;

            Checkpoints[newnode].Reset();
            Checkpoints[newnode].pt = newpt;
            OnNewNode(newnode, insertPrev, insertNext);
            CheckptCount += 1;
            int fixnode = insertNext;

            while (fixnode != FirstCheckpt)
            {
                Checkpoints[fixnode].order += 1;
                fixnode = Checkpoints[fixnode].next;
            }
            FindFirstFreeCheckpoint();
            return(newnode);
        }
Example #6
0
        public void RunPhysics(float deltaTime)
        {
            int i = 0;

            if (this.strictCollisions && this.numHits > 0)
            {
                float x = 0f;
                float y = 0f;
                for (i = 0; i < NUM_COLLISION_POINTS; i += 1)
                {
                    this.collPoint[i].set(this.oldCollPt[i]);
                    this.collPtHit[i] = this.oldCollPtHit[i];
                    x += this.collPoint[i].x;
                    y += this.collPoint[i].y;
                }
                this.position.x = x / IntToFloat(NUM_COLLISION_POINTS);
                this.position.y = y / IntToFloat(NUM_COLLISION_POINTS);
            }
            else
            {
                for (i = 0; i < NUM_COLLISION_POINTS; i += 1)
                {
                    this.oldCollPt[i].set(this.collPoint[i]);
                }
            }
            for (i = 0; i < NUM_COLLISION_POINTS; i += 1)
            {
                this.oldCollPtHit[i]    = this.collPtHit[i];
                this.oldCollPtCarHit[i] = this.collPtCarHit[i];
            }
            this.RunPhysicsBase(deltaTime);
            this.UpdateBody();
            this.UpdateEnviroment();
            this.enginePower       = this.engineMaxPower * this.engineAccelerator;
            this.driveWheelTorque  = this.enginePower;
            this.driveWheelTorque -= this.driveWheelTorque * this.brakePower;
            this.driveWheelForce   = this.driveWheelTorque * this.driveWheelGrip;
            VectorF rollDirection  = this.direction.clone();
            VectorF slideDirection = rollDirection.clone();

            slideDirection.rotate(Maths.Pi / 2.0f);
            float rollingVelocity = VectorF.projection(this.velocity, rollDirection);
            float slidingVelocity = VectorF.projection(this.velocity, slideDirection);

            this.turningAccel.makeZero();
            if (this.velocity.isZero())
            {
                this.angularVelocity = this.steeringWheelAngle * this.stillTurningVelocity;
            }
            else
            {
                if (this.steeringWheelAngle != 0.0f)
                {
                    float   steerAngle    = this.steeringWheelAngle;
                    VectorF driveWheelPos = this.position.clone();
                    VectorF steerWheelPos = this.position.clone();
                    driveWheelPos.addScaled(this.direction, -this.distanceBetweenAxles / 2.0f);
                    steerWheelPos.addScaled(this.direction, this.distanceBetweenAxles / 2.0f);
                    VectorF driveWheelMovement = rollDirection.clone();
                    VectorF steerWheelMovement = rollDirection.clone();
                    steerWheelMovement.rotate(steerAngle);
                    driveWheelPos.addScaled(driveWheelMovement, rollingVelocity);
                    steerWheelPos.addScaled(steerWheelMovement, rollingVelocity);
                    VectorF newPosDir = VectorF.subtract(steerWheelPos, driveWheelPos);
                    newPosDir.normalize();
                    this.angularVelocity  = VectorF.angleBetween(this.direction, newPosDir);
                    this.angularVelocity *= this.envGrip;
                    float dumb_drift_factor = Maths.ArcTan(Maths.AbsF(rollingVelocity / this.driftVelocityFactor)) / (Maths.Pi / 2.0f);
                    this.turningAccel = VectorF.subtract(newPosDir, rollDirection);
                    this.turningAccel.scale(rollingVelocity * (1.0f - dumb_drift_factor) * this.envGrip);
                }
                else
                {
                    this.angularVelocity = 0.0f;
                }
            }
            VectorF rollResDir = rollDirection.clone();

            rollResDir.scale(-rollingVelocity);
            rollResDir.normalize();
            VectorF slideResDir = slideDirection.clone();

            slideResDir.scale(-slidingVelocity);
            slideResDir.normalize();
            float driveForce = (this.driveWheelForce * deltaTime) / this.bodyMass;

            rollingVelocity = Maths.AbsF(rollingVelocity);
            slidingVelocity = Maths.AbsF(slidingVelocity);
            float slide_friction = this.envSlideFriction * this.weightForce;
            float roll_friction  = this.envRollFriction * this.weightForce;
            float airres_force   = 0.5f * Track.AirResistance * this.bodyAerodynamics;
            float env_res_force  = this.envResistance;
            float rollAF         = ((slide_friction * this.brakePower + roll_friction * (1.0f - this.brakePower) + airres_force * rollingVelocity * rollingVelocity + env_res_force * rollingVelocity) * deltaTime) / this.bodyMass;
            float slideAF        = ((slide_friction + airres_force * slidingVelocity * slidingVelocity + env_res_force * slidingVelocity) * deltaTime) / this.bodyMass;

            rollAF  = Maths.ClampF(rollAF, 0.0f, rollingVelocity);
            slideAF = Maths.ClampF(slideAF, 0.0f, slidingVelocity);
            this.infoRollAntiforce  = rollAF;
            this.infoSlideAntiforce = slideAF;
            this.velocity.addScaled(rollDirection, driveForce);
            float x1 = this.velocity.x;
            float y1 = this.velocity.y;

            this.velocity.addScaled(slideResDir, slideAF);
            this.velocity.addScaled(rollResDir, rollAF);
            float x2 = this.velocity.x;
            float y2 = this.velocity.y;

            if (x1 >= 0.0 && x2 < 0.0 || x1 <= 0.0 && x2 > 0.0f)
            {
                this.velocity.x = 0.0f;
            }
            if (y1 >= 0.0 && y2 < 0.0 || y1 <= 0.0 && y2 > 0.0f)
            {
                this.velocity.y = 0.0f;
            }
            this.velocity.addScaled(this.turningAccel, deltaTime);
            VectorF impactVelocity = VectorF.zero();

            this.RunCollision(impactVelocity, deltaTime);
            this.velocity.add(impactVelocity);
            this.infoImpact.set(impactVelocity);
        }