Beispiel #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 viewMatrix = new mat4(1);
            viewMatrix.col0.x = right.x;
            viewMatrix.col1.x = right.y;
            viewMatrix.col2.x = right.z;
            viewMatrix.col0.y = standardUp.x;
            viewMatrix.col1.y = standardUp.y;
            viewMatrix.col2.y = standardUp.z;
            viewMatrix.col0.z = back.x;
            viewMatrix.col1.z = back.y;
            viewMatrix.col2.z = back.z;

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

            return viewMatrix;
        }
Beispiel #2
0
        /// <summary>
        /// 把连续16个float值按照列优先的顺序转换为mat4
        /// </summary>
        /// <param name="values"></param>
        /// <param name="startIndex"></param>
        /// <returns></returns>
        public static mat4 ToMat4(this float[] values, int startIndex = 0)
        {
            mat4 result = new mat4(
                values.ToVec4(startIndex + 0), values.ToVec4(startIndex + 4), values.ToVec4(startIndex + 8), values.ToVec4(startIndex + 12));

            return result;
        }
        /// <summary>
        /// Move vertexes' position accroding to difference on screen.
        /// <para>根据<paramref name="differenceOnScreen"/>来修改指定索引处的顶点位置。</para>
        /// </summary>
        /// <param name="differenceOnScreen"></param>
        /// <param name="viewMatrix"></param>
        /// <param name="projectionMatrix"></param>
        /// <param name="viewport"></param>
        /// <param name="positionIndexes"></param>
        public override void MovePositions(Point differenceOnScreen,
            mat4 viewMatrix, mat4 projectionMatrix, vec4 viewport, params uint[] positionIndexes)
        {
            base.MovePositions(differenceOnScreen, viewMatrix, projectionMatrix, viewport, positionIndexes);

            this.needsUpdating = true;
        }
        /// <summary>
        /// Move vertexes' position accroding to difference on screen.
        /// <para>根据<paramref name="differenceOnScreen"/>来修改指定索引处的顶点位置。</para>
        /// </summary>
        /// <param name="differenceOnScreen"></param>
        /// <param name="viewMatrix"></param>
        /// <param name="projectionMatrix"></param>
        /// <param name="viewport"></param>
        /// <param name="positionIndexes"></param>
        public virtual void MovePositions(Point differenceOnScreen,
            mat4 viewMatrix, mat4 projectionMatrix, vec4 viewport, params uint[] positionIndexes)
        {
            if (positionIndexes == null) { return; }
            if (positionIndexes.Length == 0) { return; }

            this.innerPickableRenderer.MovePositions(differenceOnScreen, viewMatrix, projectionMatrix, viewport, positionIndexes);
        }
        /// <summary>
        /// Move vertexes' position accroding to difference on screen.
        /// <para>根据<paramref name="differenceOnScreen"/>来修改指定索引处的顶点位置。</para>
        /// </summary>
        /// <param name="differenceOnScreen"></param>
        /// <param name="viewMatrix"></param>
        /// <param name="projectionMatrix"></param>
        /// <param name="viewport"></param>
        /// <param name="positionIndexes"></param>
        public virtual void MovePositions(Point differenceOnScreen,
            mat4 viewMatrix, mat4 projectionMatrix, vec4 viewport, IEnumerable<uint> positionIndexes)
        {
            if (positionIndexes == null) { return; }
            if (positionIndexes.Count() == 0) { return; }

            this.innerPickableRenderer.MovePositions(differenceOnScreen, viewMatrix, projectionMatrix, viewport, positionIndexes);
        }
        mat4 IPerspectiveCamera.GetPerspectiveProjectionMatrix()
        {
            if (perspectiveCameraRecord.IsMarked())
            {
                var camera = this as IPerspectiveCamera;
                perspectiveProjectionMatrix = glm.perspective(
                    (float)(camera.FieldOfView * Math.PI / 180.0f),
                    (float)camera.AspectRatio, (float)camera.Near, (float)camera.Far);
                perspectiveCameraRecord.CancelMark();
            }

            return perspectiveProjectionMatrix;
        }
Beispiel #7
0
        /// <summary>
        /// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite.
        /// </summary>
        /// <param name="fovy">The fovy.</param>
        /// <param name="aspect">The aspect.</param>
        /// <param name="zNear">The z near.</param>
        /// <returns></returns>
        public static mat4 infinitePerspective(float fovy, float aspect, float zNear)
        {
            float range = tan(fovy / (2f)) * zNear;

            float left = -range * aspect;
            float right = range * aspect;
            float bottom = -range;
            float top = range;

            var result = new mat4(0);
            result[0, 0] = ((2f) * zNear) / (right - left);
            result[1, 1] = ((2f) * zNear) / (top - bottom);
            result[2, 2] = -(1f);
            result[2, 3] = -(1f);
            result[3, 2] = -(2f) * zNear;
            return result;
        }
Beispiel #8
0
        public void CastShadow(ShdowMappingEventArgs arg)
        {
            if (!this.IsInitialized)
            {
                this.Initialize();
            }

            LightBase light      = arg.CurrentLight;
            mat4      projection = light.GetProjectionMatrix();
            mat4      view       = light.GetViewMatrix();
            mat4      model      = this.GetModelMatrix();

            var           method  = this.RenderUnit.Methods[0]; // shadowmapBuilder
            ShaderProgram program = method.Program;

            program.SetUniform(mvpMatrix, projection * view * model);

            method.Render();
        }
Beispiel #9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="arg"></param>
        public void RenderBeforeChildren(RenderEventArgs arg)
        {
            if (!this.IsInitialized)
            {
                this.Initialize();
            }

            if (this.AutoRotate)
            {
                float delta = 6;
                this.RotationAngle += delta;
                var position = new vec3(
                    (float)Math.Cos(this.RotationAngle * Math.PI / 180.0),
                    (float)Math.Cos(this.RotationAngle / 5 * Math.PI / 180.0) + 2.2f,
                    (float)Math.Sin(this.RotationAngle * Math.PI / 180.0)) * 8;
                this.light.Position = position;
                if (this.light is DirectionalLight)
                {
                    (this.light as DirectionalLight).Direction = position;
                }
                else if (this.light is SpotLight)
                {
                    //(this.light as SpotLight).Target = position;
                }

                this.WorldPosition = position;
            }

            ICamera camera     = arg.Camera;
            mat4    projection = camera.GetProjectionMatrix();
            mat4    view       = camera.GetViewMatrix();
            mat4    model      = this.GetModelMatrix();

            var           method  = this.RenderUnit.Methods[0]; // the only render unit in this node.
            ShaderProgram program = method.Program;

            program.SetUniform(projectionMatrix, projection);
            program.SetUniform(viewMatrix, view);
            program.SetUniform(modelMatrix, model);
            program.SetUniform(color, this.light.Diffuse);

            method.Render();
        }
