コード例 #1
0
ファイル: Matrix.cs プロジェクト: Catmanwaking/3DTestArea
        /// <summary>
        /// Creates a rotation matrix of the given parameters.
        /// </summary>
        /// <param name="unitVector">Rotation axis.</param>
        /// <param name="angle">Rotation angle in radians.</param>
        /// <returns>The rotation matrix.</returns>
        public static Matrix CreateRotationMatrix(Vect3D unitVector, double angle)
        {
            if (unitVector.GetLength() != 1)
            {
                return(null);                             //UNCHECKED this may cause problems
            }
            if (angle == 0)
            {
                return(CreateMultiplicativeIdentityMatrix(3));
            }
            Matrix m = new Matrix(3, 3);

            double cos   = Math.Cos(angle);
            double sin   = Math.Sin(angle);
            double XYcos = unitVector.X * unitVector.Y * (1 - cos);
            double XZcos = unitVector.X * unitVector.Z * (1 - cos);
            double YZcos = unitVector.Y * unitVector.Z * (1 - cos);
            double Xsin  = unitVector.X * sin;
            double Ysin  = unitVector.Y * sin;
            double Zsin  = unitVector.Z * sin;

            //https://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle
            m.Mtrx[0, 0] = cos + unitVector.X * unitVector.X * (1 - cos);
            m.Mtrx[0, 1] = XYcos - Zsin;
            m.Mtrx[0, 2] = XZcos + Ysin;
            m.Mtrx[1, 0] = XYcos + Zsin;
            m.Mtrx[1, 1] = cos + unitVector.Y * unitVector.Y * (1 - cos);
            m.Mtrx[1, 2] = YZcos - Xsin;
            m.Mtrx[2, 0] = XZcos - Ysin;
            m.Mtrx[2, 1] = YZcos + Xsin;
            m.Mtrx[2, 2] = cos + unitVector.Z * unitVector.Z * (1 - cos);

            return(m);
        }
コード例 #2
0
        /// <summary>
        /// Calculates which triangles are within the camera's field of view.
        /// </summary>
        public void DetermineTrianglesInRange()
        {
            //TODO can be heavly optimized by reading directly from the objects verticies. CREATE BACKUP WHEN EDITING.

            Vect3D      toPointVector;
            Stack <int> trianglesIndex = new Stack <int>();

            foreach (Triangle3D triangle in triangles)
            {
                foreach (Point3D point in triangle.coordinates)
                {
                    toPointVector = new Vect3D(CameraPosition, point);
                    if (Relation3D.AngleBetween(toPointVector, cameraLeftPlaneNormalVector) > Math.PI / 2)
                    {
                        continue;
                    }
                    if (Relation3D.AngleBetween(toPointVector, cameraRightPlaneNormalVector) > Math.PI / 2)
                    {
                        continue;
                    }
                    if (Relation3D.AngleBetween(toPointVector, cameraTopPlaneNormalVector) > Math.PI / 2)
                    {
                        continue;
                    }
                    if (Relation3D.AngleBetween(toPointVector, cameraBottomPlaneNormalVector) > Math.PI / 2)
                    {
                        continue;
                    }
                    trianglesIndex.Push(Array.IndexOf(triangles, triangle));
                    break;
                }
            }
            trianglesOnScreenIndex = trianglesIndex.ToArray();
        }
コード例 #3
0
 /// <summary>
 /// Calculate the normal vectors used for angle calculation.
 /// </summary>
 private void CreatePlaneNormalVectors()
 {
     cameraLeftPlaneNormalVector   = cameraDirectionUnitVector.RotateVector(cameraVerticalUnitVector, CameraFieldOfView / 2 - Math.PI / 2, true);
     cameraRightPlaneNormalVector  = cameraDirectionUnitVector.RotateVector(cameraVerticalUnitVector, -(CameraFieldOfView / 2 - Math.PI / 2), true);
     cameraTopPlaneNormalVector    = cameraDirectionUnitVector.RotateVector(cameraHorizontalUnitVector, (CameraFieldOfView / AspectRatio) / 2 - Math.PI / 2, true);
     cameraBottomPlaneNormalVector = cameraDirectionUnitVector.RotateVector(cameraHorizontalUnitVector, -((CameraFieldOfView / AspectRatio) / 2 - Math.PI / 2), true);
 }
