- Timestamp:
- Nov 14, 2015, 10:09:41 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/AI_HS15/src/orxonox/controllers/CommonController.cc
r10800 r10803 47 47 RegisterClass( CommonController ); 48 48 float SPEED = 0.9f/0.02f; 49 float ROTATEFACTOR = 0.5f/0.02f;49 float ROTATEFACTOR = 1.0f/0.02f; 50 50 51 51 CommonController::CommonController( Context* context ): Controller( context ) … … 55 55 this->executingManeuver_ = false; 56 56 this->executingMoveToPoint_ = false; 57 57 this->stopLookingAtTarget(); 58 58 this->maneuverType_ = ManeuverType::NONE; 59 59 RegisterObject( CommonController ); … … 120 120 void CommonController::maneuver() 121 121 { 122 123 if ( this->target_ && this->bHasPositionOfTarget_ && this->getControllableEntity() ) 124 { 125 Vector3 thisPosition = this->getControllableEntity() ->getWorldPosition(); 126 Quaternion thisOrientation = this->getControllableEntity() ->getOrientation(); 127 128 /*this->setPositionOfTarget( getPredictedPosition( 122 counter++; 123 124 if (counter > 5) 125 counter = 0; 126 if ( this->target_ && this->getControllableEntity()) 127 { 128 Vector3 thisPosition = this->getControllableEntity()->getWorldPosition(); 129 //Quaternion thisOrientation = this->getControllableEntity()->getOrientation(); 130 131 this->setPositionOfTarget( getPredictedPosition( 129 132 thisPosition, 130 133 hardcoded_projectile_speed, 131 134 this->target_->getWorldPosition() , 132 135 this->target_->getVelocity() 133 ) );*/ 134 this->setPositionOfTarget( this->target_->getWorldPosition() ); 136 ) ); 135 137 this->setOrientationOfTarget( this->target_->getOrientation() ); 136 138 … … 140 142 Vector3 diffUnit = diffVector/diffLength; 141 143 142 Vector3 thisForwardVector = thisOrientation * WorldEntity::FRONT; 143 float thisDotProduct = diffVector.dotProduct( thisForwardVector ); 144 145 Vector3 targetForwardVector = this->orientationOfTarget_ * WorldEntity::FRONT; 146 float targetDotProduct = diffVector.dotProduct( targetForwardVector ); 147 148 float thisAngle = getAngle( thisPosition, thisForwardVector, this->positionOfTarget_ ); 149 float targetAngle = getAngle( this->positionOfTarget_, targetForwardVector, thisPosition ); 150 151 152 bool bThisIsLookingAtTarget = ( thisAngle/( diffLength*diffLength ) < math::pi/8000000.0f ); 153 bool bTargetIsLookingAtThis = ( targetAngle/( diffLength*diffLength ) < math::pi/8000000.0f ); 144 145 146 //bool bThisIsLookingAtTarget = this->isLooking ( getControllableEntity(), this->target_, math::pi/4 ); 147 bool bTargetIsLookingAtThis = this->isLooking ( this->target_, getControllableEntity(), math::pi/8.0f ); 154 148 155 float angleDiff = targetAngle - thisAngle; 156 157 //if his angle is bigger than mine 158 if ( angleDiff > 0 ) 159 { 160 //if diff is insignificant 161 if ( bThisIsLookingAtTarget && bTargetIsLookingAtThis ) 162 { 163 //no way to dodge 164 if ( diffLength < 400 ) 165 { 166 Vector3* target = new Vector3 ( 0, -200, -200 ); 167 this->setTargetPosition( this->positionOfTarget_ ); 168 169 170 } 171 //do scissors 172 else 173 { 174 Vector3 target = ( diffUnit )* 150.0f; 175 Vector3* randVector = new Vector3( 176 randomInRange( -300, 300 ), 177 randomInRange( -300, 300 ), 178 randomInRange( -300, 300 ) 179 ); 180 Vector3 projection = randVector->dotProduct( diffUnit )* diffUnit; 181 *randVector -= projection; 182 target += *randVector; 183 this->setTargetPosition( this->getControllableEntity() ->getWorldPosition() + target ); 184 185 } 186 } 187 //this has advantage 149 150 151 //too far? well, come closer then 152 if ( diffLength > 5000 ) 153 { 154 if (diffLength < 6000) 155 { 156 this->bEngaging_ = true; 157 } 188 158 else 189 159 { 190 //if too close 191 if ( diffLength < 300 ) 192 { 193 this->setTargetPosition( this->getControllableEntity() ->getWorldPosition() ); 194 } 195 //move closer 196 else 197 { 198 this->setTargetPosition( this->positionOfTarget_ - 0.6f*diffVector ); 199 } 200 } 201 } 202 else 203 { 204 //if diff is insignificant 205 if ( bThisIsLookingAtTarget && bTargetIsLookingAtThis ) 206 { 207 //no way to dodge 208 if ( diffLength < 400 ) 209 { 210 Vector3* target = new Vector3 ( 0, -200, -200 ); 211 this->setTargetPosition( this->positionOfTarget_ ); 212 213 } 214 //do scissors 215 else 216 { 217 Vector3 target = ( diffUnit )* 150.0f; 218 Vector3* randVector = new Vector3( 219 randomInRange( -300, 300 ), 220 randomInRange( -300, 300 ), 221 randomInRange( -300, 300 ) 222 ); 223 Vector3 projection = randVector->dotProduct( diffUnit )* diffUnit; 224 *randVector -= projection; 225 target += *randVector; 226 this->setTargetPosition( this->getControllableEntity() ->getWorldPosition() + target ); 227 228 } 229 } 230 //target has advantage 160 this->bEngaging_ = false; 161 } 162 this->setTargetPosition( this->positionOfTarget_ ); 163 } 164 //too close? How do u expect to dodge anything? Just attack! 165 else if ( diffLength < 600 ) 166 { 167 //at this point, just look and shoot 168 if ( diffLength < 300 ) 169 { 170 this->stopMoving(); 171 this->startLookingAtTarget(); 172 } 231 173 else 232 174 { 233 //if too close 234 if ( diffLength < 300 ) 235 { 236 this->setTargetPosition( this->getControllableEntity() ->getWorldPosition() ); 237 } 238 //move closer 239 else 240 { 241 this->setTargetPosition( this->positionOfTarget_ - 0.6f*diffVector ); 242 } 243 } 244 } 245 this->bShooting_ = true; 175 this->setTargetPosition( this->positionOfTarget_ ); 176 } 177 } 178 //Good distance? Check if target looks at us. It doesn't? Go hunt! 179 else if ( !bTargetIsLookingAtThis ) 180 { 181 this->setTargetPosition( this->positionOfTarget_ ); 182 /* if (counter == 0) 183 { 184 this->setTargetPosition( this->positionOfTarget_ ); 185 return; 186 } 187 else 188 { 189 dodge( thisPosition, diffUnit ); 190 }*/ 191 } 192 //That's unfortunate, he is looking and probably shooting... try to dodge what we can... 193 else 194 { 195 196 if (counter == 0) 197 { 198 this->setTargetPosition( this->positionOfTarget_ ); 199 return; 200 } 201 dodge( thisPosition, diffUnit ); 202 203 } 204 } 205 if ( this->getControllableEntity() && !this->target_ ) 206 { 207 this->bEngaging_ = false; 208 this->maneuverType_ = ManeuverType::NONE; 209 } 210 orxout ( internal_error ) << "ManeuverType = " << this->maneuverType_ << endl; 211 } 212 ControllableEntity* CommonController::getTarget() 213 { 214 return this->target_; 215 } 216 void CommonController::dodge(Vector3& thisPosition, Vector3& diffUnit) 217 { 218 float factorX = 0, factorY = 0, factorZ = 0; 219 float rand = randomInRange (0, 1); 220 if (rand <= 0.5) 221 { 222 factorX = 1; 223 } 224 else 225 { 226 factorX = -1; 227 } 228 rand = randomInRange (0, 1); 229 if (rand <= 0.5) 230 { 231 factorY = 1; 232 } 233 else 234 { 235 factorY = -1; 236 } 237 rand = randomInRange (0, 1); 238 if (rand <= 0.5) 239 { 240 factorZ = 1; 241 } 242 else 243 { 244 factorZ = -1; 245 } 246 Vector3 target = ( diffUnit )* 8000.0f; 247 Vector3* randVector = new Vector3( 248 factorX * randomInRange( 10000, 40000 ), 249 factorY * randomInRange( 10000, 40000 ), 250 factorZ * randomInRange( 10000, 40000 ) 251 ); 252 Vector3 projection = randVector->dotProduct( diffUnit )* diffUnit; 253 *randVector -= projection; 254 target += *randVector; 255 this->setTargetPosition( thisPosition + target ); 256 } 257 void CommonController::stopMoving() 258 { 259 this->bHasTargetPosition_ = false; 260 } 261 void CommonController::startLookingAtTarget() 262 { 263 this->bLookAtTarget_ = true; 264 } 265 void CommonController::stopLookingAtTarget() 266 { 267 this->bLookAtTarget_ = false; 268 } 269 void CommonController::lookAtTarget(float dt) 270 { 271 272 273 ControllableEntity* entity = this->getControllableEntity(); 274 if ( !entity ) 275 return; 276 Vector2 coord = get2DViewCoordinates 277 ( entity->getPosition() , 278 entity->getOrientation() * WorldEntity::FRONT, 279 entity->getOrientation() * WorldEntity::UP, 280 positionOfTarget_ ); 281 282 //rotates should be in range [-1,+1], clamp cuts off all that is not 283 float rotateX = -clamp( coord.x * 10, -1.0f, 1.0f ); 284 float rotateY = clamp( coord.y * 10, -1.0f, 1.0f ); 285 286 287 288 //Yaw and Pitch are enough to start facing the target 289 this->getControllableEntity() ->rotateYaw( ROTATEFACTOR * rotateX * dt ); 290 this->getControllableEntity() ->rotatePitch( ROTATEFACTOR * rotateY * dt ); 291 246 292 247 } 248 if ( this->getControllableEntity() && !this->target_ ) 249 { 250 this->maneuverType_ = ManeuverType::NONE; 251 } 252 orxout ( internal_error ) << "ManeuverType = " << this->maneuverType_ << endl; 253 } 254 void CommonController::chooseManeuverType() 255 { 256 257 if ( this->target_ && this->bHasPositionOfTarget_ && this->getControllableEntity() ) 258 { 259 Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity() ->getWorldPosition(); 260 Vector3 thisForwardVector = this->getControllableEntity() ->getOrientation() * WorldEntity::FRONT; 261 float thisDotProduct = diffVector.dotProduct( thisForwardVector ); 262 263 Vector3 targetForwardVector = this->target_->getOrientation() * WorldEntity::FRONT; 264 float targetDotProduct = diffVector.dotProduct( targetForwardVector ); 265 266 267 switch ( ( thisDotProduct > 0 )- ( thisDotProduct < 0 )) 268 { 269 case 1: 270 { 271 switch ( ( targetDotProduct > 0 )- ( targetDotProduct < 0 )) 272 { 273 case 1: 274 { 275 this->maneuverType_ = ManeuverType::OFFENSIVE; 276 break; 277 } 278 case 0: 279 { 280 this->maneuverType_ = ManeuverType::OFFENSIVE; 281 break; 282 } 283 case -1: 284 { 285 this->maneuverType_ = ManeuverType::NEUTRAL; 286 break; 287 } 288 } 289 break; 290 } 291 case 0: 292 { 293 switch ( ( targetDotProduct > 0 )- ( targetDotProduct < 0 )) 294 { 295 case 1: 296 { 297 this->maneuverType_ = ManeuverType::OFFENSIVE; 298 break; 299 } 300 case 0: 301 { 302 this->maneuverType_ = ManeuverType::NEUTRAL; 303 break; 304 } 305 case -1: 306 { 307 this->maneuverType_ = ManeuverType::DEFENCIVE; 308 break; 309 } 310 } 311 312 break; 313 } 314 case -1: 315 { 316 switch ( ( targetDotProduct > 0 )- ( targetDotProduct < 0 )) 317 { 318 case 1: 319 { 320 this->maneuverType_ = ManeuverType::NEUTRAL; 321 break; 322 } 323 case 0: 324 { 325 this->maneuverType_ = ManeuverType::DEFENCIVE; 326 break; 327 } 328 case -1: 329 { 330 this->maneuverType_ = ManeuverType::DEFENCIVE; 331 break; 332 } 333 } 334 break; 335 } 336 } 337 } 338 if ( this->getControllableEntity() && !this->target_ ) 339 { 340 this->maneuverType_ = ManeuverType::NONE; 341 } 342 orxout ( internal_error ) << "ManeuverType = " << this->maneuverType_ << endl; 343 } 293 } 294 344 295 bool CommonController::setWingman ( CommonController* wingman ) 345 296 { … … 396 347 setTargetOrientation( target->getOrientation() ); 397 348 } 398 399 /*void CommonController::spin()400 {401 this->moveToTargetPosition();402 this->getControllableEntity() ->rotateRoll( 8.0f );403 }404 void CommonController::turn180()405 {406 Vector2 coord = get2DViewdirection( this->getControllableEntity() ->getPosition() , this->getControllableEntity() ->getOrientation() * WorldEntity::FRONT, this->getControllableEntity() ->getOrientation() * WorldEntity::UP, this->targetPosition_ );407 408 this->getControllableEntity() ->rotateYaw( -2.0f * sgn( coord.x )* coord.x*coord.x );409 this->getControllableEntity() ->rotatePitch( 2.0f * sgn( coord.y )* coord.y*coord.y );410 411 this->getControllableEntity() ->moveFrontBack( SPEED );412 }*/413 349 414 350 … … 444 380 return; 445 381 if ( this->rank_ == Rank::DIVISIONLEADER ) 446 factor = 0. 8;382 factor = 0.9; 447 383 if ( this->rank_ == Rank::SECTIONLEADER ) 448 factor = 0.9 ;384 factor = 0.95; 449 385 450 386 //100 is ( so far )the smallest tolerance ( empirically found )that can be reached, 451 387 //with smaller distance spaceships can't reach position and go circles around it instead 452 int tolerance = 6 0;388 int tolerance = 65; 453 389 454 390 ControllableEntity* entity = this->getControllableEntity(); … … 462 398 463 399 //rotates should be in range [-1,+1], clamp cuts off all that is not 464 float rotateX = clamp( coord.x * 10, -1.0f, 1.0f );400 float rotateX = -clamp( coord.x * 10, -1.0f, 1.0f ); 465 401 float rotateY = clamp( coord.y * 10, -1.0f, 1.0f ); 466 402 … … 469 405 { 470 406 //Yaw and Pitch are enough to start facing the target 471 this->getControllableEntity() ->rotateYaw( -2.0f *ROTATEFACTOR * rotateX * dt );472 this->getControllableEntity() ->rotatePitch( 2.0f *ROTATEFACTOR * rotateY * dt );407 this->getControllableEntity() ->rotateYaw( ROTATEFACTOR * rotateX * dt ); 408 this->getControllableEntity() ->rotatePitch( ROTATEFACTOR * rotateY * dt ); 473 409 474 410 //300 works, maybe less is better … … 485 421 } 486 422 487 this->getControllableEntity() ->moveFrontBack( 1.2f*SPEED*factor * dt );423 this->getControllableEntity() ->moveFrontBack( SPEED*factor * dt ); 488 424 } 489 425 else … … 500 436 return a + r; 501 437 } 502 void CommonController::attack() 503 { 504 if ( !this->getControllableEntity() ) 505 return; 506 if ( this->target_ ) 507 { 508 this->positionOfTarget_ = getPredictedPosition( 509 this->getControllableEntity() ->getWorldPosition() , 510 hardcoded_projectile_speed, 511 this->target_->getWorldPosition() , 512 this->target_->getVelocity() 513 ); 514 Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity() ->getWorldPosition(); 515 float diffLength = diffVector.length(); 516 if ( diffLength < 100 ) 517 { 518 Vector3* targetPosition; 519 targetPosition = new Vector3 ( 520 //randomInRange( 200, 300 ), 521 0, 522 //randomInRange( -300, -200 ), 523 0, 524 randomInRange( -300, -400 ) 525 ); 526 Quaternion rotationToTarget = ( this->getControllableEntity() ->getOrientation() * WorldEntity::FRONT ).getRotationTo( diffVector ); 527 Vector3 target = rotationToTarget * ( *targetPosition ); 528 moveToPoint( 529 target, 530 randomInRange( 45, 180 ) 531 ); 532 executingMoveToPoint_ = true; 533 return; 534 } 535 this->bShooting_ = true; 536 this->positionOfTarget_ = getPredictedPosition( 537 this->getControllableEntity() ->getWorldPosition() , 538 hardcoded_projectile_speed, 539 this->target_->getWorldPosition() , 540 this->target_->getVelocity() 541 ); 542 this->targetPosition_ = positionOfTarget_; 543 544 } 545 else 546 { 547 this->chooseManeuverType(); 548 } 549 } 550 void CommonController::scissors() 551 { 552 if ( !this->getControllableEntity() ) 553 return; 554 if ( this->target_ ) 555 { 556 this->positionOfTarget_ = getPredictedPosition( 557 this->getControllableEntity() ->getWorldPosition() , 558 hardcoded_projectile_speed, 559 this->target_->getWorldPosition() , 560 this->target_->getVelocity() 561 ); 562 Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity() ->getWorldPosition(); 563 float diffLength = diffVector.length(); 564 Vector3 targetForwardVector = this->target_->getOrientation() * WorldEntity::FRONT; 565 float targetDotProduct = diffVector.dotProduct( targetForwardVector ); 566 567 int f = ( int )rnd( 100.0f ); 568 f = ( f % 2 == 0 ? 1 : -1 ); 569 570 if( !this->executingMoveToPoint_ ) 571 { 572 Vector3* targetPosition; 573 if ( diffLength < 100 ) 574 { 575 targetPosition = new Vector3 ( 576 //f * randomInRange( 200, 300 ), 577 0, 578 //f * randomInRange( -300, -200 ), 579 0, 580 //randomInRange( -300, -400 ) 581 0 582 ); 583 } 584 else 585 { 586 if ( targetDotProduct < 0 ) 587 { 588 targetPosition = new Vector3 ( 589 //f * randomInRange( 200, 300 ), 590 0, 591 //f * randomInRange( -300, -200 ), 592 0, 593 //randomInRange( -300, -400 ) 594 -300 595 ); 596 } 597 else 598 { 599 targetPosition = new Vector3 ( 600 //f * randomInRange( 200, 300 ), 601 0, 602 //f * randomInRange( -300, -200 ), 603 0, 604 //randomInRange( -300, -400 ) 605 300 606 ); 607 } 608 } 609 Quaternion rotationToTarget = ( this->getControllableEntity() ->getOrientation() * WorldEntity::FRONT ).getRotationTo( diffVector ); 610 Vector3 target = rotationToTarget * ( *targetPosition ); 611 moveToPoint( 612 target, 613 randomInRange( 45, 180 ) 614 ); 615 executingMoveToPoint_ = true; 616 } 617 } 618 619 else 620 { 621 this->chooseManeuverType(); 622 } 623 } 624 void CommonController::gunsD() 625 { 626 if ( !this->getControllableEntity() ) 627 return; 628 if ( this->target_ ) 629 { 630 this->positionOfTarget_ = getPredictedPosition( 631 this->getControllableEntity() ->getWorldPosition() , 632 hardcoded_projectile_speed, 633 this->target_->getWorldPosition() , 634 this->target_->getVelocity() 635 ); 636 Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity() ->getWorldPosition(); 637 float diffLength = diffVector.length(); 638 if( !this->executingMoveToPoint_ ) 639 { 640 Vector3* targetPosition; 641 if ( diffLength < 200 ) 642 { 643 targetPosition = new Vector3 ( 644 //f * randomInRange( 200, 300 ), 645 0, 646 //f * randomInRange( -300, -200 ), 647 0, 648 //randomInRange( -300, -400 ) 649 0 650 ); 651 } 652 else if ( diffLength < 500 ) 653 { 654 targetPosition = new Vector3 ( 655 //randomInRange( 100, 200 ), 656 0, 657 //randomInRange( -200, -100 ), 658 0, 659 //randomInRange( -400, -600 ) 660 500 661 ); 662 } 663 else 664 { 665 targetPosition = new Vector3 ( 666 //randomInRange( 200, 300 ), 667 0, 668 //randomInRange( -300, -200 ), 669 0, 670 //randomInRange( -400, -600 ) 671 500 672 ); 673 } 674 Quaternion rotationToTarget = ( this->getControllableEntity() ->getOrientation() * WorldEntity::FRONT ).getRotationTo( diffVector ); 675 Vector3 target = rotationToTarget * ( *targetPosition ); 676 moveToPoint( 677 target, 678 randomInRange( 45, 180 ) 679 ); 680 executingMoveToPoint_ = true; 681 } 682 } 683 else 684 { 685 this->chooseManeuverType(); 686 } 687 } 438 439 688 440 //to be called in action 689 441 //PRE: relativeTargetPosition is desired position relative to the spaceship, … … 769 521 if ( !this->getControllableEntity() ) 770 522 return 0; 771 if ( !this->target_ )523 if ( !this->target_ || !this->getControllableEntity() ) 772 524 return ( this->getControllableEntity() ->getPosition() .squaredDistance( this->targetPosition_ ) ); 773 525 else … … 777 529 bool CommonController::isLookingAtTarget( float angle )const 778 530 { 779 if ( !this->getControllableEntity() )531 if ( !this->getControllableEntity() || !this->target_ ) 780 532 return false; 781 533 782 return ( getAngle( this->getControllableEntity() ->getPosition() , this->getControllableEntity() ->getOrientation() * WorldEntity::FRONT, this->positionOfTarget_ ) < angle ); 534 return ( getAngle( this->getControllableEntity() ->getPosition() , 535 this->getControllableEntity() ->getOrientation() * WorldEntity::FRONT, this->positionOfTarget_ ) < angle ); 536 } 537 bool CommonController::isLooking( ControllableEntity* entityThatLooks, ControllableEntity* entityBeingLookedAt, float angle )const 538 { 539 if ( !entityThatLooks || !entityBeingLookedAt ) 540 return false; 541 return ( getAngle( entityThatLooks ->getPosition() , 542 entityThatLooks->getOrientation() * WorldEntity::FRONT, 543 entityBeingLookedAt->getWorldPosition() ) < angle ); 783 544 } 784 545 785 546 bool CommonController::canFire() 786 547 { 548 549 //no target? why fire? 550 if ( !this->target_ ) 551 return false; 552 553 Vector3 newPositionOfTarget = getPredictedPosition( this->getControllableEntity() ->getWorldPosition() , 554 hardcoded_projectile_speed, this->target_->getWorldPosition() , this->target_->getVelocity() ); 555 if ( newPositionOfTarget != Vector3::ZERO ) 556 { 557 this->setPositionOfTarget( newPositionOfTarget ); 558 } 559 787 560 float squaredDistance = squaredDistanceToTarget(); 788 this->setPositionOfTarget( this->target_->getPosition() ); 789 790 if ( this->bShooting_ && squaredDistance < 9000000 && squaredDistance > 10000 && this->isLookingAtTarget( math::pi /( 0.0002f*squaredDistance )) ) 791 { 561 562 if ( squaredDistance < 25000000.0f && this->isLookingAtTarget( math::pi / 10.0f)) { 792 563 return true; 793 564 } … … 801 572 { 802 573 if ( !this->target_ || !this->getControllableEntity() ) 574 { 803 575 return; 804 static const float hardcoded_projectile_speed = 750; 805 806 this->positionOfTarget_ = getPredictedPosition( this->getControllableEntity() ->getWorldPosition() , hardcoded_projectile_speed, this->target_->getWorldPosition() , this->target_->getVelocity() ); 807 this->bHasPositionOfTarget_ = ( this->positionOfTarget_ != Vector3::ZERO ); 808 576 } 577 578 579 809 580 Pawn* pawn = orxonox_cast<Pawn*>( this->getControllableEntity() ); 810 581
Note: See TracChangeset
for help on using the changeset viewer.