diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 6edb0ec9..66f8081f 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,6 +1,6 @@ - true + false diff --git a/src/Engine/Draw/Base/SkiaControl.Shared.cs b/src/Engine/Draw/Base/SkiaControl.Shared.cs index 312d1820..43d63d0f 100644 --- a/src/Engine/Draw/Base/SkiaControl.Shared.cs +++ b/src/Engine/Draw/Base/SkiaControl.Shared.cs @@ -984,21 +984,21 @@ protected bool CheckChildrenGesturesLocked(TouchActionResult action) { switch (LockChildrenGestures) { - case LockTouch.Enabled: - return true; + case LockTouch.Enabled: + return true; - case LockTouch.Disabled: - break; + case LockTouch.Disabled: + break; - case LockTouch.PassTap: - if (action != TouchActionResult.Tapped) - return true; - break; + case LockTouch.PassTap: + if (action != TouchActionResult.Tapped) + return true; + break; - case LockTouch.PassTapAndLongPress: - if (action != TouchActionResult.Tapped && action != TouchActionResult.LongPressing) - return true; - break; + case LockTouch.PassTapAndLongPress: + if (action != TouchActionResult.Tapped && action != TouchActionResult.LongPressing) + return true; + break; } return false; @@ -2505,6 +2505,15 @@ public virtual void SetPropertyValue(BindableProperty property, object value) //todo check adapt for MAUI + public static float DegreesToRadians(float value) + { + return (float)((value * Math.PI) / 180); + } + public static float RadiansToDegrees(float value) + { + return (float)(value * 180 / Math.PI); + } + public static double DegreesToRadians(double value) { return ((value * Math.PI) / 180); @@ -2677,93 +2686,93 @@ public SKRect CalculateLayout(SKRect destination, float widthRequest, float heig switch (layoutHorizontal.Alignment) { - case LayoutAlignment.Center when float.IsFinite(availableWidth): - { - left += (float)Math.Round(availableWidth / 2.0f - useMaxWidth / 2.0f); - right = left + useMaxWidth; + case LayoutAlignment.Center when float.IsFinite(availableWidth): + { + left += (float)Math.Round(availableWidth / 2.0f - useMaxWidth / 2.0f); + right = left + useMaxWidth; - if (left < destination.Left) - { - left = destination.Left; - right = left + useMaxWidth; - } + if (left < destination.Left) + { + left = destination.Left; + right = left + useMaxWidth; + } - if (right > destination.Right) - { - right = destination.Right; - } + if (right > destination.Right) + { + right = destination.Right; + } - break; - } - case LayoutAlignment.End when float.IsFinite(destination.Right): - { - right = destination.Right; - left = right - useMaxWidth; - if (left < destination.Left) - { - left = destination.Left; - } + break; + } + case LayoutAlignment.End when float.IsFinite(destination.Right): + { + right = destination.Right; + left = right - useMaxWidth; + if (left < destination.Left) + { + left = destination.Left; + } - break; - } - case LayoutAlignment.Fill: - case LayoutAlignment.Start: - default: - { - right = left + useMaxWidth; - if (right > destination.Right) - { - right = destination.Right; - } + break; + } + case LayoutAlignment.Fill: + case LayoutAlignment.Start: + default: + { + right = left + useMaxWidth; + if (right > destination.Right) + { + right = destination.Right; + } - break; - } + break; + } } // VerticalOptions switch (layoutVertical.Alignment) { - case LayoutAlignment.Center when float.IsFinite(availableHeight): - { - top += (float)Math.Round(availableHeight / 2.0f - useMaxHeight / 2.0f); - bottom = top + useMaxHeight; + case LayoutAlignment.Center when float.IsFinite(availableHeight): + { + top += (float)Math.Round(availableHeight / 2.0f - useMaxHeight / 2.0f); + bottom = top + useMaxHeight; - if (top < destination.Top) - { - top = destination.Top; - bottom = top + useMaxHeight; - } + if (top < destination.Top) + { + top = destination.Top; + bottom = top + useMaxHeight; + } - else if (bottom > destination.Bottom) - { - bottom = destination.Bottom; - top = bottom - useMaxHeight; - } + else if (bottom > destination.Bottom) + { + bottom = destination.Bottom; + top = bottom - useMaxHeight; + } - break; - } - case LayoutAlignment.End when float.IsFinite(destination.Bottom): - { - bottom = destination.Bottom; - top = bottom - useMaxHeight; - if (top < destination.Top) + break; + } + case LayoutAlignment.End when float.IsFinite(destination.Bottom): + { + bottom = destination.Bottom; + top = bottom - useMaxHeight; + if (top < destination.Top) + { + top = destination.Top; + } + + break; + } + case LayoutAlignment.Start: + case LayoutAlignment.Fill: + default: + + bottom = top + useMaxHeight; + if (bottom > destination.Bottom) { - top = destination.Top; + bottom = destination.Bottom; } - break; - } - case LayoutAlignment.Start: - case LayoutAlignment.Fill: - default: - - bottom = top + useMaxHeight; - if (bottom > destination.Bottom) - { - bottom = destination.Bottom; - } - break; } @@ -4619,8 +4628,9 @@ protected virtual void ApplyTransforms(SkiaDrawingContext ctx, SKRect destinatio Helper3d.RotateXDegrees(CameraAngleX); Helper3d.RotateYDegrees(CameraAngleY); Helper3d.RotateZDegrees(CameraAngleZ); - if (CameraTranslationZ != 0) - Helper3d.Translate(0, 0, CameraTranslationZ); + + //if (CameraTranslationZ != 0) + Helper3d.Translate(0, 0, CameraTranslationZ); drawingMatrix = drawingMatrix.PostConcat(Helper3d.GetMatrix()); #else @@ -4628,7 +4638,7 @@ protected virtual void ApplyTransforms(SkiaDrawingContext ctx, SKRect destinatio Helper3d.RotateXDegrees(CameraAngleX); Helper3d.RotateYDegrees(CameraAngleY); Helper3d.RotateZDegrees(CameraAngleZ); - if (CameraTranslationZ != 0) Helper3d.TranslateZ(CameraTranslationZ); + Helper3d.TranslateZ(CameraTranslationZ); drawingMatrix = drawingMatrix.PostConcat(Helper3d.Matrix); Helper3d.Restore(); #endif @@ -4658,28 +4668,28 @@ public static bool IsSimpleRectangle(SKPath path) { switch (verb) { - case SKPathVerb.Move: - if (moveToFound) - return false; // Multiple MoveTo commands - moveToFound = true; - break; + case SKPathVerb.Move: + if (moveToFound) + return false; // Multiple MoveTo commands + moveToFound = true; + break; - case SKPathVerb.Line: - if (lineToCount < 4) - { - lineToCount++; - } - else - { - return false; // More than 4 LineTo commands - } - break; + case SKPathVerb.Line: + if (lineToCount < 4) + { + lineToCount++; + } + else + { + return false; // More than 4 LineTo commands + } + break; - case SKPathVerb.Close: - return lineToCount == 4; // Ensure we have exactly 4 LineTo commands before Close + case SKPathVerb.Close: + return lineToCount == 4; // Ensure we have exactly 4 LineTo commands before Close - default: - return false; // Any other command invalidates the rectangle check + default: + return false; // Any other command invalidates the rectangle check } } @@ -5734,37 +5744,37 @@ public SKShader CreateGradient(SKRect destination, SkiaGradient gradient) switch (gradient.Type) { - case GradientType.Sweep: - - //float sweep = (float)Value3;//((float)this.Variable1 % (float)this.Variable2 / 100F) * 360.0F; - - return SKShader.CreateSweepGradient( - new SKPoint(destination.Left + destination.Width / 2.0f, - destination.Top + destination.Height / 2.0f), - colors.ToArray(), - colorPositions, - gradient.TileMode, (float)Value1, (float)(Value1 + Value2)); - - case GradientType.Circular: - return SKShader.CreateRadialGradient( - new SKPoint(destination.Left + destination.Width / 2.0f, - destination.Top + destination.Height / 2.0f), - Math.Max(destination.Width, destination.Height) / 2.0f, - colors.ToArray(), - colorPositions, - gradient.TileMode); - - case GradientType.Linear: - default: - return SKShader.CreateLinearGradient( - new SKPoint(destination.Left + destination.Width * gradient.StartXRatio, - destination.Top + destination.Height * gradient.StartYRatio), - new SKPoint(destination.Left + destination.Width * gradient.EndXRatio, - destination.Top + destination.Height * gradient.EndYRatio), - colors.ToArray(), - colorPositions, - gradient.TileMode); - break; + case GradientType.Sweep: + + //float sweep = (float)Value3;//((float)this.Variable1 % (float)this.Variable2 / 100F) * 360.0F; + + return SKShader.CreateSweepGradient( + new SKPoint(destination.Left + destination.Width / 2.0f, + destination.Top + destination.Height / 2.0f), + colors.ToArray(), + colorPositions, + gradient.TileMode, (float)Value1, (float)(Value1 + Value2)); + + case GradientType.Circular: + return SKShader.CreateRadialGradient( + new SKPoint(destination.Left + destination.Width / 2.0f, + destination.Top + destination.Height / 2.0f), + Math.Max(destination.Width, destination.Height) / 2.0f, + colors.ToArray(), + colorPositions, + gradient.TileMode); + + case GradientType.Linear: + default: + return SKShader.CreateLinearGradient( + new SKPoint(destination.Left + destination.Width * gradient.StartXRatio, + destination.Top + destination.Height * gradient.StartYRatio), + new SKPoint(destination.Left + destination.Width * gradient.EndXRatio, + destination.Top + destination.Height * gradient.EndYRatio), + colors.ToArray(), + colorPositions, + gradient.TileMode); + break; } } @@ -6119,14 +6129,14 @@ private void OnSkiaPropertyTemplateCollectionChanged(object sender, NotifyCollec { switch (e.Action) { - case NotifyCollectionChangedAction.Add: - control.OnItemTemplateChanged(); - break; + case NotifyCollectionChangedAction.Add: + control.OnItemTemplateChanged(); + break; - case NotifyCollectionChangedAction.Reset: - case NotifyCollectionChangedAction.Remove: - control.OnItemTemplateChanged(); - break; + case NotifyCollectionChangedAction.Reset: + case NotifyCollectionChangedAction.Remove: + control.OnItemTemplateChanged(); + break; } } } @@ -6242,21 +6252,21 @@ private void OnChildrenCollectionChanged(object sender, NotifyCollectionChangedE switch (e.Action) { - case NotifyCollectionChangedAction.Add: - foreach (SkiaControl newChildren in e.NewItems) - { - AddOrRemoveView(newChildren, true); - } - break; + case NotifyCollectionChangedAction.Add: + foreach (SkiaControl newChildren in e.NewItems) + { + AddOrRemoveView(newChildren, true); + } + break; - case NotifyCollectionChangedAction.Reset: - case NotifyCollectionChangedAction.Remove: - foreach (SkiaControl oldChildren in e.OldItems ?? Array.Empty()) - { - AddOrRemoveView(oldChildren, false); - } + case NotifyCollectionChangedAction.Reset: + case NotifyCollectionChangedAction.Remove: + foreach (SkiaControl oldChildren in e.OldItems ?? Array.Empty()) + { + AddOrRemoveView(oldChildren, false); + } - break; + break; } Update(); @@ -6278,54 +6288,54 @@ public static (float X, float Y) RescaleAspect(float width, float height, SKRect switch (stretch) { - case TransformAspect.None: - break; + case TransformAspect.None: + break; - case TransformAspect.Fit: - aspectX = dest.Width < width ? dest.Width / width : 1; - aspectY = dest.Height < height ? dest.Height / height : 1; - break; + case TransformAspect.Fit: + aspectX = dest.Width < width ? dest.Width / width : 1; + aspectY = dest.Height < height ? dest.Height / height : 1; + break; - case TransformAspect.Fill: - aspectX = width < dest.Width ? s1 : 1; - aspectY = height < dest.Height ? s2 : 1; - break; + case TransformAspect.Fill: + aspectX = width < dest.Width ? s1 : 1; + aspectY = height < dest.Height ? s2 : 1; + break; - case TransformAspect.AspectFit: - aspectX = Math.Min(s1, s2); - aspectY = aspectX; - break; + case TransformAspect.AspectFit: + aspectX = Math.Min(s1, s2); + aspectY = aspectX; + break; - case TransformAspect.AspectFill: - aspectX = width < dest.Width ? Math.Max(s1, s2) : 1; - aspectY = aspectX; - break; + case TransformAspect.AspectFill: + aspectX = width < dest.Width ? Math.Max(s1, s2) : 1; + aspectY = aspectX; + break; - case TransformAspect.Cover: - aspectX = s1; - aspectY = s2; - break; + case TransformAspect.Cover: + aspectX = s1; + aspectY = s2; + break; - case TransformAspect.AspectCover: - aspectX = Math.Max(s1, s2); - aspectY = aspectX; - break; + case TransformAspect.AspectCover: + aspectX = Math.Max(s1, s2); + aspectY = aspectX; + break; - case TransformAspect.AspectFitFill: - var imageAspect = width / height; - var viewportAspect = dest.Width / dest.Height; + case TransformAspect.AspectFitFill: + var imageAspect = width / height; + var viewportAspect = dest.Width / dest.Height; - if (imageAspect > viewportAspect) // Image is wider than viewport - { - aspectX = dest.Width / width; - aspectY = aspectX; - } - else // Image is taller than viewport - { - aspectY = dest.Height / height; - aspectX = aspectY; - } - break; + if (imageAspect > viewportAspect) // Image is wider than viewport + { + aspectX = dest.Width / width; + aspectY = aspectX; + } + else // Image is taller than viewport + { + aspectY = dest.Height / height; + aspectX = aspectY; + } + break; } return (aspectX, aspectY); diff --git a/src/Engine/Internals/Helpers/3D/Sk3dView.cs b/src/Engine/Internals/Helpers/3D/Sk3dView.cs index 42a378a6..02c03de3 100644 --- a/src/Engine/Internals/Helpers/3D/Sk3dView.cs +++ b/src/Engine/Internals/Helpers/3D/Sk3dView.cs @@ -1,13 +1,40 @@ -using Markdig.Extensions.Tables; -using Microsoft.Maui.Devices.Sensors; +namespace DrawnUi.Maui.Draw; + +/* + public void RotateXDegrees(float degrees) + { + var rotation = SKMatrix44.CreateRotationDegrees(1, 0, 0, degrees); + matrix44 = rotation.PreConcat(matrix44); + } + + public void RotateYDegrees(float degrees) + { + var rotation = SKMatrix44.CreateRotationDegrees(0, 1, 0, degrees); + matrix44 = rotation.PreConcat(matrix44); + } + + public void RotateZDegrees(float degrees) + { + var rotation = SKMatrix44.CreateRotationDegrees(0, 0, 1, degrees); + matrix44 = rotation.PreConcat(matrix44); + } + */ + using SkiaSharp; using System.Numerics; -using static Microsoft.Maui.ApplicationModel.Permissions; - -namespace DrawnUi.Maui.Draw; public class Sk3dView { + private Matrix4x4 matrix44; + private Vector3 cameraPosition; + private Vector3 cameraTarget; + private Vector3 cameraUp; + + private float cameraRotationX = 0; + private float cameraRotationY = 0; + private float cameraRotationZ = 0; + + private float cameraTranslationZ = 0; public Sk3dView() { @@ -16,113 +43,149 @@ public Sk3dView() public void Reset() { - fCamera = new(); - fRec = new(); - } - - const float inchesToPoints = 72.0f; - static readonly float SK_ScalarPI = (float)Math.PI; - - internal class Rec - { - public Rec() - { - fMatrix = SKMatrix44.Identity; - } - //disabled, do not need save/restore public - Rec fNext; - public SKMatrix44 fMatrix; - }; + matrix44 = Matrix4x4.Identity; + cameraRotationX = 0; + cameraRotationY = 0; + cameraRotationZ = 0; - internal Rec fRec; - internal SkCamera3D fCamera; - - public void SetCameraLocation(float x, float y, float z) - { - // the camera location is passed in inches, set in pt - float lz = z * inchesToPoints; - fCamera.fLocation = new(x * inchesToPoints, y * inchesToPoints, lz); - fCamera.fObserver = new(0, 0, lz); - fCamera.Update(); + // cameraPosition = new Vector3(0, 0, -1); + cameraTarget = new Vector3(0, 0, 0); + cameraUp = new Vector3(0, 1, 0); } - public float GetCameraLocationX() + public void RotateXDegrees(float degrees) { - return fCamera.fLocation.X / inchesToPoints; + cameraRotationX -= degrees / 360.0f; } - public float GetCameraLocationY() + public void RotateYDegrees(float degrees) { - return fCamera.fLocation.Y / inchesToPoints; + cameraRotationY += degrees / 360.0f; } - public float GetCameraLocationZ() + public void RotateZDegrees(float degrees) { - return fCamera.fLocation.X / inchesToPoints; + cameraRotationZ += degrees; } public void Translate(float x, float y, float z) { - var preTranslate = SKMatrix44.CreateTranslation(x, y, z); - fRec.fMatrix.PreConcat(preTranslate); //todo check if need use return value + cameraTranslationZ = z; + + //var translation = Matrix4x4.CreateTranslation(x, y, z); + // matrix44 = translation * matrix44; } - public void RotateX(float deg) + public SKMatrix GetMatrix() { - var preRotate = SKMatrix44.CreateRotation(1, 0, 0, deg * SK_ScalarPI / 180f); - fRec.fMatrix.PreConcat(preRotate); //todo check if need use return value + var viewMatrix = CreateViewMatrix(); + var projectionMatrix = CreateProjectionMatrix(); + var mvpMatrix = viewMatrix * projectionMatrix; - //fRec->fMatrix.preConcat(SkM44::Rotate({ 1, 0, 0}, deg* SK_ScalarPI / 180)); + return ConvertToSKMatrix(mvpMatrix); } - public void RotateY(float deg) + + private Matrix4x4 CreateViewMatrix() { - var preRotate = SKMatrix44.CreateRotation(0, -1, 0, deg * SK_ScalarPI / 180f); - fRec.fMatrix.PreConcat(preRotate); //todo check if need use return value - //fRec->fMatrix.preConcat(SkM44::Rotate({ 0,-1, 0}, deg* SK_ScalarPI / 180)); - } + // Apply camera rotations to the camera's orientation + var rotationX = Matrix4x4.CreateRotationX(SkiaControl.DegreesToRadians(cameraRotationX)); + var rotationY = Matrix4x4.CreateRotationY(SkiaControl.DegreesToRadians(cameraRotationY)); + var rotationZ = Matrix4x4.CreateRotationZ(SkiaControl.DegreesToRadians(cameraRotationZ)); - public void RotateZ(float deg) - { - var preRotate = SKMatrix44.CreateRotation(0, 0, 1, deg * SK_ScalarPI / 180f); - fRec.fMatrix.PreConcat(preRotate); //todo check if need use return value + // Combine rotations + var rotationMatrix = rotationY * rotationX * rotationZ; - //fRec->fMatrix.preConcat(SkM44::Rotate({ 0, 0, 1}, deg* SK_ScalarPI / 180)); - } + // Apply rotations to camera direction + var forward = Vector3.Transform(new Vector3(0, 0, -1), rotationMatrix); - public void RotateXDegrees(float deg) - { - var preRotate = SKMatrix44.CreateRotationDegrees(1, 0, 0, deg); - var check = fRec.fMatrix.PreConcat(preRotate); //todo check if need use return value - var test = check == fRec.fMatrix; + cameraPosition = new Vector3(0, 1 + cameraTranslationZ, 1); - } + // Update camera target + cameraTarget = cameraPosition + forward; - public void RotateYDegrees(float deg) - { - var preRotate = SKMatrix44.CreateRotationDegrees(0, -1, 0, deg); - fRec.fMatrix.PreConcat(preRotate); //todo check if need use return value - } + // Update cameraUp + cameraUp = Vector3.Transform(new Vector3(0, 1, 0), rotationMatrix); - public void RotateZDegrees(float deg) - { - var preRotate = SKMatrix44.CreateRotationDegrees(0, 0, 1, deg); - fRec.fMatrix.PreConcat(preRotate); //todo check if need use return value + // Create the view matrix + var viewMatrix = Matrix4x4.CreateLookAt(cameraPosition, cameraTarget, cameraUp); + + return viewMatrix; } - public float DotWithNormal(float x, float y, float z) + + private Matrix4x4 CreateProjectionMatrix() { - SkPatch3D patch = new(); - patch.Transform(fRec.fMatrix); - return patch.DotWith(x, y, z); + float fieldOfView = MathF.PI / 2; + float aspectRatio = 1.0f; + float nearPlane = 0.1f; + float farPlane = 1f; + + if (fieldOfView == 0 || float.IsInfinity(fieldOfView)) + { + fieldOfView = MathF.PI / 2; + } + + return Matrix4x4.CreatePerspectiveFieldOfView(fieldOfView, aspectRatio, nearPlane, farPlane); } - public SKMatrix GetMatrix() - { - SkPatch3D patch = new(); - patch.Transform(fRec.fMatrix); - return fCamera.PatchToMatrix(patch); + + private SKMatrix ConvertToSKMatrix(Matrix4x4 m) + { + //return new SKMatrix( + //m.M00, + //m.m10, + //m.m30, + //m.m01, + //m.m11, + //m.m31, + //m.m03, + //m.m13, + //m.m33); + + //-m.M11, + //-m.M21, + //-m.M41, + //m.M12, + //m.M22, + //m.M42, + //m.M14, + //m.M24, + //m.M44); + + // Extract the relevant elements for the 3x3 matrix + float m00 = m.M11; // ScaleX + float m01 = m.M21; // SkewX + float m02 = m.M41; // Translation X + float m10 = m.M21; // SkewY + float m11 = m.M22; // ScaleY + float m12 = m.M24; // Translation Y + float m20 = m.M41; // Perspective X + float m21 = m.M24; // Perspective Y + float m22 = m.M44; // Perspective W + + + // Create the SKMatrix + SKMatrix matrix = new SKMatrix + { + ScaleX = m00, + SkewX = m01, + TransX = m02, + SkewY = m10, + ScaleY = m11, + TransY = m12, + Persp0 = m20, + Persp1 = m21, + Persp2 = m22 + }; + + return matrix; } } + + + + diff --git a/src/Engine/Internals/Helpers/3D/SkCamera3D.cs b/src/Engine/Internals/Helpers/3D/SkCamera3D.cs index 5f692795..5185eccc 100644 --- a/src/Engine/Internals/Helpers/3D/SkCamera3D.cs +++ b/src/Engine/Internals/Helpers/3D/SkCamera3D.cs @@ -180,4 +180,95 @@ private float GetMatrixValue(SKMatrix matrix, int index) } } +public class SkCamera3D2 +{ + public Vector3 Position; // Camera position in world space + public Vector3 Forward; // Forward direction vector + public Vector3 Up; // Up direction vector + + private bool needToUpdate; + private SKMatrix44 viewMatrix; + + public SkCamera3D2() + { + Reset(); + } + + public void Reset() + { + Position = new Vector3(0, 0, -10); // Position the camera back along the Z-axis + Forward = new Vector3(0, 0, 1); // Looking towards positive Z + Up = new Vector3(0, 1, 0); // Up is positive Y + needToUpdate = true; + viewMatrix = SKMatrix44.CreateIdentity(); + } + + public void RotateXDegrees(float degrees) + { + Rotate(degrees, 0, 0); + } + + public void RotateYDegrees(float degrees) + { + Rotate(0, degrees, 0); + } + + public void RotateZDegrees(float degrees) + { + Rotate(0, 0, degrees); + } + + private void Rotate(float degreesX, float degreesY, float degreesZ) + { + // Convert degrees to radians + float radiansX = SkiaControl.DegreesToRadians(degreesX); + float radiansY = SkiaControl.DegreesToRadians(degreesY); + float radiansZ = SkiaControl.DegreesToRadians(degreesZ); + + // Create rotation quaternions + var rotationX = Quaternion.CreateFromAxisAngle(Vector3.UnitX, radiansX); + var rotationY = Quaternion.CreateFromAxisAngle(Vector3.UnitY, radiansY); + var rotationZ = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, radiansZ); + + // Combine rotations (order matters) + var combinedRotation = rotationZ * rotationY * rotationX; + + // Rotate the camera's forward and up vectors + Forward = Vector3.Transform(Forward, combinedRotation); + Up = Vector3.Transform(Up, combinedRotation); + + needToUpdate = true; + } + + public void Update() + { + if (needToUpdate) + { + DoUpdate(); + } + } + + private void DoUpdate() + { + // Calculate the view matrix using the camera's position, target, and up vector + Vector3 target = Position + Forward; + var viewMatrix4x4 = Matrix4x4.CreateLookAt(Position, target, Up); + + // Convert Matrix4x4 to SKMatrix44 + viewMatrix = new SKMatrix44( + viewMatrix4x4.M11, viewMatrix4x4.M12, viewMatrix4x4.M13, viewMatrix4x4.M14, + viewMatrix4x4.M21, viewMatrix4x4.M22, viewMatrix4x4.M23, viewMatrix4x4.M24, + viewMatrix4x4.M31, viewMatrix4x4.M32, viewMatrix4x4.M33, viewMatrix4x4.M34, + viewMatrix4x4.M41, viewMatrix4x4.M42, viewMatrix4x4.M43, viewMatrix4x4.M44); + + needToUpdate = false; + } + + public SKMatrix44 GetViewMatrix44() + { + Update(); + return viewMatrix; + } +} + diff --git a/src/Engine/Internals/Helpers/RestartingTimer.cs b/src/Engine/Internals/Helpers/RestartingTimer.cs index 0c62779d..8e9e210e 100644 --- a/src/Engine/Internals/Helpers/RestartingTimer.cs +++ b/src/Engine/Internals/Helpers/RestartingTimer.cs @@ -1,78 +1,78 @@ -using AppoMobi.Specials; - -namespace DrawnUi.Maui.Models; +namespace DrawnUi.Maui.Models; public class RestartingTimer //where T:class { - public bool IsRunning { get; protected set; } - - public T Context { get; protected set; } - public void Kick(T param) - { - if (IsRunning) - { - Restart(param); - } - else - { - Start(param); - } - } - - private readonly TimeSpan timespan; - - private readonly Action callback; - - private CancellationTokenSource cancellation; - - public RestartingTimer(uint ms, Action callback) - { - this.timespan = TimeSpan.FromMilliseconds(ms); - this.callback = callback; - this.cancellation = new CancellationTokenSource(); - } - public RestartingTimer(TimeSpan timespan, Action callback) - { - this.timespan = timespan; - this.callback = callback; - this.cancellation = new CancellationTokenSource(); - } - - - - public void Restart(T param) - { - Stop(); - Start(param); - } - - public void Start(T param) - { - IsRunning = true; - Context = param; - - CancellationTokenSource cts = this.cancellation; // safe copy - Tasks.StartDelayed(this.timespan, cts.Token, async () => - { - if (cts.IsCancellationRequested) return; - this.callback.Invoke(param); - IsRunning = false; - }); - } - - public void Stop() - { - Interlocked.Exchange(ref this.cancellation, new CancellationTokenSource()).Cancel(); - } - - protected bool disposed; - public void Dispose() - { - if (disposed) - return; - disposed = true; - - - } + public bool IsRunning { get; protected set; } + + public T Context { get; protected set; } + public void Kick(T param) + { + if (IsRunning) + { + Restart(param); + } + else + { + Start(param); + } + } + + private readonly TimeSpan timespan; + + private readonly Action callback; + + private CancellationTokenSource cancellation; + + public RestartingTimer(uint ms, Action callback) + { + this.timespan = TimeSpan.FromMilliseconds(ms); + this.callback = callback; + this.cancellation = new CancellationTokenSource(); + } + public RestartingTimer(TimeSpan timespan, Action callback) + { + this.timespan = timespan; + this.callback = callback; + this.cancellation = new CancellationTokenSource(); + } + + + + public void Restart(T param) + { + Stop(); + Start(param); + } + + public void Start(T param) + { + IsRunning = true; + Context = param; + + CancellationTokenSource cts = this.cancellation; // safe copy + Tasks.StartDelayed(this.timespan, cts.Token, async () => + { + if (cts.IsCancellationRequested) return; + this.callback.Invoke(param); + Stop(); + cts.Cancel(); + IsRunning = false; + }); + } + + public void Stop() + { + Interlocked.Exchange(ref this.cancellation, new CancellationTokenSource()).Cancel(); + } + + protected bool disposed; + public void Dispose() + { + if (disposed) + return; + disposed = true; + + + } } \ No newline at end of file diff --git a/src/Engine/skia2.props b/src/Engine/skia2.props index 4edee202..e51fcbc5 100644 --- a/src/Engine/skia2.props +++ b/src/Engine/skia2.props @@ -1,8 +1,9 @@ - - + + + \ No newline at end of file diff --git a/src/samples/Sandbox/AppShell.xaml b/src/samples/Sandbox/AppShell.xaml index ecc50461..3003387c 100644 --- a/src/samples/Sandbox/AppShell.xaml +++ b/src/samples/Sandbox/AppShell.xaml @@ -9,7 +9,7 @@ diff --git a/src/samples/Sandbox/Platforms/Windows/Package.appxmanifest b/src/samples/Sandbox/Platforms/Windows/Package.appxmanifest index 2320d0e1..890c3585 100644 --- a/src/samples/Sandbox/Platforms/Windows/Package.appxmanifest +++ b/src/samples/Sandbox/Platforms/Windows/Package.appxmanifest @@ -17,8 +17,8 @@ - - + + diff --git a/src/samples/Sandbox/Sandbox.csproj b/src/samples/Sandbox/Sandbox.csproj index cc9c0851..c98d16f5 100644 --- a/src/samples/Sandbox/Sandbox.csproj +++ b/src/samples/Sandbox/Sandbox.csproj @@ -2,8 +2,7 @@ net8.0-android;net8.0-ios;net8.0-maccatalyst - $(TargetFrameworks);net8.0-windows10.0.19041.0 - Exe + $(TargetFrameworks);net8.0-windows10.0.19041.0 Exe Sandbox true true @@ -23,8 +22,8 @@ 11.0 13.1 21.0 - 10.0.17763.0 - 10.0.17763.0 + 10.0.19041.0 + 10.0.19041.0