コード例 #4
0
        /// <summary>
        /// Moves the camera along an axis.
        /// </summary>
        /// <param name="direction">Direction of movement.</param>
        /// <param name="distance">Distance of movement.</param>
        public void MoveOnAxis(char direction, double distance = 0.1)
        {
            Vect3D CurrentPosition = new Vect3D(CameraPosition);

            switch (direction)
            {
            case 'r':
                CameraPosition = (CurrentPosition + cameraHorizontalUnitVector * distance).ToPoint();
                break;

            case 'l':
                CameraPosition = (CurrentPosition - cameraHorizontalUnitVector * distance).ToPoint();
                break;

            case 'u':
                CameraPosition = (CurrentPosition + cameraVerticalUnitVector * distance).ToPoint();
                break;

            case 'd':
                CameraPosition = (CurrentPosition - cameraVerticalUnitVector * distance).ToPoint();
                break;

            case 'f':
                CameraPosition = (CurrentPosition + cameraDirectionUnitVector * distance).ToPoint();
                break;

            case 'b':
                CameraPosition = (CurrentPosition - cameraDirectionUnitVector * distance).ToPoint();
                break;
            }

            DetermineTrianglesInRange();
            ProjectToScreen();
        }
コード例 #5
0
        /// <summary>
        /// Rotates the camera around an axis.
        /// </summary>
        /// <param name="axis">Rotationaxis</param>
        /// <param name="angle">Angle of rotation in degrees.</param>
        public void RotateAroundAxis(char axis, double angle = 1.5)
        {
            angle /= Relation3D.radianToDegreeConst;
            Vect3D rotationAxis = new Vect3D();

            switch (axis)
            {
            case 'x':
                rotationAxis = cameraHorizontalUnitVector;
                break;

            case 'y':
                rotationAxis = cameraDirectionUnitVector;
                break;

            case 'z':
                rotationAxis = cameraVerticalUnitVector;
                break;
            }
            Matrix rotationMatrix = Matrix.CreateRotationMatrix(rotationAxis, angle);

            cameraDirectionUnitVector     = rotationMatrix * cameraDirectionUnitVector;
            cameraVerticalUnitVector      = rotationMatrix * cameraVerticalUnitVector;
            cameraHorizontalUnitVector    = rotationMatrix * cameraHorizontalUnitVector;
            cameraLeftPlaneNormalVector   = rotationMatrix * cameraLeftPlaneNormalVector;
            cameraRightPlaneNormalVector  = rotationMatrix * cameraRightPlaneNormalVector;
            cameraTopPlaneNormalVector    = rotationMatrix * cameraTopPlaneNormalVector;
            cameraBottomPlaneNormalVector = rotationMatrix * cameraBottomPlaneNormalVector;

            DetermineTrianglesInRange();
            ProjectToScreen();
        }
コード例 #6
0
ファイル: Matrix.cs プロジェクト: Catmanwaking/3DTestArea
 /// <summary>
 /// Creates a 3x1 matrix from a vector.
 /// </summary>
 /// <param name="v">A vector.</param>
 public Matrix(Vect3D v)
 {
     Mtrx       = new double[3, 1];
     Rows       = 3;
     Columns    = 1;
     Mtrx[0, 0] = v.X;
     Mtrx[1, 0] = v.Y;
     Mtrx[2, 0] = v.Z;
 }
コード例 #7
0
 /// <summary>
 /// Resets the camera's position and direction.
 /// </summary>
 public void Reset()
 {
     CameraPosition             = new Point3D(1, -10, 1);
     cameraDirectionUnitVector  = new Vect3D(0, 1, 0);
     cameraVerticalUnitVector   = new Vect3D(0, 0, 1);
     cameraHorizontalUnitVector = new Vect3D(1, 0, 0);
     CreatePlaneNormalVectors();
     DetermineTrianglesInRange();
     ProjectToScreen();
 }
コード例 #8
0
ファイル: Matrix.cs プロジェクト: Catmanwaking/3DTestArea
        /// <summary>
        /// Turns a 3x1 matrix into a vector.
        /// </summary>
        /// <returns>Vector represented by the matrix.</returns>
        public Vect3D ToVector()
        {
            Vect3D v = new Vect3D();

            if (Rows == 3 && Columns == 1)
            {
                v.X = Mtrx[0, 0];
                v.Y = Mtrx[1, 0];
                v.Z = Mtrx[2, 0];
            }
            return(v);
        }