Beispiel #10
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="arg"></param>
        public void RenderBeforeChildren(RenderEventArgs arg)
        {
            if (!this.IsInitialized) { Initialize(); }

            ICamera camera = arg.Camera;
            mat4 projection = camera.GetProjectionMatrix();
            mat4 view = camera.GetViewMatrix();
            mat4 model = this.GetModelMatrix();
            var viewport = new int[4];
            GL.Instance.GetIntegerv((uint)GetTarget.Viewport, viewport);

            var method = this.RenderUnit.Methods[0]; // the only render unit in this node.
            ShaderProgram program = method.Program;
            program.SetUniform(projectionMatrix, projection);
            program.SetUniform(viewMatrix, view);
            program.SetUniform(modelMatrix, model);
            program.SetUniform(screenSize, new ivec2(viewport[2], viewport[3]));

            method.Render();
        }
Beispiel #11
0
        protected override void DoRender(RenderEventArgs arg)
        {
            var source = this.TextureSource;

            if (source != null)
            {
                this.SetUniform(tex, source.BindingTexture);
            }
            ICamera camera     = arg.CameraStack.Peek();
            mat4    projection = camera.GetProjectionMatrix();
            mat4    view       = camera.GetViewMatrix();
            mat4    model      = this.GetModelMatrix();

            this.SetUniform(projectionMatrix, projection);
            this.SetUniform(viewMatrix, view);
            this.SetUniform(modelMatrix, model);
            this.SetUniform(transparentBackground, this.TransparentBackground);

            base.DoRender(arg);
        }
Beispiel #12
0
        protected override void DoRender(RenderEventArgs arg)
        {
            this.RotationAngle += this.RotateSpeed;

            //var viewport = new int[4];
            ////	Get the viewport, then convert the mouse point to an opengl point.
            //GL.Instance.GetIntegerv((uint)GetTarget.Viewport, viewport);
            //////	Push matrix, set up projection, then load matrix.
            //mat4 pickMatrix = glm.pickMatrix(new vec2(viewport[2] / 2, viewport[3] / 2), new vec2(viewport[2], viewport[3]), new ivec4(viewport[0], viewport[1], viewport[2], viewport[3]));
            ICamera camera     = arg.CameraStack.Peek();
            mat4    projection = camera.GetProjectionMatrix();
            mat4    view       = camera.GetViewMatrix();
            mat4    model      = this.GetModelMatrix();

            this.SetUniform("projectionMatrix", projection);
            this.SetUniform("viewMatrix", view);
            this.SetUniform("modelMatrix", model);

            base.DoRender(arg);
        }
Beispiel #13
0
        //protected override void DoInitialize()
        //{
        //    base.DoInitialize();
        //    int location;
        //    location = this.shaderProgram.GetUniformLocation(projection);
        //    if (location < 0)
        //    { throw new Exception(string.Format("No uniform found for the name [{0}]", projection)); }
        //    else
        //    { this.projectionLocation = (uint)location; }
        //    location = this.shaderProgram.GetUniformLocation(view);
        //    if (location < 0)
        //    { throw new Exception(string.Format("No uniform found for the name [{0}]", view)); }
        //    else
        //    { this.viewLocation = (uint)location; }
        //    location = this.shaderProgram.GetUniformLocation(model);
        //    if (location < 0)
        //    { throw new Exception(string.Format("No uniform found for the name [{0}]", model)); }
        //    else
        //    { this.modelLocation = (uint)location; }
        //}
        protected bool TryGetMatrix(RenderEventArgs arg,
            out mat4 projection, out mat4 view, out mat4 model)
        {
            projection = arg.Camera.GetProjectionMat4();
            view = arg.Camera.GetViewMat4();

            SceneObject bindingObject = this.BindingObject;
            if (bindingObject != null)
            {
                model = bindingObject.Transform.GetModelMatrix();

                return true;
            }
            else
            {
                model = new mat4();

                return false;
            }
        }
Beispiel #14
0
        protected override void DoRender(RenderEventArgs arg)
        {
            ICamera camera     = arg.CameraStack.Peek();
            mat4    projection = camera.GetProjectionMatrix();
            mat4    view       = camera.GetViewMatrix();
            mat4    model      = this.GetModelMatrix();
            var     viewport   = new int[4];

            GL.Instance.GetIntegerv((uint)GetTarget.Viewport, viewport);
            this.SetUniform(projectionMatrix, projection);
            this.SetUniform(viewMatrix, view);
            this.SetUniform(modelMatrix, model);
            this.SetUniform(width, this._width);
            this.SetUniform(height, this._height);
            this.SetUniform(screenSize, new vec2(viewport[2], viewport[3]));
            this.SetUniform(tex, this.textureSource.BindingTexture);
            this.SetUniform(transparentBackground, this.TransparentBackground);
            this.SetUniform(delta, this.Delta);

            base.DoRender(arg);
        }
Beispiel #15
0
        /// <summary>
        /// Update and Get cascade model matrix.
        /// </summary>
        /// <param name="parentCascadeModelMatrix"></param>
        /// <returns></returns>
        public mat4 GetModelMatrix(mat4 parentCascadeModelMatrix)
        {
            if (this.worldSpacePropertyUpdated)
            {
                mat4 matrix = glm.translate(mat4.identity(), this.WorldPosition);
                matrix = glm.scale(matrix, this.Scale);
                matrix = glm.rotate(matrix, this.RotationAngle, this.RotationAxis);
                this.thisModelMatrix           = matrix;
                this.worldSpacePropertyUpdated = false;

                matrix = parentCascadeModelMatrix * matrix;

                this.cascadeModelMatrix = matrix;
            }
            else
            {
                this.cascadeModelMatrix = parentCascadeModelMatrix * this.thisModelMatrix;
            }

            return(this.cascadeModelMatrix);
        }
Beispiel #16
0
        public void RenderBeforeChildren(RenderEventArgs arg)
        {
            // gets mvpMat.
            ICamera camera        = arg.Camera;
            mat4    projectionMat = camera.GetProjectionMatrix();
            mat4    viewMat       = camera.GetViewMatrix();
            mat4    modelMat      = this.GetModelMatrix();
            mat4    mvpMat        = projectionMat * viewMat * modelMat;
            // a render uint wraps everything(model data, shaders, glswitches, etc.) for rendering.
            ModernRenderUnit unit = this.RenderUnit;
            // gets render method.
            // There could be more than 1 method(vertex shader + fragment shader) to render the same model data. Thus we need an method array.
            RenderMethod method = unit.Methods[0];
            // shader program wraps vertex shader and fragment shader.
            ShaderProgram program = method.Program;

            //set value for 'uniform mat4 mvpMat'; in shader.
            program.SetUniform("mvpMat", mvpMat);
            // render the cube model via OpenGL.
            method.Render();
        }
