Beispiel #1
0
        /// <summary>
        /// Gets the transformation matrix.
        /// </summary>
        public static Matrix LookAtRH(Vertex pos, Vertex lookat, Vertex updir)
        {
            Vertex zaxis = (pos - lookat); zaxis.Normalize();
            Vertex xaxis = updir; xaxis = xaxis.VectorProduct(zaxis); xaxis.Normalize();
            Vertex yaxis = zaxis; yaxis = yaxis.VectorProduct(xaxis);

            Matrix result = new Matrix(4, 4);

            result.SetIdentity();

            result[0, 0] = xaxis.X;
            result[0, 1] = xaxis.Y;
            result[0, 2] = xaxis.Z;
            result[0, 3] = -xaxis.ScalarProduct(pos);
            result[1, 0] = yaxis.X;
            result[1, 1] = yaxis.Y;
            result[1, 2] = yaxis.Z;
            result[1, 3] = -yaxis.ScalarProduct(pos);
            result[2, 0] = zaxis.X;
            result[2, 1] = zaxis.Y;
            result[2, 2] = zaxis.Z;
            result[2, 3] = -zaxis.ScalarProduct(pos);
            result[3, 0] = 0;
            result[3, 1] = 0;
            result[3, 2] = 0;
            result[3, 3] = 1.0;

            return(result);
        }
Beispiel #2
0
        /// <summary>
        /// Calculates the circle, which is defined by 3 points.
        /// </summary>
        public void calcData()
        {
            // Check whether the 3 points are in a row or not.
            if (areOnLine(startPoint, secondPoint, endPoint))
            {
                throw new Exception("The points result in no circle");
            }

            // direction vector from point b to a
            Vertex ba = startPoint - secondPoint;

            // direction vector from point b to c
            Vertex bc = endPoint - secondPoint;

            // Perpendicular to the plane of the triangle / circle.
            ba.Normalize(); bc.Normalize();
            this.normal = ba.VectorProduct(bc);
            this.normal.Normalize();

            // Calculation of the center of the circle
            this.center = getCenter();

            // Calculation of the radius
            this.radius = (float)(center - startPoint).Magnitude();


            // Determination of 2 clamping vectors.
            this.span1 = startPoint - center;
            this.span2 = span1.VectorProduct(this.normal);
        }
Beispiel #3
0
        Vertex EvaluateTrefoil(float s, float t)
        {
            float TwoPi = (float)Math.PI * 2;
            float a = 0.5f;
            float b = 0.3f;
            float c = 0.5f;
            float d = 0.1f;
            float u = (1 - s) * 2 * TwoPi;
            float v = t * TwoPi;
            float r = (float)(a + b * Math.Cos(1.5f * u));
            float x = (float)(r * Math.Cos(u));
            float y = (float)(r * Math.Sin(u));
            float z = (float)(c * Math.Sin(1.5f * u));

            Vertex dv;
            dv.X = (float)(-1.5f * b * Math.Sin(1.5f * u) * Math.Cos(u) -
                    (a + b * Math.Cos(1.5f * u)) * Math.Sin(u));
            dv.Y = (float)(-1.5f * b * Math.Sin(1.5f * u) * Math.Sin(u) +
                    (a + b * Math.Cos(1.5f * u)) * Math.Cos(u));
            dv.Z = (float)(1.5f * c * Math.Cos(1.5f * u));

            Vertex q = new Vertex(dv);
            q.Normalize();
            Vertex qvn = new Vertex(q.Y, -q.X, 0);
            qvn.Normalize();
            Vertex ww = q.VectorProduct(qvn);

            Vertex range;
            range.X = (float)(x + d * (qvn.X * Math.Cos(v) + ww.X * Math.Sin(v)));
            range.Y = (float)(y + d * (qvn.Y * Math.Cos(v) + ww.Y * Math.Sin(v)));
            range.Z = (float)(z + d * ww.Z * Math.Sin(v));
            return range;
        }
Beispiel #4
0
        private void PrepareCamera()
        {
            var camera = this.Camera;

            if (camera != null)
            {
                Vertex back  = camera.Position - camera.Target;
                Vertex right = Camera.UpVector.VectorProduct(back);
                Vertex up    = back.VectorProduct(right);
                back.Normalize();
                right.Normalize();
                up.Normalize();

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

                if (this.originalCamera == null)
                {
                    this.originalCamera = new ScientificCamera();
                }
                this.originalCamera.Position = camera.Position;
                this.originalCamera.UpVector = camera.UpVector;
            }
        }
Beispiel #5
0
        /// <summary>
        /// Rotates the view.
        /// </summary>
        private void transformView(Vertex UpVector, Vertex Position, Vertex Target, double horizontal, double vertikal, bool forceCalc)
        {
            Matrix m = null;

            if (forceCalc)
            {
                m = new Matrix(4, 4);
                m.SetIdentity();
            }

            if (vertikal == 0)
            {
                if (horizontal != 0)
                {
                    // Rotation around the Z axis
                    m = Matrix.GetRotate_Z_Matrix(horizontal);
                }
            }
            else
            {
                // x direction
                Vertex viewX = UpVector.VectorProduct(Position - Target);
                viewX.Normalize();

                if (horizontal == 0)
                {
                    // Rotation around the vector that points to the right in the image.
                    m = Matrix.GetRotateMatrix(viewX, vertikal);
                }
                else
                {
                    // Combined rotation.
                    m = Matrix.GetRotate_Z_Matrix(horizontal) * Matrix.GetRotateMatrix(viewX, vertikal);
                }
            }

            // There was a rotation at all.
            if (m != null)
            {
                Vertex lookAt = Target;            // Target
                Vertex pos    = Position - lookAt; // Position
                Vertex upDir  = UpVector;          // UpVector

                Vertex posTransformed   = lookAt + (pos * m);
                Vertex upDirTransformed = upDir * m;

                Vertex posTransformedNormalized = (posTransformed - lookAt);
                posTransformedNormalized.Normalize();

                Vertex upDirTransformedNormalized = upDirTransformed;
                upDirTransformedNormalized.Normalize();

                transformMatrix = LookAtRH(lookAt + posTransformedNormalized, lookAt, upDirTransformedNormalized);
            }
        }
Beispiel #6
0
 /// <summary>
 /// Default camera is at positive Z axis to look at negtive Z axis with up vector to positive Y axis.
 /// </summary>
 /// <param name="eyex"></param>
 /// <param name="eyey"></param>
 /// <param name="eyez"></param>
 /// <param name="centerx"></param>
 /// <param name="centery"></param>
 /// <param name="centerz"></param>
 /// <param name="upx"></param>
 /// <param name="upy"></param>
 /// <param name="upz"></param>
 public void SetCamera(float eyex, float eyey, float eyez,
                       float centerx, float centery, float centerz,
                       float upx, float upy, float upz)
 {
     _vectorCenterEye = new Vertex(eyex - centerx, eyey - centery, eyez - centerz);
     _vectorCenterEye.Normalize();
     _vectorUp    = new Vertex(upx, upy, upz);
     _vectorRight = _vectorUp.VectorProduct(_vectorCenterEye);
     _vectorRight.Normalize();
     _vectorUp = _vectorCenterEye.VectorProduct(_vectorRight);
     _vectorUp.Normalize();
 }
Beispiel #7
0
        public void MouseMove(int x, int y)
        {
            if (this.mouseDownFlag)
            {
                IViewCamera camera = this.Camera;
                if (camera == null)
                {
                    return;
                }

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

                camera.Position = camera.Target +
                                  back * (float)((camera.Position - camera.Target).Magnitude());
                camera.UpVector     = up;
                this.back           = back;
                this.right          = right;
                this.up             = up;
                this.downPosition.X = x;
                this.downPosition.Y = y;
            }
        }
Beispiel #8
0
        private void UpdateCameraAxis()
        {
            IViewCamera camera = this._camera;

            if (camera == null)
            {
                return;
            }

            _back = camera.Position - camera.Target;
            _back.Normalize();
            _right = camera.UpVector.VectorProduct(_back);
            _right.Normalize();
            _up = _back.VectorProduct(_right);
            _up.Normalize();
        }
        void IRenderable.Render(OpenGL gl, RenderMode renderMode)
        {
            ScientificCamera camera = this.Camera;

            if (camera == null)
            {
                return;
            }

            IOrthoCamera orthoCamera = camera;
            double       width       = orthoCamera.Right - orthoCamera.Left;
            double       height      = orthoCamera.Top - orthoCamera.Bottom;

            Vertex back  = camera.Position - camera.Target;
            Vertex right = camera.UpVector.VectorProduct(back);
            Vertex up    = back.VectorProduct(right);

            back.Normalize();
            right.Normalize();
            up.Normalize();
            right.X *= (float)(height / 2);
            right.Y *= (float)(height / 2);
            right.Z *= (float)(height / 2);
            up.X    *= (float)(width / 2);
            up.Y    *= (float)(width / 2);
            up.Z    *= (float)(width / 2);

            IOrthoInfo viewportInfo = this;

            viewportInfo.LeftBottom  = camera.Position - right - up;
            viewportInfo.LeftTop     = camera.Position - right + up;
            viewportInfo.RightBottom = camera.Position + right - up;
            viewportInfo.RightTop    = camera.Position + right + up;
            viewportInfo.Width       = (float)width;
            viewportInfo.Height      = (float)height;

            gl.MatrixMode(SharpGL.Enumerations.MatrixMode.Projection);
            gl.LoadIdentity();
            gl.Ortho(orthoCamera.Left, orthoCamera.Right, orthoCamera.Bottom, orthoCamera.Top, orthoCamera.Near, orthoCamera.Far);
            gl.LookAt(
                (double)camera.Position.X, (double)camera.Position.Y, (double)camera.Position.Z,
                (double)camera.Target.X, (double)camera.Target.Y, (double)camera.Target.Z,
                (double)camera.UpVector.X, (double)camera.UpVector.Y, (double)camera.UpVector.Z);
            gl.MatrixMode(Enumerations.MatrixMode.Modelview);
        }
