void URotatingMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
{
	// skip if we don't want component updated when not rendered or if updated component can't move
	if (ShouldSkipUpdate(DeltaTime))
	{
		return;
	}

	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

	if (!IsValid(UpdatedComponent))
	{
		return;
	}

	// Compute new rotation
	const FQuat OldRotation = UpdatedComponent->GetComponentQuat();
	const FQuat DeltaRotation = (RotationRate * DeltaTime).Quaternion();
	const FQuat NewRotation = bRotationInLocalSpace ? (OldRotation * DeltaRotation) : (DeltaRotation * OldRotation);

	// Compute new location
	FVector DeltaLocation = FVector::ZeroVector;
	if (!PivotTranslation.IsZero())
	{
		const FVector OldPivot = OldRotation.RotateVector(PivotTranslation);
		const FVector NewPivot = NewRotation.RotateVector(PivotTranslation);
		DeltaLocation = (OldPivot - NewPivot); // ConstrainDirectionToPlane() not necessary because it's done by MoveUpdatedComponent() below.
	}

	const bool bEnableCollision = false;
	MoveUpdatedComponent(DeltaLocation, NewRotation, bEnableCollision);
}
//Conversion - use find and replace to change behavior, no scaling version is typically used for orientations
FVector ConvertLeapToUE(Leap::Vector LeapVector)
{
	//Convert Axis
	FVector ConvertedVector = FVector(-LeapVector.z, LeapVector.x, LeapVector.y);

	//Hmd orientation adjustment
	if (LeapShouldAdjustForFacing)
	{
		FRotator Rotation = FRotator(90.f, 0.f, 180.f);
		ConvertedVector = FQuat(Rotation).RotateVector(ConvertedVector);
		
		if (LeapShouldAdjustRotationForHMD)
		{
			if (GEngine->HMDDevice.IsValid())
			{
				FQuat orientationQuat;
				FVector position;
				GEngine->HMDDevice->GetCurrentOrientationAndPosition(orientationQuat, position);
				ConvertedVector = orientationQuat.RotateVector(ConvertedVector);
			}
		}
	}

	return ConvertedVector;
}
예제 #3
0
//Conversion - use find and replace to change behavior, no scaling version is typically used for orientations
FVector convertLeapToUE(Leap::Vector leapVector)
{
    //Convert Axis
    FVector vect = FVector(-leapVector.z, leapVector.x, leapVector.y);

    //Hmd orientation adjustment
    if (LeapShouldAdjustForFacing)
    {
        FRotator rotation = FRotator(90.f, 0.f, 180.f);
        vect = FQuat(rotation).RotateVector(vect);

        if (LeapShouldAdjustRotationForHMD)
        {
            if (GEngine->HMDDevice.IsValid())
            {
                FQuat orientationQuat;
                FVector position;
                GEngine->HMDDevice->GetCurrentOrientationAndPosition(orientationQuat, position);
                vect = orientationQuat.RotateVector(vect);
            }
        }
    }

    return vect;
}
예제 #4
0
void UDestructibleComponent::SetChunksWorldTM(const TArray<FUpdateChunksInfo>& UpdateInfos)
{
	const FQuat InvRotation = ComponentToWorld.GetRotation().Inverse();

	for (const FUpdateChunksInfo& UpdateInfo : UpdateInfos)
	{
		// Bone 0 is a dummy root bone
		const int32 BoneIndex = ChunkIdxToBoneIdx(UpdateInfo.ChunkIndex);
		const FVector WorldTranslation	= UpdateInfo.WorldTM.GetLocation();
		const FQuat WorldRotation		= UpdateInfo.WorldTM.GetRotation();

		const FQuat BoneRotation = InvRotation*WorldRotation;
		const FVector BoneTranslation = InvRotation.RotateVector(WorldTranslation - ComponentToWorld.GetTranslation()) / ComponentToWorld.GetScale3D();

		GetEditableSpaceBases()[BoneIndex] = FTransform(BoneRotation, BoneTranslation);
	}

	// Mark the transform as dirty, so the bounds are updated and sent to the render thread
	MarkRenderTransformDirty();

	// New bone positions need to be sent to render thread
	MarkRenderDynamicDataDirty();

	//Update bone visibilty and flip the editable space base buffer
	FlipEditableSpaceBases();
}
예제 #5
0
FVector adjustForHMD(FVector in)
{
    if (GEngine->HMDDevice.IsValid())
    {
        FQuat orientationQuat;
        FVector position;
        GEngine->HMDDevice->GetCurrentOrientationAndPosition(orientationQuat, position);
        FVector out = orientationQuat.RotateVector(in);
        if (LeapShouldAdjustPositionForHMD)
        {
            if (LeapShouldAdjustForMountOffset)
                position += orientationQuat.RotateVector(FVector(LEAP_MOUNT_OFFSET, 0, 0));
            out += position;
        }
        return out;
    }
    else
        return in;

}
FVector USplineComponent::GetRightVectorAtSplineInputKey(float InKey, ESplineCoordinateSpace::Type CoordinateSpace) const
{
	const FQuat Quat = GetQuaternionAtSplineInputKey(InKey, ESplineCoordinateSpace::Local);
	FVector RightVector = Quat.RotateVector(FVector::RightVector);

	if (CoordinateSpace == ESplineCoordinateSpace::World)
	{
		RightVector = ComponentToWorld.TransformVectorNoScale(RightVector);
	}

	return RightVector;
}
void UBerserkCameraComponent::UpdateCameraBounds(const APlayerController* playerController)
{
	auto const* const localPlayer = Cast<ULocalPlayer>(playerController->Player);
	if (localPlayer == nullptr || localPlayer->ViewportClient == nullptr) return;

	FVector2D currentViewportSize;
	localPlayer->ViewportClient->GetViewportSize(currentViewportSize);

	// calc frustum edge direction, from bottom left corner
	if (CameraMovementBounds.GetSize() == FVector::ZeroVector || currentViewportSize != CameraMovementViewportSize)
	{
		// calc frustum edge direction, from bottom left corner
		const FVector frustumRay2dDir = FVector(1, 1, 0).GetSafeNormal();
		const FVector frustumRay2dRight = FVector::CrossProduct(frustumRay2dDir, FVector::UpVector);
		const FQuat rotQuat(frustumRay2dRight, FMath::DegreesToRadians(90.0f - playerController->PlayerCameraManager->GetFOVAngle() * 0.5f));
		const FVector frustumRayDir = rotQuat.RotateVector(frustumRay2dDir);

		// collect 3 world bounds' points and matching frustum rays (bottom left, top left, bottom right)
		auto const* const gameState = GetWorld()->GetGameState<ABerserkGameState>();
		if (gameState)
		{
			const auto worldBounds = gameState->WorldBounds;

			if (worldBounds.GetSize() != FVector::ZeroVector)
			{
				const FVector worldBoundPoints[] = {
					FVector(worldBounds.Min.X, worldBounds.Min.Y, worldBounds.Max.Z),
					FVector(worldBounds.Min.X, worldBounds.Max.Y, worldBounds.Max.Z),
					FVector(worldBounds.Max.X, worldBounds.Min.Y, worldBounds.Max.Z)
				};
				const FVector frustumRays[] = {
					FVector(frustumRayDir.X, frustumRayDir.Y, frustumRayDir.Z),
					FVector(frustumRayDir.X, -frustumRayDir.Y, frustumRayDir.Z),
					FVector(-frustumRayDir.X, frustumRayDir.Y, frustumRayDir.Z)
				};

				// get camera plane for intersections
				const auto cameraPlane = FPlane(playerController->GetFocalLocation(), FVector::UpVector);

				// get matching points on camera plane
				const FVector cameraPlanePoints[3] = {
					FProjectionUtils::IntersectRayWithPlane(worldBoundPoints[0], frustumRays[0], cameraPlane) * MiniMapBoundsLimit,
					FProjectionUtils::IntersectRayWithPlane(worldBoundPoints[1], frustumRays[1], cameraPlane) * MiniMapBoundsLimit,
					FProjectionUtils::IntersectRayWithPlane(worldBoundPoints[2], frustumRays[2], cameraPlane) * MiniMapBoundsLimit
				};

				// create new bounds
				CameraMovementBounds = FBox(cameraPlanePoints, 3);
				CameraMovementViewportSize = currentViewportSize;
			}
		}
	}
}
FVector adjustForHMDOrientation(FVector In)
{
	if (GEngine->HMDDevice.IsValid())
	{
		FQuat OrientationQuat;
		FVector Position;
		GEngine->HMDDevice->GetCurrentOrientationAndPosition(OrientationQuat, Position);
		FVector Out = OrientationQuat.RotateVector(In);
		return Out;
	}
	else
		return In;

}
FVector AdjustForHMD(FVector In)
{
	if (GEngine->HMDDevice.IsValid())
	{
		FQuat OrientationQuat;
		FVector Position;
		GEngine->HMDDevice->GetCurrentOrientationAndPosition(OrientationQuat, Position);
		FVector Out = OrientationQuat.RotateVector(In);
		if (LeapShouldAdjustPositionForHMD)
		{
			if (LeapShouldAdjustForMountOffset)
			{
				Position += OrientationQuat.RotateVector(LeapMountOffset);
			}
			Out += Position;
		}
		return Out;
	}
	else
	{
		return In;
	}
}
예제 #10
0
FVector adjustForHMDOrientation(FVector in)
{
    if (GEngine->HMDDevice.IsValid())
    {
        FQuat orientationQuat;
        FVector position;
        GEngine->HMDDevice->GetCurrentOrientationAndPosition(orientationQuat, position);
        FVector out = orientationQuat.RotateVector(in);
        return out;
    }
    else
        return in;

}
FQuat USplineComponent::GetQuaternionAtSplineInputKey(float InKey, ESplineCoordinateSpace::Type CoordinateSpace) const
{
	FQuat Quat = SplineRotInfo.Eval(InKey, FQuat::Identity);
	Quat.Normalize();

	const FVector Direction = SplineInfo.EvalDerivative(InKey, FVector::ZeroVector).GetSafeNormal();
	const FVector UpVector = Quat.RotateVector(DefaultUpVector);

	FQuat Rot = (FRotationMatrix::MakeFromXZ(Direction, UpVector)).ToQuat();

	if (CoordinateSpace == ESplineCoordinateSpace::World)
	{
		Rot = ComponentToWorld.GetRotation() * Rot;
	}

	return Rot;
}
FTransform FActorPositioning::GetSurfaceAlignedTransform(const FPositioningData& Data)
{
	// Sort out the rotation first, then do the location
	FQuat RotatorQuat = Data.StartTransform.GetRotation();

	if (Data.ActorFactory)
	{
		RotatorQuat = Data.ActorFactory->AlignObjectToSurfaceNormal(Data.SurfaceNormal, RotatorQuat);
	}

	// Choose the largest location offset of the various options (global viewport settings, collision, factory offset)
	const float SnapOffsetExtent = GetDefault<ULevelEditorViewportSettings>()->SnapToSurface.SnapOffsetExtent;
	const float CollisionOffsetExtent = FVector::BoxPushOut(Data.SurfaceNormal, Data.PlacementExtent);

	FVector LocationOffset = Data.SurfaceNormal * FMath::Max(SnapOffsetExtent, CollisionOffsetExtent);
	if (Data.ActorFactory && LocationOffset.SizeSquared() < Data.ActorFactory->SpawnPositionOffset.SizeSquared())
	{
		// Rotate the Spawn Position Offset to match our rotation
		LocationOffset = RotatorQuat.RotateVector(-Data.ActorFactory->SpawnPositionOffset);
	}

	return FTransform(Data.bAlignRotation ? RotatorQuat : Data.StartTransform.GetRotation(), Data.SurfaceLocation + LocationOffset);
}
예제 #13
0
/**
 * Updates the camera position.  Called every frame by UpdateSimulation.
 *
 * @param	UserImpulse				User impulse data for the current frame
 * @param	DeltaTime				Time interval
 * @param	MovementSpeedScale		Additional movement accel/speed scale
 * @param	CameraEuler				Current camera rotation
 * @param	InOutCameraPosition		[in, out] Camera position
 */
