Exemplo n.º 1
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();
        }
Exemplo n.º 2
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);
            }
        }