Beispiel #17
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="arg"></param>
        protected override void DoRender(CSharpGL.RenderEventArgs arg)
        {
            mat4 projection = arg.Camera.GetProjectionMatrix();
            mat4 view       = arg.Camera.GetViewMatrix();

            this.SetUniform("projectionMatrix", projection);
            this.SetUniform("viewMatrix", view);
            if (this.modelMatrixRecord.IsMarked())
            {
                mat4 model = this.GetModelMatrix();
                this.SetUniform("modelMatrix", model);
                this.modelMatrixRecord.CancelMark();
            }
            if (this.pointColorRecord.IsMarked())
            {
                this.SetUniform("PointColor", this.pointColor);
                this.pointColorRecord.CancelMark();
            }

            base.DoRender(arg);
        }
 /// <summary>
 /// Move vertexes' position accroding to difference on screen.
 /// <para>根据<paramref name="differenceOnScreen"/>来修改指定索引处的顶点位置。</para>
 /// </summary>
 /// <param name="differenceOnScreen"></param>
 /// <param name="viewMatrix"></param>
 /// <param name="projectionMatrix"></param>
 /// <param name="viewport"></param>
 /// <param name="positionIndexes"></param>
 public void MovePositions(Point differenceOnScreen,
     mat4 viewMatrix, mat4 projectionMatrix, vec4 viewport, params uint[] positionIndexes)
 {
     IntPtr pointer = this.PositionBuffer.MapBuffer(MapBufferAccess.ReadWrite);
     unsafe
     {
         mat4 modelMatrix = this.GetModelMatrix().Value;
         mat4 modelViewMatrix = viewMatrix * modelMatrix;
         var array = (vec3*)pointer.ToPointer();
         foreach (uint index in positionIndexes)
         {
             vec3 windowPos = glm.project(array[index],
                 modelViewMatrix, projectionMatrix, viewport);
             var newWindowPos = new vec3(windowPos.x + differenceOnScreen.X,
                 windowPos.y + differenceOnScreen.Y, windowPos.z);
             array[index] = glm.unProject(newWindowPos,
                 modelViewMatrix, projectionMatrix, viewport);
         }
     }
     this.PositionBuffer.UnmapBuffer();
 }
Beispiel #19
0
        /// <summary>
        /// Builds a perspective projection matrix based on a field of view.
        /// </summary>
        /// <param name="fov">The fov (in radians).</param>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <param name="zNear">The z near.</param>
        /// <param name="zFar">The z far.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentOutOfRangeException"></exception>
        public static mat4 perspectiveFov(float fov, float width, float height, float zNear, float zFar)
        {
            if (width <= 0 || height <= 0 || fov <= 0)
            {
                throw new ArgumentOutOfRangeException();
            }

            var rad = fov;

            var h = glm.cos((0.5f) * rad) / glm.sin((0.5f) * rad);
            var w = h * height / width;

            var result = new mat4(0);

            result[0, 0] = w;
            result[1, 1] = h;
            result[2, 2] = -(zFar + zNear) / (zFar - zNear);
            result[2, 3] = -(1f);
            result[3, 2] = -((2f) * zFar * zNear) / (zFar - zNear);
            return(result);
        }
Beispiel #20
0
        internal override bool SetValue(ValueType value)
        {
            if (value.GetType() != typeof(mat4))
            {
                throw new ArgumentException(string.Format("[{0}] not match [{1}]'s value.",
                                                          value.GetType().Name, this.GetType().Name));
            }

            var v = (mat4)value;

            if (v != this.value)
            {
                this.value   = v;
                this.Updated = true;
                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #21
0
        /// <summary>
        /// Define a picking region.
        /// </summary>
        /// <param name="center">The center.</param>
        /// <param name="delta">The delta.</param>
        /// <param name="viewport">The viewport.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentOutOfRangeException"></exception>
        public static mat4 pickMatrix(ivec2 center, ivec2 delta, ivec4 viewport)
        {
            if (delta.x <= 0 || delta.y <= 0)
            {
                throw new ArgumentOutOfRangeException();
            }
            var Result = new mat4(1.0f);

            if (!(delta.x > (0f) && delta.y > (0f)))
            {
                return(Result); // Error
            }
            vec3 Temp = new vec3(
                ((viewport[2]) - (2f) * (center.x - (viewport[0]))) / delta.x,
                ((viewport[3]) - (2f) * (center.y - (viewport[1]))) / delta.y,
                (0f));

            // Translate and scale the picked region to the entire window
            Result = translate(Result, Temp);
            return(scale(Result, new vec3((float)(viewport[2]) / delta.x, (float)(viewport[3]) / delta.y, (1))));
        }
        /// <summary>
        /// render with specified index buffer.
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="temporaryIndexBuffer"></param>
        private void Render4Picking(RenderEventArgs arg, IndexBuffer temporaryIndexBuffer)
        {
            UpdatePolygonMode(arg.PickingGeometryType);

            ShaderProgram program = this.Program;

            // 绑定shader
            program.Bind();
            program.glUniform("pickingBaseId", 0);
            UniformMat4 uniformmMVP4Picking = this.uniformmMVP4Picking;

            {
                mat4 projection = arg.Camera.GetProjectionMatrix();
                mat4 view       = arg.Camera.GetViewMatrix();
                mat4 model      = this.GetModelMatrix().Value;
                uniformmMVP4Picking.Value = projection * view * model;
            }
            uniformmMVP4Picking.SetUniform(program);

            PickingStateesOn();
            var oneIndexBuffer = temporaryIndexBuffer as OneIndexBuffer;

            if (oneIndexBuffer != null)
            {
                PrimitiveRestartState glState = this.GetPrimitiveRestartState(oneIndexBuffer);
                glState.On();
                this.vertexArrayObject.Render(arg, program, temporaryIndexBuffer);
                glState.Off();
            }
            else
            {
                this.vertexArrayObject.Render(arg, program, temporaryIndexBuffer);
            }
            PickingStateesOff();

            //if (mvpUpdated) { uniformmMVP4Picking.ResetUniform(program); }

            // 解绑shader
            program.Unbind();
        }
Beispiel #23
0
        void IMouseHandler.canvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (this.mouseDownFlag &&
                ((e.Button & this.lastBindingMouseButtons) != MouseButtons.None))
            {
                IViewCamera camera = this.camera;
                if (camera == null)
                {
                    return;
                }

                Point newPosition      = e.Location;
                int   diffX            = newPosition.X - this.lastPosition.X;
                int   diffY            = newPosition.Y - this.lastPosition.Y;
                mat4  viewMatrix       = this.camera.GetViewMatrix();
                mat4  projectionMatrix = this.camera.GetProjectionMatrix();
                vec3  cameraPosition   = this.camera.Position;
                vec4  viewport;
                {
                    int[] tmp = OpenGL.GetViewport();
                    viewport = new vec4(tmp[0], tmp[1], tmp[2], tmp[3]);
                }
                vec3 windowPos = glm.project(cameraPosition,
                                             viewMatrix, projectionMatrix, viewport);
                var newWindowPos = new vec3(windowPos.x - diffX,
                                            windowPos.y + diffY, windowPos.z);
                vec3 newCameraPosition = glm.unProject(newWindowPos,
                                                       viewMatrix, projectionMatrix, viewport);
                vec3 cameraDiff = newCameraPosition - cameraPosition;
                this.camera.Position = newCameraPosition;
                this.camera.Target  += cameraDiff;

                this.lastPosition = newPosition;

                if (this.canvas.RenderTrigger == RenderTrigger.Manual)
                {
                    this.canvas.Repaint();
                }
            }
        }
        /// <summary>
        /// 根据<paramref name="differenceOnScreen"/>来修改指定索引处的顶点位置。
        /// </summary>
        /// <param name="differenceOnScreen"></param>
        /// <param name="viewMatrix"></param>
        /// <param name="projectionMatrix"></param>
        /// <param name="viewport"></param>
        /// <param name="positionIndexes"></param>
        public void MovePositions(Point differenceOnScreen,
                                  mat4 viewMatrix, mat4 projectionMatrix, vec4 viewport, IEnumerable <uint> positionIndexes)
        {
            OpenGL.BindBuffer(BufferTarget.ArrayBuffer, this.positionBufferPtr.BufferId);
            IntPtr pointer = OpenGL.MapBuffer(BufferTarget.ArrayBuffer, MapBufferAccess.ReadWrite);

            unsafe
            {
                var array = (vec3 *)pointer.ToPointer();
                foreach (var index in positionIndexes)
                {
                    vec3 projected = glm.project(array[index],
                                                 viewMatrix, projectionMatrix, viewport);
                    vec3 newProjected = new vec3(projected.x + differenceOnScreen.X,
                                                 projected.y + differenceOnScreen.Y, projected.z);
                    array[index] = glm.unProject(newProjected,
                                                 viewMatrix, projectionMatrix, viewport);
                }
            }
            OpenGL.UnmapBuffer(BufferTarget.ArrayBuffer);
            OpenGL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        }
Beispiel #25
0
        void IMouseHandler.canvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (this.mouseDownFlag &&
                ((e.Button & this.lastBindingMouseButtons) != MouseButtons.None) &&
                (e.X != this.lastPosition.X || e.Y != this.lastPosition.Y))
            {
                mat4 rotationMatrix = glm.rotate(this.HorizontalRotationSpeed * (e.X - this.lastPosition.X), -this.camera.UpVector);
                var  front          = new vec4(this.camera.GetFront(), 1.0f);
                vec4 front1         = rotationMatrix * front;
                rotationMatrix = glm.rotate(this.VerticalRotationSpeed * (this.lastPosition.Y - e.Y), this.camera.GetRight());
                vec4 front2 = rotationMatrix * front1;
                front2             = front2.normalize();
                this.camera.Target = this.camera.Position + new vec3(front2);

                this.lastPosition = e.Location;

                if (this.canvas.RenderTrigger == RenderTrigger.Manual)
                {
                    this.canvas.Invalidate();
                }
            }
        }
