// calculates suffix array. // O(n*logn) vector<int> suffix_array(const vector<T>& in) { int n = (int)in.size(), c = 0; vector<int> temp(n), pos2bckt(n), bckt(n), bpos(n), out(n); for (int i = 0; i < n; i++) out[i] = i; sort(out.begin(), out.end(), [&](int a, int b) { return in[a] < in[b]; }); for (int i = 0; i < n; i++) { bckt[i] = c; if (i + 1 == n || in[out[i]] != in[out[i + 1]]) c++; } for (int h = 1; h < n && c < n; h <<= 1) { for (int i = 0; i < n; i++) pos2bckt[out[i]] = bckt[i]; for (int i = n - 1; i >= 0; i--) bpos[bckt[i]] = i; for (int i = 0; i < n; i++) if (out[i] >= n - h) temp[bpos[bckt[i]]++] = out[i]; for (int i = 0; i < n; i++) if (out[i] >= h) temp[bpos[pos2bckt[out[i] - h]]++] = out[i] - h; c = 0; for (int i = 0; i + 1 < n; i++) { int a = (bckt[i] != bckt[i + 1]) || (temp[i] >= n - h) || (pos2bckt[temp[i + 1] + h] != pos2bckt[temp[i] + h]); bckt[i] = c; c += a; } bckt[n - 1] = c++; temp.swap(out); } return out; }
void GameLogic::ProcessPlayerBullets() { if (inputManager->IsSpacebarPressed()) { //shoot Model::Bullet* b = new Model::Bullet(); Model::Position bpos(playerDraw->getDimensions().getPosition()); bpos.incY(+0.1f); b->setPosition(bpos); player->getBullets().push_back(b); //draw bullets } std::vector<Model::Bullet*> bullets = player->getBullets(); std::cout << "bullets address(1): " << &bullets << std::endl; for (std::vector<Model::Bullet*>::iterator it = bullets.begin() ; it != bullets.end(); ++it) { std::cout << (*it)->getPosition().getY() << std::endl; //(*it)->getPosition().setY(0.0f); std::cout << &(*it) << " "<< (*it)->getPosition().getY() << std::endl; } bulletDraw->Render(bullets); for (std::vector<Model::Bullet*>::iterator it = bullets.begin() ; it != bullets.end(); ++it) { //(*it)->getPosition().setY(-0.5f); std::cout << &(*it) << " "<< (*it)->getPosition().getY() << std::endl; } }
void CharacterObject::setPosition(const glm::vec3& pos) { if( physCharacter ) { btVector3 bpos(pos.x, pos.y, pos.z); if( std::abs(-100.f - pos.z) < 0.01f ) { // Find the ground position auto gpos = engine->getGroundAtPosition(pos); bpos.setZ(gpos.z+1.f); } physCharacter->warp(bpos); } position = pos; }
/*! */ void PlayerControlPainter::draw( QPainter & painter ) { const Options & opt = Options::instance(); if ( ! opt.showKickAccelArea() ) { return; } int number = opt.selectedNumber(); if ( number == 0 ) { return; } MonitorViewConstPtr view = M_main_data.getCurrentViewData(); if ( ! view ) { return; } const Ball & ball = view->ball(); if ( ! ball.hasDelta() ) { return; } const rcsc::ServerParam & SP = rcsc::ServerParam::i(); const DrawConfig & dconf = DrawConfig::instance(); const Player & player = view->players()[ ( number > 0 ? number - 1 : -number - 1 + 11 ) ]; const rcsc::PlayerType & ptype = M_main_data.viewHolder().playerType( player.type() ); rcsc::Vector2D ppos( player.x(), player.y() ); rcsc::Vector2D bpos( ball.x(), ball.y() ); rcsc::Vector2D player_to_ball = bpos - ppos; player_to_ball.rotate( - player.body() ); rcsc::Vector2D bnext( bpos.x + ball.deltaX(), bpos.y + ball.deltaY() ); double ball_dist = player_to_ball.r(); if ( ball_dist < ptype.kickableArea() ) { double max_kick_accel = SP.maxPower() //* SP.kickPowerRate() * ptype.kickPowerRate() * ( 1.0 - 0.25 * player_to_ball.th().abs() / 180.0 - 0.25 * ( ball_dist - ptype.playerSize() - SP.ballSize() ) / ptype.kickableMargin() ); if ( max_kick_accel > SP.ballAccelMax() ) { max_kick_accel = SP.ballAccelMax(); } QPointF bpos_screen( opt.screenXF( bpos.x ), opt.screenYF( bpos.y ) ); QPointF bnext_screen( opt.screenXF( bnext.x ), opt.screenYF( bnext.y ) ); double max_speed_screen = opt.scaleF( SP.ballSpeedMax() ); double max_kick_accel_screen = opt.scaleF( max_kick_accel ); painter.setPen( dconf.kickAccelPen() ); painter.setBrush( dconf.transparentBrush() ); // draw no noise next ball move only by inertia painter.drawLine( QLineF( bpos_screen, bnext_screen ) ); rcsc::Circle2D max_speed_circle( bpos, SP.ballSpeedMax() ); rcsc::Circle2D max_accel_circle( bnext, max_kick_accel ); rcsc::Vector2D intersection_1, intersection_2; if ( max_speed_circle.intersection( max_accel_circle, &intersection_1, &intersection_2 ) != 2 ) { // no intersection points // just draw a next ball reachable area by max accel painter.drawEllipse( QRectF( bnext_screen.x() - max_kick_accel_screen, bnext_screen.y() - max_kick_accel_screen, max_kick_accel_screen * 2, max_kick_accel_screen * 2 ) ); } else { // exists 2 intersection points rcsc::AngleDeg bpos_to_intersection_1 = ( intersection_1 - bpos ).th(); rcsc::AngleDeg bpos_to_intersection_2 = ( intersection_2 - bpos ).th(); rcsc::AngleDeg bpos_to_bnext_angle = ( bnext - bpos ).th(); rcsc::AngleDeg * bpos_start_angle = 0; double bpos_angle_span = 0.0; if ( bpos_to_intersection_1.isLeftOf( bpos_to_bnext_angle ) ) { bpos_start_angle = &bpos_to_intersection_1; bpos_angle_span = ( bpos_to_intersection_2 - bpos_to_intersection_1 ).degree(); if ( bpos_angle_span < 0.0 ) { bpos_angle_span += 360.0; } bpos_angle_span *= -1.0; } else { bpos_start_angle = &bpos_to_intersection_2; bpos_angle_span = ( bpos_to_intersection_1 - bpos_to_intersection_2 ).degree(); if ( bpos_angle_span < 0.0 ) { bpos_angle_span += 360.0; } bpos_angle_span *= -1.0; } if ( opt.reverseSide() ) { *bpos_start_angle += 180.0; } int bpos_start_angle_int = static_cast< int >( rint( - bpos_start_angle->degree() * 16 ) ); int bpos_angle_span_int = static_cast< int >( rint( bpos_angle_span * 16 ) ); painter.drawArc( QRectF( bpos_screen.x() - max_speed_screen, bpos_screen.y() - max_speed_screen, max_speed_screen * 2, max_speed_screen * 2 ), bpos_start_angle_int, bpos_angle_span_int ); rcsc::AngleDeg bnext_to_intersection_1 = ( intersection_1 - bnext ).th(); rcsc::AngleDeg bnext_to_intersection_2 = ( intersection_2 - bnext ).th(); rcsc::AngleDeg bnext_to_bpos_angle = bpos_to_bnext_angle + 180.0; rcsc::AngleDeg * bnext_start_angle = 0; double bnext_angle_span = 0.0; if ( bnext_to_intersection_1.isLeftOf( bnext_to_bpos_angle ) ) { bnext_start_angle = &bnext_to_intersection_1; bnext_angle_span = ( bnext_to_intersection_2 - bnext_to_intersection_1 ).degree(); if ( bnext_angle_span < 0.0 ) { bnext_angle_span += 360.0; } bnext_angle_span *= -1.0; } else { bnext_start_angle = &bnext_to_intersection_2; bnext_angle_span = ( bnext_to_intersection_1 - bnext_to_intersection_2 ).degree(); if ( bnext_angle_span < 0.0 ) { bnext_angle_span += 360.0; } bnext_angle_span *= -1.0; } if ( opt.reverseSide() ) { *bnext_start_angle += 180.0; } int bnext_start_angle_int = static_cast< int >( rint( - bnext_start_angle->degree() * 16 ) ); int bnext_angle_span_int = static_cast< int >( rint( bnext_angle_span * 16 ) ); painter.drawArc( QRectF( bnext_screen.x() - max_kick_accel_screen, bnext_screen.y() - max_kick_accel_screen, max_kick_accel_screen * 2, max_kick_accel_screen * 2 ), bnext_start_angle_int, bnext_angle_span_int ); } // draw kick info text painter.setFont( dconf.playerFont() ); painter.setPen( dconf.kickAccelPen() ); //snprintf( buf, 32, "MaxAccel=%.3f", max_kick_accel ); painter.drawText( QPointF( bnext_screen.x() + 10, bnext_screen.y() + painter.fontMetrics().ascent() ), QString( "MaxAccel=%1" ).arg( max_kick_accel, 0, 'g', 4 ) ); } }
/*! */ void PlayerPainter::drawKickAccelArea( QPainter & painter, const PlayerPainter::Param & param ) const { // // draw kick accel area // if ( ! param.ball_.hasVelocity() ) { return; } const Options & opt = Options::instance(); const rcss::rcg::ServerParamT & SP = M_main_data.serverParam(); Vector2D ppos( param.player_.x_, param.player_.y_ ); Vector2D bpos( param.ball_.x_, param.ball_.y_ ); Vector2D player_to_ball = bpos - ppos; player_to_ball.rotate( - param.player_.body_ ); double ball_dist = player_to_ball.r(); if ( ball_dist > ( param.player_type_.player_size_ + param.player_type_.kickable_margin_ + SP.ball_size_ ) ) { return; } double max_kick_accel = SP.max_power_ //* SP.kick_power_rate_ * param.player_type_.kick_power_rate_ * ( 1.0 - 0.25 * player_to_ball.th().abs() / 180.0 - 0.25 * ( ball_dist - param.player_type_.player_size_ - SP.ball_size_ ) / param.player_type_.kickable_margin_ ); if ( max_kick_accel > SP.ball_accel_max_ ) { max_kick_accel = SP.ball_accel_max_; } Vector2D bnext( bpos.x + param.ball_.vx_, bpos.y + param.ball_.vy_ ); QPoint bpos_screen( opt.screenX( bpos.x ), opt.screenY( bpos.y ) ); QPoint bnext_screen( opt.screenX( bnext.x ), opt.screenY( bnext.y ) ); int max_speed_screen = opt.scale( SP.ball_speed_max_ ); int max_kick_accel_screen = opt.scale( max_kick_accel ); painter.setPen( M_kick_accel_pen ); painter.setBrush( Qt::NoBrush ); // draw no noise ball move line painter.drawLine( bpos_screen, bnext_screen ); Circle2D max_speed_circle( bpos, SP.ball_speed_max_ ); Circle2D max_accel_circle( bnext, max_kick_accel ); Vector2D intersection_1, intersection_2; if ( max_speed_circle.intersection( max_accel_circle, &intersection_1, &intersection_2 ) != 2 ) { // no intersection points // just draw a next ball reachable area by max accel painter.drawEllipse( bnext_screen.x() - max_kick_accel_screen, bnext_screen.y() - max_kick_accel_screen, max_kick_accel_screen * 2, max_kick_accel_screen * 2 ); } else { // exists 2 intersection points AngleDeg bpos_to_intersection_1 = ( intersection_1 - bpos ).th(); AngleDeg bpos_to_intersection_2 = ( intersection_2 - bpos ).th(); AngleDeg bpos_to_bnext_angle = ( bnext - bpos ).th(); AngleDeg * bpos_start_angle = 0; double bpos_angle_span = 0.0; if ( bpos_to_intersection_1.isLeftOf( bpos_to_bnext_angle ) ) { bpos_start_angle = &bpos_to_intersection_1; bpos_angle_span = ( bpos_to_intersection_2 - bpos_to_intersection_1 ).degree(); if ( bpos_angle_span < 0.0 ) { bpos_angle_span += 360.0; } bpos_angle_span *= -1.0; } else { bpos_start_angle = &bpos_to_intersection_2; bpos_angle_span = ( bpos_to_intersection_1 - bpos_to_intersection_2 ).degree(); if ( bpos_angle_span < 0.0 ) { bpos_angle_span += 360.0; } bpos_angle_span *= -1.0; } int bpos_start_angle_int = static_cast< int >( rint( - bpos_start_angle->degree() * 16 ) ); int bpos_angle_span_int = static_cast< int >( rint( bpos_angle_span * 16 ) ); painter.drawArc( bpos_screen.x() - max_speed_screen, bpos_screen.y() - max_speed_screen, max_speed_screen * 2, max_speed_screen * 2, bpos_start_angle_int, bpos_angle_span_int ); AngleDeg bnext_to_intersection_1 = ( intersection_1 - bnext ).th(); AngleDeg bnext_to_intersection_2 = ( intersection_2 - bnext ).th(); AngleDeg bnext_to_bpos_angle = bpos_to_bnext_angle + 180.0; AngleDeg * bnext_start_angle = 0; double bnext_angle_span = 0.0; if ( bnext_to_intersection_1.isLeftOf( bnext_to_bpos_angle ) ) { bnext_start_angle = &bnext_to_intersection_1; bnext_angle_span = ( bnext_to_intersection_2 - bnext_to_intersection_1 ).degree(); if ( bnext_angle_span < 0.0 ) { bnext_angle_span += 360.0; } bnext_angle_span *= -1.0; } else { bnext_start_angle = &bnext_to_intersection_2; bnext_angle_span = ( bnext_to_intersection_1 - bnext_to_intersection_2 ).degree(); if ( bnext_angle_span < 0.0 ) { bnext_angle_span += 360.0; } bnext_angle_span *= -1.0; } int bnext_start_angle_int = static_cast< int >( rint( - bnext_start_angle->degree() * 16 ) ); int bnext_angle_span_int = static_cast< int >( rint( bnext_angle_span * 16 ) ); painter.drawArc( bnext_screen.x() - max_kick_accel_screen, bnext_screen.y() - max_kick_accel_screen, max_kick_accel_screen * 2, max_kick_accel_screen * 2, bnext_start_angle_int, bnext_angle_span_int ); } // draw kick info text painter.setFont( M_player_font ); painter.setPen( M_kick_accel_pen ); char buf[32]; snprintf( buf, 32, "MaxAccel=%.3f", max_kick_accel ); painter.drawText( bnext_screen.x() + 10, bnext_screen.y() + painter.fontMetrics().ascent(), QString::fromAscii( buf ) ); }
/*! */ void PlayerPainter::drawTackleArea( QPainter & painter, const PlayerPainter::Param & param ) const { // // draw tackle area & probability // const Options & opt = Options::instance(); const rcss::rcg::ServerParamT & SP = M_main_data.serverParam(); Vector2D ppos( param.player_.x_, param.player_.y_ ); Vector2D bpos( param.ball_.x_, param.ball_.y_ ); Vector2D player_to_ball = bpos - ppos; player_to_ball.rotate( - param.player_.body_ ); double tackle_dist = ( player_to_ball.x > 0.0 ? SP.tackle_dist_ : SP.tackle_back_dist_ ); if ( tackle_dist < 1.0e-5 ) { return; } double tackle_fail_prob = ( std::pow( player_to_ball.absX() / tackle_dist, SP.tackle_exponent_ ) + std::pow( player_to_ball.absY() / SP.tackle_width_, SP.tackle_exponent_ ) ); double foul_fail_prob = ( std::pow( player_to_ball.absX() / tackle_dist, SP.foul_exponent_ ) + std::pow( player_to_ball.absY() / SP.tackle_width_, SP.foul_exponent_ ) ); if ( tackle_fail_prob < 1.0 || foul_fail_prob < 1.0 ) { painter.save(); painter.translate( param.x_, param.y_ ); painter.rotate( param.player_.body_ ); painter.setPen( M_tackle_pen ); painter.setBrush( Qt::NoBrush ); painter.drawRect( opt.scale( - SP.tackle_back_dist_ ), opt.scale( - SP.tackle_width_ ), opt.scale( SP.tackle_dist_ + SP.tackle_back_dist_ ), opt.scale( SP.tackle_width_ * 2.0 ) ); painter.restore(); int text_radius = std::min( 40, param.draw_radius_ ); painter.setFont( M_player_font ); painter.setPen( M_tackle_pen ); if ( tackle_fail_prob < 1.0 && foul_fail_prob < 1.0 ) { painter.drawText( param.x_ + text_radius, param.y_ + 2 + painter.fontMetrics().ascent(), QString( "T=%1,F=%2" ) .arg( 1.0 - tackle_fail_prob, 0, 'g', 3 ) .arg( 1.0 - foul_fail_prob, 0, 'g', 3 ) ); } else if ( tackle_fail_prob < 1.0 ) { painter.drawText( param.x_ + text_radius, param.y_ + 2 + painter.fontMetrics().ascent(), QString( "Tackle=%1" ) .arg( 1.0 - tackle_fail_prob, 0, 'g', 3 ) ); } else if ( foul_fail_prob < 1.0 ) { painter.drawText( param.x_ + text_radius, param.y_ + 2 + painter.fontMetrics().ascent(), QString( "Foul=%1" ) .arg( 1.0 - foul_fail_prob, 0, 'g', 3 ) ); } } }
void CharacterObject::updateCharacter(float dt) { /* * You can fire weapons while moving * * Two Modes: Moving and Action * Moving covers walking & jumping * Action covers complex things like shooting, entering vehicles etc. * * Movement animation should be handled here * If Current weapon is one handed, then it can be used while walking. * This means blending the weapon animation with the walk animation. * No weapons can be used while sprinting. * Need an "aim vector" to apply torso correction. * * If movement vector is less than some threshold, fully walk animation * (time adjusted for velocity). */ if(physCharacter) { glm::vec3 walkDir = updateMovementAnimation(dt); position = getPosition(); if (canTurn()) { rotation = glm::angleAxis(m_look.x, glm::vec3{0.f, 0.f, 1.f}); } walkDir = rotation * walkDir; if( jumped ) { if( !isOnGround() ) { walkDir = rotation * glm::vec3(0.f, jumpSpeed * dt, 0.f); } } if (isAlive()) { physCharacter->setWalkDirection(btVector3(walkDir.x, walkDir.y, walkDir.z)); } else { physCharacter->setWalkDirection(btVector3(0.f, 0.f, 0.f)); } auto Pos = physCharacter->getGhostObject()->getWorldTransform().getOrigin(); position = glm::vec3(Pos.x(), Pos.y(), Pos.z()); // Handle above waist height water. auto wi = engine->data->getWaterIndexAt(getPosition()); if( wi != NO_WATER_INDEX ) { float wh = engine->data->waterHeights[wi]; auto ws = getPosition(); wh += engine->data->getWaveHeightAt(ws); // If Not in water before // If last position was above water // Now Underwater // Else Not Underwater // Else // Underwater if( ! inWater && ws.z < wh && _lastHeight > wh ) { ws.z = wh; btVector3 bpos(ws.x, ws.y, ws.z); physCharacter->warp(bpos); auto& wt = physObject->getWorldTransform(); wt.setOrigin(bpos); physObject->setWorldTransform(wt); physCharacter->setGravity(0.f); inWater = true; } else { physCharacter->setGravity(9.81f); inWater = false; } } _lastHeight = getPosition().z; } else { updateMovementAnimation(dt); } }
void down() { unsigned bp = bpos(), t = cont(VSTEP+bp); set(VSTEP+bp,0); set(bp,t); }
void up() { unsigned bp = bpos(), t = cont(bp-VSTEP); set(bp-VSTEP,0); set(bp,t); }
void right() { unsigned bp = bpos(), t = cont(HSTEP+bp); set(HSTEP+bp,0); set(bp,t); }
void left() { unsigned bp = bpos(), t = cont(bp-HSTEP); set(bp-HSTEP, 0); set(bp, t); }
short allowed_steps() { unsigned bp = bpos(); return ( (bp<4?(m1_>>(bp<<2)):(m2_>>((bp-4)<<2))) & 0xF ); }
//----------------------------------------------------------------------- // a p p l y I m p u l s e //----------------------------------------------------------------------- void TPhysicsObject::applyImpulse(const TVector3& impulse, const TVector3& rel_pos) { btVector3 bpos(rel_pos.X, rel_pos.Y, rel_pos.Z); btVector3 bimpulse(impulse.X, impulse.Y, impulse.Z); m_rigidBody->applyImpulse(bimpulse,bpos); }