// 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(); }
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); }
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); }
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); }