Beispiel #10
0
        private uint CreateVertexNormalBuffer(OpenGL gl)
        {
            Vertex[] verts = new Vertex[VertexCount * 2];
            int      count = 0;

            float ds = 1.0f / Slices;
            float dt = 1.0f / Stacks;

            // The upper bounds in these loops are tweaked to reduce the
            // chance of precision error causing an incorrect # of iterations.

            for (float s = 0; s < 1 - ds / 2; s += ds)
            {
                for (float t = 0; t < 1 - dt / 2; t += dt)
                {
                    const float E = 0.01f;
                    Vertex      p = EvaluateTrefoil(s, t);
                    Vertex      u = EvaluateTrefoil(s + E, t) - p;
                    Vertex      v = EvaluateTrefoil(s, t + E) - p;
                    Vertex      n = u.VectorProduct(v);
                    n.Normalize();
                    vertices.Add(p);
                    verts[count++] = p;
                    verts[count++] = new Vertex(0, 0, 0);//n);
                }
            }

            //  Pin the data.
            GCHandle vertsHandle = GCHandle.Alloc(verts, GCHandleType.Pinned);
            IntPtr   vertsPtr    = vertsHandle.AddrOfPinnedObject();
            var      size        = Marshal.SizeOf(typeof(Vertex)) * VertexCount;

            uint[] buffers = new uint[1];
            gl.GenBuffers(1, buffers);
            uint handle = buffers[0];

            gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, handle);
            gl.BufferData(OpenGL.GL_ARRAY_BUFFER, (int)size, vertsPtr, OpenGL.GL_STATIC_DRAW);

            //  Free the data.
            vertsHandle.Free();

            return(handle);
        }
Beispiel #11
0
 public void MouseMove(int x, int y)
 {
     if (mouseDownFlag)
     {
         this._endPosition = GetArcBallPosition(x, y);
         var cosAngle = _startPosition.ScalarProduct(_endPosition) / (_startPosition.Magnitude() * _endPosition.Magnitude());
         if (cosAngle > 1)
         {
             cosAngle = 1;
         }
         else if (cosAngle < -1)
         {
             cosAngle = -1;
         }
         var angle = 10 * (float)(Math.Acos(cosAngle) / Math.PI * 180);
         System.Threading.Interlocked.Exchange(ref _angle, angle);
         _normalVector  = _startPosition.VectorProduct(_endPosition);
         _startPosition = _endPosition;
     }
 }
Beispiel #12
0
 public void MouseMove(int x, int y)
 {
     if (mouseDownFlag)
     {
         Vertex startPosition = this._startPosition;
         Vertex endPosition   = GetArcBallPosition(x, y);
         double cosAngle      = startPosition.ScalarProduct(endPosition) / (startPosition.Magnitude() * endPosition.Magnitude());
         if (cosAngle > 1)
         {
             cosAngle = 1;
         }
         else if (cosAngle < -1)
         {
             cosAngle = -1;
         }
         float angle = 1 * (float)(Math.Acos(cosAngle) / Math.PI * 180);
         System.Threading.Interlocked.Exchange(ref _angle, angle);
         this._normalVector  = startPosition.VectorProduct(endPosition);
         this._startPosition = endPosition;
     }
 }
