|
|
@ -1,29 +1,23 @@ |
|
|
|
using System.Collections.Frozen; |
|
|
|
|
|
|
|
using System.Collections.ObjectModel; |
|
|
|
using System.Collections.ObjectModel; |
|
|
|
using System.Diagnostics; |
|
|
|
|
|
|
|
using System.Drawing.Text; |
|
|
|
|
|
|
|
using System.IO; |
|
|
|
using System.IO; |
|
|
|
using System.Text.Json.Nodes; |
|
|
|
|
|
|
|
using System.Windows; |
|
|
|
using System.Windows; |
|
|
|
using System.Windows.Media; |
|
|
|
using System.Windows.Media; |
|
|
|
using System.Windows.Media.Animation; |
|
|
|
using System.Windows.Media.Animation; |
|
|
|
using System.Windows.Media.Imaging; |
|
|
|
using System.Windows.Media.Imaging; |
|
|
|
using System.Windows.Media.Media3D; |
|
|
|
using System.Windows.Media.Media3D; |
|
|
|
using System.Windows.Threading; |
|
|
|
|
|
|
|
using HandyControl.Controls; |
|
|
|
|
|
|
|
using HelixToolkit.Wpf.SharpDX; |
|
|
|
using HelixToolkit.Wpf.SharpDX; |
|
|
|
using log4net; |
|
|
|
using log4net; |
|
|
|
using NPOI.OpenXmlFormats.Vml.Office; |
|
|
|
|
|
|
|
using SharpDX; |
|
|
|
using SharpDX; |
|
|
|
using SharpDX.Direct3D11; |
|
|
|
using SharpDX.Direct3D11; |
|
|
|
using SharpDX.DXGI; |
|
|
|
|
|
|
|
using SparkClient.Views.UserControl.ViewportData.Enum; |
|
|
|
using SparkClient.Views.UserControl.ViewportData.Enum; |
|
|
|
using SparkClient.Views.UserControl.ViewportData.Entity; |
|
|
|
using SparkClient.Views.UserControl.ViewportData.Entity; |
|
|
|
using Color = SharpDX.Color; |
|
|
|
using Color = SharpDX.Color; |
|
|
|
using GeometryModel3D = HelixToolkit.Wpf.SharpDX.GeometryModel3D; |
|
|
|
using GeometryModel3D = HelixToolkit.Wpf.SharpDX.GeometryModel3D; |
|
|
|
using NPOI.SS.Formula.Functions; |
|
|
|
|
|
|
|
using MeshGeometry3D = HelixToolkit.Wpf.SharpDX.MeshGeometry3D; |
|
|
|
using MeshGeometry3D = HelixToolkit.Wpf.SharpDX.MeshGeometry3D; |
|
|
|
using NPOI.SS.UserModel; |
|
|
|
using Point = System.Windows.Point; |
|
|
|
|
|
|
|
using PerspectiveCamera = HelixToolkit.Wpf.SharpDX.PerspectiveCamera; |
|
|
|
|
|
|
|
using System.Windows.Controls; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace SparkClient.Views.UserControl.ViewportData.Helper; |
|
|
|
namespace SparkClient.Views.UserControl.ViewportData.Helper; |
|
|
|
|
|
|
|
|
|
|
@ -1331,7 +1325,8 @@ public class ViewportHelperPro |
|
|
|
return lines; |
|
|
|
return lines; |
|
|
|
} |
|
|
|
} |
|
|
|
private static bool isDrawing = false; |
|
|
|
private static bool isDrawing = false; |
|
|
|
private static Vector3 startpoint; |
|
|
|
private static Point3D previousMousePosition; |
|
|
|
|
|
|
|
private static Vector3D _totalTranslation = new Vector3D(0, 0, 0); |
|
|
|
private static void LineA_MouseMove3D(object sender, RoutedEventArgs e) |
|
|
|
private static void LineA_MouseMove3D(object sender, RoutedEventArgs e) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (isDrawing) |
|
|
|
if (isDrawing) |
|
|
@ -1339,15 +1334,40 @@ public class ViewportHelperPro |
|
|
|
if (e is HelixToolkit.Wpf.SharpDX.MouseMove3DEventArgs ev) |
|
|
|
if (e is HelixToolkit.Wpf.SharpDX.MouseMove3DEventArgs ev) |
|
|
|
{ |
|
|
|
{ |
|
|
|
var line = sender as LineGeometryModel3D; |
|
|
|
var line = sender as LineGeometryModel3D; |
|
|
|
var newPoint = ev.HitTestResult.PointHit; |
|
|
|
var mousePosition = ev.Position; |
|
|
|
var moveDirection = newPoint - startpoint; |
|
|
|
var hitResult = ev.Viewport.FindNearestPoint(mousePosition); |
|
|
|
|
|
|
|
if (hitResult == null) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
var lineDirection = line.Geometry.Positions[1] - line.Geometry.Positions[0]; |
|
|
|
var lineDirection = line.Geometry.Positions[1] - line.Geometry.Positions[0]; |
|
|
|
|
|
|
|
lineDirection.Normalize(); |
|
|
|
|
|
|
|
|
|
|
|
var perpendicularDirection = Vector3.Cross(lineDirection, Vector3.Cross(moveDirection, lineDirection)); |
|
|
|
Vector3D referenceVector = new Vector3D(0, 1, 0); |
|
|
|
|
|
|
|
Vector3D perpendicularDirection = Vector3D.CrossProduct(lineDirection.ToVector3D(), referenceVector); |
|
|
|
perpendicularDirection.Normalize(); |
|
|
|
perpendicularDirection.Normalize(); |
|
|
|
|
|
|
|
|
|
|
|
line.Geometry.Positions[0] += perpendicularDirection * Vector3.Dot(moveDirection, perpendicularDirection); |
|
|
|
var currentMousePosition = Get3DPointFromMouse(mousePosition, ev.Viewport); |
|
|
|
line.Geometry.Positions[1] += perpendicularDirection * Vector3.Dot(moveDirection, perpendicularDirection); |
|
|
|
//// 计算垂直于线的移动分量 |
|
|
|
|
|
|
|
//var perpendicularDirection = Vector3.Cross(lineDirection, Vector3.Cross(moveDirection,lineDirection)); |
|
|
|
|
|
|
|
//perpendicularDirection.Normalize(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var point = hitResult.Value; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var dragVector = point - ev.HitTestResult.PointHit.ToPoint3D(); |
|
|
|
|
|
|
|
double dotProduct = Vector3D.DotProduct(dragVector, perpendicularDirection); |
|
|
|
|
|
|
|
Vector3D projectedVector = dotProduct * perpendicularDirection; |
|
|
|
|
|
|
|
projectedVector.Y = 0; |
|
|
|
|
|
|
|
//// 计算垂直距离 |
|
|
|
|
|
|
|
//float perpendicularDistance = Vector3.Dot(moveDirection, perpendicularDirection); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//line.Geometry.Positions[0] += perpendicularDirection * perpendicularDistance; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//line.Geometry.Positions[1] += perpendicularDirection * perpendicularDistance; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_totalTranslation += projectedVector; |
|
|
|
|
|
|
|
var transform = new TranslateTransform3D(projectedVector); |
|
|
|
|
|
|
|
line.Transform = transform; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -1361,10 +1381,36 @@ public class ViewportHelperPro |
|
|
|
{ |
|
|
|
{ |
|
|
|
isDrawing = true; |
|
|
|
isDrawing = true; |
|
|
|
if(e is HelixToolkit.Wpf.SharpDX.MouseDown3DEventArgs ev){ |
|
|
|
if(e is HelixToolkit.Wpf.SharpDX.MouseDown3DEventArgs ev){ |
|
|
|
startpoint = ev.HitTestResult.PointHit; |
|
|
|
// 获取鼠标点击的位置 |
|
|
|
|
|
|
|
var mousePosition = ev.Position; |
|
|
|
|
|
|
|
var a = ev.Viewport; |
|
|
|
|
|
|
|
previousMousePosition = Get3DPointFromMouse(mousePosition, a); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var line = sender as LineGeometryModel3D; |
|
|
|
|
|
|
|
//var transform = new TranslateTransform3D(10, 0, 10); |
|
|
|
|
|
|
|
//line.Transform = transform; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private static Point3D Get3DPointFromMouse(Point mousePosition, Viewport3DX Viewport) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// 将2D屏幕坐标转换为3D世界坐标 |
|
|
|
|
|
|
|
var ray = GetRayFromMouse(mousePosition, Viewport); |
|
|
|
|
|
|
|
var plane = new Plane3D(new Point3D(0, 0, 0), new Vector3D(0, 0, 1)); // 假设平面为Z=0 |
|
|
|
|
|
|
|
var intersection = plane.IntersectWith(ray); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return intersection ?? new Point3D(0, 0, 0); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static Ray3D GetRayFromMouse(Point mousePosition, Viewport3DX Viewport) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// 获取从相机发出的射线 |
|
|
|
|
|
|
|
var camera = Viewport.Camera as PerspectiveCamera; |
|
|
|
|
|
|
|
var rayDirection = new Vector3D(mousePosition.X - Viewport.ActualWidth / 2, -(mousePosition.Y - Viewport.ActualHeight / 2), -camera.Position.Z); |
|
|
|
|
|
|
|
rayDirection.Normalize(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return new Ray3D(camera.Position, rayDirection); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static LineGeometryModel3D ShowCircleLine(double radius = 1.0, double thickness = 1.0) |
|
|
|
public static LineGeometryModel3D ShowCircleLine(double radius = 1.0, double thickness = 1.0) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -1652,3 +1698,38 @@ public class ViewportHelperPro |
|
|
|
#endregion |
|
|
|
#endregion |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 辅助类:表示3D射线 |
|
|
|
|
|
|
|
public class Ray3D |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
public Point3D Origin { get; } |
|
|
|
|
|
|
|
public Vector3D Direction { get; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Ray3D(Point3D origin, Vector3D direction) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Origin = origin; |
|
|
|
|
|
|
|
Direction = direction; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 辅助类:表示3D平面 |
|
|
|
|
|
|
|
public class Plane3D |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
public Point3D Point { get; } |
|
|
|
|
|
|
|
public Vector3D Normal { get; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Plane3D(Point3D point, Vector3D normal) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Point = point; |
|
|
|
|
|
|
|
Normal = normal; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Point3D? IntersectWith(Ray3D ray) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
var denominator = Vector3D.DotProduct(ray.Direction, Normal); |
|
|
|
|
|
|
|
if (Math.Abs(denominator) < 1e-6) return null; // 平行,无交点 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var t = Vector3D.DotProduct(Point - ray.Origin, Normal) / denominator; |
|
|
|
|
|
|
|
return ray.Origin + t * ray.Direction; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |