Пример #1
0
 public void MouseMove(System.Windows.Forms.MouseEventArgs e, GLCamera camera)
 {
     if (e.Button == System.Windows.Forms.MouseButtons.Right)
     {
         // Update the mouse location.
         mouseTranslation = Intersect(e.X, e.Y, camera) - mouseTranslationOrigin;
     }
 }
Пример #2
0
 public void MouseButtonDown(System.Windows.Forms.MouseEventArgs e, GLCamera camera)
 {
     if (e.Button == System.Windows.Forms.MouseButtons.Right)
     {
         // Store the origin of the mouse.
         mouseTranslationOrigin = Intersect(e.X, e.Y, camera);
         mouseTranslation       = Vector3.Zero;
     }
 }
Пример #3
0
        public void MouseButtonUp(System.Windows.Forms.MouseEventArgs e, GLCamera camera)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                // Get the current location of the mouse.
                mouseTranslation = Intersect(e.X, e.Y, camera) - mouseTranslationOrigin;

                // Compute the new model location.
                modelTranslation += mouseTranslation;

                // Clear the mouse origin.
                mouseTranslationOrigin = Vector3.Zero;
                mouseTranslation       = Vector3.Zero;
            }
        }
Пример #4
0
        /// <summary>
        /// Computes the intersection point between the mouse coordinate vector and the plane
        /// formed by the model's location and the camera's eye.
        /// </summary>
        /// <param name="x">The X mouse coordinate.</param>
        /// <param name="y">The Y mouse coordinate.</param>
        /// <param name="camera">The camera.</param>
        private Vector3 Intersect(int x, int y, GLCamera camera)
        {
            // Invert the transformation pipeline.
            Matrix4 inverseProjectionView = camera.View * camera.Projection;

            inverseProjectionView.Invert();

            // Transform mouse coordinates into world space.

            // We are "mouse" space.  Need to convert into screen space.
            Vector4 worldMouse = new Vector4(x, y, 1, 1);

            int[] viewport = new int[4];
            GL.GetInteger(GetPName.Viewport, viewport);

            worldMouse.X = (2.0f * (worldMouse.X - viewport[0]) / viewport[2]) - 1.0f;
            worldMouse.Y = -((2.0f * (worldMouse.Y - viewport[1]) / viewport[3]) - 1.0f);

            // We are in screen space.  Need to convert into view space and then world space.
            worldMouse = Vector4.Transform(worldMouse, inverseProjectionView);

            if (worldMouse.W > float.Epsilon || worldMouse.W < float.Epsilon)
            {
                worldMouse.X /= worldMouse.W;
                worldMouse.Y /= worldMouse.W;
                worldMouse.Z /= worldMouse.W;
            }

            // The model translation is applied in VIEW space.  So, we need to project it back
            // into world space for these calculations.  We need to remove the translation components of the view
            // matrix.

            Matrix4 viewRotation = camera.View;

            viewRotation.M41 = 0;
            viewRotation.M42 = 0;
            viewRotation.M43 = 0;

            Matrix4 inverseViewRotation = Matrix4.Invert(viewRotation);

            Vector3 worldModelTranslation = Vector3.Transform(modelTranslation, inverseViewRotation);

            // Get the world location of the model.  This is the point on the plane.
            Vector3 planePoint = worldModelTranslation;

            // Get the camera eye.  This is the line origin.
            Vector3 lineOrigin = camera.Eye;

            // Create the normal of the plane.
            Vector3 planeNormal = lineOrigin - planePoint;

            planeNormal.Normalize();

            // Create the direction of the line intersecting the plane.
            Vector3 lineDirection = new Vector3(worldMouse);

            lineDirection -= lineOrigin;
            lineDirection.Normalize();

            // Computes the distance along the line until it intersects the plane.
            // Note: In pure math, there are three possible solutions.
            //      1.) The line intersects the plane once.  Normal solution.
            //      2.) The line is outside and parallel to the plane. Denom -> 0 -> Undefined solution.
            //      3.) The line is contained inside the plane. Denom & Num -> 0 -> Indeterminate solution.
            // However, in the scope of this problem, only solution 1.) is possible because of the constraints of the camera class.
            // So, we assume nothing crazy can happen with this computation (which is probably a terrible assumption but oh well).
            float distance = Vector3.Dot(planePoint - lineOrigin, planeNormal) / Vector3.Dot(lineDirection, planeNormal);

            // Calculate the new model location.
            Vector3 result = lineOrigin + lineDirection * distance;

            // Convert back into view space.
            result = Vector3.Transform(result, viewRotation);

            return(result);
        }