Beispiel #13
0
        /// <summary>
        /// Evaluates the trefoil, providing the vertex at a given coordinate.
        /// </summary>
        /// <param name="s">The s.</param>
        /// <param name="t">The t.</param>
        /// <returns>The vertex at (s,t).</returns>
        private static Vertex EvaluateTrefoil(float s, float t)
        {
            const float TwoPi = (float)Math.PI * 2;

            float a = 0.5f;
            float b = 0.3f;
            float c = 0.5f;
            float d = 0.1f;
            float u = (1 - s) * 2 * TwoPi;
            float v = t * TwoPi;
            float r = (float)(a + b * Math.Cos(1.5f * u));
            float x = (float)(r * Math.Cos(u));
            float y = (float)(r * Math.Sin(u));
            float z = (float)(c * Math.Sin(1.5f * u));

            var dv = new Vertex
            {
                X = (float)(-1.5f * b * Math.Sin(1.5f * u) * Math.Cos(u) - (a + b * Math.Cos(1.5f * u)) * Math.Sin(u)),
                Y = (float)(-1.5f * b * Math.Sin(1.5f * u) * Math.Sin(u) + (a + b * Math.Cos(1.5f * u)) * Math.Cos(u)),
                Z = (float)(1.5f * c * Math.Cos(1.5f * u))
            };

            Vertex q = new Vertex(dv);

            q.Normalize();
            Vertex qvn = new Vertex(q.Y, -q.X, 0);

            qvn.Normalize();
            Vertex ww = q.VectorProduct(qvn);

            Vertex range = new Vertex()
            {
                X = (float)(x + d * (qvn.X * Math.Cos(v) + ww.X * Math.Sin(v))),
                Y = (float)(y + d * (qvn.Y * Math.Cos(v) + ww.Y * Math.Sin(v))),
                Z = (float)(z + d * ww.Z * Math.Sin(v))
            };

            return(range);
        }
Beispiel #14
0
        protected void InitializeVAO(OpenGL gl, out uint[] vao, out BeginMode primitiveMode, out int vertexCount)
        {
            primitiveMode = BeginMode.QuadStrip;
            vertexCount   = (faceCount * 2 + 2) * (this.pipe.Count - 1);

            UnmanagedArray <Vertex> positionArray = new UnmanagedArray <Vertex>(vertexCount);
            {
                int index = 0;
                for (int i = 1; i < this.pipe.Count; i++)
                {
                    Vertex p1     = this.pipe[i - 1];
                    Vertex p2     = this.pipe[i];
                    Vertex vector = p2 - p1;// 从p1到p2的向量
                    // 找到互相垂直的三个向量:vector, orthogontalVector1和orthogontalVector2
                    Vertex orthogontalVector1 = new Vertex(vector.Y - vector.Z, vector.Z - vector.X, vector.X - vector.Y);
                    Vertex orthogontalVector2 = vector.VectorProduct(orthogontalVector1);
                    orthogontalVector1.Normalize();
                    orthogontalVector2.Normalize();
                    orthogontalVector1 *= (float)Math.Sqrt(this.radius);
                    orthogontalVector2 *= (float)Math.Sqrt(this.radius);
                    for (int faceIndex = 0; faceIndex < faceCount + 1; faceIndex++)
                    {
                        double angle = (Math.PI * 2 * faceIndex) / faceCount;
                        Vertex point = orthogontalVector1 * (float)Math.Cos(angle) + orthogontalVector2 * (float)Math.Sin(angle);
                        positionArray[index++] = p2 + point;
                        positionArray[index++] = p1 + point;
                    }

                    //positionArray[index++] = new vec3();//用于分割圆柱体
                }
            }

            UnmanagedArray <Vertex> colorArray = new UnmanagedArray <Vertex>(vertexCount);
            {
                Vertex vColor = new Vertex(this.color.R, this.color.G, this.color.B);
                for (int i = 0; i < colorArray.Length; i++)
                {
                    colorArray[i] = vColor;
                    // 测试时用此代码区分各个圆柱
                    //if ((i / (faceCount * 2 + 2)) % 3 == 0)
                    //{
                    //    colorArray[i] = new vec3(1, 0, 0);
                    //}
                    //else if ((i / (faceCount * 2 + 2)) % 3 == 1)
                    //{
                    //    colorArray[i] = new vec3(0, 1, 0);
                    //}
                    //else
                    //{
                    //    colorArray[i] = new vec3(0, 0, 1);
                    //}
                }
            }

            UnmanagedArray <uint> indexArray = new UnmanagedArray <uint>(vertexCount + (this.pipe.Count - 1));

            {
                uint positionIndex = 0;
                for (int i = 0; i < indexArray.Length; i++)
                {
                    if (i % (faceCount * 2 + 2 + 1) == (faceCount * 2 + 2))
                    {
                        indexArray[i] = uint.MaxValue;//分割各个圆柱体
                    }
                    else
                    {
                        indexArray[i] = positionIndex++;
                    }
                }
            }

            vao = new uint[1];
            gl.GenVertexArrays(1, vao);
            gl.BindVertexArray(vao[0]);
            {
                uint[] ids = new uint[1];
                gl.GenBuffers(1, ids);
                gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, ids[0]);

                int location = gl.GetAttribLocation(shaderProgram.ShaderProgramObject, strin_Position);
                if (location < 0)
                {
                    throw new Exception();
                }
                uint positionLocation = (uint)location;

                gl.BufferData(OpenGL.GL_ARRAY_BUFFER, positionArray.ByteLength, positionArray.Header, OpenGL.GL_STATIC_DRAW);
                gl.VertexAttribPointer(positionLocation, 3, OpenGL.GL_FLOAT, false, 0, IntPtr.Zero);
                gl.EnableVertexAttribArray(positionLocation);

                positionArray.Dispose();
                this.positionBufferObject = ids[0];
            }
            {
                uint[] ids = new uint[1];
                gl.GenBuffers(1, ids);
                gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, ids[0]);

                int location = gl.GetAttribLocation(shaderProgram.ShaderProgramObject, strin_Color);
                if (location < 0)
                {
                    throw new Exception();
                }
                uint colorLocation = (uint)location;

                gl.BufferData(OpenGL.GL_ARRAY_BUFFER, colorArray.ByteLength, colorArray.Header, OpenGL.GL_STATIC_DRAW);
                gl.VertexAttribPointer(colorLocation, 3, OpenGL.GL_FLOAT, false, 0, IntPtr.Zero);
                gl.EnableVertexAttribArray(colorLocation);

                colorArray.Dispose();
                this.colorBufferObject = ids[0];
            }
            {
                uint[] ids = new uint[1];
                gl.GenBuffers(1, ids);
                gl.BindBuffer(OpenGL.GL_ELEMENT_ARRAY_BUFFER, ids[0]);
                gl.BufferData(OpenGL.GL_ELEMENT_ARRAY_BUFFER, indexArray.ByteLength, indexArray.Header, OpenGL.GL_STATIC_DRAW);

                indexArray.Dispose();
                this.indexBufferObject = ids[0];
            }

            //  Unbind the vertex array, we've finished specifying data for it.
            gl.BindVertexArray(0);
        }
