예제 #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);
        }
예제 #2
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;
                }
            }
        }
예제 #3
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);
        }
예제 #4
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);
            }
        }
예제 #5
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;
        }