Problem with Arc ball camera

May 16, 2012 at 9:33 PM

I am using SceneControl and added arc ball camera in my project. it seems as if its not performing properly like an arc ball. It is showing some strange behavior can some one help me in this regard.

Jul 9, 2012 at 9:12 PM

I confirm, it definitely looks buggy... Is that a known issue?

Jul 9, 2012 at 11:13 PM

Thanks phil for verifying. I think Dave or some one can help on this. I am still trying to figure out proper fix to that

Coordinator
Jul 10, 2012 at 10:47 AM

Hi Guys,

I think as there seems to be some problems with this the best thing for me to do would be to raise a task in the issue tracker to create a small camera sample, which not only shows how to use the cameras and arc ball but also allows their behaviour to be throughly tested - what do you think?

Jul 17, 2012 at 8:20 PM

That would be great Dave.

Jan 5, 2014 at 4:33 PM
Hello, Could anyone tell me if this issue has been resolved?
Thanks
Jan 29, 2014 at 6:39 PM
Edited Jan 29, 2014 at 6:41 PM
I think this will solve the problem.
    [Serializable()]
    public class ArcBall
    {
        bool mouseDownFlag;
        float angle, length, radiusRadius;
        Double[] currentTransform = new Double[16], lastTransform = new Double[16] { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
        Vertex startPosition, endPosition, normalVector;

        private int width;
        private int height;

        public void SetBounds(int width, int height)
        {
            this.width = width; this.height = height;
            length = width > height ? width : height;
            radiusRadius = (float)(Math.Pow((width / length) / 2, 2) + Math.Pow((height / length) / 2, 2));
            if (radiusRadius < 0)
            {
                radiusRadius = 0;
            }
        }

        public void MouseDown(int x, int y)
        {
            var zz = radiusRadius
                - Math.Pow((x - width / 2) / length, 2)
                - Math.Pow((height / 2 - y) / length, 2);
            if (zz >= 0)
            {
                startPosition = new Vertex(
                   (x - width / 2) / length,
                   (height / 2 - y) / length,
                   (float)Math.Sqrt(zz));
            }
            else
            {
                startPosition = new Vertex(
                   (x - width / 2) / length,
                   (height / 2 - y) / length,
                   0);
            }
            mouseDownFlag = true;
        }

        public void MouseMove(int x, int y)
        {
            if (mouseDownFlag)
            {
                endPosition = new Vertex(
                    (x - width / 2) / length,
                    (height / 2 - y) / length,
                    (float)Math.Sqrt(
                        radiusRadius
                        - Math.Pow((x - width / 2) / length, 2)
                        - Math.Pow((height / 2 - y) / length, 2))
                            );
                angle = 10*(float)(Math.Acos(
                    startPosition.ScalarProduct(endPosition) / (startPosition.Magnitude() * endPosition.Magnitude()))
                    / Math.PI * 180);
                normalVector = startPosition.VectorProduct(endPosition);
                startPosition = endPosition;
            }
        }

        public void MouseUp(int x, int y)
        {
            mouseDownFlag = false;
        }

        public void TransformMatrix(OpenGL gl)
        {
            gl.PushMatrix();
            gl.LoadIdentity();
            gl.PushMatrix();
            gl.Rotate(2 * angle, normalVector.X, normalVector.Y, normalVector.Z);
            gl.GetDouble(SharpGL.Enumerations.GetTarget.ModelviewMatix, currentTransform);
            gl.PopMatrix();
            gl.PopMatrix();
            gl.MultMatrix(currentTransform);
            gl.MultMatrix(lastTransform);
            gl.GetDouble(SharpGL.Enumerations.GetTarget.ModelviewMatix, lastTransform);
            angle = 0;
        }
    }
Just replace oldder "ArcBall" class with it and set camera by this:
gl.LookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);