Beispiel #15
0
        /// <summary>
        /// Internal auxiliary function for calculating the intersection of two straight lines.
        ///
        /// TODO: Still not working if the coefficient matrix of x and y values is singular. Maybe use pivoting.
        /// </summary>
        private bool intersectInternal(Line l2, out float s, out float t)
        {
            Vertex u = this.Dir;
            Vertex v = l2.Dir;
            Vertex a = this.startPoint;
            Vertex b = l2.startPoint;
            Vertex c = b - a;

            Vertex cross = u.VectorProduct(v);

            s = t = 0;

            // parallel?
            if (cross.Magnitude() < 0.00001)
            {
                return(false);
            }

            Plane pl = new Plane(a, cross);

            if (Math.Abs(pl.GetPointDistance(b)) + Math.Abs(pl.GetPointDistance(this.EndPoint)) + Math.Abs(pl.GetPointDistance(l2.EndPoint)) > 1)
            {
                return(false);
            }

            //1. case
            float u1 = u.X, u2 = u.Y;
            float v1 = v.X, v2 = v.Y;
            float c1 = c.X, c2 = c.Y;
            float det = -u1 * v2 + v1 * u2;

            //2. case
            float temp = -u1 * v.Z + v1 * u.Z;

            if (Math.Abs(temp) > Math.Abs(det))
            {
                u2  = u.Z;
                v2  = v.Z;
                c2  = c.Z;
                det = temp;
            }

            //3. case
            temp = -u.Y * v.Z + v.Y * u.Z;
            if (Math.Abs(temp) > Math.Abs(det))
            {
                u2  = u.Z;
                v2  = v.Z;
                c2  = c.Z;
                u1  = u.Y;
                v1  = v.Y;
                c1  = c.Y;
                det = temp;
            }

            float ds = -c1 * v2 + v1 * c2;
            float dt = u1 * c2 - c1 * u2;

            s = ds / det;
            t = dt / det;
            return(true);
        }