void EditorPoint::setMinAndMaxShiftPoint(int p_index) { if (p_index >= 0 && p_index < m_track.getPointCount()) { const TrackPoint& trackPoint = m_track.getPoint(p_index); float minShift = -1.0f - trackPoint.getShift(); float maxShift = 1.0f - trackPoint.getShift(); float radius = trackPoint.getRadius(); CL_Vec2f guide = m_gfxLevel.getTrackTriangulator().getGuide(p_index); guide /= guide.length(); CL_Vec2f minShiftGuide = guide; setToPerpendicular(minShiftGuide, true); minShiftGuide *= radius * minShift; CL_Vec2f maxShiftGuide = guide; setToPerpendicular(maxShiftGuide, true); maxShiftGuide *= radius * maxShift; const CL_Pointf& pos = trackPoint.getPosition(); m_impl->m_minShiftPoint = pos + minShiftGuide; m_impl->m_maxShiftPoint = pos + maxShiftGuide; } }
void Car::applyCollision(const CL_LineSegment2f &p_seg) { static const float DAMAGE_MULT = 0.2f; const float side = -p_seg.point_right_of_line(m_impl->m_position); const CL_Vec2f segVec = p_seg.q - p_seg.p; // need front normal (crash side) CL_Vec2f fnormal(segVec.y, -segVec.x); // right side normal fnormal.normalize(); if (side < 0) { fnormal *= -1; } // move away m_impl->m_position += (fnormal * fabs(m_impl->m_speed)); // calculate collision angle to estaminate speed reduction CL_Angle angleDiff(m_impl->m_phyMoveRot - m_impl->vecToAngle(fnormal)); Workarounds::clAngleNormalize180(&angleDiff); const float colAngleDeg = fabs(angleDiff.to_degrees()) - 90.0f; const float reduction = fabs(1.0f - fabs(colAngleDeg - 90.0f) / 90.0f); // calculate and apply damage const float damage = m_impl->m_speed * reduction * DAMAGE_MULT; m_impl->m_damage = Math::Float::reduce(m_impl->m_damage + damage, 0.0f, 1.0f); cl_log_event(LOG_DEBUG, "damage: %1, total: %2", damage, m_impl->m_damage); // reduce speed m_impl->m_speed -= m_impl->m_speed * reduction; // bounce movement vector and angle away // get mirror point if (m_impl->m_phyMoveVec.length() > 0.01f) { m_impl->m_phyMoveVec.normalize(); const float lengthProj = m_impl->m_phyMoveVec.length() * cos(segVec.angle(m_impl->m_phyMoveVec).to_radians()); const CL_Vec2f mirrorPoint(segVec * (lengthProj / segVec.length())); // invert move vector by mirror point const CL_Vec2f mirrorVec = (m_impl->m_phyMoveVec - mirrorPoint) * -1; m_impl->m_phyMoveVec = mirrorPoint + mirrorVec; // update physics angle m_impl->m_phyMoveRot = m_impl->vecToAngle(m_impl->m_phyMoveVec); } }
void Misil::mover(float dt) { if(perseguidor) { int tiempdodesdedisparo= CL_System::get_time() - tiempodisparo; if(tiempdodesdedisparo >= 10) { CL_Vec2f vector = Posicion - TargetTanque->getPos(); float distancia = vector.length(); mundo->AgregarCadenaChat(cl_format("%1",distancia)); CL_Vec2f up(0.0f, 1.0f); float angulodest = up.angle(vector).to_degrees(); /*if(TargetTanque->getPos().x < Posicion.x) angulodest = 360.0f - angulo;*/ /* else angulodest = 360.0f angulo;*/ angulodelta = angulodest - angulo; if(distancia < 150) { if(angulodelta > 0) angulodelta +=5; } if(angulodelta > 180.0f) { angulodelta -= 360.0f; angulo += 360.0f; } if(angulodelta < -180.0f) { angulodelta += 360.0f; angulo -= 360.0f; } angulo +=angulodelta*dt/velocidad; setAngulo(angulo); } } Posicion.x += dt* float(sin(angulo* CL_PI / 180.0f)); Posicion.y += dt* float(-cos(angulo * CL_PI / 180.0f)); collisionMisil->set_translation(Posicion.x, Posicion.y); }
void EditorPoint::getShiftRect(int p_index, int* x1, int* y1, int* x2, int* y2) { const TrackPoint& p_trackPoint = m_track.getPoint(p_index); CL_Vec2f guide = m_gfxLevel.getTrackTriangulator().getGuide(p_index); float guideLength = guide.length(); guide *= p_trackPoint.getShift() * p_trackPoint.getRadius(); guide /= guideLength; setToPerpendicular(guide, false); const CL_Pointf& pos = p_trackPoint.getPosition(); *x1 = pos.x; *y1 = pos.y; *x2 = pos.x + guide.x; *y2 = pos.y + guide.y; }
bool IntersectRaySphere(CL_Vec2f p, CL_Vec2f d, rtCircle s, float &t, CL_Vec2f &q) { CL_Vec2f m = p - s.c; float b = m.dot(d); float c = m.dot(m) - s.r * s.r; // Exit if r’s origin outside s (c > 0) and r pointing away from s (b > 0) if (c > 0.0f && b > 0.0f) return false; float discr = b*b - c; // A negative discriminant corresponds to ray missing sphere if (discr < 0.0f) return false; // Ray now found to intersect sphere, compute smallest t value of intersection t = -b - sqrt(discr); // If t is negative, ray started inside sphere so clamp t to zero if (t < 0.0f) t = 0.0f; q=p+(d*t); return true; }
CL_Angle CarImpl::vecToAngle(const CL_Vec2f &p_vec) { const static CL_Vec2f ANGLE_ZERO(1.0f, 0.0f); CL_Angle angle = p_vec.angle(ANGLE_ZERO); if (p_vec.y < 0) { angle.set_radians(-angle.to_radians()); } return angle; }
bool CircleSegmentIntersect(CL_Vec2f C, float r, CL_Vec2f A, CL_Vec2f B, CL_Vec2f& P) { CL_Vec2f AC = C - A; CL_Vec2f AB = B - A; float ab2 = AB.dot(AB); float acab = AC.dot(AB); float t = acab / ab2; if (t < 0.0f) t = 0.0f; else if (t > 1.0f) t = 1.0f; P = A + AB * t; CL_Vec2f H = P - C; float h2 = H.dot(H); float r2 = r * r; if(h2 > r2) return false; else return true; }
void DrawLine( GLuint rgba, float ax, float ay, float bx, float by, float lineWidth ) { SetupOrtho(); //g_globalBatcher.Flush(); glDisable( GL_TEXTURE_2D ); glEnableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_CULL_FACE); static GLfloat vertices[3*4]; CL_Vec2f start = CL_Vec2f(ax, ay); CL_Vec2f end = CL_Vec2f(bx, by); float dx = ax - bx; float dy = ay - by; CL_Vec2f rightSide = CL_Vec2f(dy, -dx); if (rightSide.length() > 0) { rightSide.normalize(); rightSide *= lineWidth/2; } CL_Vec2f leftSide =CL_Vec2f(-dy, dx); if (leftSide.length() > 0) { leftSide.normalize(); leftSide *= lineWidth/2; } CL_Vec2f one = leftSide + start; CL_Vec2f two = rightSide + start; CL_Vec2f three = rightSide + end; CL_Vec2f four = leftSide = end; vertices[0*3+0] = one.x; vertices[0*3+1] = one.y; vertices[1*3+0] = two.x; vertices[1*3+1] = two.y; vertices[2*3+0] = three.x; vertices[2*3+1] = three.y; vertices[3*3+0] = four.x; vertices[3*3+1] = four.y; //set the Z vertices[0*3+2] = 0; vertices[1*3+2] = 0; vertices[2*3+2] = 0; vertices[3*3+2] = 0; glVertexPointer(3, GL_FLOAT, 0, vertices); //glColor4f(1, 1, 1, 1); glEnable( GL_BLEND ); glColor4x( (rgba >>8 & 0xFF)*256, (rgba>>16& 0xFF)*256, (rgba>>24& 0xFF)*256, (rgba&0xFF)*256); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glColor4x(1 << 16, 1 << 16, 1 << 16, 1 << 16); glEnable(GL_CULL_FACE); glDisable( GL_BLEND ); glEnable( GL_TEXTURE_2D ); glEnableClientState(GL_TEXTURE_COORD_ARRAY); CHECK_GL_ERROR(); }
void CarImpl::update1_60() { static const float BRAKE_POWER = 0.1f; static const float ACCEL_POWER = 0.014f; static const float SPEED_LIMIT = 15.0f; static const float WHEEL_TURN_SPEED = 1.0f / 10.0f; static const float TURN_POWER = (2 * CL_PI / 360.0f) * 2.5f; static const float MOV_ALIGN_POWER = TURN_POWER / 2.0f; static const float ROT_ALIGN_POWER = TURN_POWER * 0.7f; static const float AIR_RESITANCE = 0.003f; // per one speed unit static const float DRIFT_SPEED_REDUCTION_RATE = 0.1f; // speed limit under what physics angle reduction will be more aggressive static const float LOWER_SPEED_ANGLE_REDUCTION = 6.0f; // speed limit under what angle difference will be lower than normal static const float LOWER_SPEED_ROTATION_REDUCTION = 6.0f; // speed limit under what turn power will decrease static const float LOWER_SPEED_TURN_REDUCTION = 2.0f; // increase the iteration id // be aware of 32-bit integer limit if (m_iterId != std::numeric_limits<int32_t>::max()) { m_iterId++; } else { m_iterId = 0; } // don't do anything if car is locked if (m_inputLocked) { return; } const float prevSpeed = m_speed; // for m_phySpeedDelta // apply inputs to speed if (m_inputState.brake) { m_speed -= BRAKE_POWER; } else if (m_inputState.accel) { // only if not choking if (!isChoking()) { m_chocking = false; m_speed += (SPEED_LIMIT - m_speed) * ACCEL_POWER; } else { m_chocking = true; } } // rotate steering wheels const float diff = m_inputState.turn - m_phyWheelsTurn; if (fabs(diff) > WHEEL_TURN_SPEED) { m_phyWheelsTurn += diff > 0.0f ? WHEEL_TURN_SPEED : -WHEEL_TURN_SPEED; } else { m_phyWheelsTurn = m_inputState.turn; } const float absSpeed = fabs(m_speed); // calculate rotations if (m_phyWheelsTurn != 0.0f) { // rotate corpse and later physics movement CL_Angle turnAngle(TURN_POWER * m_phyWheelsTurn, cl_radians); if (absSpeed <= LOWER_SPEED_TURN_REDUCTION) { // reduce turn if car speed is too low turnAngle.set_radians(turnAngle.to_radians() * (absSpeed / LOWER_SPEED_TURN_REDUCTION)); } if (m_speed > 0.0f) { m_rotation += turnAngle; } else { m_rotation -= turnAngle; } // rotate corpse and physics movement if (absSpeed > LOWER_SPEED_ROTATION_REDUCTION) { alignRotation(m_phyMoveRot, m_rotation, MOV_ALIGN_POWER); } else { alignRotation(m_phyMoveRot, m_rotation, MOV_ALIGN_POWER * ((LOWER_SPEED_ROTATION_REDUCTION + 1.0f) - absSpeed)); } } else { // align corpse back to physics movement alignRotation(m_rotation, m_phyMoveRot, MOV_ALIGN_POWER); // makes car stop rotating if speed is too low if (absSpeed > LOWER_SPEED_ANGLE_REDUCTION) { alignRotation(m_phyMoveRot, m_rotation, ROT_ALIGN_POWER); } else { alignRotation(m_phyMoveRot, m_rotation, ROT_ALIGN_POWER * ((LOWER_SPEED_ANGLE_REDUCTION + 1.0f) - absSpeed)); } // normalize rotations only when equal if (m_rotation == m_phyMoveRot) { Workarounds::clAngleNormalize(&m_rotation); Workarounds::clAngleNormalize(&m_phyMoveRot); } } Workarounds::clAngleNormalize(&m_phyMoveRot); Workarounds::clAngleNormalize(&m_rotation); // reduce speed const CL_Angle diffAngle = m_rotation - m_phyMoveRot; float diffDegAbs = fabs(diffAngle.to_degrees()); if (diffDegAbs > 0.1f) { CL_Angle diffAngleNorm = diffAngle; Workarounds::clAngleNormalize180(&diffAngleNorm); // 0.0 when going straight, 1.0 when 90 deg, > 1.0 when more than 90 deg const float angleRate = fabs(1.0f - (fabs(diffAngleNorm.to_degrees()) - 90.0f) / 90.0f); const float speedReduction = -DRIFT_SPEED_REDUCTION_RATE * angleRate; if (absSpeed > speedReduction) { m_speed += m_speed > 0.0f ? speedReduction : -speedReduction; } else { m_speed = 0.0f; } } // car cannot travel too quickly m_speed -= m_speed * AIR_RESITANCE; // calculate next move vector const float m_rotationRad = m_phyMoveRot.to_radians(); m_phyMoveVec.x = cos(m_rotationRad); m_phyMoveVec.y = sin(m_rotationRad); m_phyMoveVec.normalize(); m_phyMoveVec *= m_speed; // apply movement (invert y) m_position.x += m_phyMoveVec.x; m_position.y += m_phyMoveVec.y; // set speed delta m_phySpeedDelta = m_speed - prevSpeed; #if defined(CLIENT) #if !defined(NDEBUG) // print debug information DebugLayer *dbgl = Gfx::Stage::getDebugLayer(); dbgl->putMessage("speed", cl_format("%1", m_speed)); // if (!m_level) { // const float resistance = m_level->getResistance(m_position.x, m_position.y); // dbgl->putMessage("resist", cl_format("%1", resistance)); // } #endif // NDEBUG #endif // CLIENT }