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); }
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); }
//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); }
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); }
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); }
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])); }
//Public interface public virtual RayResult OnIntersection(RayResult original, Vector2f O, float angle, RayCaster caster) { original.Valid = true; return(original); }
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++; } } }