const YsMatrix4x4 &YsViewPoint::GetViewMatrix(void) const { if(YSTRUE!=matrixCached) { matrix.LoadIdentity(); switch(YsCoordSysModel) { case YSRIGHT_ZMINUS_YPLUS: matrix.Translate(YsVec3(0.0,0.0,-GetViewDistance())); matrix.RotateXY(-GetViewAttitude().b()); matrix.RotateZY(-GetViewAttitude().p()); matrix.RotateXZ(-GetViewAttitude().h()); break; case YSLEFT_ZPLUS_YPLUS: matrix.Scale(1.0,1.0,-1.0); matrix.Translate(YsVec3(0.0,0.0,GetViewDistance())); matrix.RotateXY(-GetViewAttitude().b()); matrix.RotateZY(-GetViewAttitude().p()); matrix.RotateXZ(-GetViewAttitude().h()); break; } matrix.Translate(-GetViewTarget()); matrixCached=YSTRUE; // Memo: Equivalent OpenGL transformation. // glTranslated(0.0,0.0,-GetViewDistance()); // glRotated(-YsRadToDeg(GetViewAttitude().b()),0.0,0.0,1.0); // glRotated(-YsRadToDeg(GetViewAttitude().p()),1.0,0.0,0.0); // glRotated(-YsRadToDeg(GetViewAttitude().h()),0.0,1.0,0.0); // glTranslated(-GetViewTarget().x(),-GetViewTarget().y(),-GetViewTarget().z()); } return matrix; }
bool AController::LineOfSightTo(const AActor* Other, FVector ViewPoint, bool bAlternateChecks) { if( !Other ) { return false; } if ( ViewPoint.IsZero() ) { AActor* ViewTarg = GetViewTarget(); ViewPoint = ViewTarg->GetActorLocation(); if( ViewTarg == Pawn ) { ViewPoint.Z += Pawn->BaseEyeHeight; //look from eyes } } static FName NAME_LineOfSight = FName(TEXT("LineOfSight")); FCollisionQueryParams CollisionParms(NAME_LineOfSight, true, Other); CollisionParms.AddIgnoredActor(this->GetPawn()); FVector TargetLocation = Other->GetTargetLocation(Pawn); bool bHit = GetWorld()->LineTraceTest(ViewPoint, TargetLocation, ECC_Visibility, CollisionParms); if( !bHit ) { return true; } // if other isn't using a cylinder for collision and isn't a Pawn (which already requires an accurate cylinder for AI) // then don't go any further as it likely will not be tracing to the correct location if (!Cast<const APawn>(Other) && Cast<UCapsuleComponent>(Other->GetRootComponent()) == NULL) { return false; } float distSq = (Other->GetActorLocation() - ViewPoint).SizeSquared(); if ( distSq > FARSIGHTTHRESHOLDSQUARED ) { return false; } if ( !Cast<const APawn>(Other) && (distSq > NEARSIGHTTHRESHOLDSQUARED) ) { return false; } float OtherRadius, OtherHeight; Other->GetSimpleCollisionCylinder(OtherRadius, OtherHeight); //try viewpoint to head bHit = GetWorld()->LineTraceTest(ViewPoint, Other->GetActorLocation() + FVector(0.f,0.f,OtherHeight), ECC_Visibility, CollisionParms); return !bHit; }
bool AAIController::LineOfSightTo(const AActor* Other, FVector ViewPoint, bool bAlternateChecks) { if( !Other ) { return false; } if ( ViewPoint.IsZero() ) { AActor* ViewTarg = GetViewTarget(); ViewPoint = ViewTarg->GetActorLocation(); if( ViewTarg == GetPawn() ) { ViewPoint.Z += GetPawn()->BaseEyeHeight; //look from eyes } } static FName NAME_LineOfSight = FName(TEXT("LineOfSight")); FVector TargetLocation = Other->GetTargetLocation(GetPawn()); FCollisionQueryParams CollisionParams(NAME_LineOfSight, true, this->GetPawn()); CollisionParams.AddIgnoredActor(Other); bool bHit = GetWorld()->LineTraceTest(ViewPoint, TargetLocation, ECC_Visibility, CollisionParams); if( !bHit ) { return true; } // if other isn't using a cylinder for collision and isn't a Pawn (which already requires an accurate cylinder for AI) // then don't go any further as it likely will not be tracing to the correct location const APawn * OtherPawn = Cast<const APawn>(Other); if (!OtherPawn && Cast<UCapsuleComponent>(Other->GetRootComponent()) == NULL) { return false; } const FVector OtherActorLocation = Other->GetActorLocation(); float distSq = (OtherActorLocation - ViewPoint).SizeSquared(); if ( distSq > FARSIGHTTHRESHOLDSQUARED ) { return false; } if ( !OtherPawn && (distSq > NEARSIGHTTHRESHOLDSQUARED) ) { return false; } float OtherRadius, OtherHeight; Other->GetSimpleCollisionCylinder(OtherRadius, OtherHeight); if ( !bAlternateChecks || !bLOSflag ) { //try viewpoint to head bHit = GetWorld()->LineTraceTest(ViewPoint, OtherActorLocation + FVector(0.f,0.f,OtherHeight), ECC_Visibility, CollisionParams); if ( !bHit ) { return true; } } if( !bSkipExtraLOSChecks && (!bAlternateChecks || bLOSflag) ) { // only check sides if width of other is significant compared to distance if( OtherRadius * OtherRadius/(OtherActorLocation - ViewPoint).SizeSquared() < 0.0001f ) { return false; } //try checking sides - look at dist to four side points, and cull furthest and closest FVector Points[4]; Points[0] = OtherActorLocation - FVector(OtherRadius, -1 * OtherRadius, 0); Points[1] = OtherActorLocation + FVector(OtherRadius, OtherRadius, 0); Points[2] = OtherActorLocation - FVector(OtherRadius, OtherRadius, 0); Points[3] = OtherActorLocation + FVector(OtherRadius, -1 * OtherRadius, 0); int32 imin = 0; int32 imax = 0; float currentmin = (Points[0] - ViewPoint).SizeSquared(); float currentmax = currentmin; for ( int32 i=1; i<4; i++ ) { float nextsize = (Points[i] - ViewPoint).SizeSquared(); if (nextsize > currentmax) { currentmax = nextsize; imax = i; } else if (nextsize < currentmin) { currentmin = nextsize; imin = i; } } for ( int32 i=0; i<4; i++ ) { if ( (i != imin) && (i != imax) ) { bHit = GetWorld()->LineTraceTest(ViewPoint, Points[i], ECC_Visibility, CollisionParams); if ( !bHit ) { return true; } } } } return false; }