Beispiel #26
0
        /// <summary>
        /// 根据<paramref name="differenceOnWindow"/>来修改指定索引处的顶点位置。
        /// </summary>
        /// <param name="differenceOnWindow"></param>
        /// <param name="viewMatrix"></param>
        /// <param name="projectionMatrix"></param>
        /// <param name="viewport"></param>
        /// <param name="positionIndexes"></param>
        public void MovePositions(Point differenceOnWindow,
                                  mat4 viewMatrix, mat4 projectionMatrix, vec4 viewport, params uint[] positionIndexes)
        {
            OpenGL.BindBuffer(BufferTarget.ArrayBuffer, this.positionBufferPtr.BufferId);
            IntPtr pointer = OpenGL.MapBuffer(BufferTarget.ArrayBuffer, MapBufferAccess.ReadWrite);

            unsafe
            {
                var array = (vec3 *)pointer.ToPointer();
                foreach (var index in positionIndexes)
                {
                    vec3 windowPos = glm.project(array[index],
                                                 viewMatrix, projectionMatrix, viewport);
                    vec3 newWindowPos = new vec3(windowPos.x + differenceOnWindow.X,
                                                 windowPos.y + differenceOnWindow.Y, windowPos.z);
                    array[index] = glm.unProject(newWindowPos,
                                                 viewMatrix, projectionMatrix, viewport);
                }
            }
            OpenGL.UnmapBuffer(BufferTarget.ArrayBuffer);
            OpenGL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        }
Beispiel #27
0
        internal override bool SetValue(ValueType value)
        {
            #if DEBUG
            if (value.GetType() != typeof(mat4))
            {
                throw new ArgumentException(string.Format("[{0}] not match [{1}]'s value.",
                    value.GetType().Name, this.GetType().Name));
            }
            #endif

            var v = (mat4)value;
            if (v != this.value)
            {
                this.value = v;
                this.Updated = true;
                return true;
            }
            else
            {
                return false;
            }
        }
Beispiel #28
0
        /// <summary>
        /// Build a look at view matrix.
        /// </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);

            Result[0, 0] = right.x;
            Result[1, 0] = right.y;
            Result[2, 0] = right.z;
            Result[0, 1] = standardUp.x;
            Result[1, 1] = standardUp.y;
            Result[2, 1] = standardUp.z;
            Result[0, 2] = -forward.x;
            Result[1, 2] = -forward.y;
            Result[2, 2] = -forward.z;
            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);
        }
Beispiel #29
0
        public override void RenderBeforeChildren(RenderEventArgs arg)
        {
            if (!this.IsInitialized)
            {
                this.Initialize();
            }

            this.RotationAngle += this.RotateSpeed;

            ICamera camera     = arg.CameraStack.Peek();
            mat4    projection = camera.GetProjectionMatrix();
            mat4    view       = camera.GetViewMatrix();
            mat4    model      = this.GetModelMatrix();

            var           method  = this.RenderUnit.Methods[0]; // the only render unit in this node.
            ShaderProgram program = method.Program;

            program.SetUniform(projectionMatrix, projection);
            program.SetUniform(viewMatrix, view);
            program.SetUniform(modelMatrix, model);

            if (this.RenderWireframe)
            {
                // render wireframe.
                program.SetUniform("renderWireframe", true);
                polygonMode.On();
                polygonOffsetState.On();
                method.Render();
                polygonOffsetState.Off();
                polygonMode.Off();
            }

            if (this.RenderBody)
            {
                // render solid body.
                program.SetUniform("renderWireframe", false);
                method.Render();
            }
        }
Beispiel #30
0
        public override void RenderBeforeChildren(RenderEventArgs arg)
        {
            if (!this.IsInitialized) { Initialize(); }

            ICamera camera = arg.CameraStack.Peek();
            mat4 projection = camera.GetProjectionMatrix();
            mat4 view = camera.GetViewMatrix();
            mat4 model = this.GetModelMatrix();

            var method = this.RenderUnit.Methods[0];
            ShaderProgram program = method.Program;
            program.SetUniform(model_matrix, model);
            program.SetUniform(view_matrix, view);
            program.SetUniform(projection_matrix, projection);
            program.SetUniform(light_position, new vec3(view * new vec4(LightPosition, 1.0f)));
            //program.SetUniform(material_ambient, this.Ambient);
            program.SetUniform(material_diffuse, this.Diffuse);
            program.SetUniform(material_specular, this.Specular);
            program.SetUniform(material_specular_power, this.SpecularPower);

            method.Render();
        }
