Ejemplo n.º 1
0
        /// <summary>
        /// Build a look at view matrix.
        /// transform object's coordinate from world's space to camera's space.
        /// </summary>
        /// <param name="eye">The eye.</param>
        /// <param name="center">The center.</param>
        /// <param name="up">Up.</param>
        /// <returns></returns>
        public static mat4 lookAt(vec3 eye, vec3 center, vec3 up)
        {
            // camera's back in world space coordinate system
            vec3 back = (eye - center).normalize();
            // camera's right in world space coordinate system
            vec3 right = up.cross(back).normalize();
            // camera's up in world space coordinate system
            vec3 standardUp = back.cross(right);

            mat4 viewMat = new mat4(1);

            viewMat.col0.x = right.x;
            viewMat.col1.x = right.y;
            viewMat.col2.x = right.z;
            viewMat.col0.y = standardUp.x;
            viewMat.col1.y = standardUp.y;
            viewMat.col2.y = standardUp.z;
            viewMat.col0.z = back.x;
            viewMat.col1.z = back.y;
            viewMat.col2.z = back.z;

            // Translation in world space coordinate system
            viewMat.col3.x = -eye.dot(right);
            viewMat.col3.y = -eye.dot(standardUp);
            viewMat.col3.z = -eye.dot(back);

            return(viewMat);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Build a look at view matrix.
        /// transform object's coordinate from world's space to camera's space.
        /// </summary>
        /// <param name="eye">The eye.</param>
        /// <param name="center">The center.</param>
        /// <param name="up">Up.</param>
        /// <returns></returns>
        public static mat4 lookAt(vec3 eye, vec3 center, vec3 up)
        {
            vec3 forward    = (center - eye).normalize();
            vec3 right      = forward.cross(up).normalize();
            vec3 standardUp = right.cross(forward);

            mat4 Result = new mat4(1);

            // Left (X) Axis
            Result[0, 0] = right.x;
            Result[0, 1] = standardUp.x;
            Result[0, 2] = -forward.x;
            // Up (Y) Axis
            Result[1, 0] = right.y;
            Result[1, 1] = standardUp.y;
            Result[1, 2] = -forward.y;
            // Forward (Z) Axis
            Result[2, 0] = right.z;
            Result[2, 1] = standardUp.z;
            Result[2, 2] = -forward.z;
            // Translation
            Result[3, 0] = -right.dot(eye);      // dot(s, eye);
            Result[3, 1] = -standardUp.dot(eye); // dot(u, eye);
            Result[3, 2] = forward.dot(eye);     // dot(f, eye);
            return(Result);
        }
Ejemplo n.º 3
0
        void IMouseHandler.canvas_MouseMove(object sender, GLMouseEventArgs e)
        {
            if (this.mouseDownFlag &&
                ((e.Button & this.lastBindingMouseButtons) != GLMouseButtons.None) &&
                (e.X != lastPosition.x || e.Y != lastPosition.y))
            {
                IViewCamera camera = this.camera;
                if (camera == null)
                {
                    return;
                }

                vec3    back         = this.back;
                vec3    right        = this.right;
                vec3    up           = this.up;
                GUISize bound        = this.bound;
                ivec2   downPosition = this.lastPosition;
                {
                    float deltaX  = -this.HorizontalRotationFactor * (e.X - downPosition.x) / (float)bound.Width;
                    float cos     = (float)Math.Cos(deltaX);
                    float sin     = (float)Math.Sin(deltaX);
                    vec3  newBack = new vec3(
                        back.x * cos + right.x * sin,
                        back.y * cos + right.y * sin,
                        back.z * cos + right.z * sin);
                    back  = newBack;
                    right = up.cross(back);
                    back  = back.normalize();
                    right = right.normalize();
                }
                {
                    float deltaY  = this.VerticalRotationFactor * (e.Y - downPosition.y) / (float)bound.Height;
                    float cos     = (float)Math.Cos(deltaY);
                    float sin     = (float)Math.Sin(deltaY);
                    vec3  newBack = new vec3(
                        back.x * cos - up.x * sin,
                        back.y * cos - up.y * sin,
                        back.z * cos - up.z * sin);
                    back = newBack;
                    up   = back.cross(right);
                    back = back.normalize();
                    up   = up.normalize();
                }

                //camera.Position = camera.Target +
                //    back * (float)((camera.Position - camera.Target).length());
                rootNode.RotationAxis = up;
                camera.UpVector       = up;
                this.back             = back;
                this.right            = right;
                this.up           = up;
                this.lastPosition = e.Location;

                IGLCanvas canvas = this.canvas;
                if (canvas != null && canvas.RenderTrigger == RenderTrigger.Manual)
                {
                    canvas.Repaint();
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Get left vector in world space.
        /// </summary>
        /// <returns></returns>
        public static vec3 GetLeft(this IViewCamera camera)
        {
            vec3 back   = camera.Position - camera.Target;
            vec3 result = back.cross(camera.UpVector);

            return(result);
        }
Ejemplo n.º 5
0
        void IMouseHandler.canvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (mouseDownFlag && ((e.Button & this.lastBindingMouseButtons) != MouseButtons.None))
            {
                if (!cameraState.IsSameState(this.camera))
                {
                    SetCamera(this.camera.Position, this.camera.Target, this.camera.UpVector);
                }

                this._endPosition = GetArcBallPosition(e.X, e.Y);
                var cosAngle = _startPosition.dot(_endPosition) / (_startPosition.length() * _endPosition.length());
                if (cosAngle > 1.0f)
                {
                    cosAngle = 1.0f;
                }
                else if (cosAngle < -1)
                {
                    cosAngle = -1.0f;
                }
                var angle = MouseSensitivity * (float)(Math.Acos(cosAngle) / Math.PI * 180);
                _normalVector = _startPosition.cross(_endPosition).normalize();
                if (!
                    ((_normalVector.x == 0 && _normalVector.y == 0 && _normalVector.z == 0) ||
                     float.IsNaN(_normalVector.x) || float.IsNaN(_normalVector.y) || float.IsNaN(_normalVector.z)))
                {
                    _startPosition = _endPosition;

                    mat4 newRotation = glm.rotate(angle, _normalVector);
                    this.totalRotation = newRotation * totalRotation;
                }
            }
        }
        void IKeyboardHandler.canvas_KeyPress(object sender, GLKeyPressEventArgs e)
        {
            bool updated = false;

            if (e.KeyChar == frontKey || e.KeyChar == upcaseFrontKey)
            {
                vec3 right         = this.camera.GetRight();
                vec3 standardFront = this.camera.UpVector.cross(right).normalize();
                this.camera.Position += standardFront * this.StepLength;
                this.camera.Target   += standardFront * this.StepLength;
                updated = true;
            }
            else if (e.KeyChar == backKey || e.KeyChar == upcaseBackKey)
            {
                vec3 right        = this.camera.GetRight();
                vec3 standardBack = right.cross(this.camera.UpVector).normalize();
                this.camera.Position += standardBack * this.StepLength;
                this.camera.Target   += standardBack * this.StepLength;
                updated = true;
            }
            else if (e.KeyChar == leftKey || e.KeyChar == upcaseLeftKey)
            {
                vec3 right = this.camera.GetRight();
                vec3 left  = (-right).normalize();
                this.camera.Position += left * this.StepLength;
                this.camera.Target   += left * this.StepLength;
                updated = true;
            }
            else if (e.KeyChar == rightKey || e.KeyChar == upcaseRightKey)
            {
                vec3 right = this.camera.GetRight().normalize();
                this.camera.Position += right * this.StepLength;
                this.camera.Target   += right * this.StepLength;
                updated = true;
            }
            else if (e.KeyChar == upKey || e.KeyChar == upcaseUpKey)
            {
                vec3 up = this.camera.UpVector.normalize();
                this.camera.Position += up * this.StepLength;
                this.camera.Target   += up * this.StepLength;
                updated = true;
            }
            else if (e.KeyChar == downKey || e.KeyChar == upcaseDownKey)
            {
                vec3 down = -this.camera.UpVector.normalize();
                this.camera.Position += down * this.StepLength;
                this.camera.Target   += down * this.StepLength;
                updated = true;
            }

            if (updated)
            {
                IGLCanvas canvas = this.canvas;
                if (canvas.RenderTrigger == RenderTrigger.Manual)
                {
                    canvas.Repaint();
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Gets standard down.
        /// </summary>
        /// <param name="camera"></param>
        /// <returns></returns>
        public static vec3 GetDown(this IViewCamera camera)
        {
            vec3 back  = camera.Position - camera.Target;
            vec3 right = camera.UpVector.cross(back);
            vec3 down  = right.cross(back);

            return(down);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Gets standard up.
        /// </summary>
        /// <param name="camera"></param>
        /// <returns></returns>
        public static vec3 GetUp(this IViewCamera camera)
        {
            vec3 back  = camera.Position - camera.Target;
            vec3 right = camera.UpVector.cross(back);
            vec3 up    = back.cross(right);

            return(up);
        }
Ejemplo n.º 9
0
        void IMouseHandler.canvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (this.mouseDownFlag &&
                ((e.Button & this.lastBindingMouseButtons) != MouseButtons.None) &&
                (e.X != lastPosition.X || e.Y != lastPosition.Y))
            {
                IViewCamera camera = this.camera;
                if (camera == null)
                {
                    return;
                }

                vec3  back         = this.back;
                vec3  right        = this.right;
                vec3  up           = this.up;
                Size  bound        = this.bound;
                Point downPosition = this.lastPosition;
                {
                    float deltaX  = -this.HorizontalRotationFactor * (e.X - downPosition.X) / bound.Width;
                    float cos     = (float)Math.Cos(deltaX);
                    float sin     = (float)Math.Sin(deltaX);
                    vec3  newBack = new vec3(
                        back.x * cos + right.x * sin,
                        back.y * cos + right.y * sin,
                        back.z * cos + right.z * sin);
                    back  = newBack;
                    right = up.cross(back);
                    back  = back.normalize();
                    right = right.normalize();
                }
                {
                    float deltaY  = this.VerticalRotationFactor * (e.Y - downPosition.Y) / bound.Height;
                    float cos     = (float)Math.Cos(deltaY);
                    float sin     = (float)Math.Sin(deltaY);
                    vec3  newBack = new vec3(
                        back.x * cos + up.x * sin,
                        back.y * cos + up.y * sin,
                        back.z * cos + up.z * sin);
                    back = newBack;
                    up   = back.cross(right);
                    back = back.normalize();
                    up   = up.normalize();
                }

                camera.Position = camera.Target +
                                  back * (float)((camera.Position - camera.Target).length());
                camera.UpVector   = up;
                this.back         = back;
                this.right        = right;
                this.up           = up;
                this.lastPosition = e.Location;

                if (this.canvas.RenderTrigger == RenderTrigger.Manual)
                {
                    this.canvas.Invalidate();
                }
            }
        }
Ejemplo n.º 10
0
        private static void GenNormals()
        {
            var faceNormals = new vec3[faceData.Length / 3];

            for (int i = 0; i < faceData.Length / 3; i++)
            {
                ushort vertexId1 = faceData[i * 3 + 0];
                ushort vertexId2 = faceData[i * 3 + 1];
                ushort vertexId3 = faceData[i * 3 + 2];
                vec3   vertex0   = new vec3(
                    positionData[(vertexId1 - 1) * 3 + 0],
                    positionData[(vertexId1 - 1) * 3 + 1],
                    positionData[(vertexId1 - 1) * 3 + 2]);
                vec3 vertex1 = new vec3(
                    positionData[(vertexId2 - 1) * 3 + 0],
                    positionData[(vertexId2 - 1) * 3 + 1],
                    positionData[(vertexId2 - 1) * 3 + 2]);
                vec3 vertex2 = new vec3(
                    positionData[(vertexId3 - 1) * 3 + 0],
                    positionData[(vertexId3 - 1) * 3 + 1],
                    positionData[(vertexId3 - 1) * 3 + 2]);
                vec3 v1 = vertex0 - vertex2;
                vec3 v2 = vertex2 - vertex1;
                faceNormals[i] = v2.cross(v1).normalize();
            }

            var normals = new float[positionData.Length];

            for (int i = 0; i < positionData.Length / 3; i++)
            {
                vec3 sum    = new vec3();
                int  shared = 0;
                for (int j = 0; j < faceData.Length / 3; j++)
                {
                    ushort vertexId1 = faceData[j * 3 + 0];
                    ushort vertexId2 = faceData[j * 3 + 1];
                    ushort vertexId3 = faceData[j * 3 + 2];
                    if (vertexId1 - 1 == i || vertexId2 - 1 == i || vertexId3 - 1 == i)
                    {
                        sum = sum + faceNormals[j];
                        shared++;
                    }
                }

                if (shared > 0)
                {
                    sum = (sum / shared).normalize();
                }

                normals[i * 3 + 0] = sum.x;
                normals[i * 3 + 1] = sum.y;
                normals[i * 3 + 2] = sum.z;
            }

            TeapotModel.normals = normals;
        }
Ejemplo n.º 11
0
        private void SetCamera(vec3 position, vec3 target, vec3 up)
        {
            _vectorBack  = (position - target).normalize();
            _vectorRight = up.cross(_vectorBack).normalize();
            _vectorUp    = _vectorBack.cross(_vectorRight).normalize();

            this.cameraState.position = position;
            this.cameraState.target   = target;
            this.cameraState.up       = up;
        }
Ejemplo n.º 12
0
        public void MouseMove(int x, int y)
        {
            if (MouseDownFlag)
            {
                Debug.WriteLine("    =================>MouseMove:", listenerName);
                if (!cameraState.IsSameState(this.Camera))
                {
                    SetCamera(this.Camera.Position, this.Camera.Target, this.Camera.UpVector);
                    Debug.WriteLine(string.Format(
                                        "    update camera state: {0}, {1}, {2}",
                                        this.cameraState.position, this.cameraState.target, this.cameraState.up), listenerName);
                }

                this._endPosition = GetArcBallPosition(x, y);
                Debug.WriteLine(string.Format(
                                    "    End position: {0}", this._endPosition), listenerName);
                var cosAngle = _startPosition.dot(_endPosition) / (_startPosition.Magnitude() * _endPosition.Magnitude());
                if (cosAngle > 1)
                {
                    cosAngle = 1;
                }
                else if (cosAngle < -1)
                {
                    cosAngle = -1;
                }
                Debug.Write(string.Format("    cos angle: {0}", cosAngle), listenerName);
                var angle = mouseSensitivity * (float)(Math.Acos(cosAngle) / Math.PI * 180);
                Debug.WriteLine(string.Format(
                                    ", angle: {0}", angle), listenerName);
                _normalVector = _startPosition.cross(_endPosition).normalize();
                if ((_normalVector.x == 0 && _normalVector.y == 0 && _normalVector.z == 0) ||
                    float.IsNaN(_normalVector.x) || float.IsNaN(_normalVector.y) || float.IsNaN(_normalVector.z))
                {
                    Debug.WriteLine("    no movement recorded.", listenerName);
                }
                else
                {
                    Debug.WriteLine(string.Format(
                                        "    normal vector: {0}", _normalVector), listenerName);
                    _startPosition = _endPosition;

                    mat4 newRotation = glm.rotate(angle, _normalVector);
                    Debug.WriteLine(string.Format(
                                        "    new rotation matrix:   {0}", newRotation), listenerName);
                    this.totalRotation = newRotation * totalRotation;
                    Debug.WriteLine(string.Format(
                                        "    total rotation matrix: {0}", totalRotation), listenerName);
                }
                Debug.WriteLine("    -------------------MouseMove end.", listenerName);
            }
        }
Ejemplo n.º 13
0
        private void PrepareCamera()
        {
            var camera = this.camera;

            if (camera != null)
            {
                vec3 back  = camera.Position - camera.Target;
                vec3 right = camera.UpVector.cross(back);
                vec3 up    = back.cross(right);

                this.back  = back.normalize();
                this.right = right.normalize();
                this.up    = up.normalize();
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public void MouseMove(int x, int y)
        {
            if (this.MouseDownFlag)
            {
                IViewCamera camera = this.Camera;
                if (camera == null)
                {
                    return;
                }

                vec3  back         = this.back;
                vec3  right        = this.right;
                vec3  up           = this.up;
                Size  bound        = this.bound;
                Point downPosition = this.downPosition;
                {
                    float deltaX  = -horizontalRotationFactor * (x - downPosition.X) / bound.Width;
                    float cos     = (float)Math.Cos(deltaX);
                    float sin     = (float)Math.Sin(deltaX);
                    vec3  newBack = new vec3(
                        back.x * cos + right.x * sin,
                        back.y * cos + right.y * sin,
                        back.z * cos + right.z * sin);
                    back  = newBack.normalize();
                    right = up.cross(back).normalize();
                }
                {
                    float deltaY  = verticalRotationFactor * (y - downPosition.Y) / bound.Height;
                    float cos     = (float)Math.Cos(deltaY);
                    float sin     = (float)Math.Sin(deltaY);
                    vec3  newBack = new vec3(
                        back.x * cos + up.x * sin,
                        back.y * cos + up.y * sin,
                        back.z * cos + up.z * sin);
                    back = newBack.normalize();
                    up   = back.cross(right).normalize();
                }

                camera.Position = camera.Target +
                                  back * (float)((camera.Position - camera.Target).Magnitude());
                camera.UpVector     = up;
                this.back           = back;
                this.right          = right;
                this.up             = up;
                this.downPosition.X = x;
                this.downPosition.Y = y;
            }
        }
Ejemplo n.º 15
0
        private void PrepareCamera()
        {
            var camera = this.Camera;

            if (camera != null)
            {
                vec3 back  = (camera.Position - camera.Target).normalize();
                vec3 right = Camera.UpVector.cross(back).normalize();
                vec3 up    = back.cross(right).normalize();

                this.back  = back;
                this.right = right;
                this.up    = up;

                if (this.originalCamera == null)
                {
                    this.originalCamera = new Camera();
                }
                this.originalCamera.Position = camera.Position;
                this.originalCamera.UpVector = camera.UpVector;
            }
        }
Ejemplo n.º 16
0
            private static void GenNormals(TeapotModel model)
            {
                var faceNormals = new vec3[model.faces.Count];

                model.normals.AddRange(new vec3[model.positions.Count]);

                for (int i = 0; i < model.faces.Count; i++)
                {
                    var  face    = model.faces[i];
                    vec3 vertex0 = model.positions[face.Item1 - 1];
                    vec3 vertex1 = model.positions[face.Item2 - 1];
                    vec3 vertex2 = model.positions[face.Item3 - 1];
                    vec3 v1      = vertex0 - vertex2;
                    vec3 v2      = vertex2 - vertex1;
                    faceNormals[i] = v2.cross(v1).normalize();
                }

                for (int i = 0; i < model.positions.Count; i++)
                {
                    vec3 sum    = new vec3();
                    int  shared = 0;
                    for (int j = 0; j < model.faces.Count; j++)
                    {
                        var face = model.faces[j];
                        if (face.Item1 - 1 == i || face.Item2 - 1 == i || face.Item3 - 1 == i)
                        {
                            sum = sum + faceNormals[j];
                            shared++;
                        }
                    }
                    if (shared > 0)
                    {
                        sum = (sum / shared).normalize();
                    }
                    model.normals[i] = sum;
                }
            }
Ejemplo n.º 17
0
        // https://www.cnblogs.com/bitzhuwei/p/opengl-Computing-Tangent-Space-Basis-Vectors.html
        public override void Parse(ObjVNFContext context)
        {
            ObjVNFMesh mesh = context.Mesh;

            vec3[] vertexes  = mesh.vertexes;// positions
            vec2[] texCoords = mesh.texCoords;
            vec3[] normals   = mesh.normals;
            if (vertexes == null || texCoords == null || normals == null)
            {
                return;
            }
            if (vertexes.Length != texCoords.Length || vertexes.Length != normals.Length)
            {
                return;
            }

            ObjVNFFace[] faces = mesh.faces;
            if (faces == null || faces.Length == 0)
            {
                return;
            }
            // if (not triangles) { return; }
            if (faces[0].VertexIndexes().Count() != 3)
            {
                return;
            }

            var tangents   = new vec3[normals.Length];
            var biTangents = new vec3[normals.Length];

            for (int i = 0; i < faces.Length; i++)
            {
                var face = faces[i] as ObjVNFTriangle;
                if (face == null)
                {
                    return;
                }                             // no dealing with quad.

                uint[] vertexIndexes = face.VertexIndexes();
                uint   i0            = vertexIndexes[0];
                uint   i1            = vertexIndexes[1];
                uint   i2            = vertexIndexes[2];
                vec3   p0            = vertexes[i0];
                vec3   p1            = vertexes[i1];
                vec3   p2            = vertexes[i2];
                vec2   uv0           = texCoords[i0];
                vec2   uv1           = texCoords[i1];
                vec2   uv2           = texCoords[i2];

                float x1 = p1.x - p0.x;
                float y1 = p1.y - p0.y;
                float z1 = p1.z - p0.z;
                float x2 = p2.x - p0.x;
                float y2 = p2.y - p0.y;
                float z2 = p2.z - p0.z;

                float s1 = uv1.x - uv0.x;
                float t1 = uv1.y - uv0.y;
                float s2 = uv2.x - uv0.x;
                float t2 = uv2.y - uv0.y;

                float r    = 1.0F / (s1 * t2 - s2 * t1);
                var   sdir = new vec3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
                                      (t2 * z1 - t1 * z2) * r);
                var tdir = new vec3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
                                    (s1 * z2 - s2 * z1) * r);

                //tangents[i0] += sdir;
                tangents[i0] = (float)i / (float)(i + 1) * tangents[i0] + sdir / (float)(i + 1);
                //tangents[i1] += sdir;
                tangents[i1] = (float)i / (float)(i + 1) * tangents[i1] + sdir / (float)(i + 1);
                //tangents[i2] += sdir;
                tangents[i2] = (float)i / (float)(i + 1) * tangents[i2] + sdir / (float)(i + 1);

                //biTangents[i0] += tdir;
                biTangents[i0] = (float)i / (float)(i + 1) * biTangents[i0] + sdir / (float)(i + 1);
                //biTangents[i1] += tdir;
                biTangents[i1] = (float)i / (float)(i + 1) * biTangents[i1] + sdir / (float)(i + 1);
                //biTangents[i2] += tdir;
                biTangents[i2] = (float)i / (float)(i + 1) * biTangents[i2] + sdir / (float)(i + 1);
            }

            var finalTangents = new vec4[normals.Length];

            for (long a = 0; a < normals.Length; a++)
            {
                vec3 n = normals[a];
                vec3 t = tangents[a];

                // Calculate handedness
                float w = (n.cross(t).dot(biTangents[a]) < 0.0F) ? -1.0F : 1.0F;

                // Gram-Schmidt orthogonalize
                finalTangents[a] = new vec4((t - n * n.dot(t)).normalize(), w);
            }

            mesh.tangents = finalTangents;
        }