void FEditorCameraController::UpdatePosition( const FCameraControllerUserImpulseData& UserImpulse, const float DeltaTime, const float MovementSpeedScale, const FVector& CameraEuler, FVector& InOutCameraPosition )
{
	// Compute local impulse
	FVector LocalSpaceImpulse;
	{
		// NOTE: Forward/back and right/left impulse are applied in local space, but up/down impulse is
		//		 applied in world space.  This is because it feels more intuitive to always move straight
		//		 up or down with those controls.
		LocalSpaceImpulse =
			FVector( UserImpulse.MoveForwardBackwardImpulse,		// Local space forward/back
					 UserImpulse.MoveRightLeftImpulse,				// Local space right/left
					 0.0f );										// Local space up/down
	}


	// Compute world space acceleration
	FVector WorldSpaceAcceleration;
	{
		// Compute camera orientation, then rotate our local space impulse to world space
		const FQuat CameraOrientation = FQuat::MakeFromEuler( CameraEuler );
		FVector WorldSpaceImpulse = CameraOrientation.RotateVector( LocalSpaceImpulse );

		// Accumulate any world space impulse we may have
		// NOTE: Up/down impulse is applied in world space.  See above comments for more info.
		WorldSpaceImpulse +=
			FVector( 0.0f,											// World space forward/back
					 0.0f,											// World space right/left
					 UserImpulse.MoveUpDownImpulse );				// World space up/down

		// Cap impulse by normalizing, but only if our magnitude is greater than 1.0
		//if( WorldSpaceImpulse.SizeSquared() > 1.0f )
		{
			//WorldSpaceImpulse = WorldSpaceImpulse.UnsafeNormal();
		}

		// Compute world space acceleration
		WorldSpaceAcceleration = WorldSpaceImpulse * Config.MovementAccelerationRate * MovementSpeedScale;
	}


	if( Config.bUsePhysicsBasedMovement )
	{
		// Accelerate the movement velocity
		MovementVelocity += WorldSpaceAcceleration * DeltaTime;


		// Apply damping
		{
			const float DampingFactor = FMath::Clamp( Config.MovementVelocityDampingAmount * DeltaTime, 0.0f, 0.75f );

			// Decelerate
			MovementVelocity += -MovementVelocity * DampingFactor;
		}
	}
	else
	{
		// No physics, so just use the acceleration as our velocity
		MovementVelocity = WorldSpaceAcceleration;
	}


	// Constrain maximum movement speed
	if( MovementVelocity.Size() > Config.MaximumMovementSpeed * MovementSpeedScale )
	{
		MovementVelocity = MovementVelocity.GetUnsafeNormal() * Config.MaximumMovementSpeed * MovementSpeedScale;
	}


	// Clamp velocity to a reasonably small number
	if( MovementVelocity.Size() < KINDA_SMALL_NUMBER )
	{
		MovementVelocity = FVector::ZeroVector;
	}


	// Update camera position
	InOutCameraPosition += MovementVelocity * DeltaTime;
}
예제 #14
0
void FViewExtension::PreRenderView_RenderThread(FRHICommandListImmediate& RHICmdList, FSceneView& View)
{
	check(IsInRenderingThread());
	FViewExtension& RenderContext = *this;
	FGameFrame* CurrentFrame = static_cast<FGameFrame*>(RenderContext.RenderFrame.Get());

	if (!RenderContext.ShowFlags.Rendering || !CurrentFrame || !CurrentFrame->Settings->IsStereoEnabled())
	{
		return;
	}

	const ovrEyeType eyeIdx = (View.StereoPass == eSSP_LEFT_EYE) ? ovrEye_Left : ovrEye_Right;
	if (RenderContext.ShowFlags.Rendering && CurrentFrame->Settings->Flags.bUpdateOnRT)
	{
		FQuat	CurrentEyeOrientation;
		FVector	CurrentEyePosition;
		CurrentFrame->PoseToOrientationAndPosition(RenderContext.CurEyeRenderPose[eyeIdx], CurrentEyeOrientation, CurrentEyePosition);

		FQuat ViewOrientation = View.ViewRotation.Quaternion();

		// recalculate delta control orientation; it should match the one we used in CalculateStereoViewOffset on a game thread.
		FVector GameEyePosition;
		FQuat GameEyeOrient;

		CurrentFrame->PoseToOrientationAndPosition(CurrentFrame->EyeRenderPose[eyeIdx], GameEyeOrient, GameEyePosition);
		const FQuat DeltaControlOrientation =  ViewOrientation * GameEyeOrient.Inverse();
		// make sure we use the same viewrotation as we had on a game thread
		check(View.ViewRotation == CurrentFrame->CachedViewRotation[eyeIdx]);

		if (CurrentFrame->Flags.bOrientationChanged)
		{
			// Apply updated orientation to corresponding View at recalc matrices.
			// The updated position will be applied from inside of the UpdateViewMatrix() call.
			const FQuat DeltaOrient = View.BaseHmdOrientation.Inverse() * CurrentEyeOrientation;
			View.ViewRotation = FRotator(ViewOrientation * DeltaOrient);
			
			//UE_LOG(LogHMD, Log, TEXT("VIEWDLT: Yaw %.3f Pitch %.3f Roll %.3f"), DeltaOrient.Rotator().Yaw, DeltaOrient.Rotator().Pitch, DeltaOrient.Rotator().Roll);
		}

		if (!CurrentFrame->Flags.bPositionChanged)
		{
			// if no positional change applied then we still need to calculate proper stereo disparity.
			// use the current head pose for this calculation instead of the one that was saved on a game thread.
			FQuat HeadOrientation;
			CurrentFrame->PoseToOrientationAndPosition(RenderContext.CurHeadPose, HeadOrientation, View.BaseHmdLocation);
		}

		// The HMDPosition already has HMD orientation applied.
		// Apply rotational difference between HMD orientation and ViewRotation
		// to HMDPosition vector. 
		const FVector DeltaPosition = CurrentEyePosition - View.BaseHmdLocation;
		const FVector vEyePosition = DeltaControlOrientation.RotateVector(DeltaPosition) + CurrentFrame->Settings->PositionOffset;
		View.ViewLocation += vEyePosition;

		//UE_LOG(LogHMD, Log, TEXT("VDLTPOS: %.3f %.3f %.3f"), vEyePosition.X, vEyePosition.Y, vEyePosition.Z);

		if (CurrentFrame->Flags.bOrientationChanged || CurrentFrame->Flags.bPositionChanged)
		{
			View.UpdateViewMatrix();
		}
	}

	FSettings* FrameSettings = CurrentFrame->GetSettings();
	check(FrameSettings);
	FrameSettings->EyeLayer.EyeFov.RenderPose[eyeIdx] = RenderContext.CurEyeRenderPose[eyeIdx];
}