Opentk相机旋转会破坏场景对象的旋转

时间:2015-05-14 13:03:47

标签: c# opengl-es opentk

我与它争斗了2天并搜索互联网但我对我的问题没有任何答案。简而言之,我想让屏幕上的轨道相机和我想要的物体也独立于我的相机旋转。我实现了Arcball旋转控制器,我用它来旋转场景中的所有对象(可能这会引起问题)。当我有相机在起点时看起来不错但是当我开始移动它并且我想在场景上旋转物体时它看起来像所有物体在相机起点像im一样旋转。也许这里有人可以提供帮助:D

我的Arcball课程:

public class ArcBallGL{

    private bool isBeingDragged;

    private Vector3 downPoint;
    private Vector3 currentPoint;
    public Vector3 BallCenter { get; set; }
    private Quaternion down;
    public Quaternion Now { get; set; }

    private float width, height;

    public ArcBallGL()
    {
        Reset();

        width = height = 0.0f;
    }

    public void Reset()
    {
        isBeingDragged = false;

        downPoint = Vector3.Zero;
        currentPoint = Vector3.Zero;

        down = Quaternion.Identity;
        Now = Quaternion.Identity;
    }

    public void SetWindow(float width, float height)
    {
        this.width = width;
        this.height = height;
    }

    public void OnBeginDrag(float x, float y)
    {
        isBeingDragged = true;
        down = Now;
        downPoint = ScreenToVector(x, y);
    }

    public void OnMove(float x, float y)
    {
        if (isBeingDragged == true)
        {
            currentPoint = ScreenToVector(x, y);
            Now = down * QuatFromBallPoints(downPoint, currentPoint);
        }
    }

    public void OnStopDrag()
    {
        isBeingDragged = false;
    }

    public Matrix4 GetRotationMatrix()
    {
        return Matrix4.CreateFromQuaternion(Now);
    }

    public Matrix4 GetRotationMatrixFormViewPort(Matrix4 camera)
    {


        var viewMatrix = Matrix4.CreateFromQuaternion(Now).Inverted();
        viewMatrix.Normalize();
        return viewMatrix * Matrix4.CreateFromQuaternion( camera.ExtractRotation()).Inverted();
    }

    private Vector3 ScreenToVector(float screentPointX, float screenPointY)
    {
        float x = (screentPointX - width * 0.5f) / (width * 0.5f);
        float y = (screenPointY - height * 0.5f) / height;
        float z = 0.0f;

        float mag = x * x + y * y;

        if (mag > 1.0f)
        {
            float scale = 1.0f / (float)Math.Sqrt(mag);

            x *= scale;
            y *= scale;
        }
        else
        {
            z = (float)Math.Sqrt(1.0f - mag);
        }

        return new Vector3(-x, y, -z);
    }

    private Quaternion QuatFromBallPoints(Vector3 from, Vector3 to)
    {
        float dot = Vector3.Dot(from, to);
        Vector3 part = Vector3.Cross(from, to);
        return new Quaternion(part.X, part.Y, part.Z, dot);
    }
}

我的相机课程:

public class Camera{
    public Vector3 Position = Vector3.Zero;

    private Vector3 Up = Vector3.UnitY;
    public float MoveSpeed = 0.2f;
    public float RotationSpeed = 0.01f;

    public Quaternion RotQuar { get; set; } 


    public Camera(Vector3 startPos = new Vector3())
    {
        Position = startPos;
        RotQuar = Quaternion.Identity;
    }

    public Matrix4 GetViewMatrix(Vector3 target)
    {
        //RotQuar.Conjugate();
        var rotMatrix = Matrix4.CreateFromQuaternion(RotQuar);

        var camPosition = Vector3.Transform(Position, rotMatrix);

        var camDir = target - camPosition;
        camDir.Normalize();
        var camRight = Vector3.Cross(camDir, Vector3.UnitY);
        camRight.Normalize();
        var camUp = Vector3.Cross(camRight, camDir);
        camUp.Normalize();

        var cameraMat = Matrix4.LookAt(camPosition, target ,  camUp) ;

        return cameraMat;
    }
}

我的老鼠搬家了

private void MouseMoved(object sender, MouseMoveEventArgs e)
    {

        if (e.Mouse.IsButtonDown(MouseButton.Left) && RIsDown)
        {
            foreach (Shape s in _shapes)
            {
                if (s.IsSelected)
                {
                    Rotation.OnMove(e.Position.X, e.Position.Y);
                    s.RoatationQuat = Rotation.Now;
                    s.RotationMatrix = Rotation.GetRotationMatrixFormViewPort(_camera.GetViewMatrix(Vector3.Zero));
                }

            }

        }
        if (e.Mouse.IsButtonDown(MouseButton.Left) && CIsDown)
        {
            Rotation.OnMove(e.Position.X, e.Position.Y);
            _camera.RotQuar = Rotation.Now;
        }

    }

我使用索引缓冲区在场景上绘制我的对象。我认为问题在于计算相机坐标的相机坐标,但我不知道我必须在哪里计算它。谢谢你的帮助

0 个答案:

没有答案