コード例 #9
0
        public override RGBColor Shade(ShadeRec sr)
        {
            RGBColor L = base.Shade(sr); //Factor in all direct illumination

            Vect3D reflectedDirection = -sr.Ray.Direction; //Vector pointing towards camera
            Vect3D perfectReflection = new Vect3D(1.0f,1.0f,1.0f); //Vector equivalent to perfect reflection
            RGBColor fr = reflectiveBRDF.SampleF(sr, ref perfectReflection, ref reflectedDirection); //Set vectors for reflection to correct values
            Point3D hitPoint = sr.HitPoint + (perfectReflection * GlobalVars.SHAD_K_EPSILON); //Avoid salt+pepper noise
            Ray reflectedRay = new Ray(hitPoint, perfectReflection); //Cast ray from point of incidence

            L += fr * sr.WorldPointer.CurrentTracer.TraceRay(reflectedRay, sr.RecursionDepth + 1) * (sr.Normal * perfectReflection); //Recurse!

            return L;
        }
コード例 #10
0
        /// <summary>
        /// Calculates the triangles position on the screen and adds them to the screens collection of triangles.
        /// </summary>
        public void ProjectToScreen()
        {
            screen.ClearTriangles();

            //Used for angle calculation.
            Vect3D toPointVector;
            Vect3D toPointVerticalPlaneNormalVector;
            Vect3D toPointHorizontalPlaneNormalVector;

            //Angles.
            double angleLeft;
            double angleTop;

            //Position on screen: 0 = left/top, 1 = right/bottom.
            double screenScalar;

            Point[] triangleCoordinatesOnScreen;
            BackFaceCulling();
            foreach (int triangleIndex in trianglesOnScreenIndex)
            {
                triangleCoordinatesOnScreen = new Point[3];
                for (int i = 0; i < 3; i++)
                {
                    toPointVector = new Vect3D(CameraPosition, triangles[triangleIndex].coordinates[i]);

                    toPointVerticalPlaneNormalVector   = Vect3D.VectorProduct(toPointVector, cameraVerticalUnitVector);
                    toPointHorizontalPlaneNormalVector = Vect3D.VectorProduct(toPointVector, cameraHorizontalUnitVector);
                    angleLeft = Relation3D.AngleBetween(toPointVerticalPlaneNormalVector, cameraLeftPlaneNormalVector);
                    angleTop  = Relation3D.AngleBetween(toPointHorizontalPlaneNormalVector, cameraTopPlaneNormalVector);

                    toPointVerticalPlaneNormalVector.SwitchOrientation();
                    toPointHorizontalPlaneNormalVector.SwitchOrientation();

                    screenScalar = widthScalar * Math.Sin(angleLeft) / Math.Sin(Math.PI - angleLeft - (Math.PI - CameraFieldOfView) / 2);
                    if (Relation3D.AngleBetween(toPointVerticalPlaneNormalVector, cameraRightPlaneNormalVector) > CameraFieldOfView)
                    {
                        screenScalar *= -1;
                    }
                    triangleCoordinatesOnScreen[i].X = Math.Round(screenScalar * screen.Width, 0);

                    screenScalar = heightScalar * Math.Sin(angleTop) / Math.Sin(Math.PI - angleTop - (Math.PI - (CameraFieldOfView / AspectRatio)) / 2);
                    if (Relation3D.AngleBetween(toPointHorizontalPlaneNormalVector, cameraBottomPlaneNormalVector) > CameraFieldOfView / AspectRatio)
                    {
                        screenScalar *= -1;
                    }
                    triangleCoordinatesOnScreen[i].Y = Math.Round(screenScalar * screen.Height, 0);
                }
                screen.AddTriangleToScreen(triangleCoordinatesOnScreen);
            }
        }
コード例 #11
0
ファイル: ShadeRec.cs プロジェクト: segafult/SCSRaytracer
 //Copy constructor
 public ShadeRec(ShadeRec shadeRec)
 {
     HitAnObject = shadeRec.HitAnObject;
     ObjectMaterial = shadeRec.ObjectMaterial;
     HitPoint = shadeRec.HitPoint;
     HitPointLocal = shadeRec.HitPointLocal;
     Normal = shadeRec.Normal;
     Color = shadeRec.Color;
     WorldPointer = shadeRec.WorldPointer;
     Ray = shadeRec.Ray;
     RecursionDepth = shadeRec.RecursionDepth;
     Direction = shadeRec.Direction;
     TMinimum = shadeRec.TMinimum;
     U = shadeRec.U;
     V = shadeRec.V;
 }
コード例 #12
0
ファイル: ShadeRec.cs プロジェクト: segafult/SCSRaytracer
 //Constructor
 public ShadeRec(World worldRef)
 {
     HitAnObject = false;
     ObjectMaterial = null;
     RecursionDepth = 0;
     WorldPointer = worldRef;
     HitPoint = new Point3D(0, 0, 0);
     HitPointLocal = new Point3D(0, 0, 0);
     Normal = new Normal(0, 0, 0);
     Color = new RGBColor(0, 0, 0);
     TMinimum = GlobalVars.K_HUGE_VALUE;
     Ray = new Ray(new Point3D(0, 0, 0), new Vect3D(0, 0, 0));
     Direction = new Vect3D(0, 0, 0);
     U = 0;
     V = 0;
 }
