Почему при перетаскивании объекта, он перетаскивается не конкретно с курсором, а слегка обтекая его (попытался отобразить на скриншотах ниже)?
На скриншотах, по порядку:
1. Начинаю тянуть за центр объекта
2. Если оттягиваю мышь влево
3. Если оттягиваю мышь вверх
Вправо и вниз, соответственно, ситуация та же.
Ниже приведу фрагменты своего кода.
Объект будто опаздывает за курсором.
Метод при перемещении мыши:
private void MainWindow_MouseMove(object sender, MouseMoveEventArgs e)
{
if (e.Mouse.LeftButton == ButtonState.Pressed)
{
if (CardManager.SelectedCard != null)
{
Ray.Create(e.X, e.Y, camera);
Vector3 prePos = CardManager.SelectedCard.IntersectionPoint;
float planeDist = camera.Position.Z - prePos.Z;
Vector3 curPos = -Ray.Direction * (planeDist / Ray.Direction.Z) + camera.Position;
CardManager.SelectedCard.IntersectionPoint = curPos;
curPos = curPos - prePos;
CardManager.SelectedCard.object3d.translationMatrix *= Matrix4.CreateTranslation(curPos);
}
}
}
Как я получаю IntersectionPoint из этой строки:
Vector3 prePos = CardManager.SelectedCard.IntersectionPoint;
В этом методе:
public bool RayIntersect(Vector3 rayStart, Vector3 rayDir, Camera camera)
{
Vector3 cmin = Vector3.TransformPosition(object3d.objectMin, object3d.Object3DMatrix);
Vector3 cmax = Vector3.TransformPosition(object3d.objectMax, object3d.Object3DMatrix);
Vector3 rs = rayStart;
Vector3 rd = rayDir;
Vector3 diff0 = cmin - rs;
Vector3 diff1 = cmax - rs;
Vector3 t0 = new Vector3(diff0.X / rd.X, diff0.Y / rd.Y, diff0.Z / rd.Z);
Vector3 t1 = new Vector3(diff1.X / rd.X, diff1.Y / rd.Y, diff1.Z / rd.Z);
Vector3 tMin = new Vector3(Math.Min(t0.X, t1.X), Math.Min(t0.Y, t1.Y), Math.Min(t0.Z, t1.Z));
Vector3 tMax = new Vector3(Math.Max(t0.X, t1.X), Math.Max(t0.Y, t1.Y), Math.Max(t0.Z, t1.Z));
float tnear = Math.Max(Math.Max(tMin.X, tMin.Y), tMin.Z);
float tfar = Math.Min(Math.Min(tMax.X, tMax.Y), tMax.Z);
if (tnear <= tfar)
{
IntersectionPoint = rd * tnear + camera.Position;
return true;
}
return false;
}
Класс Ray:
public static class Ray
{
public static Vector3 Start = Vector3.Zero;
public static Vector3 End = Vector3.Zero;
public static Vector3 Direction = Vector3.Zero;
public static void Create(int mouse_x, int mouse_y, Camera camera)
{
int[] viewport = new int[4];
GL.GetInteger(GetPName.Viewport, viewport);
Start = new Vector3(mouse_x, mouse_y, 0.0f).UnProject(camera, new Size(viewport[2], viewport[3]));
End = new Vector3(mouse_x, mouse_y, 1.0f).UnProject(camera, new Size(viewport[2], viewport[3]));
Direction = End - Start;
Direction.Normalize();
}
}
И метод UnProject:
public static Vector3 UnProject(this Vector3 mouse, Camera camera, Size viewport)
{
Vector4 vec;
vec.X = 2.0f * mouse.X / viewport.Width - 1;
vec.Y = -(2.0f * mouse.Y / viewport.Height - 1);
vec.Z = mouse.Z;
vec.W = 1.0f;
Matrix4 projInv = Matrix4.Invert(camera.ProjectionPerspectiveMatrix);
Matrix4 viewInv = Matrix4.Invert(camera.ViewMatrix);
Vector4.Transform(ref vec, ref projInv, out vec);
Vector4.Transform(ref vec, ref viewInv, out vec);
if (vec.W > 0.000001f || vec.W < -0.000001f)
{
vec.X /= vec.W;
vec.Y /= vec.W;
vec.Z /= vec.W;
}
return vec.Xyz;
}
Проблема была в неверном способе нахождения точки пересечения луча и объекта (IntersectionPoint) в методе RayIntersect.
Нужно заменить
IntersectionPoint = rd * tnear + camera.Position;
на
IntersectionPoint = rd * tnear + rs;
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Виртуальный выделенный сервер (VDS) становится отличным выбором
Как повернуть объект по направлению к другому через transformRotate только по оси у?
Есть некоторый сервис, который дёргает два репозитория (первый - к сущности Order, второй - к сущности OrderPosition) и возвращает уже собранный заказ...
Задача: повредить файл, для обеспечения невозможности его чтения(И удачного восстановления если его удалить программным способом, на той...
Делаю попытку обнаружения устройств с помощью Bluetooth LE, сделал как написано в этой библиотеке для Xamarin, однако обнаруженных устройств 0