Пример #5
0
        /// <summary>
        /// Draws the scene.
        /// </summary>
        /// <param name="camera">The camera for the scene.</param>
        public void Render(GLCamera camera)
        {
            // Clear back buffers.
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit);

            // Enable a normal depth test without stenciling.
            GL.Enable(EnableCap.DepthTest);
            GL.Disable(EnableCap.StencilTest);
            GL.DepthFunc(DepthFunction.Less);

            GLShaderProgram program = null;

            // Add the translation in view space.  This allows the model to rotate around
            // itself instead of the origin in world space.
            Matrix4 view = camera.View;

            view.M41 += modelTranslation.X + mouseTranslation.X;
            view.M42 += modelTranslation.Y + mouseTranslation.Y;
            view.M43 += modelTranslation.Z + mouseTranslation.Z;

            //
            // Load shaders for Phong lit static models.
            //

            program = programs["phong"];
            program.Load();

            //
            // Update parameters for phong lighting.
            //

            // Vertex Shader Uniforms
            program.UpdateUniform("u_WorldView",
                                  world * view);
            program.UpdateUniform("u_WorldViewProjection",
                                  world * view * camera.Projection);

            // Fragment Shader Uniforms
            program.UpdateUniform("u_LightDirection", new Vector3(0.0f, 0.0f, 1.0f));
            program.UpdateUniform("u_LightDiffuse",
                                  new Vector4(1.0f, 1.0f, 1.0f, 1.0f));
            program.UpdateUniform("u_KA", 0.85f);
            program.UpdateUniform("u_KD", 0.1f);
            program.UpdateUniform("u_KS", 0.05f);
            program.UpdateUniform("u_SExponent", 8.0f);

            // Draw Static Model

            // Load the model's texture for the shader.
            GL.ActiveTexture(TextureUnit.Texture0);
            program.UpdateUniform("u_Texture", 0);
            if (staticModel.TextureName != String.Empty)
            {
                textures[staticModel.TextureName].Bind(); // not checking return value
            }

            staticModel.Draw();

            GL.UseProgram(0);

            //
            // Load shaders for Phong lit rigged models.
            //

            program = programs["phongRigged"];
            program.Load();

            //
            // Update parameters for phong lighting.
            //

            // Fragment Shader Uniforms
            program.UpdateUniform("u_LightDirection", new Vector3(0.0f, 0.0f, 1.0f));
            program.UpdateUniform("u_LightDiffuse",
                                  new Vector4(1.0f, 1.0f, 1.0f, 1.0f));
            program.UpdateUniform("u_KA", 0.85f);
            program.UpdateUniform("u_KD", 0.1f);
            program.UpdateUniform("u_KS", 0.05f);
            program.UpdateUniform("u_SExponent", 8.0f);

            // Draw Rigged Model

            //
            // Update the uniforms.
            //

            // Textures vary.
            GL.ActiveTexture(TextureUnit.Texture0);
            program.UpdateUniform("u_Texture", 0);
            if (riggedModel.TextureName != String.Empty)
            {
                textures[riggedModel.TextureName].Bind(); // not checking return value
            }

            //
            // Bone Transforms
            //

            if (IsSkinning == true)
            {
                // Get the transformations from the rig.
                boneTransforms = riggedModel.GetBoneTransformations(ref boneTransforms);
            }

            program.UpdateUniform("u_BoneTransform", boneTransforms);

            //
            // World Transform.
            //
            Matrix4 worldView = world * view;

            // Vertex Shader Uniforms
            program.UpdateUniform("u_WorldView",
                                  worldView);
            program.UpdateUniform("u_WorldViewProjection",
                                  worldView * camera.Projection);

            riggedModel.Draw();

            // Unload shaders.
            GL.UseProgram(0);
        }