예제 #1
0
        /// <summary>
        /// Set the heading of the camera as an angle in degrees.
        /// </summary>
        /// <param name="angle">The camera's new heading (clamped -90 to 90).</param>
        public void RotateHeadingTo(float angle)
        {
            heading = angle;

            //heading constraints of (-90 <= heading <= 90)
            if (heading >= 90)
            {
                heading = 90;
            }

            if (heading <= -90)
            {
                heading = -90;
            }

            //the radius of the circle that the up axis will have to lie on - think of a unit sphere as differently sized circles stacked vertically.
            float headingRad = heading * (MathHelper.Pi / 180f);
            float radius     = (float)Math.Sin(headingRad);

            //The cos of the heading will get us the height of the up axis.
            upAxis.Y = (float)Math.Cos(headingRad);

            //X and Z: rotate right axis 90 degrees for the direction of upAxis on the X/Z plane,
            //use cos/sin to get the X and Z coordinates in the unit circle in the middle of the sphere (think of stacked circles again),
            //scale by our new radius to get X and Z coordinates on the circle that upAxis.Y is on (multiply by radius)
            float headingDirection = (pitch + 90) * (MathHelper.Pi / 180f);

            upAxis.X = radius * (float)Math.Cos(headingDirection);
            upAxis.Z = radius * (float)Math.Sin(headingDirection);

            //update the lookAxis
            lookAxis = Vector3.Normalize(Vector3.Cross(rightAxis, upAxis));

            //update the view matrix so our changes are reflected in the world
            RebuildView();
        }
예제 #2
0
        public void PreviewMesh(Mesh mesh)
        {
            _mesh          = mesh;
            viewMatrixData = Matrix4.CreateRotationY(-(float)Math.PI / 4) * Matrix4.CreateRotationX(-(float)Math.PI / 6);

            if (_vaoModel != 0)
            {
                GL.DeleteVertexArray(_vaoModel);
                GL.DeleteBuffer(_indexBufferObject);
                GL.DeleteBuffer(_vertexBufferObject);
            }

            Visible = true;

            // Vertices
            verticeData = new float[mesh.m_Vertices.Length * 2];
            for (int v = 0; v < mesh.m_Vertices.Length; v += 3)
            {
                for (int i = 0; i < 3; i++)
                {
                    verticeData[v * 2 + i] = mesh.m_Vertices[v + i];
                }
            }

            // Calculate Bounding
            float[] min = new float[3];
            float[] max = new float[3];

            for (int i = 0; i < 3; i++)
            {
                min[i] = verticeData[i];
                max[i] = verticeData[i];
            }

            for (int v = 0; v < verticeData.Length; v += 6)
            {
                for (int i = 0; i < 3; i++)
                {
                    min[i] = Math.Min(min[i], verticeData[v + i]);
                    max[i] = Math.Max(max[i], verticeData[v + i]);
                }
            }

            // Calculate modelMatrix
            Vector3 dist = Vector3.One, offset = Vector3.Zero;

            for (int i = 0; i < 3; i++)
            {
                dist[i]   = max[i] - min[i];
                offset[i] = (max[i] + min[i]) / 2;
            }
            float d = Math.Max(1e-5f, dist.Length);

            modelMatrixData = Matrix4.CreateTranslation(-offset) * Matrix4.CreateScale(2f / d);

            // Indicies
            indiceData = mesh.m_SubMeshes.SelectMany(m => m.indices).ToArray();

            // calculate normal by ourself
            int[] normalCalculatedCount = new int[verticeData.Length / 6];
            for (int i = 0; i < indiceData.Length; i += 3)
            {
                Vector3 vertex0 = new Vector3(verticeData[indiceData[i + 0] * 6], verticeData[indiceData[i + 0] * 6 + 1], verticeData[indiceData[i + 0] * 6 + 2]);
                Vector3 vertex1 = new Vector3(verticeData[indiceData[i + 1] * 6], verticeData[indiceData[i + 1] * 6 + 1], verticeData[indiceData[i + 1] * 6 + 2]);
                Vector3 vertex2 = new Vector3(verticeData[indiceData[i + 2] * 6], verticeData[indiceData[i + 2] * 6 + 1], verticeData[indiceData[i + 2] * 6 + 2]);
                Vector3 normal  = Vector3.Cross(vertex1 - vertex0, vertex2 - vertex0);
                normal.Normalize();
                for (int j = 0; j < 3; j++)
                {
                    verticeData[indiceData[i + j] * 6 + 3] += normal.X;
                    verticeData[indiceData[i + j] * 6 + 4] += normal.Y;
                    verticeData[indiceData[i + j] * 6 + 5] += normal.Z;
                    normalCalculatedCount[indiceData[i + j]]++;
                }
            }
            for (int i = 0; i < normalCalculatedCount.Length; i++)
            {
                if (normalCalculatedCount[i] == 0)
                {
                    verticeData[i * 6 + 3] = 0;
                    verticeData[i * 6 + 4] = 1;
                    verticeData[i * 6 + 5] = 0;
                }
                else
                {
                    verticeData[i * 6 + 3] /= normalCalculatedCount[i];
                    verticeData[i * 6 + 4] /= normalCalculatedCount[i];
                    verticeData[i * 6 + 5] /= normalCalculatedCount[i];
                }
            }

            _vertexBufferObject = GL.GenBuffer();
            GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBufferObject);
            GL.BufferData(BufferTarget.ArrayBuffer, verticeData.Length * sizeof(float), verticeData, BufferUsageHint.StaticDraw);

            _indexBufferObject = GL.GenBuffer();
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, _indexBufferObject);
            GL.BufferData(BufferTarget.ElementArrayBuffer, indiceData.Length * sizeof(uint), indiceData, BufferUsageHint.StaticDraw);

            _vaoModel = GL.GenVertexArray();
            GL.BindVertexArray(_vaoModel);

            var positionLocation = _shader.GetAttribLocation("aPos");

            GL.EnableVertexAttribArray(positionLocation);
            GL.VertexAttribPointer(positionLocation, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 0);

            var normalLocation = _shader.GetAttribLocation("aNormal");

            GL.EnableVertexAttribArray(normalLocation);
            GL.VertexAttribPointer(normalLocation, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), 3 * sizeof(float));

            ChangeGLSize(Size);
            Invalidate();
        }