Beispiel #31
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="arg"></param>
        protected override void DoRender(CSharpGL.RenderEventArgs arg)
        {
            mat4 projection = arg.Camera.GetProjectionMatrix();
            mat4 view       = arg.Camera.GetViewMatrix();

            this.SetUniform("projectionMatrix", projection);
            this.SetUniform("viewMatrix", view);
            MarkableStruct <mat4> model = this.GetModelMatrix();

            if (this.modelTicks != model.UpdateTicks)
            {
                this.SetUniform("modelMatrix", model.Value);
                this.modelTicks = model.UpdateTicks;
            }
            if (this.pointColorRecord.IsMarked())
            {
                this.SetUniform("PointColor", this.pointColor);
                this.pointColorRecord.CancelMark();
            }

            base.DoRender(arg);
        }
 public AdjacentCubeModel(vec3 size)
 {
     this.size = size;
     size      = size / 2;
     {
         var instancePositions = new vec3[positions.Length];
         for (int i = 0; i < positions.Length; i++)
         {
             instancePositions[i] = positions[i] * size;
         }
         this.instancePositions = instancePositions;
     }
     {
         mat4 matrix          = glm.transpose(glm.inverse(glm.scale(mat4.identity(), size)));
         var  instanceNormals = new vec3[normals.Length];
         for (int i = 0; i < normals.Length; i++)
         {
             instanceNormals[i] = new vec3((matrix * new vec4(normals[i], 0))).normalize();
         }
         this.instanceNormals = instanceNormals;
     }
 }
Beispiel #33
0
        public override void RenderBeforeChildren(RenderEventArgs arg)
        {
            if (!this.IsInitialized)
            {
                this.Initialize();
            }

            ICamera camera     = arg.CameraStack.Peek();
            mat4    projection = camera.GetProjectionMatrix();
            mat4    view       = camera.GetViewMatrix();
            mat4    model      = this.GetModelMatrix();

            var           method  = this.RenderUnit.Methods[0]; // the only render unit in this node.
            ShaderProgram program = method.Program;

            program.SetUniform(projectionMatrix, projection);
            program.SetUniform(viewMatrix, view);
            program.SetUniform(modelMatrix, model);
            program.SetUniform(color, this.Color);

            method.Render();
        }
        /// <summary>
        /// Move vertexes' position accroding to difference on screen.
        /// <para>根据<paramref name="differenceOnScreen"/>来修改指定索引处的顶点位置。</para>
        /// </summary>
        /// <param name="differenceOnScreen"></param>
        /// <param name="viewMatrix"></param>
        /// <param name="projectionMatrix"></param>
        /// <param name="viewport"></param>
        /// <param name="positionIndexes"></param>
        public void MovePositions(Point differenceOnScreen,
                                  mat4 viewMatrix, mat4 projectionMatrix, vec4 viewport, params uint[] positionIndexes)
        {
            IntPtr pointer = this.PositionBufferPtr.MapBuffer(MapBufferAccess.ReadWrite);

            unsafe
            {
                mat4 modelMatrix     = this.GetModelMatrix();
                mat4 modelViewMatrix = viewMatrix * modelMatrix;
                var  array           = (vec3 *)pointer.ToPointer();
                foreach (var index in positionIndexes)
                {
                    vec3 windowPos = glm.project(array[index],
                                                 modelViewMatrix, projectionMatrix, viewport);
                    var newWindowPos = new vec3(windowPos.x + differenceOnScreen.X,
                                                windowPos.y + differenceOnScreen.Y, windowPos.z);
                    array[index] = glm.unProject(newWindowPos,
                                                 modelViewMatrix, projectionMatrix, viewport);
                }
            }
            this.PositionBufferPtr.UnmapBuffer();
        }
Beispiel #35
0
        public void RenderBeforeChildren(RenderEventArgs arg)
        {
            if (!this.IsInitialized)
            {
                this.Initialize();
            }

            ICamera camera     = arg.Camera;
            mat4    projection = camera.GetProjectionMatrix();
            mat4    view       = camera.GetViewMatrix();
            mat4    model      = this.GetModelMatrix();

            var           method  = this.RenderUnit.Methods[0]; // renderBuilder
            ShaderProgram program = method.Program;

            program.SetUniform(projectionMat, projection);
            program.SetUniform(viewMat, view);
            program.SetUniform(modelMat, model);
            program.SetUniform(color, this.Color);

            method.Render();
        }
Beispiel #36
0
        void IMouseHandler.canvas_MouseMove(object sender, GLMouseEventArgs e)
        {
            if (mouseDownFlag && ((e.Button & this.lastBindingMouseButtons) != GLMouseButtons.None))
            {
                if (!cameraState.IsSameState(this.camera))
                {
                    SetCamera(this.camera.Position, this.camera.Target, this.camera.UpVector);
                }

                this._endPosition = GetArcBallPosition(e.X, e.Y);
                var cosRadian = _startPosition.dot(_endPosition) / (_startPosition.length() * _endPosition.length());
                if (cosRadian > 1.0f)
                {
                    cosRadian = 1.0f;
                }
                else if (cosRadian < -1)
                {
                    cosRadian = -1.0f;
                }
                float angle = MouseSensitivity * (float)(Math.Acos(cosRadian) / 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;
                }

                IGLCanvas canvas = this.canvas;
                if (canvas != null && canvas.RenderTrigger == RenderTrigger.Manual)
                {
                    canvas.Repaint();
                }
            }
        }
Beispiel #37
0
        public void RenderBeforeChildren(RenderEventArgs arg)
        {
            if (!this.IsInitialized)
            {
                this.Initialize();
            }

            ICamera camera     = arg.Camera;
            mat4    projection = camera.GetProjectionMatrix();
            mat4    view       = camera.GetViewMatrix();
            mat4    model      = this.GetModelMatrix();

            var           method  = this.RenderUnit.Methods[0]; // the only render unit in this node.
            ShaderProgram program = method.Program;

            program.SetUniform(projectionMatrix, projection);
            program.SetUniform(viewMatrix, view);
            program.SetUniform(modelMatrix, model);
            program.SetUniform(tex, this.texture);
            program.SetUniform(alpha, this.Alpha);

            method.Render();
        }
Beispiel #38
0
        void IMouseHandler.canvas_MouseMove(object sender, GLMouseEventArgs e)
        {
            if (mouseDownFlag && ((e.Button & this.lastBindingMouseButtons) != GLMouseButtons.None))
            {
                if (!cameraState.IsSameState(this.camera))
                {
                    SetCamera(this.camera.Position, this.camera.Target, this.camera.UpVector);
                }

                Point location           = new Point(e.X, this.canvas.Height - e.Y - 1);
                Point differenceOnScreen = new Point(location.X - this._lastPosition.X, location.Y - this._lastPosition.Y);
                mat4  model      = this.renderer.GetModelMatrix();
                mat4  view       = this.camera.GetViewMatrix();
                mat4  projection = this.camera.GetProjectionMatrix();
                vec4  viewport;
                {
                    var result = new int[4];
                    GL.Instance.GetIntegerv((uint)GetTarget.Viewport, result);
                    viewport = new vec4(result[0], result[1], result[2], result[3]);
                }
                var  position         = new vec3(0.0f);// imangine we have a point at (0, 0, 0).
                vec3 windowPos        = glm.project(position, view * model, projection, viewport);
                var  newWindowPos     = new vec3(windowPos.x + differenceOnScreen.X, windowPos.y + differenceOnScreen.Y, windowPos.z);
                vec3 newPosition      = glm.unProject(newWindowPos, view * model, projection, viewport);
                var  worldPosition    = new vec3(model * new vec4(position, 1.0f));
                var  newWorldPosition = new vec3(model * new vec4(newPosition, 1.0f));
                this.renderer.WorldPosition += newWorldPosition - worldPosition;

                this._lastPosition = location;

                IGLCanvas canvas = this.canvas;
                if (canvas != null && canvas.RenderTrigger == RenderTrigger.Manual)
                {
                    canvas.Repaint();
                }
            }
        }
