本文整理汇总了C++中FVector::IsNearlyZero方法的典型用法代码示例。如果您正苦于以下问题:C++ FVector::IsNearlyZero方法的具体用法?C++ FVector::IsNearlyZero怎么用?C++ FVector::IsNearlyZero使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类FVector
的用法示例。
在下文中一共展示了FVector::IsNearlyZero方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: PushCommandRotation
void UFlareSpacecraftNavigationSystem::PushCommandRotation(const FVector& RotationTarget, const FVector& LocalShipAxis)
{
if (RotationTarget.IsNearlyZero() || LocalShipAxis.IsNearlyZero())
{
return;
}
FFlareShipCommandData Command;
Command.Type = EFlareCommandDataType::CDT_Rotation;
Command.RotationTarget = RotationTarget;
Command.LocalShipAxis = LocalShipAxis;
FLOGV("UFlareSpacecraftNavigationSystem::PushCommandRotation RotationTarget '%s'", *RotationTarget.ToString());
FLOGV("UFlareSpacecraftNavigationSystem::PushCommandRotation LocalShipAxis '%s'", *LocalShipAxis.ToString());
PushCommand(Command);
}
示例2: EvaluateBoneTransforms
void FAnimNode_HandIKRetargeting::EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, const FBoneContainer& RequiredBones, FA2CSPose& MeshBases, TArray<FBoneTransform>& OutBoneTransforms)
{
checkSlow(OutBoneTransforms.Num() == 0);
// Get component space transforms for all of our IK and FK bones.
FTransform const RightHandFKTM = MeshBases.GetComponentSpaceTransform(RightHandFK.BoneIndex);
FTransform const LeftHandFKTM = MeshBases.GetComponentSpaceTransform(LeftHandFK.BoneIndex);
FTransform const RightHandIKTM = MeshBases.GetComponentSpaceTransform(RightHandIK.BoneIndex);
FTransform const LeftHandIKTM = MeshBases.GetComponentSpaceTransform(LeftHandIK.BoneIndex);
// Compute weight FK and IK hand location. And translation from IK to FK.
FVector const FKLocation = FMath::Lerp<FVector>(LeftHandFKTM.GetTranslation(), RightHandFKTM.GetTranslation(), HandFKWeight);
FVector const IKLocation = FMath::Lerp<FVector>(LeftHandIKTM.GetTranslation(), RightHandIKTM.GetTranslation(), HandFKWeight);
FVector const IK_To_FK_Translation = FKLocation - IKLocation;
// If we're not translating, don't send any bones to update.
if (!IK_To_FK_Translation.IsNearlyZero())
{
// Move desired bones
for (int32 BoneIndex = 0; BoneIndex < IKBonesToMove.Num(); BoneIndex++)
{
FBoneReference const & BoneReference = IKBonesToMove[BoneIndex];
if (BoneReference.IsValid(RequiredBones))
{
FTransform BoneTransform = MeshBases.GetComponentSpaceTransform(BoneReference.BoneIndex);
BoneTransform.AddToTranslation(IK_To_FK_Translation);
OutBoneTransforms.Add(FBoneTransform(BoneReference.BoneIndex, BoneTransform));
}
}
}
}
示例3: EvaluateBoneTransforms
void FAnimNode_HandIKRetargeting::EvaluateBoneTransforms(USkeletalMeshComponent* SkelComp, FCSPose<FCompactPose>& MeshBases, TArray<FBoneTransform>& OutBoneTransforms)
{
checkSlow(OutBoneTransforms.Num() == 0);
const FBoneContainer& BoneContainer = MeshBases.GetPose().GetBoneContainer();
// Get component space transforms for all of our IK and FK bones.
const FTransform& RightHandFKTM = MeshBases.GetComponentSpaceTransform(RightHandFK.GetCompactPoseIndex(BoneContainer));
const FTransform& LeftHandFKTM = MeshBases.GetComponentSpaceTransform(LeftHandFK.GetCompactPoseIndex(BoneContainer));
const FTransform& RightHandIKTM = MeshBases.GetComponentSpaceTransform(RightHandIK.GetCompactPoseIndex(BoneContainer));
const FTransform& LeftHandIKTM = MeshBases.GetComponentSpaceTransform(LeftHandIK.GetCompactPoseIndex(BoneContainer));
// Compute weight FK and IK hand location. And translation from IK to FK.
FVector const FKLocation = FMath::Lerp<FVector>(LeftHandFKTM.GetTranslation(), RightHandFKTM.GetTranslation(), HandFKWeight);
FVector const IKLocation = FMath::Lerp<FVector>(LeftHandIKTM.GetTranslation(), RightHandIKTM.GetTranslation(), HandFKWeight);
FVector const IK_To_FK_Translation = FKLocation - IKLocation;
// If we're not translating, don't send any bones to update.
if (!IK_To_FK_Translation.IsNearlyZero())
{
// Move desired bones
for (const FBoneReference& BoneReference : IKBonesToMove)
{
if (BoneReference.IsValid(BoneContainer))
{
FCompactPoseBoneIndex BoneIndex = BoneReference.GetCompactPoseIndex(BoneContainer);
FTransform BoneTransform = MeshBases.GetComponentSpaceTransform(BoneIndex);
BoneTransform.AddToTranslation(IK_To_FK_Translation);
OutBoneTransforms.Add(FBoneTransform(BoneIndex, BoneTransform));
}
}
}
}
示例4: TickComponent
void UCollidingPawnMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
// some amazing coding here
// Make sure that every thing is still valid and we are allowed to move
if (!PawnOwner || !UpdatedComponent || ShouldSkipUpdate(DeltaTime))
{
return;
}
// Get (and then clear) the movement vector that we set in ACollidingPawn::Tick
FVector DesiredMovementThisFrame = ConsumeInputVector().GetClampedToMaxSize(1.0f)*DeltaTime*150.0f;
if (!DesiredMovementThisFrame.IsNearlyZero())
{
FHitResult Hit;
SafeMoveUpdatedComponent(DesiredMovementThisFrame, UpdatedComponent->GetComponentRotation(), true, Hit);
// If we bumped into something, try to slide along it // this check is important because otherwise the pawn will simply stop
/* if (Hit.IsValidBlockingHit())
{
SlideAlongSurface(DesiredMovementThisFrame, 1.f - Hit.Time, Hit.Normal, Hit);
}*/
}
}
示例5: Set
void FBasedPosition::Set(class AActor* InBase, const FVector& InPosition)
{
if( InPosition.IsNearlyZero() )
{
Base = NULL;
Position = FVector::ZeroVector;
return;
}
Base = (InBase && InBase->GetRootComponent() && (InBase->GetRootComponent()->Mobility != EComponentMobility::Static)) ? InBase : NULL;
if( Base )
{
const FVector BaseLocation = Base->GetActorLocation();
const FRotator BaseRotation = Base->GetActorRotation();
CachedBaseLocation = BaseLocation;
CachedBaseRotation = BaseRotation;
CachedTransPosition = InPosition;
Position = FTransform(BaseRotation).InverseTransformPosition(InPosition - BaseLocation);
}
else
{
Position = InPosition;
}
}
示例6: SlideAlongSurface
float UMovementComponent::SlideAlongSurface(const FVector& Delta, float Time, const FVector& Normal, FHitResult& Hit, bool bHandleImpact)
{
if (!Hit.bBlockingHit)
{
return 0.f;
}
float PercentTimeApplied = 0.f;
const FVector OldHitNormal = Normal;
FVector SlideDelta = ComputeSlideVector(Delta, Time, Normal, Hit);
if ((SlideDelta | Delta) > 0.f)
{
const FQuat Rotation = UpdatedComponent->GetComponentQuat();
SafeMoveUpdatedComponent(SlideDelta, Rotation, true, Hit);
const float FirstHitPercent = Hit.Time;
PercentTimeApplied = FirstHitPercent;
if (Hit.IsValidBlockingHit())
{
// Notify first impact
if (bHandleImpact)
{
HandleImpact(Hit, FirstHitPercent * Time, SlideDelta);
}
// Compute new slide normal when hitting multiple surfaces.
TwoWallAdjust(SlideDelta, Hit, OldHitNormal);
// Only proceed if the new direction is of significant length and not in reverse of original attempted move.
if (!SlideDelta.IsNearlyZero(1e-3f) && (SlideDelta | Delta) > 0.f)
{
// Perform second move
SafeMoveUpdatedComponent(SlideDelta, Rotation, true, Hit);
const float SecondHitPercent = Hit.Time * (1.f - FirstHitPercent);
PercentTimeApplied += SecondHitPercent;
// Notify second impact
if (bHandleImpact && Hit.bBlockingHit)
{
HandleImpact(Hit, SecondHitPercent * Time, SlideDelta);
}
}
}
return FMath::Clamp(PercentTimeApplied, 0.f, 1.f);
}
return 0.f;
}
示例7: SnapDragLocationToNearestVertex
bool FVertexSnappingImpl::SnapDragLocationToNearestVertex( const FVector& BaseLocation, FVector& DragDelta, FLevelEditorViewportClient* ViewportClient )
{
int32 MouseX = ViewportClient->Viewport->GetMouseX();
int32 MouseY = ViewportClient->Viewport->GetMouseY();
FVector2D MousePosition = FVector2D( MouseX, MouseY ) ;
EAxisList::Type CurrentAxis = ViewportClient->GetCurrentWidgetAxis();
bool bSnapped = false;
if( !DragDelta.IsNearlyZero() )
{
FVector Direction = DragDelta.GetSafeNormal();
FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues(
ViewportClient->Viewport,
ViewportClient->GetScene(),
ViewportClient->EngineShowFlags )
.SetRealtimeUpdate( ViewportClient->IsRealtime() ));
FSceneView* View = ViewportClient->CalcSceneView( &ViewFamily );
FVector DesiredUnsnappedLocation = BaseLocation+DragDelta;
FBoxSphereBounds SnappingAreaBox( FBox( DesiredUnsnappedLocation-VertexSnappingConstants::MaxSnappingDistance, DesiredUnsnappedLocation+VertexSnappingConstants::MaxSnappingDistance ) );
FBox AllowedSnappingBox = SnappingAreaBox.GetBox();
AllowedSnappingBox += DragDelta;
FPlane ActorPlane( DesiredUnsnappedLocation, Direction );
TSet< TWeakObjectPtr<AActor> > NoActorsToIgnore;
FVertexSnappingArgs Args
(
ActorPlane,
DesiredUnsnappedLocation,
ViewportClient,
View,
MousePosition,
CurrentAxis,
true
);
SnapDragDelta( Args, BaseLocation, AllowedSnappingBox, NoActorsToIgnore, DragDelta );
}
return bSnapped;
}
示例8: TickComponent
void UFloatingPawnMovement::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (!PawnOwner || !UpdatedComponent || ShouldSkipUpdate(DeltaTime))
{
return;
}
const AController* Controller = PawnOwner->GetController();
if (Controller && Controller->IsLocalController())
{
ApplyControlInputToVelocity(DeltaTime);
LimitWorldBounds();
bPositionCorrected = false;
// Move actor
FVector Delta = Velocity * DeltaTime;
if (!Delta.IsNearlyZero(1e-6f))
{
const FVector OldLocation = UpdatedComponent->GetComponentLocation();
const FRotator Rotation = UpdatedComponent->GetComponentRotation();
FVector TraceStart = OldLocation;
FHitResult Hit(1.f);
SafeMoveUpdatedComponent(Delta, Rotation, true, Hit);
if (Hit.IsValidBlockingHit())
{
HandleImpact(Hit, DeltaTime, Delta);
// Try to slide the remaining distance along the surface.
SlideAlongSurface(Delta, 1.f-Hit.Time, Hit.Normal, Hit, true);
}
// Update velocity
// We don't want position changes to vastly reverse our direction (which can happen due to penetration fixups etc)
if (!bPositionCorrected)
{
const FVector NewLocation = UpdatedComponent->GetComponentLocation();
Velocity = ((NewLocation - OldLocation) / DeltaTime);
}
}
// Finalize
UpdateComponentVelocity();
}
};
示例9: SetupNonUniformHelper
void SetupNonUniformHelper(FVector& Scale3D, float& MinScale, float& MinScaleAbs, FVector& Scale3DAbs)
{
// if almost zero, set min scale
// @todo fixme
if (Scale3D.IsNearlyZero())
{
// set min scale
Scale3D = FVector(0.1f);
}
Scale3DAbs = Scale3D.GetAbs();
MinScaleAbs = Scale3DAbs.GetMin();
MinScale = FMath::Max3(Scale3D.X, Scale3D.Y, Scale3D.Z) < 0.f ? -MinScaleAbs : MinScaleAbs; //if all three values are negative make minScale negative
if (FMath::IsNearlyZero(MinScale))
{
// only one of them can be 0, we make sure they have mini set up correctly
MinScale = 0.1f;
MinScaleAbs = 0.1f;
}
}
示例10: GetMovementBaseTangentialVelocity
FVector GetMovementBaseTangentialVelocity(const UPrimitiveComponent* MovementBase, const FName BoneName, const FVector& WorldLocation)
{
if (MovementBaseUtility::IsDynamicBase(MovementBase))
{
if (const FBodyInstance* BodyInstance = MovementBase->GetBodyInstance(BoneName))
{
const FVector BaseAngVel = BodyInstance->GetUnrealWorldAngularVelocity();
if (!BaseAngVel.IsNearlyZero())
{
FVector BaseLocation;
FQuat BaseRotation;
if (MovementBaseUtility::GetMovementBaseTransform(MovementBase, BoneName, BaseLocation, BaseRotation))
{
const FVector RadialDistanceToBase = WorldLocation - BaseLocation;
const FVector TangentialVel = FVector::DegreesToRadians(BaseAngVel) ^ RadialDistanceToBase;
return TangentialVel;
}
}
}
}
return FVector::ZeroVector;
}
示例11: TickComponent
void UProjectileMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
{
QUICK_SCOPE_CYCLE_COUNTER( STAT_ProjectileMovementComponent_TickComponent );
// skip if don't want component updated when not rendered or updated component can't move
if (HasStoppedSimulation() || ShouldSkipUpdate(DeltaTime))
{
return;
}
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
AActor* ActorOwner = UpdatedComponent->GetOwner();
if ( !ActorOwner || !CheckStillInWorld() )
{
return;
}
if (UpdatedComponent->IsSimulatingPhysics())
{
return;
}
float RemainingTime = DeltaTime;
uint32 NumBounces = 0;
int32 Iterations = 0;
FHitResult Hit(1.f);
while( RemainingTime >= MIN_TICK_TIME && (Iterations < MaxSimulationIterations) && !ActorOwner->IsPendingKill() && !HasStoppedSimulation() )
{
Iterations++;
// subdivide long ticks to more closely follow parabolic trajectory
const float TimeTick = ShouldUseSubStepping() ? GetSimulationTimeStep(RemainingTime, Iterations) : RemainingTime;
RemainingTime -= TimeTick;
Hit.Time = 1.f;
const FVector OldVelocity = Velocity;
const FVector MoveDelta = ComputeMoveDelta(OldVelocity, TimeTick);
const FRotator NewRotation = (bRotationFollowsVelocity && !OldVelocity.IsNearlyZero(0.01f)) ? OldVelocity.Rotation() : ActorOwner->GetActorRotation();
// Move the component
if (bShouldBounce)
{
// If we can bounce, we are allowed to move out of penetrations, so use SafeMoveUpdatedComponent which does that automatically.
SafeMoveUpdatedComponent( MoveDelta, NewRotation, true, Hit );
}
else
{
// If we can't bounce, then we shouldn't adjust if initially penetrating, because that should be a blocking hit that causes a hit event and stop simulation.
TGuardValue<EMoveComponentFlags> ScopedFlagRestore(MoveComponentFlags, MoveComponentFlags | MOVECOMP_NeverIgnoreBlockingOverlaps);
MoveUpdatedComponent(MoveDelta, NewRotation, true, &Hit );
}
// If we hit a trigger that destroyed us, abort.
if( ActorOwner->IsPendingKill() || HasStoppedSimulation() )
{
return;
}
// Handle hit result after movement
if( !Hit.bBlockingHit )
{
PreviousHitTime = 1.f;
bIsSliding = false;
// Only calculate new velocity if events didn't change it during the movement update.
if (Velocity == OldVelocity)
{
Velocity = ComputeVelocity(Velocity, TimeTick);
}
}
else
{
// Only calculate new velocity if events didn't change it during the movement update.
if (Velocity == OldVelocity)
{
// re-calculate end velocity for partial time
Velocity = (Hit.Time > KINDA_SMALL_NUMBER) ? ComputeVelocity(OldVelocity, TimeTick * Hit.Time) : OldVelocity;
}
// Handle blocking hit
float SubTickTimeRemaining = TimeTick * (1.f - Hit.Time);
const EHandleBlockingHitResult HandleBlockingResult = HandleBlockingHit(Hit, TimeTick, MoveDelta, SubTickTimeRemaining);
if (HandleBlockingResult == EHandleBlockingHitResult::Abort || HasStoppedSimulation())
{
break;
}
else if (HandleBlockingResult == EHandleBlockingHitResult::Deflect)
{
NumBounces++;
HandleDeflection(Hit, OldVelocity, NumBounces, SubTickTimeRemaining);
PreviousHitTime = Hit.Time;
PreviousHitNormal = ConstrainNormalToPlane(Hit.Normal);
}
else if (HandleBlockingResult == EHandleBlockingHitResult::AdvanceNextSubstep)
{
// Reset deflection logic to ignore this hit
PreviousHitTime = 1.f;
//.........这里部分代码省略.........
示例12: HandleViewportDrag
bool FInstancedStaticMeshSCSEditorCustomization::HandleViewportDrag(class USceneComponent* InSceneComponent, class USceneComponent* InComponentTemplate, const FVector& InDeltaTranslation, const FRotator& InDeltaRotation, const FVector& InDeltaScale, const FVector& InPivot)
{
check(InSceneComponent->IsA(UInstancedStaticMeshComponent::StaticClass()));
UInstancedStaticMeshComponent* InstancedStaticMeshComponentScene = CastChecked<UInstancedStaticMeshComponent>(InSceneComponent);
UInstancedStaticMeshComponent* InstancedStaticMeshComponentTemplate = CastChecked<UInstancedStaticMeshComponent>(InComponentTemplate);
// transform pivot into component's space
const FVector LocalPivot = InstancedStaticMeshComponentScene->GetComponentToWorld().InverseTransformPosition(InPivot);
// Ensure that selected instances are up-to-date
ValidateSelectedInstances(InstancedStaticMeshComponentScene);
bool bMovedInstance = false;
check(InstancedStaticMeshComponentScene->SelectedInstances.Num() == InstancedStaticMeshComponentScene->PerInstanceSMData.Num());
for(int32 InstanceIndex = 0; InstanceIndex < InstancedStaticMeshComponentScene->SelectedInstances.Num(); InstanceIndex++)
{
if (InstancedStaticMeshComponentScene->SelectedInstances[InstanceIndex] && InstancedStaticMeshComponentTemplate->PerInstanceSMData.IsValidIndex(InstanceIndex))
{
FMatrix& MatrixScene = InstancedStaticMeshComponentScene->PerInstanceSMData[InstanceIndex].Transform;
FMatrix& MatrixTemplate = InstancedStaticMeshComponentTemplate->PerInstanceSMData[InstanceIndex].Transform;
FVector Translation = MatrixScene.GetOrigin();
FRotator Rotation = MatrixScene.Rotator();
FVector Scale = MatrixScene.GetScaleVector();
FVector NewTranslation = Translation;
FRotator NewRotation = Rotation;
FVector NewScale = Scale;
if( !InDeltaRotation.IsZero() )
{
NewRotation = FRotator( InDeltaRotation.Quaternion() * Rotation.Quaternion() );
NewTranslation -= LocalPivot;
NewTranslation = FRotationMatrix( InDeltaRotation ).TransformPosition( NewTranslation );
NewTranslation += LocalPivot;
}
NewTranslation += InDeltaTranslation;
if( !InDeltaScale.IsNearlyZero() )
{
const FScaleMatrix ScaleMatrix( InDeltaScale );
FVector DeltaScale3D = ScaleMatrix.TransformPosition( Scale );
NewScale = Scale + DeltaScale3D;
NewTranslation -= LocalPivot;
NewTranslation += ScaleMatrix.TransformPosition( NewTranslation );
NewTranslation += LocalPivot;
}
MatrixScene = FScaleRotationTranslationMatrix(NewScale, NewRotation, NewTranslation);
MatrixTemplate = FScaleRotationTranslationMatrix(NewScale, NewRotation, NewTranslation);
bMovedInstance = true;
}
}
return bMovedInstance;
}
示例13: SnapDraggedActorsToNearestVertex
bool FVertexSnappingImpl::SnapDraggedActorsToNearestVertex( FVector& DragDelta, FLevelEditorViewportClient* ViewportClient )
{
int32 MouseX = ViewportClient->Viewport->GetMouseX();
int32 MouseY = ViewportClient->Viewport->GetMouseY();
FVector2D MousePosition = FVector2D( MouseX, MouseY ) ;
EAxisList::Type CurrentAxis = ViewportClient->GetCurrentWidgetAxis();
bool bSnapped = false;
if( !DragDelta.IsNearlyZero() )
{
// Are there selected actors?
USelection* Selection = GEditor->GetSelectedActors();
FVector Direction = DragDelta.GetSafeNormal();
FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues(
ViewportClient->Viewport,
ViewportClient->GetScene(),
ViewportClient->EngineShowFlags )
.SetRealtimeUpdate( ViewportClient->IsRealtime() ));
FSceneView* View = ViewportClient->CalcSceneView( &ViewFamily );
FVector StartLocation = ViewportClient->GetModeTools()->PivotLocation;
FVector DesiredUnsnappedLocation = StartLocation+DragDelta;
// Plane facing in the direction of axis movement. This is for clipping actors which are behind the desired location (they should not be considered for snap)
FPlane ActorPlane( DesiredUnsnappedLocation, Direction );
TSet< TWeakObjectPtr<AActor> > ActorsToIgnore;
// Snap each selected actor
for ( FSelectionIterator It( GEditor->GetSelectedActorIterator() ) ; It ; ++It )
{
// Build up a region that actors must be in for snapping
FBoxSphereBounds SnappingAreaBox( FBox( DesiredUnsnappedLocation-VertexSnappingConstants::MaxSnappingDistance, DesiredUnsnappedLocation+VertexSnappingConstants::MaxSnappingDistance ) );
AActor* Actor = CastChecked<AActor>( *It );
if( Actor->GetRootComponent() != NULL )
{
// Get a bounding box around the actor
const bool bNonColliding = true;
FBoxSphereBounds ActorBounds = Actor->GetComponentsBoundingBox(bNonColliding);
// The allowed snapping box is a box around the selected actor plus a region around the actor that other actors must be in for snapping
FBox AllowedSnappingBox = ActorBounds.GetBox();
// Extend the box to include the drag point
AllowedSnappingBox += SnappingAreaBox.GetBox();
GetActorsToIgnore( Actor, ActorsToIgnore );
FVertexSnappingArgs Args
(
ActorPlane,
DesiredUnsnappedLocation,
ViewportClient,
View,
MousePosition,
CurrentAxis,
true
);
// Snap the drag delta
SnapDragDelta( Args, StartLocation, AllowedSnappingBox, ActorsToIgnore, DragDelta );
}
}
}
return bSnapped;
}
示例14: PhysicSubTick
void UFlareSpacecraftNavigationSystem::PhysicSubTick(float DeltaSeconds)
{
TArray<UActorComponent*> Engines = Spacecraft->GetComponentsByClass(UFlareEngine::StaticClass());
if (Spacecraft->GetDamageSystem()->IsPowered())
{
// Linear physics
FVector DeltaV = LinearTargetVelocity - Spacecraft->GetLinearVelocity();
FVector DeltaVAxis = DeltaV;
DeltaVAxis.Normalize();
bool Log = false;
if (Spacecraft->GetParent()->GetCompany() == Spacecraft->GetGame()->GetPC()->GetCompany())
{
//Log = true;
}
bool HasUsedOrbitalBoost = false;
float LinearMasterAlpha = 0.f;
float LinearMasterBoostAlpha = 0.f;
if(Log) {
FLOGV("PhysicSubTick DeltaSeconds=%f", DeltaSeconds);
FLOGV("PhysicSubTick LinearTargetVelocity=%s", *LinearTargetVelocity.ToString());
FLOGV("PhysicSubTick Spacecraft->GetLinearVelocity()=%s", *Spacecraft->GetLinearVelocity().ToString());
FLOGV("PhysicSubTick DeltaV=%s", *DeltaV.ToString());
}
if (!DeltaV.IsNearlyZero())
{
// First, try without using the boost
FVector Acceleration = DeltaVAxis * GetTotalMaxThrustInAxis(Engines, -DeltaVAxis, false).Size() / Spacecraft->GetSpacecraftMass();
float AccelerationDeltaV = Acceleration.Size() * DeltaSeconds;
LinearMasterAlpha = FMath::Clamp(DeltaV.Size()/ AccelerationDeltaV, 0.0f, 1.0f);
// Second, if the not enought trust check with the boost
if (UseOrbitalBoost && AccelerationDeltaV < DeltaV.Size() )
{
FVector AccelerationWithBoost = DeltaVAxis * GetTotalMaxThrustInAxis(Engines, -DeltaVAxis, true).Size() / Spacecraft->GetSpacecraftMass();
if (AccelerationWithBoost.Size() > Acceleration.Size())
{
HasUsedOrbitalBoost = true;
float BoostDeltaV = (AccelerationWithBoost.Size() - Acceleration.Size()) * DeltaSeconds;
float DeltaVAfterClassicalAcceleration = DeltaV.Size() - AccelerationDeltaV;
LinearMasterBoostAlpha = FMath::Clamp(DeltaVAfterClassicalAcceleration/ BoostDeltaV, 0.0f, 1.0f);
Acceleration = AccelerationWithBoost;
}
}
FVector ClampedAcceleration = Acceleration.GetClampedToMaxSize(DeltaV.Size() / DeltaSeconds);
Spacecraft->Airframe->SetPhysicsLinearVelocity(ClampedAcceleration * DeltaSeconds * 100, true); // Multiply by 100 because UE4 works in cm
}
// Angular physics
FVector DeltaAngularV = AngularTargetVelocity - Spacecraft->Airframe->GetPhysicsAngularVelocity();
FVector DeltaAngularVAxis = DeltaAngularV;
DeltaAngularVAxis.Normalize();
if (!DeltaAngularV.IsNearlyZero())
{
FVector SimpleAcceleration = DeltaAngularVAxis * AngularAccelerationRate;
// Scale with damages
float TotalMaxTorqueInAxis = GetTotalMaxTorqueInAxis(Engines, DeltaAngularVAxis, false);
if (!FMath::IsNearlyZero(TotalMaxTorqueInAxis))
{
float DamageRatio = GetTotalMaxTorqueInAxis(Engines, DeltaAngularVAxis, true) / TotalMaxTorqueInAxis;
FVector DamagedSimpleAcceleration = SimpleAcceleration * DamageRatio;
FVector ClampedSimplifiedAcceleration = DamagedSimpleAcceleration.GetClampedToMaxSize(DeltaAngularV.Size() / DeltaSeconds);
Spacecraft->Airframe->SetPhysicsAngularVelocity(ClampedSimplifiedAcceleration * DeltaSeconds, true);
}
}
// Update engine alpha
for (int32 EngineIndex = 0; EngineIndex < Engines.Num(); EngineIndex++)
{
UFlareEngine* Engine = Cast<UFlareEngine>(Engines[EngineIndex]);
FVector ThrustAxis = Engine->GetThrustAxis();
float LinearAlpha = 0;
float AngularAlpha = 0;
if (Spacecraft->IsPresentationMode())
{
LinearAlpha = true;
}
else if (!DeltaV.IsNearlyZero() || !DeltaAngularV.IsNearlyZero())
{
if(Engine->IsA(UFlareOrbitalEngine::StaticClass()))
{
if(HasUsedOrbitalBoost)
//.........这里部分代码省略.........
示例15: UpdateAngularAttitudeAuto
void UFlareSpacecraftNavigationSystem::UpdateAngularAttitudeAuto(float DeltaSeconds)
{
TArray<UActorComponent*> Engines = Spacecraft->GetComponentsByClass(UFlareEngine::StaticClass());
// Rotation data
FFlareShipCommandData Command;
CommandData.Peek(Command);
FVector TargetAxis = Command.RotationTarget;
FVector LocalShipAxis = Command.LocalShipAxis;
FVector AngularVelocity = Spacecraft->Airframe->GetPhysicsAngularVelocity();
FVector WorldShipAxis = Spacecraft->Airframe->GetComponentToWorld().GetRotation().RotateVector(LocalShipAxis);
WorldShipAxis.Normalize();
TargetAxis.Normalize();
FVector RotationDirection = FVector::CrossProduct(WorldShipAxis, TargetAxis);
if (RotationDirection.IsNearlyZero())
{
RotationDirection=FVector(0,0,1);
}
RotationDirection.Normalize();
float Dot = FVector::DotProduct(WorldShipAxis, TargetAxis);
float angle = FMath::RadiansToDegrees(FMath::Acos(Dot));
FVector DeltaVelocity = -AngularVelocity;
FVector DeltaVelocityAxis = DeltaVelocity;
DeltaVelocityAxis.Normalize();
float TimeToFinalVelocity;
if (FMath::IsNearlyZero(DeltaVelocity.SizeSquared()))
{
TimeToFinalVelocity = 0;
}
else {
FVector SimpleAcceleration = DeltaVelocityAxis * AngularAccelerationRate;
// Scale with damages
float DamageRatio = GetTotalMaxTorqueInAxis(Engines, DeltaVelocityAxis, true) / GetTotalMaxTorqueInAxis(Engines, DeltaVelocityAxis, false);
FVector DamagedSimpleAcceleration = SimpleAcceleration * DamageRatio;
FVector Acceleration = DamagedSimpleAcceleration;
float AccelerationInAngleAxis = FMath::Abs(FVector::DotProduct(DamagedSimpleAcceleration, RotationDirection));
TimeToFinalVelocity = (DeltaVelocity.Size() / AccelerationInAngleAxis);
}
float AngleToStop = (DeltaVelocity.Size() / 2) * (TimeToFinalVelocity + DeltaSeconds);
FVector RelativeResultSpeed;
if (AngleToStop > angle)
{
RelativeResultSpeed = FVector::ZeroVector;
}
else
{
float MaxPreciseSpeed = FMath::Min((angle - AngleToStop) / DeltaSeconds, AngularMaxVelocity);
RelativeResultSpeed = RotationDirection;
RelativeResultSpeed *= MaxPreciseSpeed;
}
// Under this angle we consider the variation negligible, and ensure null delta + null speed
if (angle < AngularDeadAngle && DeltaVelocity.Size() < AngularDeadAngle)
{
Spacecraft->Airframe->SetPhysicsAngularVelocity(FVector::ZeroVector, false); // TODO remove
ClearCurrentCommand();
RelativeResultSpeed = FVector::ZeroVector;
}
AngularTargetVelocity = RelativeResultSpeed;
}