コード例 #13
0
        public void BackFaceCulling()
        {
            Stack <int> trianglesIndex = new Stack <int>();
            Vect3D      camToCorner;
            Vect3D      cornerVector1;
            Vect3D      cornerVector2;

            foreach (int index in trianglesOnScreenIndex)
            {
                cornerVector1 = new Vect3D(triangles[index].coordinates[0], triangles[index].coordinates[1]);
                cornerVector2 = new Vect3D(triangles[index].coordinates[0], triangles[index].coordinates[2]);
                camToCorner   = new Vect3D(CameraPosition, triangles[index].coordinates[0]);
                if (Vect3D.VectorProduct(cornerVector1, cornerVector2) * camToCorner >= 0.0)
                {
                    trianglesIndex.Push(index);
                }
            }
            trianglesOnScreenIndex = trianglesIndex.ToArray();
        }
コード例 #14
0
ファイル: Ray.cs プロジェクト: segafult/SCSRaytracer
 //Constructors
 public Ray(Point3D origin, Vect3D direction)
 {
     _origin = new Point3D(origin);
     _direction = new Vect3D(direction.Hat());
 }
コード例 #15
0
 /// <summary>
 /// Creates the a plane in three dimensional space using three points in three dimensional space.
 /// </summary>
 /// <param name="point1">First point.</param>
 /// <param name="point2">Second point.</param>
 /// <param name="point3">Third point.</param>
 public Plane3D(Point3D point1, Point3D point2, Point3D point3)
 {
     SupportVector       = new Vect3D(point1);
     DirectionVectors[0] = new Vect3D(point1, point2);
     DirectionVectors[1] = new Vect3D(point1, point3);
 }
コード例 #16
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="triangle"></param>
 public Plane3D(Triangle3D triangle)
 {
     SupportVector       = new Vect3D(triangle.coordinates[0]);
     DirectionVectors[0] = new Vect3D(triangle.coordinates[0], triangle.coordinates[1]);
     DirectionVectors[1] = new Vect3D(triangle.coordinates[0], triangle.coordinates[2]);
 }
コード例 #17
0
ファイル: Line3D.cs プロジェクト: Catmanwaking/3DTestArea
 /// <summary>
 /// Creates a line from two points in three dimensional space.
 /// </summary>
 /// <param name="p1">First point.</param>
 /// <param name="p2">Second point.</param>
 public Line3D(Point3D p1, Point3D p2)
 {
     SupportVector   = new Vect3D(p1);
     DirectionVector = new Vect3D(p1, p2);
 }
コード例 #18
0
ファイル: Line3D.cs プロジェクト: Catmanwaking/3DTestArea
 /// <summary>
 /// Creates a line from a point on the line and a direction vector.
 /// </summary>
 /// <param name="point">Point on the line.</param>
 /// <param name="directionVector">Direction of the line.</param>
 public Line3D(Point3D point, Vect3D directionVector)
 {
     SupportVector   = new Vect3D(point);
     DirectionVector = directionVector;
 }
コード例 #19
0
ファイル: Line3D.cs プロジェクト: Catmanwaking/3DTestArea
 /// <summary>
 /// Creates a line from a support vector and a direction vector.
 /// </summary>
 /// <param name="supportVector">The support vector.</param>
 /// <param name="directionVector">The direction vector.</param>
 public Line3D(Vect3D supportVector, Vect3D directionVector)
 {
     SupportVector   = supportVector;
     DirectionVector = directionVector;
 }
コード例 #20
0
ファイル: BRDF.cs プロジェクト: segafult/SCSRaytracer
 public virtual RGBColor SampleF(ShadeRec sr, ref Vect3D incomingDirection, ref Vect3D reflectedDirection)
 {
     return GlobalVars.COLOR_BLACK;
 }
コード例 #21
0
ファイル: BRDF.cs プロジェクト: segafult/SCSRaytracer
 public virtual RGBColor Rho(ShadeRec sr, Vect3D reflectedDirection)
 {
     return GlobalVars.COLOR_BLACK;
 }
コード例 #22
0
ファイル: Ray.cs プロジェクト: segafult/SCSRaytracer
 //Copy constructor
 public Ray(Ray ray)
 {
     _origin = new Point3D(ray.Origin);
     _direction = new Vect3D(ray.Direction);
 }