Пример #1
0
void ACharacter::OnRep_ReplicatedBasedMovement()
{	
	if (Role != ROLE_SimulatedProxy)
	{
		return;
	}

	// Skip base updates while playing root motion, it is handled inside of OnRep_RootMotion
	if (IsPlayingNetworkedRootMotionMontage())
	{
		return;
	}

	TGuardValue<bool> bInBaseReplicationGuard(bInBaseReplication, true);

	const bool bBaseChanged = (BasedMovement.MovementBase != ReplicatedBasedMovement.MovementBase || BasedMovement.BoneName != ReplicatedBasedMovement.BoneName);
	if (bBaseChanged)
	{
		// Even though we will copy the replicated based movement info, we need to use SetBase() to set up tick dependencies and trigger notifications.
		SetBase(ReplicatedBasedMovement.MovementBase, ReplicatedBasedMovement.BoneName);
	}

	// Make sure to use the values of relative location/rotation etc from the server.
	BasedMovement = ReplicatedBasedMovement;

	if (ReplicatedBasedMovement.HasRelativeLocation())
	{
		// Update transform relative to movement base
		const FVector OldLocation = GetActorLocation();
		const FQuat OldRotation = GetActorQuat();
		MovementBaseUtility::GetMovementBaseTransform(ReplicatedBasedMovement.MovementBase, ReplicatedBasedMovement.BoneName, CharacterMovement->OldBaseLocation, CharacterMovement->OldBaseQuat);
		const FVector NewLocation = CharacterMovement->OldBaseLocation + ReplicatedBasedMovement.Location;

		if (ReplicatedBasedMovement.HasRelativeRotation())
		{
			// Relative location, relative rotation
			FRotator NewRotation = (FRotationMatrix(ReplicatedBasedMovement.Rotation) * FQuatRotationMatrix(CharacterMovement->OldBaseQuat)).Rotator();
			
			// TODO: need a better way to not assume we only use Yaw.
			NewRotation.Pitch = 0.f;
			NewRotation.Roll = 0.f;

			SetActorLocationAndRotation(NewLocation, NewRotation);	
		}
		else
		{
			// Relative location, absolute rotation
			SetActorLocationAndRotation(NewLocation, ReplicatedBasedMovement.Rotation);
		}

		// When position or base changes, movement mode will need to be updated. This assumes rotation changes don't affect that.
		CharacterMovement->bJustTeleported |= (bBaseChanged || GetActorLocation() != OldLocation);

		INetworkPredictionInterface* PredictionInterface = Cast<INetworkPredictionInterface>(GetMovementComponent());
		if (PredictionInterface)
		{
			PredictionInterface->SmoothCorrection(OldLocation, OldRotation);
		}
	}
}
Пример #2
0
FMatrix FEditorModeTools::GetCustomDrawingCoordinateSystem()
{
	FMatrix Matrix = FMatrix::Identity;

	switch (GetCoordSystem())
	{
		case COORD_Local:
		{
			// Let the current mode have a shot at setting the local coordinate system.
			// If it doesn't want to, create it by looking at the currently selected actors list.

			bool CustomCoordinateSystemProvided = false;
			for (const auto& Mode : Modes)
			{
				if (Mode->GetCustomDrawingCoordinateSystem(Matrix, nullptr))
				{
					CustomCoordinateSystemProvided = true;
					break;
				}
			}

			if (!CustomCoordinateSystemProvided)
			{
				const int32 Num = GetSelectedActors()->CountSelections<AActor>();

				// Coordinate system needs to come from the last actor selected
				if (Num > 0)
				{
					Matrix = FQuatRotationMatrix(GetSelectedActors()->GetBottom<AActor>()->GetActorQuat());
				}
			}

			if (!Matrix.Equals(FMatrix::Identity))
			{
				Matrix.RemoveScaling();
			}
		}
		break;

		case COORD_World:
			break;

		default:
			break;
	}

	return Matrix;
}
Пример #3
0
bool FEdModeGeometry::GetCustomDrawingCoordinateSystem( FMatrix& InMatrix, void* InData )
{
	if( GetSelectionState() == GSS_None )
	{
		return 0;
	}

	if( InData )
	{
		FGeomBase* GeomBase = static_cast<FGeomBase*>(InData);
		FGeomObjectPtr GeomObject = GeomBase->GetParentObject();
		check(GeomObject.IsValid());
		ABrush* Brush = GeomObject->GetActualBrush();
		InMatrix = FRotationMatrix(GeomBase->GetNormal().Rotation()) * FQuatRotationMatrix(Brush->GetActorQuat());
	}
	else
	{
		// If we don't have a specific geometry object to get the normal from
		// use the one that was last selected.

		for( int32 o = 0 ; o < GeomObjects.Num() ; ++o )
		{
			FGeomObjectPtr go = GeomObjects[o];
			go->CompileSelectionOrder();

			if( go->SelectionOrder.Num() )
			{
				FGeomBase* GeomBase = go->SelectionOrder[go->SelectionOrder.Num() - 1];
				check(GeomBase != nullptr);
				FGeomObjectPtr GeomObject = GeomBase->GetParentObject();
				check(GeomObject.IsValid());
				ABrush* Brush = GeomObject->GetActualBrush();
				InMatrix = FRotationMatrix( go->SelectionOrder[ go->SelectionOrder.Num()-1 ]->GetWidgetRotation() ) * FQuatRotationMatrix(Brush->GetActorQuat());
				return 1;
			}
		}
	}

	return 0;
}
void UParticleModuleVelocityCone::Render3DPreview(FParticleEmitterInstance* Owner, const FSceneView* View,FPrimitiveDrawInterface* PDI)
{
#if WITH_EDITOR
	float ConeMaxAngle = 0.0f;
	float ConeMinAngle = 0.0f;
	Angle.GetOutRange(ConeMinAngle, ConeMaxAngle);

	float ConeMaxVelocity = 0.0f;
	float ConeMinVelocity = 0.0f;
	Velocity.GetOutRange(ConeMinVelocity, ConeMaxVelocity);

	float MaxLifetime = 0.0f;
	TArray<UParticleModule*>& Modules = Owner->SpriteTemplate->GetCurrentLODLevel(Owner)->Modules;
	for (int32 ModuleIndex = 0; ModuleIndex < Modules.Num(); ModuleIndex++)
	{
		UParticleModuleLifetimeBase* LifetimeMod = Cast<UParticleModuleLifetimeBase>(Modules[ModuleIndex]);
		if (LifetimeMod != NULL)
		{
			MaxLifetime = LifetimeMod->GetMaxLifetime();
			break;
		}
	}

	const int32 ConeSides = 16;
	const float ConeRadius = ConeMaxVelocity * MaxLifetime;

	// Calculate direction transform
	const FVector DefaultDirection(0.0f, 0.0f, 1.0f);
	const FVector ForwardDirection = (Direction != FVector::ZeroVector)? Direction.GetSafeNormal(): DefaultDirection;
	FVector UpDirection(0.0f, 0.0f, 1.0f);
	FVector RightDirection(1.0f, 0.0f, 0.0f);

	if ((ForwardDirection != UpDirection) && (-ForwardDirection != UpDirection))
	{
		RightDirection = UpDirection ^ ForwardDirection;
		UpDirection = ForwardDirection ^ RightDirection;
	}
	else
	{
		UpDirection = ForwardDirection ^ RightDirection;
		RightDirection = UpDirection ^ ForwardDirection;
	}

	FMatrix DirectionRotation;
	DirectionRotation.SetIdentity();
	DirectionRotation.SetAxis(0, RightDirection.GetSafeNormal());
	DirectionRotation.SetAxis(1, UpDirection.GetSafeNormal());
	DirectionRotation.SetAxis(2, ForwardDirection);

	// Calculate the owning actor's scale and rotation
	UParticleLODLevel* LODLevel	= Owner->SpriteTemplate->GetCurrentLODLevel(Owner);
	check(LODLevel);
	FVector OwnerScale(1.0f);
	FMatrix OwnerRotation(FMatrix::Identity);
	FVector LocalToWorldOrigin(0.0f);
	FMatrix LocalToWorld(FMatrix::Identity);
	if (Owner->Component)
	{
		AActor* Actor = Owner->Component->GetOwner();
		if (Actor)
		{
			if (bApplyOwnerScale == true)
			{
				OwnerScale = Owner->Component->ComponentToWorld.GetScale3D();
			}

			OwnerRotation = FQuatRotationMatrix(Actor->GetActorQuat());
		}
	  LocalToWorldOrigin = Owner->Component->ComponentToWorld.GetLocation();
	  LocalToWorld = Owner->Component->ComponentToWorld.ToMatrixWithScale().RemoveTranslation();
	  LocalToWorld.RemoveScaling();
	}
	FMatrix Transform;
	Transform.SetIdentity();

	// DrawWireCone() draws a cone down the X axis, but this cone's default direction is down Z
	const FRotationMatrix XToZRotation(FRotator((int32)(HALF_PI * 10430), 0, 0));
	Transform *= XToZRotation;

	// Apply scale
	Transform.SetAxis(0, Transform.GetScaledAxis( EAxis::X ) * OwnerScale.X);
	Transform.SetAxis(1, Transform.GetScaledAxis( EAxis::Y ) * OwnerScale.Y);
	Transform.SetAxis(2, Transform.GetScaledAxis( EAxis::Z ) * OwnerScale.Z);

	// Apply direction transform
	Transform *= DirectionRotation;

	// Transform according to world and local space flags 
	if (!LODLevel->RequiredModule->bUseLocalSpace && !bInWorldSpace)
	{
		Transform *= LocalToWorld;
	}
	else if (LODLevel->RequiredModule->bUseLocalSpace && bInWorldSpace)
	{
		Transform *= OwnerRotation;
		Transform *= LocalToWorld.InverseFast();
	}
	else if (!bInWorldSpace)
	{
		Transform *= OwnerRotation;
	}

	// Apply translation
	Transform.SetOrigin(LocalToWorldOrigin);

	TArray<FVector> OuterVerts;
	TArray<FVector> InnerVerts;

	// Draw inner and outer cones
	DrawWireCone(PDI, InnerVerts, Transform, ConeRadius, ConeMinAngle, ConeSides, ModuleEditorColor, SDPG_World);
	DrawWireCone(PDI, OuterVerts, Transform, ConeRadius, ConeMaxAngle, ConeSides, ModuleEditorColor, SDPG_World);

	// Draw radial spokes
	for (int32 i = 0; i < ConeSides; ++i)
	{
		PDI->DrawLine( OuterVerts[i], InnerVerts[i], ModuleEditorColor, SDPG_World );
	}
#endif
}