void GetNiceRotatorValue(FRotator& Rotator1, FRotator& Rotator2) {
    Rotator1.Normalize();
    Rotator2.Normalize();
    GetNiceAngleValue(Rotator1.Pitch, Rotator2.Pitch);
    GetNiceAngleValue(Rotator1.Yaw, Rotator2.Yaw);
    GetNiceAngleValue(Rotator1.Roll, Rotator2.Roll);
}
Esempio n. 2
0
void AARCharacter::MoveForward(float Value)
{
	if ((Controller != NULL) && (Value != 0.0f))
	{
		//if (Value < 0)
		//{
		//	float orignal = CharacterMovement->MaxWalkSpeed;
		//	CharacterMovement->MaxWalkSpeed = CharacterMovement->MaxWalkSpeed / 2;
		//	FRotator Rotation = GetBaseAimRotation();

		//	FVector Location; //not used, just need for below.
		//	//Controller->GetPlayerViewPoint(Location, Rotation);
		//	Rotation.Normalize();
		//	FRotator YawRotation(0, Rotation.Yaw, 0);
		//	//const FVector Direction = FRotationMatrix(Rotation).GetScaledAxis( EAxis::X );
		//	const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
		//	AddMovementInput(Direction, Value);
		//	CharacterMovement->MaxWalkSpeed = orignal;
		//	return;
		//}
		FRotator Rotation = GetBaseAimRotation();

		FVector Location; //not used, just need for below.
		//Controller->GetPlayerViewPoint(Location, Rotation);
		Rotation.Normalize();
		FRotator YawRotation(0, Rotation.Yaw, 0);
		//const FVector Direction = FRotationMatrix(Rotation).GetScaledAxis( EAxis::X );
		const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
		AddMovementInput(Direction, Value);
	}
}
void AActor::EditorApplyRotation(const FRotator& DeltaRotation, bool bAltDown, bool bShiftDown, bool bCtrlDown)
{
	if( RootComponent != NULL )
	{
		const FRotator Rot = RootComponent->GetAttachParent() != NULL ? GetActorRotation() : RootComponent->RelativeRotation;

		FRotator ActorRotWind, ActorRotRem;
		Rot.GetWindingAndRemainder(ActorRotWind, ActorRotRem);

		const FQuat ActorQ = ActorRotRem.Quaternion();
		const FQuat DeltaQ = DeltaRotation.Quaternion();
		const FQuat ResultQ = DeltaQ * ActorQ;
		const FRotator NewActorRotRem = FRotator( ResultQ );
		FRotator DeltaRot = NewActorRotRem - ActorRotRem;
		DeltaRot.Normalize();

		if( RootComponent->GetAttachParent() != NULL )
		{
			RootComponent->SetWorldRotation( Rot + DeltaRot );
		}
		else
		{
			// No attachment.  Directly set relative rotation (to support winding)
			RootComponent->SetRelativeRotation( Rot + DeltaRot );
		}
	}
	else
	{
		UE_LOG(LogActor, Warning, TEXT("WARNING: EditorApplyRotation %s has no root component"), *GetName() );
	}
}
void APlayerCameraManager::ProcessViewRotation(float DeltaTime, FRotator& OutViewRotation, FRotator& OutDeltaRot)
{
	for( int32 ModifierIdx = 0; ModifierIdx < ModifierList.Num(); ModifierIdx++ )
	{
		if( ModifierList[ModifierIdx] != NULL && 
			!ModifierList[ModifierIdx]->IsDisabled() )
		{
			if( ModifierList[ModifierIdx]->ProcessViewRotation(ViewTarget.Target, DeltaTime, OutViewRotation, OutDeltaRot) )
			{
				break;
			}
		}
	}

	// Add Delta Rotation
	OutViewRotation += OutDeltaRot;
	OutDeltaRot = FRotator::ZeroRotator;

	if(GEngine->HMDDevice.IsValid() && GEngine->IsStereoscopic3D())
	{
		// With the HMD devices, we can't limit the view pitch, because it's bound to the player's head.  A simple normalization will suffice
		OutViewRotation.Normalize();
	}
	else
	{
		// Limit Player View Axes
		LimitViewPitch( OutViewRotation, ViewPitchMin, ViewPitchMax );
		LimitViewYaw( OutViewRotation, ViewYawMin, ViewYawMax );
		LimitViewRoll( OutViewRotation, ViewRollMin, ViewRollMax );
	}
}
bool AKinectPlayerController::FindDeathCameraSpot(FVector& CameraLocation, FRotator& CameraRotation)
{

	const FVector PawnLocation = GetPawn()->GetActorLocation();
	FRotator ViewDir = GetControlRotation();
	ViewDir.Pitch = -45.0f;

	const float YawOffsets[] = { 0.0f, -180.0f, 90.0f, -90.0f, 45.0f, -45.0f, 135.0f, -135.0f };
	const float CameraOffset = 600.0f;
	FCollisionQueryParams TraceParams(TEXT("DeathCamera"), true, GetPawn());

	for (int32 i = 0; i < ARRAY_COUNT(YawOffsets); i++)
	{
		FRotator CameraDir = ViewDir;
		CameraDir.Yaw += YawOffsets[i];
		CameraDir.Normalize();

		const FVector TestLocation = PawnLocation - CameraDir.Vector() * CameraOffset;
		const bool bBlocked = GetWorld()->LineTraceTest(PawnLocation, TestLocation, ECC_Camera, TraceParams);

		if (!bBlocked)
		{
			CameraLocation = TestLocation;
			CameraRotation = CameraDir;
			return true;
		}
	}

	return false;
}
void FSpriteSelectedSocket::ApplyDelta(const FVector2D& Delta, const FRotator& Rotation, const FVector& Scale3D, FWidget::EWidgetMode MoveMode)
{
	if (UPrimitiveComponent* PreviewComponent = PreviewComponentPtr.Get())
	{
		UObject* AssociatedAsset = const_cast<UObject*>(PreviewComponent->AdditionalStatObject());
		if (UPaperSprite* Sprite = Cast<UPaperSprite>(AssociatedAsset))
		{
			if (FPaperSpriteSocket* Socket = Sprite->FindSocket(SocketName))
			{
				const bool bDoRotation = (MoveMode == FWidget::WM_Rotate) || (MoveMode == FWidget::WM_TranslateRotateZ);
				const bool bDoTranslation = (MoveMode == FWidget::WM_Translate) || (MoveMode == FWidget::WM_TranslateRotateZ);
				const bool bDoScale = MoveMode == FWidget::WM_Scale;

				if (bDoTranslation)
				{
					//@TODO: Currently sockets are in unflipped pivot space,
					const FVector Delta3D_UU = (PaperAxisX * Delta.X) + (PaperAxisY * -Delta.Y);
					const FVector Delta3D = Delta3D_UU * Sprite->GetPixelsPerUnrealUnit();
					Socket->LocalTransform.SetLocation(Socket->LocalTransform.GetLocation() + Delta3D);
				}

				if (bDoRotation)
				{
					const FRotator CurrentRot = Socket->LocalTransform.GetRotation().Rotator();
					FRotator SocketWinding;
					FRotator SocketRotRemainder;
					CurrentRot.GetWindingAndRemainder(SocketWinding, SocketRotRemainder);

					const FQuat ActorQ = SocketRotRemainder.Quaternion();
					const FQuat DeltaQ = Rotation.Quaternion();
					const FQuat ResultQ = DeltaQ * ActorQ;
					const FRotator NewSocketRotRem = FRotator( ResultQ );
					FRotator DeltaRot = NewSocketRotRem - SocketRotRemainder;
					DeltaRot.Normalize();

					const FRotator NewRotation(CurrentRot + DeltaRot);
					Socket->LocalTransform.SetRotation(NewRotation.Quaternion());
				}
				
				if (bDoScale)
				{
					const FVector4 LocalSpaceScaleOffset = Socket->LocalTransform.TransformVector(Scale3D);

					Socket->LocalTransform.SetScale3D(Socket->LocalTransform.GetScale3D() + LocalSpaceScaleOffset);
				}
			}
		}
	}
}
void AARCharacter::MoveRight(float Value)
{
	if ( (Controller != NULL) && (Value != 0.0f) )
	{
		FRotator Rotation;
		FVector Location; //not used, just need for below.
		Controller->GetPlayerViewPoint(Location, Rotation);
		Rotation.Normalize();
		FRotator YawRotation(0, Rotation.Yaw, 0);
		const FVector Direction = FRotationMatrix(YawRotation).GetScaledAxis(EAxis::Y);
		// add movement in that direction
		AddMovementInput(Direction, Value);

	}
}
Esempio n. 8
0
void FSteamVRHMD::ResetOrientation(float Yaw)
{
	FRotator ViewRotation;
	ViewRotation = FRotator(TrackingFrame.DeviceOrientation[vr::k_unTrackedDeviceIndex_Hmd]);
	ViewRotation.Pitch = 0;
	ViewRotation.Roll = 0;

	if (Yaw != 0.f)
	{
		// apply optional yaw offset
		ViewRotation.Yaw -= Yaw;
		ViewRotation.Normalize();
	}

	BaseOrientation = ViewRotation.Quaternion();
}
Esempio n. 9
0
void FOSVRHMD::ResetOrientation(float yaw)
{
    FRotator ViewRotation;
    ViewRotation = FRotator(CurHmdOrientation);
    ViewRotation.Pitch = 0;
    ViewRotation.Roll = 0;
    ViewRotation.Yaw += BaseOrientation.Rotator().Yaw;

    if (yaw != 0.f)
    {
        // apply optional yaw offset
        ViewRotation.Yaw -= yaw;
        ViewRotation.Normalize();
    }

    BaseOrientation = ViewRotation.Quaternion();
}
Esempio n. 10
0
void FSimpleHMD::ApplyHmdRotation(APlayerController* PC, FRotator& ViewRotation)
{
	ViewRotation.Normalize();

	GetCurrentPose(CurHmdOrientation);
	LastHmdOrientation = CurHmdOrientation;

	const FRotator DeltaRot = ViewRotation - PC->GetControlRotation();
	DeltaControlRotation = (DeltaControlRotation + DeltaRot).GetNormalized();

	// Pitch from other sources is never good, because there is an absolute up and down that must be respected to avoid motion sickness.
	// Same with roll.
	DeltaControlRotation.Pitch = 0;
	DeltaControlRotation.Roll = 0;
	DeltaControlOrientation = DeltaControlRotation.Quaternion();

	ViewRotation = FRotator(DeltaControlOrientation * CurHmdOrientation);
}
Esempio n. 11
0
void FOSVRHMD::ApplyHmdRotation(APlayerController* PC, FRotator& ViewRotation)
{
    ViewRotation.Normalize();

    FQuat lastHmdOrientation, hmdOrientation;
    FVector lastHmdPosition, hmdPosition;
    UpdateHeadPose(lastHmdOrientation, lastHmdPosition, hmdOrientation, hmdPosition);

    const FRotator DeltaRot = ViewRotation - PC->GetControlRotation();
    DeltaControlRotation = (DeltaControlRotation + DeltaRot).GetNormalized();

    // Pitch from other sources is never good, because there is an absolute up and down that must be respected to avoid motion sickness.
    // Same with roll. Retain yaw by default - mouse/controller based yaw movement still isn't pleasant, but
    // it's necessary for sitting VR experiences.
    DeltaControlRotation.Pitch = 0;
    DeltaControlRotation.Roll = 0;
    DeltaControlOrientation = DeltaControlRotation.Quaternion();

    ViewRotation = FRotator(DeltaControlOrientation * hmdOrientation);
}
void FSpriteSelectedShape::ApplyDelta(const FVector2D& Delta, const FRotator& Rotation, const FVector& Scale3D, FWidget::EWidgetMode MoveMode)
{
	if (Geometry.Shapes.IsValidIndex(ShapeIndex))
	{
		FSpriteGeometryShape& Shape = Geometry.Shapes[ShapeIndex];

		const bool bDoRotation = (MoveMode == FWidget::WM_Rotate) || (MoveMode == FWidget::WM_TranslateRotateZ);
		const bool bDoTranslation = (MoveMode == FWidget::WM_Translate) || (MoveMode == FWidget::WM_TranslateRotateZ);
		const bool bDoScale = MoveMode == FWidget::WM_Scale;

		if (bDoTranslation)
		{
			const FVector WorldSpaceDelta = (PaperAxisX * Delta.X) + (PaperAxisY * Delta.Y);
			const FVector2D TextureSpaceDelta = EditorContext->SelectedItemConvertWorldSpaceDeltaToLocalSpace(WorldSpaceDelta);

			Shape.BoxPosition += TextureSpaceDelta;

			Geometry.GeometryType = ESpritePolygonMode::FullyCustom;
		}

		if (bDoScale)
		{
			const float ScaleDeltaX = FVector::DotProduct(Scale3D, PaperAxisX);
			const float ScaleDeltaY = FVector::DotProduct(Scale3D, PaperAxisY);

			const FVector2D OldSize = Shape.BoxSize;
			const FVector2D NewSize(OldSize.X + ScaleDeltaX, OldSize.Y + ScaleDeltaY);

			if (!FMath::IsNearlyZero(NewSize.X, KINDA_SMALL_NUMBER) && !FMath::IsNearlyZero(NewSize.Y, KINDA_SMALL_NUMBER))
			{
				const FVector2D ScaleFactor(NewSize.X / OldSize.X, NewSize.Y / OldSize.Y);
				Shape.BoxSize = NewSize;

				// Now apply it to the verts
				for (FVector2D& Vertex : Shape.Vertices)
				{
					Vertex.X *= ScaleFactor.X;
					Vertex.Y *= ScaleFactor.Y;
				}

				Geometry.GeometryType = ESpritePolygonMode::FullyCustom;
			}
		}

		if (bDoRotation)
		{
			//@TODO: This stuff should probably be wrapped up into a utility method (also used for socket editing)
			const FRotator CurrentRot(Shape.Rotation, 0.0f, 0.0f);
			FRotator SocketWinding;
			FRotator SocketRotRemainder;
			CurrentRot.GetWindingAndRemainder(SocketWinding, SocketRotRemainder);

			const FQuat ActorQ = SocketRotRemainder.Quaternion();
			const FQuat DeltaQ = Rotation.Quaternion();
			const FQuat ResultQ = DeltaQ * ActorQ;
			const FRotator NewSocketRotRem = FRotator(ResultQ);
			FRotator DeltaRot = NewSocketRotRem - SocketRotRemainder;
			DeltaRot.Normalize();

			const FRotator NewRotation(CurrentRot + DeltaRot);

			Shape.Rotation = NewRotation.Pitch;
			Geometry.GeometryType = ESpritePolygonMode::FullyCustom;
		}
	}
}
FRotator UKismetMathLibrary::NormalizedDeltaRotator(FRotator A, FRotator B)
{
	FRotator Delta = A - B;
	Delta.Normalize();
	return Delta;
}
void AFollowRoadCamera::Tick(float Delta) {
    if (!Running) {
        return;
    }

    if (!Roadmap) {
        return;
    }

    float SpeedCMs = Speed / 0.036;

    float CurrentTime = GetWorld()->GetTimeSeconds();

    float TimePassed = CurrentTime - StartTime;

    float DistancePassed = TimePassed * SpeedCMs;

    if (Rev) {
        DistancePassed = MaxDist - DistancePassed;
    }

    float TValue = SplineInfoDistance.Eval(DistancePassed, 0);

    FVector Location = Roadmap->SplineInfo.Eval(TValue, FVector(0, 0, 0));
    FVector Tangent = Roadmap->SplineInfo.EvalDerivative(TValue, FVector(0, 0, 0)).GetSafeNormal2D();
    FVector Side = FVector::CrossProduct(FVector::UpVector, Tangent);

    Location += Tangent * Offset.X;
    Location += Side * Offset.Y;
    Location += FVector::UpVector * Offset.Z;

    FVector LookAtLocation;

    if (ReplayPlayer && ReplayPlayer->LookAtActor) {
        LookAtLocation = ReplayPlayer->LookAtActor->GetActorLocation();
    }
    else {

        float DistanceLookAt = 0;

        if (Rev) {
            DistanceLookAt = DistancePassed - LookAtDistance;
        }
        else {
            DistanceLookAt = DistancePassed + LookAtDistance;
        }

        float TValueLookAt = SplineInfoDistance.Eval(DistanceLookAt, 0);
        LookAtLocation = Roadmap->SplineInfo.Eval(TValueLookAt, FVector(0, 0, 0));
        FVector LookAtTangent = Roadmap->SplineInfo.EvalDerivative(TValueLookAt, FVector(0, 0, 0)).GetSafeNormal2D();
        FVector LookAtSide = FVector::CrossProduct(FVector::UpVector, LookAtTangent);

        LookAtLocation += LookAtTangent * LookAtOffset.X;
        LookAtLocation += LookAtSide * LookAtOffset.Y;
        LookAtLocation += FVector::UpVector * LookAtOffset.Z;
    }

    FRotator NewRotation = (LookAtLocation - Location).Rotation();
    NewRotation.Pitch += DegreesAboveFollow;

    if (FirstTick) {
        SetActorLocation(Location);
        SetActorRotation(NewRotation);
        FirstTick = false;
        return;
    }

    FVector LastLocation = GetActorLocation();
    FRotator LastRotation = GetActorRotation();
    // Note: This will not work if LastRotation and NewRotation are too far from
    // each other (more than 20 degrees), however, in that case, nothing will
    // work...
    GetNiceRotatorValue(NewRotation, LastRotation);
    NewRotation = NewRotation * (1-FollowSmooth) + LastRotation * FollowSmooth;
    NewRotation.Normalize();
    SetActorLocation(Location * 0.1 + LastLocation * 0.9);
    SetActorRotation(NewRotation);
}
// Read motion data from Axis Neuron
bool UPerceptionNeuronBPLibrary::NeuronRead(APerceptionNeuronController *Controller, USkeletalMeshComponent *Mesh, FVector& Translation, FRotator& Rotation, FVector AdditionalTranslation, FRotator AdditionalRotation, EPerceptionNeuronBonesEnum BVHBone, FName CustomBoneName, bool InverseForward)
{
	if (Controller == nullptr)
	{
		if (GEngine)
		{
			GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Controller is invalid.")));
		}
		Rotation.Yaw = Rotation.Pitch = Rotation.Roll = 0;
		Translation.X = Translation.Y = Translation.Z = 0;
		return false;
	}
	else if ((Controller->bConnected == false) && (Controller->bPlay == false))
	{
		Rotation.Yaw = Rotation.Pitch = Rotation.Roll = 0;
		Translation.X = Translation.Y = Translation.Z = 0;
		return false;
	}

	int32 BVHBoneIndex = (int32)BVHBone;
	if (BVHBoneIndex >= Controller->Skeleton.BoneNr)
	{
		if (GEngine)
		{
			GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Boneindex %d exceeds maximum available bones %d."), BVHBoneIndex, Controller->Skeleton.BoneNr));
		}
		Rotation.Yaw = Rotation.Pitch = Rotation.Roll = 0;
		Translation.X = Translation.Y = Translation.Z = 0;
		return false;
	}

	int32 FloatsPerBone = 6; // 3 for x,y,z translation and 3 for x,y,z rotation
	if (Controller->bDisplacement == false)
	{
		FloatsPerBone = 3;	// If there is no displacement (translation) info we have only 3 floats for rotation left
	}
	if ((BVHBoneIndex * FloatsPerBone) > Controller->FloatCount)
	{
		Rotation.Yaw = Rotation.Pitch = Rotation.Roll = 0;
		Translation.X = Translation.Y = Translation.Z = 0;
		return false;
	}

	// Get the rotation of the reference pose bone
	FQuat RefQuat(FQuat::Identity);
	if (Mesh != nullptr && Mesh->SkeletalMesh != nullptr)
	{
		const FReferenceSkeleton& RefSkeleton(Mesh->SkeletalMesh->RefSkeleton);
		int32 RefBoneIndex = Mesh->GetBoneIndex(CustomBoneName);
		while (RefBoneIndex != INDEX_NONE)
		{
			RefQuat = RefSkeleton.GetRefBonePose()[RefBoneIndex].GetRotation() * RefQuat;
			RefBoneIndex = RefSkeleton.GetParentIndex(RefBoneIndex);
		}
	}

	//
	// Translation
	//

	if (Controller->bDisplacement == true)
	{
		// Read translation values and remove BVH reference position
		float X = Controller->MotionLine[(BVHBoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BVHBoneIndex].XPos] - Controller->Skeleton.Bones[BVHBoneIndex].Offset[0];
		float Y = Controller->MotionLine[(BVHBoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BVHBoneIndex].YPos] - Controller->Skeleton.Bones[BVHBoneIndex].Offset[1];
		float Z = Controller->MotionLine[(BVHBoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BVHBoneIndex].ZPos] - Controller->Skeleton.Bones[BVHBoneIndex].Offset[2];

		// Map BVH translation to UE4 world coordinate system (Inverse if forward direction is -Y)
		if (InverseForward)
		{
			Translation = FVector(-X, -Z, Y);
		}			
		else
		{
			Translation = FVector(X, Z, Y);
		}			

		// Map UE4 world translation to bone space	
		Translation = RefQuat.Inverse().RotateVector(Translation);
	}
	else
	{
		Translation.X = Translation.Y = Translation.Z = 0;
	}

	// Add additional translation
	Translation.X += AdditionalTranslation.X;
	Translation.Y += AdditionalTranslation.Y;
	Translation.Z += AdditionalTranslation.Z;


	//
	// Rotation 
	//

	// Read rotation values and map to pitch, yaw, roll (y, z, x)
	float XR = Controller->MotionLine[(BVHBoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BVHBoneIndex].XRot] * PI / 180.f;
	float YR = Controller->MotionLine[(BVHBoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BVHBoneIndex].YRot] * PI / 180.f;
	float ZR = Controller->MotionLine[(BVHBoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BVHBoneIndex].ZRot] * PI / 180.f;

	// Calculate Rotation Matrix and map to Quaternion
	FQuat BVHQuat = CalculateQuat(XR, YR, ZR, Controller->Skeleton.Bones[BVHBoneIndex].RotOrder);

	// Map BVH rotation to UE4 world coordinate system (Inverse if forward direction is -Y)
	float Y = BVHQuat.Y;
	float Z = BVHQuat.Z;
	if (InverseForward)
	{
		BVHQuat.X *= -1.0;
		BVHQuat.Y = -Z;
		BVHQuat.Z = Y;
	}
	else
	{
		BVHQuat.Y = Z;
		BVHQuat.Z = Y;
	}

	// Map UE4 world rotation to bone space
	FQuat Quat(RefQuat.Inverse() * BVHQuat * RefQuat);
	
	// Add additional rotation
	FQuat AddRot(AdditionalRotation);
	Quat *= AddRot;

	// Convert to Rotator
	Rotation = Quat.Rotator();
	Rotation.Normalize();

	return true;
}
// Read motion data from Axis Neuron
// Deprecated
bool UPerceptionNeuronBPLibrary::NeuronReadMotion(APerceptionNeuronController *Controller, FVector& Translation, FRotator& Rotation, FVector AdditionalTranslation, FRotator AdditionalRotation, int32 BoneIndex, ENeuronSkeletonEnum SkeletonType)
{
	if (Controller == nullptr)
	{
		if (GEngine)
		{
			GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Controller is invalid.")));
		}
		Rotation.Yaw = Rotation.Pitch = Rotation.Roll = 0;
		Translation.X = Translation.Y = Translation.Z = 0;
		return false;
	}
	else if ((Controller->bConnected == false) && (Controller->bPlay == false))
	{
		Rotation.Yaw = Rotation.Pitch = Rotation.Roll = 0;
		Translation.X = Translation.Y = Translation.Z = 0;
		return false;
	}
	else if (BoneIndex >= Controller->Skeleton.BoneNr)
	{
		if (GEngine)
		{
			GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Boneindex %d exceeds maximum available bones %d."), BoneIndex, Controller->Skeleton.BoneNr));
		}
		Rotation.Yaw = Rotation.Pitch = Rotation.Roll = 0;
		Translation.X = Translation.Y = Translation.Z = 0;
		return false;
	}

	int32 FloatsPerBone = 6; // 3 for x,y,z translation and 3 for x,y,z rotation
	if (Controller->bDisplacement == false)
	{
		FloatsPerBone = 3;	// If there is no displacement (translation) info we have only 3 floats for rotation left
	}

	if ((BoneIndex * FloatsPerBone) > Controller->FloatCount)
	{
		Rotation.Yaw = Rotation.Pitch = Rotation.Roll = 0;
		Translation.X = Translation.Y = Translation.Z = 0;
		return false;
	}


	//
	// Translation
	//

	if (Controller->bDisplacement == true)
	{
		// Read translation values and remove BVH reference position
		float X = Controller->MotionLine[(BoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BoneIndex].XPos] - Controller->Skeleton.Bones[BoneIndex].Offset[0];
		float Y = Controller->MotionLine[(BoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BoneIndex].YPos] - Controller->Skeleton.Bones[BoneIndex].Offset[1];
		float Z = Controller->MotionLine[(BoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BoneIndex].ZPos] - Controller->Skeleton.Bones[BoneIndex].Offset[2];

		// Map BVH right hand system to local bone coordinate system
		switch (SkeletonType)
		{
		case ENeuronSkeletonEnum::VE_Neuron:  // Neuron BVH skeleton
		{
			if (BoneIndex == 0)
			{	// Hips
				Translation = FVector(X, -Y, Z);
			}
			else if ((BoneIndex >= 1) && (BoneIndex <= 6))
			{	// Legs
				Translation = FVector(X, Y, -Z);
			}
			else if ((BoneIndex >= 7) && (BoneIndex <= 12))
			{	// Spine,...
				Translation = FVector(X, -Y, -Z);
			}
			else if ((BoneIndex >= 13) && (BoneIndex <= 35))
			{	// Right arm
				Translation = FVector(-Z, X, Y);
			}
			else if ((BoneIndex >= 36) && (BoneIndex <= 58))
			{	// Left arm
				Translation = FVector(Z, -X, Y);
			}
			break;
		}
		case ENeuronSkeletonEnum::VE_TPP_Hero:	// Hero_TPP, Old blue Unreal default skeleton with T-Pose
		case ENeuronSkeletonEnum::VE_Mannequin: // Mannequin, New Unreal default skeleton with A-Pose
		{
			if (BoneIndex == 0)
			{	// Hips
				Translation = FVector(Y, Z, -X);
			}
			// Ignore other bones
			break;
		}
		case ENeuronSkeletonEnum::VE_Map: // Map to configured bone map
		{
			// Map translation with configured Bonemap
			float Map[3] = { X, Y, Z };

			Translation = FVector(Map[Controller->Bonemap[BoneIndex].XYZ[0]] * Controller->Bonemap[BoneIndex].Sign[0],
				Map[Controller->Bonemap[BoneIndex].XYZ[1]] * Controller->Bonemap[BoneIndex].Sign[1],
				Map[Controller->Bonemap[BoneIndex].XYZ[2]] * Controller->Bonemap[BoneIndex].Sign[2]);
			break;
		}
		case ENeuronSkeletonEnum::VE_UE4: // Map to UE4 world coordinate system
		{
			Translation = FVector(X, Z, Y);
			break;
		}
		case ENeuronSkeletonEnum::VE_None: // Map to nothing, use BVH translation as it is
		default:
		{
			Translation = FVector(X, Y, Z);
			break;
		}
		}
	}
	else
	{
		Translation.X = Translation.Y = Translation.Z = 0;
	}

	// Add additional translation
	Translation.X += AdditionalTranslation.X;
	Translation.Y += AdditionalTranslation.Y;
	Translation.Z += AdditionalTranslation.Z;



	//
	// Rotation 
	//

	// Read rotation values and map to pitch, yaw, roll (y, z, x)
	float XR = Controller->MotionLine[(BoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BoneIndex].XRot] * PI / 180.f;
	float YR = Controller->MotionLine[(BoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BoneIndex].YRot] * PI / 180.f;
	float ZR = Controller->MotionLine[(BoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BoneIndex].ZRot] * PI / 180.f;

	// Calculate Rotation Matrix and map to Quaternion
	FQuat Quat = CalculateQuat(XR, YR, ZR, Controller->Skeleton.Bones[BoneIndex].RotOrder);

	// Map BVH coordinate system to each bone coordinate system dependend on skeleton type
	switch (SkeletonType)
	{
	case ENeuronSkeletonEnum::VE_Neuron:  // Neuron BVH skeleton
	{
		if ((BoneIndex >= 1) && (BoneIndex <= 6))
		{	// Legs
			Quat.Z *= -1.f;
		}
		else if ((BoneIndex >= 13) && (BoneIndex <= 35))
		{	// Right Arm
			float X = Quat.X;
			float Y = Quat.Y;
			float Z = Quat.Z;
			Quat.X = -Z;
			Quat.Y = X;
			Quat.Z = Y;
		}
		else if ((BoneIndex >= 36) && (BoneIndex <= 58))
		{	// Left Arm
			float X = Quat.X;
			float Y = Quat.Y;
			float Z = Quat.Z;
			Quat.X = Z;
			Quat.Y = -X;
			Quat.Z = Y;
		}
		else
		{
			Quat.Y *= -1.f;
		}
		break;
	}
	case ENeuronSkeletonEnum::VE_TPP_Hero:	// Hero_TPP, Old blue Unreal default skeleton with T-Pose
	case ENeuronSkeletonEnum::VE_Mannequin: // Mannequin, New Unreal default skeleton with A-Pose
	{
		if ((BoneIndex >= 1) && (BoneIndex <= 3))
		{	// Right Leg
			float X = Quat.X;
			float Y = Quat.Y;
			float Z = Quat.Z;
			Quat.X = -Y;
			Quat.Y = -Z;
			Quat.Z = -X;
		}
		else if (BoneIndex == 16)
		{	// Right Hand
			Quat.Y *= -1.f;
		}
		else if ((BoneIndex >= 13) && (BoneIndex <= 19))
		{	// Right Arm and Thumb
			float Y = Quat.Y;
			float Z = Quat.Z;
			Quat.Y = -Z;
			Quat.Z = -Y;
		}
		else if ((BoneIndex >= 20) && (BoneIndex <= 35))
		{	// Right Finger
			Quat.Y *= -1.f;
		}
		else if (BoneIndex == 39)
		{	// Left Hand
			Quat.Z *= -1.f;
		}
		else if ((BoneIndex >= 36) && (BoneIndex <= 42))
		{	// Left Arm and Thumb
			float Y = Quat.Y;
			float Z = Quat.Z;
			Quat.Y = Z;
			Quat.Z = Y;
		}
		else if ((BoneIndex >= 43) && (BoneIndex <= 58))
		{	// Left Finger
			Quat.Z *= -1.f;
		}
		else
		{	// Left Leg, Hips, Spine, Neck, Head
			float X = Quat.X;
			float Y = Quat.Y;
			float Z = Quat.Z;
			Quat.X = Y;
			Quat.Y = Z;
			Quat.Z = -X;
		}
		break;
	}
	case ENeuronSkeletonEnum::VE_Map: // Map to configured bone map
	{
		// Map Quat.X/Y/Z with configured Bonemap				
		float Map[3] = { Quat.X, Quat.Y, Quat.Z };

		Quat.X = Map[Controller->Bonemap[BoneIndex].XYZ[0]] * Controller->Bonemap[BoneIndex].Sign[0];
		Quat.Y = Map[Controller->Bonemap[BoneIndex].XYZ[1]] * Controller->Bonemap[BoneIndex].Sign[1];
		Quat.Z = Map[Controller->Bonemap[BoneIndex].XYZ[2]] * Controller->Bonemap[BoneIndex].Sign[2];
		break;
	}
	case ENeuronSkeletonEnum::VE_UE4: // Map to UE4 world coordinate system
	{
		float Y = Quat.Y;
		float Z = Quat.Z;
		Quat.Y = Z;
		Quat.Z = Y;
		break;
	}
	case ENeuronSkeletonEnum::VE_None: // Map to nothing, use BVH rotation as it is
	default:
	{
		// Nothing to do, Quaternion is already BVH
		break;
	}
	}

	// Convert to Rotator
	Rotation = Quat.Rotator();

	// Add additional rotation
	Rotation.Yaw += AdditionalRotation.Yaw;
	Rotation.Pitch += AdditionalRotation.Pitch;
	Rotation.Roll += AdditionalRotation.Roll;
	Rotation.Normalize();

	return true;
}
bool FStaticMeshEditorViewportClient::InputWidgetDelta( FViewport* Viewport, EAxisList::Type CurrentAxis, FVector& Drag, FRotator& Rot, FVector& Scale )
{
	bool bHandled = false;
	if (bManipulating)
	{
		if (CurrentAxis != EAxisList::None)
		{
			UStaticMeshSocket* SelectedSocket = StaticMeshEditorPtr.Pin()->GetSelectedSocket();
			if(SelectedSocket)
			{
				UProperty* ChangedProperty = NULL;
				const FWidget::EWidgetMode MoveMode = GetWidgetMode();
				if(MoveMode == FWidget::WM_Rotate)
				{
					ChangedProperty = FindField<UProperty>( UStaticMeshSocket::StaticClass(), "RelativeRotation" );
					SelectedSocket->PreEditChange(ChangedProperty);

					FRotator CurrentRot = SelectedSocket->RelativeRotation;
					FRotator SocketWinding, SocketRotRemainder;
					CurrentRot.GetWindingAndRemainder(SocketWinding, SocketRotRemainder);

					const FQuat ActorQ = SocketRotRemainder.Quaternion();
					const FQuat DeltaQ = Rot.Quaternion();
					const FQuat ResultQ = DeltaQ * ActorQ;
					const FRotator NewSocketRotRem = FRotator( ResultQ );
					FRotator DeltaRot = NewSocketRotRem - SocketRotRemainder;
					DeltaRot.Normalize();

					SelectedSocket->RelativeRotation += DeltaRot;
					SelectedSocket->RelativeRotation = SelectedSocket->RelativeRotation.Clamp();
				}
				else if(MoveMode == FWidget::WM_Translate)
				{
					ChangedProperty = FindField<UProperty>( UStaticMeshSocket::StaticClass(), "RelativeLocation" );
					SelectedSocket->PreEditChange(ChangedProperty);

					//FRotationMatrix SocketRotTM( SelectedSocket->RelativeRotation );
					//FVector SocketMove = SocketRotTM.TransformVector( Drag );

					SelectedSocket->RelativeLocation += Drag;
				}
				if ( ChangedProperty )
				{			
					FPropertyChangedEvent PropertyChangedEvent( ChangedProperty );
					SelectedSocket->PostEditChangeProperty(PropertyChangedEvent);
				}

				StaticMeshEditorPtr.Pin()->GetStaticMesh()->MarkPackageDirty();
			}
			else
			{
				const bool bSelectedPrim = StaticMeshEditorPtr.Pin()->HasSelectedPrims();
				if (bSelectedPrim && CurrentAxis != EAxisList::None)
				{
					const FWidget::EWidgetMode MoveMode = GetWidgetMode();
					if (MoveMode == FWidget::WM_Rotate)
					{
						StaticMeshEditorPtr.Pin()->RotateSelectedPrims(Rot);
					}
					else if (MoveMode == FWidget::WM_Scale)
					{
						StaticMeshEditorPtr.Pin()->ScaleSelectedPrims(Scale);
					}
					else if (MoveMode == FWidget::WM_Translate)
					{
						StaticMeshEditorPtr.Pin()->TranslateSelectedPrims(Drag);
					}

					StaticMeshEditorPtr.Pin()->GetStaticMesh()->MarkPackageDirty();
				}
			}
		}

		Invalidate();		
		bHandled = true;
	}

	return bHandled;
}
void AARCharacter::MoveForward(float Value)
{
	if ((Controller != NULL) && (Value != 0.0f))
	{
		// find out which way is forward
		FRotator Rotation = GetBaseAimRotation();

		FVector Location; //not used, just need for below.
		//Controller->GetPlayerViewPoint(Location, Rotation);
		Rotation.Normalize();
		FRotator YawRotation(0, Rotation.Yaw, 0);
		const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
		AddMovementInput(Direction, Value);

	}
}