744 lines
26 KiB
C#
744 lines
26 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using global::System.Windows.Forms;
|
|
using global::OpenTK;
|
|
|
|
namespace Pilz.Drawing.Drawing3D.OpenGLFactory.CameraN
|
|
{
|
|
public class Camera
|
|
{
|
|
public event NeedSelectedObjectEventHandler NeedSelectedObject;
|
|
|
|
public delegate void NeedSelectedObjectEventHandler(object sender, NeedSelectedObjectEventArgs e);
|
|
|
|
public event PerspectiveChangedEventHandler PerspectiveChanged;
|
|
|
|
public delegate void PerspectiveChangedEventHandler(object sender, EventArgs e);
|
|
|
|
// P R I V A T E F I E L D S
|
|
|
|
private readonly float TAU = (float)(Math.PI * 2d);
|
|
private CameraMode myCamMode = CameraMode.FLY;
|
|
private Vector3 pos = new Vector3(-5000.0f, 3000.0f, 4000.0f);
|
|
private Vector3 myLookat = new Vector3(0f, 0f, 0f);
|
|
private Vector3 myFarPoint = new Vector3(0f, 0f, 0f);
|
|
private Vector3 myNearPoint = new Vector3(0f, 0f, 0f);
|
|
private int lastMouseX = -1;
|
|
private int lastMouseY = -1;
|
|
private float CamAngleX = 0f;
|
|
private float CamAngleY = (float)-(Math.PI / 2d);
|
|
private bool resetMouse = true;
|
|
private float orbitDistance = 500.0f;
|
|
private float orbitTheta = 0.0f;
|
|
private float orbitPhi = 0.0f;
|
|
private LookDirection currentLookDirection;
|
|
private Vector3[] lookPositions = new Vector3[] { new Vector3(0f, 12500f, 0f), new Vector3(0f, -12500, 0f), new Vector3(-12500, 0f, 0f), new Vector3(12500f, 0f, 0f), new Vector3(0f, 0f, 12500f), new Vector3(0f, 0f, -12500) };
|
|
|
|
// A U T O M A T I C P R O P E R T I E S
|
|
|
|
public float CamSpeedMultiplier { get; set; } = 1f;
|
|
|
|
// P R O P E R T I E S
|
|
|
|
public CameraMode CamMode
|
|
{
|
|
get
|
|
{
|
|
return myCamMode;
|
|
}
|
|
}
|
|
|
|
public float Yaw
|
|
{
|
|
get
|
|
{
|
|
return CamAngleX;
|
|
}
|
|
}
|
|
|
|
public float Pitch
|
|
{
|
|
get
|
|
{
|
|
return CamAngleY;
|
|
}
|
|
}
|
|
|
|
public float Yaw_Degrees
|
|
{
|
|
get
|
|
{
|
|
return CamAngleX * (180.0f / 3.14159274f);
|
|
}
|
|
}
|
|
|
|
public float Pitch_Degrees
|
|
{
|
|
get
|
|
{
|
|
return CamAngleY * (180.0f / 3.14159274f);
|
|
}
|
|
}
|
|
|
|
public Vector3 Position
|
|
{
|
|
get
|
|
{
|
|
return pos;
|
|
}
|
|
|
|
set
|
|
{
|
|
pos = value;
|
|
}
|
|
}
|
|
|
|
public Vector3 LookAt
|
|
{
|
|
get
|
|
{
|
|
return myLookat;
|
|
}
|
|
|
|
set
|
|
{
|
|
myLookat = value;
|
|
}
|
|
}
|
|
|
|
public Vector3 NearPoint
|
|
{
|
|
get
|
|
{
|
|
return myNearPoint;
|
|
}
|
|
|
|
set
|
|
{
|
|
myNearPoint = value;
|
|
}
|
|
}
|
|
|
|
public Vector3 FarPoint
|
|
{
|
|
get
|
|
{
|
|
return myFarPoint;
|
|
}
|
|
|
|
set
|
|
{
|
|
myFarPoint = value;
|
|
}
|
|
}
|
|
|
|
// C O N S T R U C T O R
|
|
|
|
public Camera()
|
|
{
|
|
SetRotationFromLookAt();
|
|
}
|
|
|
|
// F E A T U R E S
|
|
|
|
private float Clampf(float value, float min, float max)
|
|
{
|
|
return value > max ? max : value < min ? min : value;
|
|
}
|
|
|
|
private void OrientateCam(float ang, float ang2)
|
|
{
|
|
float CamLX = (float)Math.Sin(ang) * (float)Math.Sin(-ang2);
|
|
float CamLY = (float)Math.Cos(ang2);
|
|
float CamLZ = (float)-Math.Cos(ang) * (float)Math.Sin(-ang2);
|
|
myLookat.X = pos.X + -CamLX * 100.0f;
|
|
myLookat.Y = pos.Y + -CamLY * 100.0f;
|
|
myLookat.Z = pos.Z + -CamLZ * 100.0f;
|
|
}
|
|
|
|
private void OffsetCam(int xAmt, int yAmt, int zAmt)
|
|
{
|
|
double pitch_Renamed = CamAngleY - Math.PI / 2d;
|
|
float CamLX = (float)Math.Sin(CamAngleX) * (float)Math.Cos(-pitch_Renamed);
|
|
float CamLY = (float)Math.Sin(pitch_Renamed);
|
|
float CamLZ = (float)-Math.Cos(CamAngleX) * (float)Math.Cos(-pitch_Renamed);
|
|
pos.X = pos.X + xAmt * CamLX * CamSpeedMultiplier;
|
|
pos.Y = pos.Y + yAmt * CamLY * CamSpeedMultiplier;
|
|
pos.Z = pos.Z + zAmt * CamLZ * CamSpeedMultiplier;
|
|
}
|
|
|
|
public void Move(float y, ref Matrix4 camMtx)
|
|
{
|
|
OffsetCam(0, (int)y, 0);
|
|
OrientateCam(CamAngleX, CamAngleY);
|
|
UpdateMatrix(ref camMtx);
|
|
}
|
|
|
|
public void Move(float x, float z, ref Matrix4 camMtx)
|
|
{
|
|
UpdateCameraOffsetDirectly((int)x, (int)z, ref camMtx);
|
|
OrientateCam(CamAngleX, CamAngleY);
|
|
UpdateMatrix(ref camMtx);
|
|
}
|
|
|
|
public void SetRotationFromLookAt()
|
|
{
|
|
float x_diff = myLookat.X - pos.X;
|
|
float y_diff = myLookat.Y - pos.Y;
|
|
float z_diff = myLookat.Z - pos.Z;
|
|
float dist = (float)Math.Sqrt(x_diff * x_diff + y_diff * y_diff + z_diff * z_diff);
|
|
if (z_diff == 0f)
|
|
{
|
|
z_diff = 0.001f;
|
|
}
|
|
|
|
float nxz_ratio = -x_diff / z_diff;
|
|
if (z_diff < 0f)
|
|
{
|
|
CamAngleX = (float)(Math.Atan(nxz_ratio) + Math.PI);
|
|
}
|
|
else
|
|
{
|
|
CamAngleX = (float)Math.Atan(nxz_ratio);
|
|
}
|
|
|
|
CamAngleY = -3.1459f - ((float)Math.Asin(y_diff / dist) - 1.57f);
|
|
}
|
|
|
|
public void ResetOrbitToSelectedObject()
|
|
{
|
|
var objs = GetSelectedObject();
|
|
if (objs?.Length > 0 == true)
|
|
{
|
|
orbitTheta = -(CalculateCenterYRotationOfObjects(objs) * ((float)Math.PI / 180.0f));
|
|
orbitPhi = -0.3f;
|
|
orbitDistance = 1200.0f;
|
|
}
|
|
}
|
|
|
|
public void UpdateOrbitCamera(ref Matrix4 cameraMatrix)
|
|
{
|
|
if (myCamMode == CameraMode.ORBIT)
|
|
{
|
|
var objs = GetSelectedObject();
|
|
if (objs?.Length > 0 == true)
|
|
{
|
|
var centerPos = CalculateCenterPositionOfObjects(objs);
|
|
pos.X = centerPos.X + (float)(Math.Cos(orbitPhi) * -Math.Sin(orbitTheta) * orbitDistance);
|
|
pos.Y = centerPos.Y + (float)(-Math.Sin(orbitPhi) * orbitDistance);
|
|
pos.Z = centerPos.Z + (float)(Math.Cos(orbitPhi) * Math.Cos(orbitTheta) * orbitDistance);
|
|
myLookat.X = centerPos.X;
|
|
myLookat.Y = centerPos.Y;
|
|
myLookat.Z = centerPos.Z;
|
|
UpdateMatrix(ref cameraMatrix);
|
|
SetRotationFromLookAt();
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool IsOrbitCamera()
|
|
{
|
|
return myCamMode == CameraMode.ORBIT;
|
|
}
|
|
|
|
public void SetCameraMode(CameraMode mode, ref Matrix4 cameraMatrix)
|
|
{
|
|
myCamMode = mode;
|
|
if (IsOrbitCamera())
|
|
{
|
|
ResetOrbitToSelectedObject();
|
|
UpdateOrbitCamera(ref cameraMatrix);
|
|
}
|
|
}
|
|
|
|
public void SetCameraMode_LookDirection(LookDirection dir, ref Matrix4 cameraMatrix)
|
|
{
|
|
myCamMode = CameraMode.LOOK_DIRECTION;
|
|
currentLookDirection = dir;
|
|
switch (currentLookDirection)
|
|
{
|
|
case LookDirection.Top:
|
|
{
|
|
pos = lookPositions[(int)LookDirection.Top];
|
|
myLookat = new Vector3(pos.X, -25000, pos.Z - 1f);
|
|
UpdateMatrix(ref cameraMatrix);
|
|
SetRotationFromLookAt();
|
|
break;
|
|
}
|
|
|
|
case LookDirection.Bottom:
|
|
{
|
|
pos = lookPositions[(int)LookDirection.Bottom];
|
|
myLookat = new Vector3(pos.X, 25000f, pos.Z + 1f);
|
|
UpdateMatrix(ref cameraMatrix);
|
|
SetRotationFromLookAt();
|
|
break;
|
|
}
|
|
|
|
case LookDirection.Left:
|
|
{
|
|
pos = lookPositions[(int)LookDirection.Left];
|
|
myLookat = new Vector3(25000f, pos.Y, pos.Z);
|
|
UpdateMatrix(ref cameraMatrix);
|
|
SetRotationFromLookAt();
|
|
break;
|
|
}
|
|
|
|
case LookDirection.Right:
|
|
{
|
|
pos = lookPositions[(int)LookDirection.Right];
|
|
myLookat = new Vector3(-25000, pos.Y, pos.Z);
|
|
UpdateMatrix(ref cameraMatrix);
|
|
SetRotationFromLookAt();
|
|
break;
|
|
}
|
|
|
|
case LookDirection.Front:
|
|
{
|
|
pos = lookPositions[(int)LookDirection.Front];
|
|
myLookat = new Vector3(pos.X, pos.Y, -25000);
|
|
UpdateMatrix(ref cameraMatrix);
|
|
SetRotationFromLookAt();
|
|
break;
|
|
}
|
|
|
|
case LookDirection.Back:
|
|
{
|
|
pos = lookPositions[(int)LookDirection.Back];
|
|
myLookat = new Vector3(pos.X, pos.Y, 25000f);
|
|
UpdateMatrix(ref cameraMatrix);
|
|
SetRotationFromLookAt();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void UpdateCameraMatrixWithMouse(int mouseX, int mouseY, ref Matrix4 cameraMatrix)
|
|
{
|
|
if (myCamMode == CameraMode.ORBIT && GetSelectedObject() is object)
|
|
{
|
|
UpdateCameraMatrixWithMouse_ORBIT(mouseX, mouseY, ref cameraMatrix);
|
|
}
|
|
else if (myCamMode == CameraMode.LOOK_DIRECTION)
|
|
{
|
|
UpdateCameraMatrixWithMouse_LOOK(pos, mouseX, mouseY, ref cameraMatrix);
|
|
}
|
|
else
|
|
{
|
|
UpdateCameraMatrixWithMouse_FLY(mouseX, mouseY, ref cameraMatrix);
|
|
}
|
|
}
|
|
|
|
public void UpdateCameraOffsetWithMouse(Vector3 orgPos, int mouseX, int mouseY, int w, int h, ref Matrix4 cameraMatrix)
|
|
{
|
|
if (myCamMode == CameraMode.ORBIT && GetSelectedObject() is object)
|
|
{
|
|
UpdateCameraOffsetWithMouse_ORBIT(mouseX, mouseY, ref cameraMatrix);
|
|
}
|
|
else if (myCamMode == CameraMode.LOOK_DIRECTION)
|
|
{
|
|
UpdateCameraMatrixWithMouse_LOOK(pos, mouseX, mouseY, ref cameraMatrix);
|
|
}
|
|
else
|
|
{
|
|
UpdateCameraOffsetWithMouse_FLY(orgPos, mouseX, mouseY, w, h, ref cameraMatrix);
|
|
}
|
|
}
|
|
|
|
public void UpdateCameraMatrixWithScrollWheel(int amt, ref Matrix4 cameraMatrix)
|
|
{
|
|
if (myCamMode == CameraMode.ORBIT && GetSelectedObject() is object)
|
|
{
|
|
UpdateCameraMatrixWithScrollWheel_ORBIT(amt, ref cameraMatrix);
|
|
}
|
|
else if (myCamMode == CameraMode.LOOK_DIRECTION)
|
|
{
|
|
UpdateCameraMatrixWithScrollWheel_LOOK(amt, ref cameraMatrix);
|
|
}
|
|
else
|
|
{
|
|
UpdateCameraMatrixWithScrollWheel_FLY(amt, ref cameraMatrix);
|
|
}
|
|
}
|
|
|
|
private void UpdateCameraMatrixWithScrollWheel_FLY(int amt, ref Matrix4 cameraMatrix)
|
|
{
|
|
OffsetCam(amt, amt, amt);
|
|
OrientateCam(CamAngleX, CamAngleY);
|
|
UpdateMatrix(ref cameraMatrix);
|
|
}
|
|
|
|
public void RaisePerspectiveChanged()
|
|
{
|
|
PerspectiveChanged?.Invoke(this, new EventArgs());
|
|
}
|
|
|
|
public void UpdateMatrix(ref Matrix4 cameraMatrix)
|
|
{
|
|
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, myLookat.X, myLookat.Y, myLookat.Z, 0f, 1f, 0f);
|
|
RaisePerspectiveChanged();
|
|
}
|
|
|
|
private void UpdateCameraMatrixWithScrollWheel_LOOK(int amt, ref Matrix4 cameraMatrix)
|
|
{
|
|
OffsetCam(amt, amt, amt);
|
|
OrientateCam(CamAngleX, CamAngleY);
|
|
switch (currentLookDirection)
|
|
{
|
|
case LookDirection.Top:
|
|
{
|
|
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, myLookat.X, myLookat.Y, myLookat.Z - 1f, 0f, 1f, 0f);
|
|
RaisePerspectiveChanged();
|
|
break;
|
|
}
|
|
|
|
case LookDirection.Bottom:
|
|
{
|
|
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, myLookat.X, myLookat.Y, myLookat.Z + 1f, 0f, 1f, 0f);
|
|
RaisePerspectiveChanged();
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
UpdateMatrix(ref cameraMatrix);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void UpdateCameraMatrixWithMouse_LOOK(Vector3 orgPos, int mouseX, int mouseY, ref Matrix4 cameraMatrix)
|
|
{
|
|
if (resetMouse)
|
|
{
|
|
lastMouseX = mouseX;
|
|
lastMouseY = mouseY;
|
|
resetMouse = false;
|
|
}
|
|
|
|
int MousePosX = mouseX - lastMouseX;
|
|
int MousePosY = mouseY - lastMouseY;
|
|
double pitch_Renamed = CamAngleY - Math.PI / 2d;
|
|
double yaw_Renamed = CamAngleX - Math.PI / 2d;
|
|
float CamLX = (float)Math.Sin(yaw_Renamed);
|
|
float CamLY = (float)Math.Cos(pitch_Renamed);
|
|
float CamLZ = (float)-Math.Cos(yaw_Renamed);
|
|
float m = 8.0f;
|
|
switch (currentLookDirection)
|
|
{
|
|
case LookDirection.Top:
|
|
{
|
|
pos.X = orgPos.X - MousePosX * CamSpeedMultiplier * CamLX * m - MousePosY * CamSpeedMultiplier * CamLZ * m;
|
|
pos.Z = orgPos.Z - MousePosX * CamSpeedMultiplier * CamLZ * m - MousePosY * CamSpeedMultiplier * CamLX * m;
|
|
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, pos.X, pos.Y - 1000f, pos.Z - 1f, 0f, 1f, 0f);
|
|
lookPositions[(int)currentLookDirection] = pos;
|
|
break;
|
|
}
|
|
|
|
case LookDirection.Bottom:
|
|
{
|
|
pos.X = orgPos.X - MousePosX * CamSpeedMultiplier * CamLX * m + MousePosY * CamSpeedMultiplier * CamLZ * m;
|
|
pos.Z = orgPos.Z - MousePosX * CamSpeedMultiplier * CamLZ * m + MousePosY * CamSpeedMultiplier * CamLX * m;
|
|
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, pos.X, pos.Y + 1000f, pos.Z + 1f, 0f, 1f, 0f);
|
|
lookPositions[(int)currentLookDirection] = pos;
|
|
break;
|
|
}
|
|
|
|
case LookDirection.Left:
|
|
{
|
|
pos.X = orgPos.X - MousePosX * CamSpeedMultiplier * CamLX * m;
|
|
pos.Y = orgPos.Y - MousePosY * CamSpeedMultiplier * -1.0f * m;
|
|
pos.Z = orgPos.Z - MousePosX * CamSpeedMultiplier * CamLZ * m;
|
|
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, pos.X + 12500f, pos.Y, pos.Z, 0f, 1f, 0f);
|
|
lookPositions[(int)currentLookDirection] = pos;
|
|
break;
|
|
}
|
|
|
|
case LookDirection.Right:
|
|
{
|
|
pos.X = orgPos.X - MousePosX * CamSpeedMultiplier * CamLX * m;
|
|
pos.Y = orgPos.Y - MousePosY * CamSpeedMultiplier * -1.0f * m;
|
|
pos.Z = orgPos.Z - MousePosX * CamSpeedMultiplier * CamLZ * m;
|
|
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, pos.X - 12500f, pos.Y, pos.Z, 0f, 1f, 0f);
|
|
lookPositions[(int)currentLookDirection] = pos;
|
|
break;
|
|
}
|
|
|
|
case LookDirection.Front:
|
|
{
|
|
pos.X = orgPos.X - MousePosX * CamSpeedMultiplier * CamLX * m;
|
|
pos.Y = orgPos.Y - MousePosY * CamSpeedMultiplier * -1.0f * m;
|
|
pos.Z = orgPos.Z - MousePosX * CamSpeedMultiplier * CamLZ * m;
|
|
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, pos.X, pos.Y, pos.Z - 12500f, 0f, 1f, 0f);
|
|
lookPositions[(int)currentLookDirection] = pos;
|
|
break;
|
|
}
|
|
|
|
case LookDirection.Back:
|
|
{
|
|
pos.X = orgPos.X - MousePosX * CamSpeedMultiplier * CamLX * m;
|
|
pos.Y = orgPos.Y - MousePosY * CamSpeedMultiplier * -1.0f * m;
|
|
pos.Z = orgPos.Z - MousePosX * CamSpeedMultiplier * CamLZ * m;
|
|
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, pos.X, pos.Y, pos.Z + 12500f, 0f, 1f, 0f);
|
|
lookPositions[(int)currentLookDirection] = pos;
|
|
break;
|
|
}
|
|
}
|
|
|
|
RaisePerspectiveChanged();
|
|
lastMouseX = mouseX;
|
|
lastMouseY = mouseY;
|
|
// Console.WriteLine("CamAngleX = " + CamAngleX + ", CamAngleY = " + CamAngleY);
|
|
// setRotationFromLookAt();
|
|
}
|
|
|
|
private void UpdateCameraMatrixWithMouse_FLY(int mouseX, int mouseY, ref Matrix4 cameraMatrix)
|
|
{
|
|
if (resetMouse)
|
|
{
|
|
lastMouseX = mouseX;
|
|
lastMouseY = mouseY;
|
|
resetMouse = false;
|
|
}
|
|
|
|
int MousePosX = mouseX - lastMouseX;
|
|
int MousePosY = mouseY - lastMouseY;
|
|
CamAngleX = CamAngleX + 0.01f * MousePosX;
|
|
// This next part isn't neccessary, but it keeps the Yaw rotation value within [0, 2*pi] which makes debugging simpler.
|
|
if (CamAngleX > TAU)
|
|
{
|
|
CamAngleX -= TAU;
|
|
}
|
|
else if (CamAngleX < 0f)
|
|
{
|
|
CamAngleX += TAU;
|
|
}
|
|
|
|
// Lock pitch rotation within the bounds of [-3.1399.0, -0.0001], otherwise the LookAt function will snap to the
|
|
// opposite side and reverse mouse looking controls.
|
|
CamAngleY = Clampf(CamAngleY + 0.01f * MousePosY, -3.1399f, -0.0001f);
|
|
lastMouseX = mouseX;
|
|
lastMouseY = mouseY;
|
|
OrientateCam(CamAngleX, CamAngleY);
|
|
UpdateMatrix(ref cameraMatrix);
|
|
// Console.WriteLine("CamAngleX = " + CamAngleX + ", CamAngleY = " + CamAngleY);
|
|
// setRotationFromLookAt();
|
|
}
|
|
|
|
private void UpdateCameraOffsetWithMouse_FLY(Vector3 orgPos, int mouseX, int mouseY, int w, int h, ref Matrix4 cameraMatrix)
|
|
{
|
|
if (resetMouse)
|
|
{
|
|
lastMouseX = mouseX;
|
|
lastMouseY = mouseY;
|
|
resetMouse = false;
|
|
}
|
|
|
|
int MousePosX = -mouseX + lastMouseX;
|
|
int MousePosY = -mouseY + lastMouseY;
|
|
double pitch_Renamed = CamAngleY - Math.PI / 2d;
|
|
double yaw_Renamed = CamAngleX - Math.PI / 2d;
|
|
float CamLX = (float)Math.Sin(yaw_Renamed);
|
|
float CamLZ = (float)-Math.Cos(yaw_Renamed);
|
|
pos.X = orgPos.X - MousePosX * CamSpeedMultiplier * CamLX * 6.0f;
|
|
pos.Y = orgPos.Y - MousePosY * CamSpeedMultiplier * -1.0f * 6.0f;
|
|
pos.Z = orgPos.Z - MousePosX * CamSpeedMultiplier * CamLZ * 6.0f;
|
|
OrientateCam(CamAngleX, CamAngleY);
|
|
UpdateMatrix(ref cameraMatrix);
|
|
}
|
|
|
|
public void UpdateCameraOffsetDirectly(int horz_amount, int vert_amount, ref Matrix4 cameraMatrix)
|
|
{
|
|
if (myCamMode == CameraMode.ORBIT)
|
|
{
|
|
UpdateCameraOffsetDirectly_ORBIT((int)(horz_amount / 5d), (int)(vert_amount / 5d), ref cameraMatrix);
|
|
}
|
|
else
|
|
{
|
|
// Console.WriteLine(MousePosX+","+ MousePosY);
|
|
double pitch_Renamed = CamAngleY - Math.PI / 2d;
|
|
double yaw_Renamed = CamAngleX - Math.PI / 2d;
|
|
float CamLX = (float)Math.Sin(yaw_Renamed);
|
|
// float CamLY = (float)Math.Cos(pitch);
|
|
float CamLZ = (float)-Math.Cos(yaw_Renamed);
|
|
pos.X += horz_amount * CamSpeedMultiplier * CamLX;
|
|
pos.Y += vert_amount * CamSpeedMultiplier * -1.0f;
|
|
pos.Z += horz_amount * CamSpeedMultiplier * CamLZ;
|
|
OrientateCam(CamAngleX, CamAngleY);
|
|
UpdateMatrix(ref cameraMatrix);
|
|
}
|
|
}
|
|
|
|
private void UpdateCameraOffsetDirectly_ORBIT(int moveSpeedX, int moveSpeedY, ref Matrix4 cameraMatrix)
|
|
{
|
|
int MousePosX = moveSpeedX;
|
|
int MousePosY = moveSpeedY;
|
|
orbitTheta += MousePosX * 0.01f * CamSpeedMultiplier;
|
|
orbitPhi -= MousePosY * 0.01f * CamSpeedMultiplier;
|
|
orbitPhi = Clampf(orbitPhi, -1.57f, 1.57f);
|
|
UpdateOrbitCamera(ref cameraMatrix);
|
|
}
|
|
|
|
private void UpdateCameraMatrixWithMouse_ORBIT(int mouseX, int mouseY, ref Matrix4 cameraMatrix)
|
|
{
|
|
UpdateCameraOffsetWithMouse_ORBIT(mouseX, mouseY, ref cameraMatrix);
|
|
}
|
|
|
|
private void UpdateCameraOffsetWithMouse_ORBIT(int mouseX, int mouseY, ref Matrix4 cameraMatrix)
|
|
{
|
|
if (resetMouse)
|
|
{
|
|
lastMouseX = mouseX;
|
|
lastMouseY = mouseY;
|
|
resetMouse = false;
|
|
}
|
|
|
|
int MousePosX = -mouseX + lastMouseX;
|
|
int MousePosY = -mouseY + lastMouseY;
|
|
orbitTheta += MousePosX * 0.01f * CamSpeedMultiplier;
|
|
orbitPhi -= MousePosY * 0.01f * CamSpeedMultiplier;
|
|
orbitPhi = Clampf(orbitPhi, -1.57f, 1.57f);
|
|
UpdateOrbitCamera(ref cameraMatrix);
|
|
lastMouseX = mouseX;
|
|
lastMouseY = mouseY;
|
|
}
|
|
|
|
private void UpdateCameraMatrixWithScrollWheel_ORBIT(int amt, ref Matrix4 cameraMatrix)
|
|
{
|
|
orbitDistance -= amt;
|
|
if (orbitDistance < 300.0f)
|
|
{
|
|
orbitDistance = 300.0f;
|
|
}
|
|
|
|
UpdateOrbitCamera(ref cameraMatrix);
|
|
}
|
|
|
|
public void ResetMouseStuff()
|
|
{
|
|
resetMouse = true;
|
|
}
|
|
|
|
private System.Numerics.Vector3 CalculateCenterPositionOfObjects(ICameraPoint[] objs)
|
|
{
|
|
if (objs.Length <= 1)
|
|
{
|
|
var obj = objs.FirstOrDefault();
|
|
if (obj is null)
|
|
{
|
|
return System.Numerics.Vector3.Zero;
|
|
}
|
|
else
|
|
{
|
|
return new System.Numerics.Vector3(obj.Position.X, obj.Position.Y, obj.Position.Z);
|
|
}
|
|
}
|
|
|
|
float? maxX = default;
|
|
float? maxY = default;
|
|
float? maxZ = default;
|
|
float? minX = default;
|
|
float? minY = default;
|
|
float? minZ = default;
|
|
foreach (ICameraPoint obj in objs)
|
|
{
|
|
var pos = obj.Position;
|
|
if (maxX is null || pos.X > maxX)
|
|
maxX = pos.X;
|
|
if (maxY is null || pos.Y > maxY)
|
|
maxY = pos.Y;
|
|
if (maxZ is null || pos.Z > maxZ)
|
|
maxZ = pos.Z;
|
|
if (minX is null || pos.X < minX)
|
|
minX = pos.X;
|
|
if (minY is null || pos.Y < minY)
|
|
minY = pos.Y;
|
|
if (minZ is null || pos.Z < minZ)
|
|
minZ = pos.Z;
|
|
}
|
|
|
|
if (maxX is null)
|
|
maxX = 0;
|
|
if (maxY is null)
|
|
maxY = 0;
|
|
if (maxZ is null)
|
|
maxZ = 0;
|
|
if (minX is null)
|
|
minX = 0;
|
|
if (minY is null)
|
|
minY = 0;
|
|
if (minZ is null)
|
|
minZ = 0;
|
|
var upper = new System.Numerics.Vector3((float)maxX, (float)maxY, (float)maxZ);
|
|
var lower = new System.Numerics.Vector3((float)minX, (float)minY, (float)minZ);
|
|
var middle = (upper + lower) / 2f;
|
|
return middle;
|
|
}
|
|
|
|
private float CalculateCenterYRotationOfObjects(ICameraPoint[] objs)
|
|
{
|
|
if (objs.Length <= 1)
|
|
{
|
|
var obj = objs.FirstOrDefault();
|
|
if (obj is null)
|
|
{
|
|
return 0f;
|
|
}
|
|
else
|
|
{
|
|
return obj.Rotation.Y;
|
|
}
|
|
}
|
|
|
|
var yRot = new List<float>();
|
|
foreach (ICameraPoint obj in objs)
|
|
yRot.Add(obj.Rotation.Y);
|
|
return yRot.Average();
|
|
}
|
|
|
|
private ICameraPoint[] GetSelectedObject()
|
|
{
|
|
var e = new NeedSelectedObjectEventArgs();
|
|
NeedSelectedObject?.Invoke(this, e);
|
|
var stopw = new Stopwatch();
|
|
stopw.Start();
|
|
while (!e.HasObjectSetted && stopw.ElapsedMilliseconds <= 1000L)
|
|
Application.DoEvents();
|
|
stopw.Stop();
|
|
return e.Points;
|
|
}
|
|
|
|
// C A P S E L T C L A S S E S
|
|
|
|
public class NeedSelectedObjectEventArgs : EventArgs
|
|
{
|
|
private bool _HasObjectSetted = false;
|
|
|
|
public bool HasObjectSetted
|
|
{
|
|
get
|
|
{
|
|
return _HasObjectSetted;
|
|
}
|
|
}
|
|
|
|
private ICameraPoint[] _Points = null;
|
|
|
|
public ICameraPoint[] Points
|
|
{
|
|
get
|
|
{
|
|
return _Points;
|
|
}
|
|
|
|
set
|
|
{
|
|
_Points = value;
|
|
_HasObjectSetted = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |