public Bitmap Scan(Bitmap baseImage, Rayable drawnObject, Vector3 pov, float lengthCutoff = 50)
        {
            Bitmap image = new Bitmap(baseImage);

            for (int iy = 1; iy < resolution_Y; iy++)
            {
                for (int ix = 1; ix < resolution_X; ix++)
                {
                    RayResult result = Ray(RayDirection(ix, iy), drawnObject, pov, 0.005f, lengthCutoff, 50);
                    //int color = (int)((1 - (result.Closest /0.05f)) * 255);
                    //int color = (int)((1 - (result.RayLength / 20)) * 255);
                    //int color = (int)(( (result.RayLength/lengthCutoff)) * 255);
                    int color = (int)((1 - (result.Steps / 50f)) * 255);
                    if (color > 255 || result.RayLength > lengthCutoff)
                    {
                        color = 0;
                    }
                    if (color < 0)
                    {
                        color = 0;
                    }
                    //if(color>100)
                    {
                        Color color1 = Color.FromArgb(color, color, color);
                        //image.SetPixel(resolution_X-ix, resolution_Y-iy, color1);
                        image.SetPixel(ix, resolution_Y - iy, color1);
                        //DrawPixel(baseImage, color1, ix, resolution_Y - iy);
                    }
                }
            }
            return(image);
        }
示例#2
0
        public virtual (Vector2f top, Vector2f bottom) CalculateTextureCoords(RayResult original, Vector2f O, float angle, RayCaster caster)
        {
            Vector2f textureCordUp;
            Vector2f textureCordDown;

            switch (original.Side)
            {
            case Side.Down:
                textureCordUp = new Vector2f(
                    DownAtlas.X * caster.CellSize + (original.Position.X % caster.CellSize),
                    DownAtlas.Y * caster.CellSize);
                textureCordDown = new Vector2f(
                    textureCordUp.X,
                    textureCordUp.Y + caster.CellSize);
                break;

            case Side.Up:
                textureCordUp = new Vector2f(
                    UpAtlas.X * caster.CellSize + (original.Position.X % caster.CellSize),
                    UpAtlas.Y * caster.CellSize);
                textureCordDown = new Vector2f(
                    textureCordUp.X,
                    textureCordUp.Y + caster.CellSize);
                break;

            case Side.Left:
                textureCordUp = new Vector2f(
                    LeftAtlas.X * caster.CellSize + (original.Position.Y % caster.CellSize),
                    LeftAtlas.Y * caster.CellSize);
                textureCordDown = new Vector2f(
                    textureCordUp.X,
                    textureCordUp.Y + caster.CellSize);
                break;

            case Side.Right:
                textureCordUp = new Vector2f(
                    RightAtlas.X * caster.CellSize + (original.Position.Y % caster.CellSize),
                    RightAtlas.Y * caster.CellSize);
                textureCordDown = new Vector2f(
                    textureCordUp.X,
                    textureCordUp.Y + caster.CellSize);
                break;

            default:
                textureCordUp = new Vector2f(
                    (original.Position.Y % caster.CellSize),
                    RightAtlas.Y * caster.CellSize);
                textureCordDown = new Vector2f(
                    textureCordUp.X,
                    textureCordUp.Y + caster.CellSize - 1);
                break;
            }

            return(textureCordUp, textureCordDown);
        }
        public RayResult AddRequest(RayRequest req)
        {
            int       numWorkItems = 5;
            RayResult res          = new RayResult {
                PixelData = new BlockStream(numWorkItems, 0xa1070b6d)
            };

            m_Requests.Add(req);
            m_Results.Add(res);
            return(res);
        }
        public RayResult AddRequest(RayRequest req)
        {
            int numWorkItems = 5;
            var res          = new RayResult {
                PixelData = new NativeStream(numWorkItems, Allocator.TempJob)
            };

            m_Requests.Add(req);
            m_Results.Add(res);
            return(res);
        }
示例#5
0
        //Private methods
        private float CalculateLampIntensityAtPoint(Vector2f mPos, Vector2f lPos)
        {
            RayResult r = Caster.RayCast(lPos, Atan2D(mPos, lPos));

            if (r.Magnitude + 1 >= Distance(mPos, lPos))
            {
                return(1f / ((float)Math.Pow(Distance(mPos, lPos), 2) / LightMultiplier));
            }
            else
            {
                return(0);
            }
        }
        private Vector3 CalculateTargetedRezLocation(
            RayResult ray,
            Vector3 scale,
            Vector3 projectedWaterLocation)
        {
            Vector3 pos = ray.HitNormalWorld.Cross(scale);

            pos *= 0.5;
            pos += ray.HitPointWorld;

            if (projectedWaterLocation.Z > pos.Z)
            {
                pos = projectedWaterLocation;
            }
            return(pos);
        }
示例#7
0
        public override (Vector2f top, Vector2f bottom) CalculateTextureCoords(RayResult original, Vector2f O, float angle, RayCaster caster)
        {
            float tx = Atan2(caster.CellSize * original.Tile.Y + (caster.CellSize / 2) - original.Position.Y,
                             caster.CellSize * original.Tile.X + (caster.CellSize / 2) - original.Position.X) + (float)Math.PI;

            tx  = (float)((tx * caster.CellSize) / (Math.PI * 2));
            tx *= 4;
            tx %= (float)(Math.PI * 2);
            Vector2f top = new Vector2f(
                DownAtlas.X * caster.CellSize + tx,
                DownAtlas.Y * caster.CellSize);
            Vector2f bottom = new Vector2f(
                top.X,
                top.Y + caster.CellSize);

            return(top, bottom);
        }
示例#8
0
        public override RayResult OnIntersection(RayResult original, Vector2f O, float angle, RayCaster caster)
        {
            int points = LineCircleIntersections(caster.CellSize * original.Tile.X + (caster.CellSize / 2),
                                                 caster.CellSize * original.Tile.Y + (caster.CellSize / 2),
                                                 caster.CellSize / 2,
                                                 original.Position,
                                                 original.Position + new Vector2f(300 * CosD(angle), 300 * SinD(angle)),
                                                 out Vector2f p1, out Vector2f p2);

            switch (points)
            {
            case 0:
                original.Valid = false;
                return(original);

            case 1:
                return(new RayResult
                {
                    Valid = true,
                    Magnitude = Distance(O, p1),
                    Side = Side.None,
                    Position = p1,
                    Tile = original.Tile
                });

            case 2:
                Vector2f final = Distance(O, p1) <= Distance(O, p2) ? p1 : p2;
                return(new RayResult
                {
                    Valid = true,
                    Magnitude = Distance(O, final),
                    Side = Side.None,
                    Position = final,
                    Tile = original.Tile
                });
            }

            original.Valid = true;
            return(original);
        }
示例#9
0
        public void Render(Vector2f player, float angle, float height, float look, List <Sprite> sprites, List <Light> lamps)
        {
            List <Vertex> spritesLines = new List <Vertex>();

            ParallelLoopResult floorResult = Parallel.For((int)look, (int)Buffer.Size.Y, i => CalculateFloor(player, angle, i, height, look, ref FloorVertices, ref lamps));
            ParallelLoopResult ceilResult  = Parallel.For(0, (int)look - 1, i => CalculateCeil(player, angle, i, height, look, ref FloorVertices, ref lamps));


            for (int x = 0; x < Buffer.Size.X; x++)
            {
                float     rayAngle = Angles[x];
                RayResult ray      = Caster.RayCast(player, angle + rayAngle);
                Tile      t        = Map[ray.Tile.X, ray.Tile.Y];

                (Vector2f textureCordUp, Vector2f textureCordDown) = t.CalculateTextureCoords(ray, player, angle, Caster);

                Color col;

                if (!DynamicLight)
                {
                    int pX = (int)(ray.Position.X * LightMapScaler);
                    if (pX >= LightMap.GetLength(0))
                    {
                        pX = LightMap.GetLength(0) - 1;
                    }
                    if (pX < 0)
                    {
                        pX = 0;
                    }

                    int pY = (int)(ray.Position.Y * LightMapScaler);
                    if (pY >= LightMap.GetLength(1))
                    {
                        pY = LightMap.GetLength(1) - 1;
                    }
                    if (pY < 0)
                    {
                        pY = 0;
                    }
                    col = LightMap[pX, pY];
                }
                else
                {
                    col = getLightAtPoint(ray.Position, lamps);
                }


                DepthPerStrip[x] = ray.Magnitude * CosD(rayAngle);

                var ratio        = DistanceToProjectionPlane / DepthPerStrip[x];
                var bottomOfWall = (ratio * height + look);
                var scale        = (ratio * Caster.CellSize);
                var topOfWall    = bottomOfWall - scale;

                WallVertices[x << 1] = new Vertex
                {
                    Position  = new Vector2f(x, bottomOfWall),
                    Color     = col,
                    TexCoords = textureCordUp
                };
                WallVertices[(x << 1) + 1] = new Vertex
                {
                    Position  = new Vector2f(x, topOfWall),
                    Color     = col,
                    TexCoords = textureCordDown
                };
            }


            List <Sprite> finalList = new List <Sprite>();

            foreach (Sprite spr in sprites)
            {
                if (!DynamicLight)
                {
                    int pX = (int)(spr.Position.X * LightMapScaler);
                    if (pX >= LightMap.GetLength(0))
                    {
                        pX = LightMap.GetLength(0) - 1;
                    }
                    if (pX < 0)
                    {
                        pX = 0;
                    }

                    int pY = (int)(spr.Position.Y * LightMapScaler);
                    if (pY >= LightMap.GetLength(0))
                    {
                        pY = LightMap.GetLength(1) - 1;
                    }
                    if (pY < 0)
                    {
                        pY = 0;
                    }

                    spr.Light = LightMap[pX, pY];
                }
                else
                {
                    spr.Light = getLightAtPoint(spr.Position, lamps);
                }

                spr.TransformedPosition = Rotate(spr.Position - player, -angle);
                spr.DistanceToPlayer    = spr.TransformedPosition.X;
                if (spr.DistanceToPlayer > 0)
                {
                    finalList.Add(spr);
                }
            }

            finalList = finalList.OrderByDescending(s => s.TransformedPosition.X).ToList();

            foreach (Sprite spr in finalList)
            {
                int lineHeight = FloorInt((Caster.CellSize / spr.DistanceToPlayer) * DistanceToProjectionPlane);
                int px         = (int)(Buffer.Size.X / 2 + (spr.TransformedPosition.Y / spr.DistanceToPlayer) * DistanceToProjectionPlane);
                for (int x = 0; x < lineHeight; x++)
                {
                    int posX = (px + lineHeight / 2) - x;
                    if (posX >= 0 && posX < Buffer.Size.X && DepthPerStrip[posX] > spr.DistanceToPlayer)
                    {
                        float tex = (float)x * (Caster.CellSize) / lineHeight;

                        Vector2f textureCordUp = new Vector2f(
                            (spr.AtlasTexture.X + 1) * Caster.CellSize - 0.00001f - tex,
                            spr.AtlasTexture.Y * Caster.CellSize);

                        Vector2f textureCordDown = new Vector2f(
                            textureCordUp.X,
                            textureCordUp.Y + Caster.CellSize);

                        var ratio        = DistanceToProjectionPlane / spr.DistanceToPlayer;
                        var bottomOfWall = (ratio * height + look);
                        var scale        = (ratio * Caster.CellSize);
                        var topOfWall    = bottomOfWall - scale;

                        spritesLines.Add(new Vertex
                        {
                            Position  = new Vector2f(posX, topOfWall),
                            Color     = spr.Light,
                            TexCoords = textureCordUp
                        });
                        spritesLines.Add(new Vertex
                        {
                            Position  = new Vector2f(posX, bottomOfWall),
                            Color     = spr.Light,
                            TexCoords = textureCordDown
                        });
                    }
                }
            }

            while (!floorResult.IsCompleted)
            {
                Thread.Sleep(0);
            }

            while (!ceilResult.IsCompleted)
            {
                Thread.Sleep(0);
            }

            Buffer.Draw(FloorVertices, 0, (uint)FloorVertices.Length, PrimitiveType.Points, new RenderStates(Textures[MapAtlasInUse]));
            Buffer.Draw(WallVertices, 0, (uint)WallVertices.Length, PrimitiveType.Lines, new RenderStates(Textures[MapAtlasInUse]));
            Buffer.Draw(spritesLines.ToArray(), 0, (uint)spritesLines.Count, PrimitiveType.Lines, new RenderStates(Textures[MapAtlasInUse]));
        }
示例#10
0
 //Public interface
 public virtual RayResult OnIntersection(RayResult original, Vector2f O, float angle, RayCaster caster)
 {
     original.Valid = true;
     return(original);
 }
示例#11
0
        public void StartSFMLProgram()
        {
            #region Initialization
            Map Map = new Map(_m.GetLength(0), _m.GetLength(1));

            for (int y = 0; y < _m.GetLength(1); y++)
            {
                for (int x = 0; x < _m.GetLength(0); x++)
                {
                    switch (_m[y, x])
                    {
                    case 1:
                        Map[x, y] = new Tile
                        {
                            Solid      = true,
                            DownAtlas  = new Vector2i(1, 0),
                            UpAtlas    = new Vector2i(1, 0),
                            LeftAtlas  = new Vector2i(1, 0),
                            RightAtlas = new Vector2i(1, 0)
                        };
                        break;

                    case 2:
                        Map[x, y] = new CircleTile
                        {
                            Solid      = true,
                            DownAtlas  = new Vector2i(1, 0),
                            UpAtlas    = new Vector2i(1, 0),
                            LeftAtlas  = new Vector2i(1, 0),
                            RightAtlas = new Vector2i(1, 0),
                            CeilAtlas  = new Vector2i(0, 0),
                            FloorAtlas = new Vector2i(2, 0),
                            //IsCeilMap = true
                        };
                        break;

                    case 5:
                        Map[x, y] = new Tile
                        {
                            Solid      = false,
                            DownAtlas  = new Vector2i(0, 0),
                            UpAtlas    = new Vector2i(0, 0),
                            LeftAtlas  = new Vector2i(1, 0),
                            RightAtlas = new Vector2i(1, 0),
                            CeilAtlas  = new Vector2i(0, 0),
                            FloorAtlas = new Vector2i(5, 0)
                        };
                        break;

                    case 0:
                        Map[x, y] = new Tile
                        {
                            Solid      = false,
                            DownAtlas  = new Vector2i(0, 0),
                            UpAtlas    = new Vector2i(0, 0),
                            LeftAtlas  = new Vector2i(1, 0),
                            RightAtlas = new Vector2i(1, 0),
                            CeilAtlas  = new Vector2i(0, 0),
                            FloorAtlas = new Vector2i(5, 0)
                        };
                        break;

                    case 6:
                        Map[x, y] = new Tile
                        {
                            Solid      = false,
                            DownAtlas  = new Vector2i(0, 0),
                            UpAtlas    = new Vector2i(0, 0),
                            LeftAtlas  = new Vector2i(1, 0),
                            RightAtlas = new Vector2i(1, 0),
                            CeilAtlas  = new Vector2i(0, 0),
                            FloorAtlas = new Vector2i(5, 0),
                            IsCeilMap  = true
                        };
                        break;
                    }
                }
            }


            window = new RenderWindow(new VideoMode(800, 600), "SFML window", Styles.Default);
            window.SetVisible(true);
            window.Closed     += new EventHandler(OnClosed);
            window.KeyPressed += new EventHandler <KeyEventArgs>(OnKeyPressed);
            window.MouseMoved += Window_MouseMoved;

            //Vector2f screen = new Vector2f(200, 100);

            Vector2f screen = new Vector2f(window.Size.X, window.Size.Y);
            screen *= 0.3f;
            rs      = new RenderTexture((uint)screen.X, (uint)screen.Y);

            caster = new RayCaster(Map, 32);

            Renderer ren = new Renderer(caster, window, rs, Map, fov, new Color(16, 16, 16));
            ren.Textures.Add(new Texture("Texture.png"));
            ren.MapAtlasInUse = 0;
            #endregion

            Vector2f player = new Vector2f(caster.CellSize * 6 + 8, caster.CellSize * 5 + 8);
            Vector2f sp1    = player + new Vector2f(70, 15);
            Vector2f sp2    = player + new Vector2f(50, 70);

            Vector2f sp3  = new Vector2f(caster.CellSize * 6 + 8, caster.CellSize * 5 + 8) + new Vector2f(30, -30);
            Vector2f scen = sp1 + new Vector2f(60, 60);

            Vector2f M;

            font = new Font("Perfect DOS VGA 437 Win.ttf");
            Text t          = new Text("Fps: ", font, 16);
            int  fps        = 0;
            int  fpsCounter = 0;
            int  ticks      = Environment.TickCount;
            int  ticksFps   = Environment.TickCount;


            int timeDelta = 0;

            var lamps = new List <Light>();
            //{
            //    new Light (
            //        new Vector2f(sp1.X,sp1.Y),
            //        new Color(255,255,255)
            //    ),
            //    new Light (
            //        new Vector2f(sp2.X,sp2.Y),
            //        new Color(128,128,0)
            //    )
            //};



            List <Sprite> sprites = new List <Sprite>();
            Random        r       = new Random();

            for (int i = 0; i < 5; i++)
            {
                sprites.Add(new Sprite
                            (
                                new Vector2f((float)r.NextDouble() * caster.CellSize * Map.Tiles.GetLength(0), (float)r.NextDouble() * caster.CellSize * Map.Tiles.GetLength(1)),
                                new Vector2i(3, 0)
                            ));
            }
            Random rand = new Random();
            lamps = sprites.Select(s => new Light(s.Position, new Color((byte)(rand.NextDouble() * 80), 0, (byte)(rand.NextDouble() * 80)))).ToList();


            ren.GenerateLightMap(lamps, 0.5f);
            //sprites.Add(new Sprite
            //(
            //    sp2,
            //    new Vector2i(3, 0)
            //));

            //Sprite p = new Sprite
            //(
            //    sp1,
            //    new Vector2i(3, 0)
            //);
            //sprites.Add(p);

            AudioSystem audio        = new AudioSystem(32, Map, caster);
            Sprite      playerSprite = new Sprite(player, new Vector2i(0, 0));
            audio.Listener = playerSprite;
            int a = audio.LoadSound("ts.wav");
            audio.PlaySound(a, true, sp1);

            float look   = rs.Size.Y / 2;
            float height = caster.CellSize / 2;
            ren.SkyPosition = new Vector2f(5, 5);
            ren.SkyAtlas    = new Vector2i(6, 0);

            window.MouseWheelScrolled += (o, e) =>
            {
                height += e.Delta / 1;
                if (height > caster.CellSize)
                {
                    height = caster.CellSize;
                }

                if (height < 0)
                {
                    height = 0;
                }
            };

            while (window.IsOpen)
            {
                if (Environment.TickCount - ticksFps >= timeDelta)
                {
                    ticksFps = Environment.TickCount;
                    if (Environment.TickCount - ticks >= 1000)
                    {
                        fps        = fpsCounter;
                        fpsCounter = 0;
                        ticks      = Environment.TickCount;
                    }

                    angle -= (window.Size.X / 2 - Mouse.GetPosition(window).X) / 4f;
                    look  += (window.Size.Y / 2 - Mouse.GetPosition(window).Y) / 3f;

                    if (look < 0)
                    {
                        look = 0;
                    }
                    if (look > rs.Size.Y)
                    {
                        look = rs.Size.Y;
                    }

                    ren.SkyPosition += new Vector2f(0.01f, 0.05f);


                    if (Keyboard.IsKeyPressed(Keyboard.Key.P))
                    {
                        lamps.Add(
                            new Light(player, new Color(255, 255, 255)));
                    }

                    angle -= Keyboard.IsKeyPressed(Keyboard.Key.Left) ? 2 : 0;
                    angle += Keyboard.IsKeyPressed(Keyboard.Key.Right) ? 2 : 0;

                    M = new Vector2f(0, 0);

                    if (Keyboard.IsKeyPressed(Keyboard.Key.W))
                    {
                        M += new Vector2f(CosD(angle) * 2, SinD(angle) * 2);
                    }

                    if (Keyboard.IsKeyPressed(Keyboard.Key.S))
                    {
                        M -= new Vector2f(CosD(angle) * 2, SinD(angle) * 2);
                    }

                    if (Keyboard.IsKeyPressed(Keyboard.Key.D))
                    {
                        M += new Vector2f(CosD(angle + 90) * 2, SinD(angle + 90) * 2);
                    }

                    if (Keyboard.IsKeyPressed(Keyboard.Key.A))
                    {
                        M += new Vector2f(CosD(angle - 90) * 2, SinD(angle - 90) * 2);
                    }


                    RayResult R = caster.RayCast(player, 0);
                    if (R.Magnitude < Math.Abs(M.X) + 10 && Math.Sign(M.X) == 1)
                    {
                        M.X = 0;
                    }

                    R = caster.RayCast(player, 180);
                    if (R.Magnitude < Math.Abs(M.X) + 10 && Math.Sign(M.X) == -1)
                    {
                        M.X = 0;
                    }

                    R = caster.RayCast(player, 90);
                    if (R.Magnitude < Math.Abs(M.Y) + 10 && Math.Sign(M.Y) == 1)
                    {
                        M.Y = 0;
                    }

                    R = caster.RayCast(player, 270);
                    if (R.Magnitude < Math.Abs(M.Y) + 10 && Math.Sign(M.Y) == -1)
                    {
                        M.Y = 0;
                    }

                    player += M;



                    Mouse.SetPosition(new Vector2i((int)window.Size.X / 2, (int)window.Size.Y / 2), window);

                    window.DispatchEvents();
                    rs.Clear(Color.Black);



                    playerSprite.Position = player;
                    playerSprite.Angle    = angle;
                    audio.UpdateAudio();
                    ren.Render(player, angle, height, look, sprites, lamps);
                    t.DisplayedString = $"Fps: {fps} - Lights: {lamps.Count}";
                    rs.Draw(t);
                    ren.ShowBuffer();
                    Thread.Sleep(0);

                    fpsCounter++;
                }
            }
        }