Beispiel #39
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="arg"></param>
        protected override void DoRender(RenderEventArgs arg)
        {
            if (this.modelMatrixRecord.IsMarked())
            {
                this.SetUniform("billboardCenter_worldspace",
                                this.ModelMatrix.GetTranslate());
                this.modelMatrixRecord.CancelMark();
            }
            if (labelHeightRecord.IsMarked())
            {
                this.SetUniform("labelHeight", this.LabelHeight);
                labelHeightRecord.CancelMark();
            }
            if (textRecord.IsMarked())
            {
                if (this.model != null)
                {
                    this.model.SetText(this.text, this.fontTexture);
                }
            }
            if (discardTransparencyRecord.IsMarked())
            {
                bool discard = this.DiscardTransparency;
                this.SetUniform("discardTransparency", discard);
                this.blendSwitch.InUse = discard;
            }
            int[] viewport = OpenGL.GetViewport();
            this.SetUniform("viewportSize", new vec2(viewport[2], viewport[3]));
            mat4 projection = arg.Camera.GetProjectionMat4();
            mat4 view       = arg.Camera.GetViewMat4();

            this.SetUniform("projection", projection);
            this.SetUniform("view", view);

            base.DoRender(arg);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="arg"></param>
        public void Render4Picking(RenderEventArgs arg)
        {
            if (!this.IsInitialized)
            {
                this.Initialize();
            }

            UpdatePolygonMode(arg.PickingGeometryType);

            ShaderProgram program = this.Program;

            // 绑定shader
            program.Bind();
            program.glUniform("pickingBaseId",
                              (int)this.PickingBaseId);
            UniformMat4 uniformmMVP4Picking = this.uniformmMVP4Picking;

            {
                mat4 projection = arg.Camera.GetProjectionMatrix();
                mat4 view       = arg.Camera.GetViewMatrix();
                mat4 model      = this.GetModelMatrix().Value;
                uniformmMVP4Picking.Value = projection * view * model;
            }
            uniformmMVP4Picking.SetUniform(program);

            PickingStateesOn();

            this.vertexArrayObject.Render(arg, program);

            PickingStateesOff();

            //if (mvpUpdated) { uniformmMVP4Picking.ResetUniform(program); }

            // 解绑shader
            program.Unbind();
        }
        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 cosRadian = _startPosition.dot(_endPosition) / (_startPosition.length() * _endPosition.length());
                if (cosRadian > 1.0f) { cosRadian = 1.0f; }
                else if (cosRadian < -1) { cosRadian = -1.0f; }
                float angle = MouseSensitivity * (float)(Math.Acos(cosRadian) / 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;
                }
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public mat4 GetViewMatrix()
        {
            if (this.viewMatrixRecord.IsMarked())
            {
                this.viewMatrix = glm.lookAt(this.position, this.target, this.upVector);
                this.viewMatrixRecord.CancelMark();
            }

            return this.viewMatrix;
        }
        public bool SetUniform(string varNameInShader, mat4[] value)
        {
            bool gotUniform = false;
            bool updated = false;
            if (value.Length <= 0) { return updated; }

            foreach (var item in this.uniformVariables)
            {
                if (item.VarName == varNameInShader)
                {
                    (item as UniformMat4Array).Value = value;
                    updated = true;
                    gotUniform = true;
                    break;
                }
            }

            if (!gotUniform)
            {
                int location = ShaderProgram.GetUniformLocation(varNameInShader);
                if (location < 0)
                {
                    throw new Exception(string.Format(
                        "uniform variable [{0}] not exists!", varNameInShader));
                }

                var variable = GetVariableArray(value, varNameInShader) as UniformMat4Array;
                variable.Value = value;
                this.uniformVariables.Add(variable);
                updated = true;
            }

            return updated;
        }
Beispiel #44
0
        /// <summary>
        /// Multiplies the <paramref name="lhs"/> matrix by the <paramref name="rhs"/> matrix.
        /// </summary>
        /// <param name="lhs">The LHS matrix.</param>
        /// <param name="rhs">The RHS matrix.</param>
        /// <returns>The product of <paramref name="lhs"/> and <paramref name="rhs"/>.</returns>
        public static mat4 operator *(mat4 lhs, mat4 rhs)
        {
            mat4 result = new mat4(
                new vec4(
                    lhs[0][0] * rhs[0][0] + lhs[1][0] * rhs[0][1] + lhs[2][0] * rhs[0][2] + lhs[3][0] * rhs[0][3],
                    lhs[0][1] * rhs[0][0] + lhs[1][1] * rhs[0][1] + lhs[2][1] * rhs[0][2] + lhs[3][1] * rhs[0][3],
                    lhs[0][2] * rhs[0][0] + lhs[1][2] * rhs[0][1] + lhs[2][2] * rhs[0][2] + lhs[3][2] * rhs[0][3],
                    lhs[0][3] * rhs[0][0] + lhs[1][3] * rhs[0][1] + lhs[2][3] * rhs[0][2] + lhs[3][3] * rhs[0][3]
                    ),
                new vec4(
                    lhs[0][0] * rhs[1][0] + lhs[1][0] * rhs[1][1] + lhs[2][0] * rhs[1][2] + lhs[3][0] * rhs[1][3],
                    lhs[0][1] * rhs[1][0] + lhs[1][1] * rhs[1][1] + lhs[2][1] * rhs[1][2] + lhs[3][1] * rhs[1][3],
                    lhs[0][2] * rhs[1][0] + lhs[1][2] * rhs[1][1] + lhs[2][2] * rhs[1][2] + lhs[3][2] * rhs[1][3],
                    lhs[0][3] * rhs[1][0] + lhs[1][3] * rhs[1][1] + lhs[2][3] * rhs[1][2] + lhs[3][3] * rhs[1][3]
                    ),
                new vec4(
                    lhs[0][0] * rhs[2][0] + lhs[1][0] * rhs[2][1] + lhs[2][0] * rhs[2][2] + lhs[3][0] * rhs[2][3],
                    lhs[0][1] * rhs[2][0] + lhs[1][1] * rhs[2][1] + lhs[2][1] * rhs[2][2] + lhs[3][1] * rhs[2][3],
                    lhs[0][2] * rhs[2][0] + lhs[1][2] * rhs[2][1] + lhs[2][2] * rhs[2][2] + lhs[3][2] * rhs[2][3],
                    lhs[0][3] * rhs[2][0] + lhs[1][3] * rhs[2][1] + lhs[2][3] * rhs[2][2] + lhs[3][3] * rhs[2][3]
                    ),
                new vec4(
                    lhs[0][0] * rhs[3][0] + lhs[1][0] * rhs[3][1] + lhs[2][0] * rhs[3][2] + lhs[3][0] * rhs[3][3],
                    lhs[0][1] * rhs[3][0] + lhs[1][1] * rhs[3][1] + lhs[2][1] * rhs[3][2] + lhs[3][1] * rhs[3][3],
                    lhs[0][2] * rhs[3][0] + lhs[1][2] * rhs[3][1] + lhs[2][2] * rhs[3][2] + lhs[3][2] * rhs[3][3],
                    lhs[0][3] * rhs[3][0] + lhs[1][3] * rhs[3][1] + lhs[2][3] * rhs[3][2] + lhs[3][3] * rhs[3][3]
                    )
                    );

            return result;
        }
Beispiel #45
0
        /// <summary>
        /// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates.
        /// </summary>
        /// <param name="windowPos">The win.</param>
        /// <param name="view">The view.</param>
        /// <param name="proj">The proj.</param>
        /// <param name="viewport">The viewport.</param>
        /// <returns></returns>
        public static vec3 unProject(vec3 windowPos, mat4 view, mat4 proj, vec4 viewport)
        {
            mat4 Inverse = glm.inverse(proj * view);

            vec4 tmp = new vec4(windowPos, (1f));
            tmp.x = (tmp.x - (viewport[0])) / (viewport[2]);
            tmp.y = (tmp.y - (viewport[1])) / (viewport[3]);
            tmp = tmp * (2f) - new vec4(1, 1, 1, 1);// after this, tmp is normalized device coordinate.

            vec4 obj = Inverse * tmp;
            obj /= obj.w;// after this, tmp is model coordinate.

            return new vec3(obj);
        }
Beispiel #46
0
        /// <summary>
        /// Creates a matrix for a symmetric perspective-view frustum with far plane
        /// at infinite for graphics hardware that doesn't support depth clamping.
        /// </summary>
        /// <param name="fovy">The fovy.</param>
        /// <param name="aspect">The aspect.</param>
        /// <param name="zNear">The z near.</param>
        /// <returns></returns>
        public static mat4 tweakedInfinitePerspective(float fovy, float aspect, float zNear)
        {
            float range = tan(fovy / (2)) * zNear;
            float left = -range * aspect;
            float right = range * aspect;
            float bottom = -range;
            float top = range;

            mat4 Result = new mat4((0f));
            Result[0, 0] = ((2) * zNear) / (right - left);
            Result[1, 1] = ((2) * zNear) / (top - bottom);
            Result[2, 2] = (0.0001f) - (1f);
            Result[2, 3] = (-1);
            Result[3, 2] = -((0.0001f) - (2)) * zNear;
            return Result;
        }
Beispiel #47
0
 /// <summary>
 /// Applies a translation transformation to matrix <paramref name="m"/> by vector <paramref name="v"/>.
 /// </summary>
 /// <param name="m">The matrix to transform.</param>
 /// <param name="v">The vector to translate by.</param>
 /// <returns><paramref name="m"/> translated by <paramref name="v"/>.</returns>
 public static mat4 translate(mat4 m, vec3 v)
 {
     mat4 result = m;
     result.col3 = m.col0 * v.x + m.col1 * v.y + m.col2 * v.z + m.col3;
     return result;
 }
Beispiel #48
0
 /// <summary>
 /// Applies a scale transformation to matrix <paramref name="m"/> by vector <paramref name="v"/>.
 /// </summary>
 /// <param name="m">The matrix to transform.</param>
 /// <param name="v">The vector to scale by.</param>
 /// <returns><paramref name="m"/> scaled by <paramref name="v"/>.</returns>
 public static mat4 scale(mat4 m, vec3 v)
 {
     mat4 result = m;
     result[0] = m[0] * v[0];
     result[1] = m[1] * v[1];
     result[2] = m[2] * v[2];
     result[3] = m[3];
     return result;
 }
Beispiel #49
0
        /// <summary>
        /// Builds a rotation 4 * 4 matrix created from an axis vector and an angle.
        /// </summary>
        /// <param name="m">The m.</param>
        /// <param name="angleDegree">ANgle in Degree.</param>
        /// <param name="v">The v.</param>
        /// <returns></returns>
        public static mat4 rotate(mat4 m, float angleDegree, vec3 v)
        {
            float c = (float)Math.Cos(angleDegree * Math.PI / 180.0);
            float s = (float)Math.Sin(angleDegree * Math.PI / 180.0);

            vec3 axis = v.normalize();
            vec3 temp = (1.0f - c) * axis;

            mat4 rotate = mat4.identity();
            rotate[0, 0] = c + temp[0] * axis[0];
            rotate[0, 1] = 0 + temp[0] * axis[1] + s * axis[2];
            rotate[0, 2] = 0 + temp[0] * axis[2] - s * axis[1];

            rotate[1, 0] = 0 + temp[1] * axis[0] - s * axis[2];
            rotate[1, 1] = c + temp[1] * axis[1];
            rotate[1, 2] = 0 + temp[1] * axis[2] + s * axis[0];

            rotate[2, 0] = 0 + temp[2] * axis[0] + s * axis[1];
            rotate[2, 1] = 0 + temp[2] * axis[1] - s * axis[0];
            rotate[2, 2] = c + temp[2] * axis[2];

            mat4 result = mat4.identity();
            result[0] = m[0] * rotate[0][0] + m[1] * rotate[0][1] + m[2] * rotate[0][2];
            result[1] = m[0] * rotate[1][0] + m[1] * rotate[1][1] + m[2] * rotate[1][2];
            result[2] = m[0] * rotate[2][0] + m[1] * rotate[2][1] + m[2] * rotate[2][2];
            result[3] = m[3];
            return result;
        }
Beispiel #50
0
        /// <summary>
        /// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates.
        /// </summary>
        /// <param name="modelPosition">The object.</param>
        /// <param name="view">The view.</param>
        /// <param name="proj">The proj.</param>
        /// <param name="viewport">The viewport.</param>
        /// <returns></returns>
        public static vec3 project(vec3 modelPosition, mat4 view, mat4 proj, vec4 viewport)
        {
            vec4 tmp = new vec4(modelPosition, (1f));
            tmp = view * tmp;
            tmp = proj * tmp;// this is gl_Position

            tmp /= tmp.w;// after this, tmp is normalized device coordinate.

            tmp = tmp * 0.5f + new vec4(0.5f, 0.5f, 0.5f, 0.5f);
            tmp[0] = tmp[0] * viewport[2] + viewport[0];
            tmp[1] = tmp[1] * viewport[3] + viewport[1];// after this, tmp is window coordinate.

            return new vec3(tmp.x, tmp.y, tmp.z);
        }
Beispiel #51
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="projection"></param>
        /// <param name="view"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public string ToString(mat4 projection, mat4 view, mat4 model)
        {
            StringBuilder builder = BasicInfo();
            builder.AppendLine();

            vec3[] positions = this.Positions;
            if (positions == null) { positions = new vec3[0]; }
            uint[] indexes = this.VertexIds;
            var worldPos = new vec4[positions.Length];
            var viewPos = new vec4[positions.Length];
            var projectionPos = new vec4[positions.Length];
            var normalizedPos = new vec3[positions.Length];
            var screenPos = new vec3[positions.Length];

            builder.Append("Positions in World Space:");
            builder.AppendLine();

            for (int i = 0; i < positions.Length; i++)
            {
                var pos4 = new vec4(positions[i], 1);
                worldPos[i] = model * pos4;
                builder.Append('['); builder.Append(indexes[i]); builder.Append("]: ");
                builder.Append(worldPos[i]);
                builder.AppendLine();
            }

            builder.Append("Positions in Camera/View Space:");
            builder.AppendLine();

            for (int i = 0; i < positions.Length; i++)
            {
                var pos4 = new vec4(positions[i], 1);
                viewPos[i] = view * worldPos[i];
                builder.Append('['); builder.Append(indexes[i]); builder.Append("]: ");
                builder.Append(viewPos[i]);
                builder.AppendLine();
            }
            builder.Append("Positions in Projection Space:");
            builder.AppendLine();
            for (int i = 0; i < positions.Length; i++)
            {
                projectionPos[i] = projection * viewPos[i];
                builder.Append('['); builder.Append(indexes[i]); builder.Append("]: ");
                builder.Append(projectionPos[i]);
                builder.AppendLine();
            }
            builder.Append("Positions in Normalized Space:");
            builder.AppendLine();
            for (int i = 0; i < positions.Length; i++)
            {
                builder.Append('['); builder.Append(indexes[i]); builder.Append("]: ");
                normalizedPos[i] = new vec3(projectionPos[i] / projectionPos[i].w);
                builder.Append(normalizedPos[i]);
                builder.AppendLine();
            }
            builder.Append("Positions in Screen Space:");
            builder.AppendLine();
            int x, y, width, height;
            OpenGL.GetViewport(out x, out y, out width, out height);
            float near, far;
            OpenGL.GetDepthRange(out near, out far);
            for (int i = 0; i < positions.Length; i++)
            {
                builder.Append('['); builder.Append(indexes[i]); builder.Append("]: ");
                screenPos[i] = new vec3(
                    normalizedPos[i].x * width / 2 + (x + width / 2),
                    normalizedPos[i].y * height / 2 + (y + height / 2),
                    normalizedPos[i].z * (far - near) / 2 + ((far + near) / 2)
                    );
                builder.Append(screenPos[i]);
                builder.AppendLine();
            }

            return builder.ToString();
        }
        /// <summary>
        /// Get model matrix that transform model's position from model space to world space,
        /// Make sure the scene object list is traversed in pre-order.
        /// </summary>
        /// <returns></returns>
        public mat4 GetModelMatrix()
        {
            SceneObject obj = this.BindingObject;
            if (obj != null)
            {
                mat4 matrix = mat4.identity();
                matrix = glm.translate(matrix, this.Position);
                matrix = glm.scale(matrix, this.Scale);
                matrix = glm.rotate(matrix, (float)(this.Rotation.x * Math.PI / 180.0), xAxis);
                matrix = glm.rotate(matrix, (float)(this.Rotation.y * Math.PI / 180.0), yAxis);
                matrix = glm.rotate(matrix, (float)(this.Rotation.z * Math.PI / 180.0), zAxis);

                // matrix equals to (translate * scale * rotation) as below:
                //mat4 translate = glm.translate(mat4.identity(), this.Position);
                //mat4 scale = glm.scale(mat4.identity(), this.Scale);
                //mat4 rotation = glm.rotate(mat4.identity(), (float)(this.Rotation.x * Math.PI / 180.0), xAxis);
                //rotation = glm.rotate(rotation, (float)(this.Rotation.y * Math.PI / 180.0), yAxis);
                //rotation = glm.rotate(rotation, (float)(this.Rotation.z * Math.PI / 180.0), zAxis);

                this.selfMatrix = matrix;
            }

            return this.selfMatrix;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="varNameInShader"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool GetUniformMat4ArrayValue(string varNameInShader, out mat4[] value)
        {
            //if ((!this.Initialized) && (!this.Initializing)) { this.Initialize(); }

            value = null;
            bool gotUniform = false;

            foreach (UniformVariable item in this.uniformVariables)
            {
                if (item.VarName == varNameInShader)
                {
                    value = (item as UniformMat4Array).Value.Array;
                    gotUniform = true;
                    break;
                }
            }

            return gotUniform;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="varNameInShader"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool SetUniform(string varNameInShader, mat4[] value)
        {
            //if ((!this.Initialized) && (!this.Initializing)) { this.Initialize(); }

            bool gotUniform = false;
            bool updated = false;
            if (value.Length <= 0) { return updated; }

            foreach (UniformVariable item in this.uniformVariables)
            {
                if (item.VarName == varNameInShader)
                {
                    (item as UniformMat4Array).Value = new NoisyArray<mat4>(value);
                    updated = true;
                    gotUniform = true;
                    break;
                }
            }

            if (!gotUniform)
            {
                //int location = Program.GetUniformLocation(varNameInShader);
                //if (location < 0)
                {
                    //throw new Exception(string.Format(
                    //"niform variable [{0}] not exists! Remember to invoke RendererBase.Initialize(); before this method.", varNameInShader));
                }

                var variable = GetVariableArray(value, varNameInShader) as UniformMat4Array;
                variable.Value = new NoisyArray<mat4>(value);
                this.uniformVariables.Add(variable);
                updated = true;
            }

            return updated;
        }
Beispiel #55
0
        /// <summary>
        /// Builds a perspective projection matrix based on a field of view.
        /// </summary>
        /// <param name="fov">The fov (in radians).</param>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <param name="zNear">The z near.</param>
        /// <param name="zFar">The z far.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentOutOfRangeException"></exception>
        public static mat4 perspectiveFov(float fov, float width, float height, float zNear, float zFar)
        {
            if (width <= 0 || height <= 0 || fov <= 0)
                throw new ArgumentOutOfRangeException();

            var rad = fov;

            var h = glm.cos((0.5f) * rad) / glm.sin((0.5f) * rad);
            var w = h * height / width;

            var result = new mat4(0);
            result[0, 0] = w;
            result[1, 1] = h;
            result[2, 2] = -(zFar + zNear) / (zFar - zNear);
            result[2, 3] = -(1f);
            result[3, 2] = -((2f) * zFar * zNear) / (zFar - zNear);
            return result;
        }
Beispiel #56
0
        /// <summary>
        /// Define a picking region.
        /// </summary>
        /// <param name="center">The center.</param>
        /// <param name="delta">The delta.</param>
        /// <param name="viewport">The viewport.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentOutOfRangeException"></exception>
        public static mat4 pickMatrix(vec2 center, vec2 delta, vec4 viewport)
        {
            if (delta.x <= 0 || delta.y <= 0)
                throw new ArgumentOutOfRangeException();
            var Result = new mat4(1.0f);

            if (!(delta.x > (0f) && delta.y > (0f)))
                return Result; // Error

            vec3 Temp = new vec3(
                ((viewport[2]) - (2f) * (center.x - (viewport[0]))) / delta.x,
                ((viewport[3]) - (2f) * (center.y - (viewport[1]))) / delta.y,
                (0f));

            // Translate and scale the picked region to the entire window
            Result = translate(Result, Temp);
            return scale(Result, new vec3((viewport[2]) / delta.x, (viewport[3]) / delta.y, (1)));
        }
        public bool GetUniformMat4ArrayValue(string varNameInShader, out mat4[] value)
        {
            value = null;
            bool gotUniform = false;

            foreach (var item in this.uniformVariables)
            {
                if (item.VarName == varNameInShader)
                {
                    value = (item as UniformMat4Array).Value;
                    gotUniform = true;
                    break;
                }
            }

            return gotUniform;
        }
Beispiel #58
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.length() * _endPosition.length());
                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);
            }
        }