dwmkerr / sharpgl

Use OpenGL in .NET applications. SharpGL wraps all modern OpenGL features and offers a powerful scene graph to aid development.
MIT License
755 stars 299 forks source link

Update ArcBall.cs #104

Closed bitzhuwei closed 9 years ago

bitzhuwei commented 9 years ago

I rewrite this ArcBall class months ago. You can set the camera to any position and towards anywhere(any center and up vector is OK). Hope this helps.

GianlucaGrotto commented 4 years ago

Hi, I'm integrating your class in my project (its a 3D CAD). It is really cool, but I would like to get the rotation angles in order to save differents view, the class doesn't provide a method, so I'm tryng to do it myself, but I have difficulties to understand how to proceed. Could you help me? is there any documentation I can use to get the answer? or better do you have a method alredy done?

thank you very much

Gianluca

bitzhuwei commented 4 years ago

@GianlucaGrotto I think the field private float _angle; is what you need. you can make a public property from it.

GianlucaGrotto commented 4 years ago

thank for your fast answer, but I have three angles

GianlucaGrotto commented 4 years ago

below the class variables, as you can see there are no angles.

private float radius = 1.0f;
private float adjustWidth = 1.0f;
private float adjustHeight = 1.0f;
public Vertex startVector = new Vertex(0, 0, 0);
public Vertex currentVector = new Vertex(0, 0, 0);

Matrix transformMatrix = new Matrix(4, 4);
Matrix lastRotationMatrix = new Matrix(3, 3);
Matrix thisRotationMatrix = new Matrix(3, 3);
bitzhuwei commented 4 years ago

the _angle means how the _normalVector rotates and the target object should rotate just like _normalVector. check the mat4 GetRotation() method to see how it is turned into a matrix, you can get 3 angles in the matrix.

bitzhuwei commented 4 years ago

you know 3 angles can be turned into a rotation matrix directly.

GianlucaGrotto commented 4 years ago

thank you I will check.

GianlucaGrotto commented 4 years ago

Another question because I'm quite new of OpenGL.
I suppose I have do use the modelview matrix in oder to get the angles. Could you confirm?

PS. I used your class in a openGLControl and not in SheneControl.

bitzhuwei commented 4 years ago

It's a long story. Here is my understanding about it: Imagine there is an axis of X, Y and Z, which describe positions in the physical world with (x, y, z). Now we put a small cube in the world, make sure its center is at (0, 0, 0). Then we translate/move it, rotate it, and scale it. Let's say its new position in the world is (x1, y1, z1). The model matrix can be used to describe the translation, rotation and scaling, which means that (x1, y1, z1, 1) = modelMatrix * (0, 0, 0, 1). Don't bother about the last 1, it's a math thing. The cube exists, you can't see it without your eyes. If you move/rotate your eyes(move yourself or tilt), the picture of cube in your retina will appear differently. Let's say its position in your retina is (x2, y2, z2). The view matrix can be used to describe the translation, rotation and scaling of eye/camera, which means that (x2, y2, z2, 1) = viewMatrix * (x1, y1, z1, 1). Don't bother about scaling eyes. You know displacement of objects are relative. So when we moved the cube, we can take it like that we moved our eyes/camera in the opposite direction instead of moving the cube. So are rotation and scaling.(Now you can take 'scaling your eye' like 'scaling the cube' in 1/scaling) So, we can use (viewMatrix * modelMatrix) to represent that we only moved the cube or we only moved our eye/camera. (x2, y2, z2), (x1, y1, z1), (0, 0, 0) are different in values, but they are all describing the only center point of the cube. The values are different because they are measured in different axises. So, every OpenGL library can use view matrix and model matrix differently. You can only make sure how they are used before using its data. Hope this helps. I have a book about junior OpenGL however it's in Chinese.

GianlucaGrotto commented 4 years ago

I appreciate very much your help, so the ArcBall algorithm in short modify the View using the view matrix or model view?

In SharpGL I can get the only the ModelView matrix that is a result of the model and view matrix multiplication.

gl.GetDouble(OpenGL.GL_MODELVIEW_MATRIX, mv);

So in general I can detect the angles using data in ModelView matrix, isn't it?

bitzhuwei commented 4 years ago

ArcBall algorithm in short modify the rotation angles of object(View is not accurate) using the model matrix as I remembered. ArcBall takes the view matrix as parameter to deal with camera's displacement, it never changes the view matrix, it only changes the model matrix. This is where you can get angles in Arcball:

        public mat4 GetRotation()
        {
            var angle = (float)(_angle * Math.PI / 180.0f);
            var rotation = glm.rotate(angle, new vec3(_normalVector.X, _normalVector.Y, _normalVector.Z));
            rotation = rotation * originalRotation;
            originalRotation = rotation;
            System.Threading.Interlocked.Exchange(ref _angle, 0);
            return rotation;
        }

You can put a snippet inside this method to get angles like this:

        public float eulerAngleX;
        public float eulerAngleY;
        public float eulerAngleZ;

        public mat4 GetRotation()
        {
            Quaternion q = new Quaternion(angle, _normalVector);
            // TODO: convert q to Euler angles and keep them in eulerAngleX etc.

            var angle = (float)(_angle * Math.PI / 180.0f);
            var rotation = glm.rotate(angle, new vec3(_normalVector.X, _normalVector.Y, _normalVector.Z));
            rotation = rotation * originalRotation;
            originalRotation = rotation;
            System.Threading.Interlocked.Exchange(ref _angle, 0);
            return rotation;
        }

If you want the combined rotation angles of (object and camera), then yes. If you only want rotation angles of object, then no.

GianlucaGrotto commented 4 years ago

Thakyou so much ...but in SharpGL source code I don't find the code you mention

mat4 GetRotation() ...

bitzhuwei commented 4 years ago

Oh, it's in here(https://github.com/dwmkerr/sharpgl/pull/104/commits/9a838f22b80a462ffad5ddc3afd5136e1fd47872) SharpGL didn't accept my pull request. You have to add it manually. Also, it's been written long long ago, I can't promise it's still working with SharpGL.

GianlucaGrotto commented 4 years ago

thank you again, now I will explore!

bye