public void AttachToNeighbors() { global::System.Diagnostics.Debug.Assert(NeighborPipes.Count == 0); foreach (var entity in Manager.World.EnumerateIntersectingObjects(this.BoundingBox.Expand(0.1f), CollisionType.Static)) { if (Object.ReferenceEquals(entity, this)) { continue; } var neighborPipe = entity as SteamPoweredObject; if (neighborPipe == null) { continue; } var distance = (neighborPipe.Position - Position).Length2D(); if (distance > 1.1f) { continue; } AttachNeighbor(neighborPipe.GlobalID); neighborPipe.AttachNeighbor(this.GlobalID); } Primitive = null; }
private static void AddQuad( RawPrimitive Into, ExtendedVertex[] Verticies, short[] Indicies) { Into.AddOffsetIndicies(Indicies, Into.VertexCount, 6); for (var vertex = 0; vertex < 4; ++vertex) { Into.AddVertex(Verticies[vertex]); } }
public void DetachFromNeighbors() { foreach (var neighbor in NeighborPipes.Select(connection => Manager.FindComponent(connection))) { if (neighbor is SteamPoweredObject neighborPipe) { neighborPipe.DetachNeighbor(this.GlobalID); } } NeighborPipes.Clear(); Primitive = null; }
public override void CreateCosmeticChildren(ComponentManager manager) { base.CreateCosmeticChildren(manager); Sheet = new SpriteSheet(ContentPaths.Entities.Furniture.elevator, 32, 32); AddChild(new GenericVoxelListener(manager, Matrix.Identity, new Vector3(1.5f, 1.5f, 1.5f), Vector3.Zero, (_event) => { Primitive = null; })).SetFlag(Flag.ShouldSerialize, false); UVs[0] = Sheet.GenerateTileUVs(new Point(0, 0), out Bounds[0]); UVs[1] = Sheet.GenerateTileUVs(new Point(1, 0), out Bounds[1]); }
override public void Render(DwarfTime gameTime, ChunkManager chunks, Camera camera, SpriteBatch spriteBatch, GraphicsDevice graphicsDevice, Shader effect, bool renderingForWater) { base.Render(gameTime, chunks, camera, spriteBatch, graphicsDevice, effect, renderingForWater); if (Primitive == null) { var bounds = Vector4.Zero; var uvs = Sheet.GenerateTileUVs(new Point(2, 0), out bounds); Primitive = new RawPrimitive(); Primitive.AddQuad(Matrix.Identity, Color.White, Color.White, uvs, bounds); } if (Primitive.VertexCount == 0) { return; } var under = new VoxelHandle(chunks, GlobalVoxelCoordinate.FromVector3(Position)); if (under.IsValid) { Color color = new Color(under.Sunlight ? 255 : 0, 255, 0); LightRamp = color; } else { LightRamp = new Color(200, 255, 0); } Color origTint = effect.VertexColorTint; effect.VertexColorTint = VertexColor; effect.LightRamp = LightRamp; effect.World = GlobalTransform; effect.MainTexture = Sheet.GetTexture(); effect.EnableWind = false; foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Apply(); Primitive.Render(graphicsDevice); } effect.VertexColorTint = origTint; }
private static void GenerateSliceGeometry( RawPrimitive Into, VoxelChunk Chunk, int LocalY, TerrainTileSheet TileSheet, WorldManager World, SliceCache Cache) { for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x) { for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z) { GenerateVoxelGeometry(Into, VoxelHandle.UnsafeCreateLocalHandle(Chunk, new LocalVoxelCoordinate(x, LocalY, z)), TileSheet, World, Cache); } } }
private static void GenerateHangingCornerFringe( RawPrimitive Into, Geo.TemplateFace Face, TerrainTileSheet TileSheet, SliceCache Cache, GrassType decalType, Geo.TemplateCorner Corner, Vector3 Sag) { var vertex = Cache.FaceGeometry[Corner.Vertex]; Cache.TempVerticies[0] = new ExtendedVertex( vertex.Position, vertex.Color, vertex.VertColor, TileSheet.MapTileUVs(new Vector2(0.0f, 0.0f), decalType.FringeTiles[2]), TileSheet.GetTileBounds(decalType.FringeTiles[2])); Cache.TempVerticies[1] = new ExtendedVertex( Cache.EdgeFringeTempVerticies[Corner.EdgeA].Set ? Cache.EdgeFringeTempVerticies[Corner.EdgeA].End : (vertex.Position + OrientationHelper.GetFaceNeighborOffset(Face.Edges[Corner.EdgeA].Orientation).AsVector3() * 0.5f + Sag), vertex.Color, vertex.VertColor, TileSheet.MapTileUVs(new Vector2(0.5f, 0.0f), decalType.FringeTiles[2]), TileSheet.GetTileBounds(decalType.FringeTiles[2])); Cache.TempVerticies[2] = new ExtendedVertex( vertex.Position + OrientationHelper.GetFaceNeighborOffset(Face.Edges[Corner.EdgeA].Orientation).AsVector3() * 0.5f + OrientationHelper.GetFaceNeighborOffset(Face.Edges[Corner.EdgeB].Orientation).AsVector3() * 0.5f + Sag, vertex.Color, vertex.VertColor, TileSheet.MapTileUVs(new Vector2(0.5f, 0.5f), decalType.FringeTiles[2]), TileSheet.GetTileBounds(decalType.FringeTiles[2])); Cache.TempVerticies[3] = new ExtendedVertex( Cache.EdgeFringeTempVerticies[Corner.EdgeB].Set ? Cache.EdgeFringeTempVerticies[Corner.EdgeB].Start : (vertex.Position + OrientationHelper.GetFaceNeighborOffset(Face.Edges[Corner.EdgeB].Orientation).AsVector3() * 0.5f + Sag), vertex.Color, vertex.VertColor, TileSheet.MapTileUVs(new Vector2(0.0f, 0.5f), decalType.FringeTiles[2]), TileSheet.GetTileBounds(decalType.FringeTiles[2])); AddQuad(Into, Cache.TempVerticies, QuadIndicies); }
public static void GenerateFaceGeometry( RawPrimitive Into, VoxelHandle Voxel, Geo.TemplateFace Face, TerrainTileSheet TileSheet, WorldManager World, SliceCache Cache) { if (Face.CullType == Geo.FaceCullType.Cull && !IsFaceVisible(Voxel, Face, World.ChunkManager, out var neighbor)) { return; } if (Face.Orientation == FaceOrientation.Top) { if (Voxel.GrassType != 0) { var decalType = Library.GetGrassType(Voxel.GrassType); PrepVerticies(World, Voxel, Face, Cache, GetVoxelVertexExploredNeighbors(Voxel, Face, Cache), TileSheet, decalType.Tile, true, 0.0f); GenerateGrassFringe(Into, Voxel, Face, TileSheet, Cache, decalType); } else { PrepVerticies(World, Voxel, Face, Cache, GetVoxelVertexExploredNeighbors(Voxel, Face, Cache), TileSheet, SelectTile(Voxel.Type, Face.Orientation), true, 0.0f); } AddQuad(Into, Cache.FaceGeometry, QuadIndicies); if (Voxel.DecalType != 0) { var decalType = Library.GetDecalType(Voxel.DecalType); PrepVerticies(World, Voxel, Face, Cache, GetVoxelVertexExploredNeighbors(Voxel, Face, Cache), TileSheet, decalType.Tile, true, 0.02f); AddQuad(Into, Cache.FaceGeometry, QuadIndicies); } } else { PrepVerticies(World, Voxel, Face, Cache, GetVoxelVertexExploredNeighbors(Voxel, Face, Cache), TileSheet, SelectTile(Voxel.Type, Face.Orientation), true, 0.0f); AddQuad(Into, Cache.FaceGeometry, QuadIndicies); } }
public static void GenerateVoxelGeometry( RawPrimitive Into, VoxelHandle Voxel, TerrainTileSheet TileSheet, WorldManager World, SliceCache Cache) { BuildDesignationGeometry(Into, Voxel, Cache, TileSheet, World); if (Voxel.IsEmpty && Voxel.IsExplored) { return; } var templateSolid = TemplateSolidLibrary.GetTemplateSolid(Voxel.Type.TemplateSolid); foreach (var face in templateSolid.Faces) { GenerateFaceGeometry(Into, Voxel, face, TileSheet, World, Cache); } }
private static void GenerateEdgeFringe( RawPrimitive Into, Geo.TemplateFace Face, int EdgeIndex, TerrainTileSheet TileSheet, SliceCache Cache, GrassType decalType, Vector3 Sag, float Scale) { var start = Cache.FaceGeometry[Face.Edges[EdgeIndex].Start]; var end = Cache.FaceGeometry[Face.Edges[EdgeIndex].End]; Cache.EdgeFringeTempVerticies[EdgeIndex].Set = true; Cache.TempVerticies[0] = new ExtendedVertex( start.Position, start.Color, start.VertColor, TileSheet.MapTileUVs(new Vector2(0.0f, 0.0f), decalType.FringeTiles[0]), TileSheet.GetTileBounds(decalType.FringeTiles[0])); Cache.TempVerticies[1] = new ExtendedVertex( end.Position, end.Color, end.VertColor, TileSheet.MapTileUVs(new Vector2(1.0f, 0.0f), decalType.FringeTiles[0]), TileSheet.GetTileBounds(decalType.FringeTiles[0])); Cache.EdgeFringeTempVerticies[EdgeIndex].End = end.Position + OrientationHelper.GetFaceNeighborOffset(Face.Edges[EdgeIndex].Orientation).AsVector3() * Scale + Sag; Cache.TempVerticies[2] = new ExtendedVertex( Cache.EdgeFringeTempVerticies[EdgeIndex].End, end.Color, end.VertColor, TileSheet.MapTileUVs(new Vector2(1.0f, 0.5f), decalType.FringeTiles[0]), TileSheet.GetTileBounds(decalType.FringeTiles[0])); Cache.EdgeFringeTempVerticies[EdgeIndex].Start = start.Position + OrientationHelper.GetFaceNeighborOffset(Face.Edges[EdgeIndex].Orientation).AsVector3() * Scale + Sag; Cache.TempVerticies[3] = new ExtendedVertex( Cache.EdgeFringeTempVerticies[EdgeIndex].Start, start.Color, start.VertColor, TileSheet.MapTileUVs(new Vector2(0.0f, 0.5f), decalType.FringeTiles[0]), TileSheet.GetTileBounds(decalType.FringeTiles[0])); AddQuad(Into, Cache.TempVerticies, QuadIndicies); }
public void CreatBalloonMesh(Overworld Overworld) { BalloonPrimitive = new RawPrimitive(); if (IconTexture == null) { IconTexture = AssetManager.GetContentTexture("GUI\\map_icons"); } var iconSheet = new SpriteSheet(IconTexture, 16, 16); var bounds = Vector4.Zero; var uvs = iconSheet.GenerateTileUVs(new Point(2, 0), out bounds); var angle = MathFunctions.Rand() * (float)System.Math.PI; BalloonPrimitive.AddQuad( Matrix.CreateRotationX(-(float)System.Math.PI / 2) * Matrix.CreateScale(6.0f / Overworld.Width), Color.White, Color.White, uvs, bounds); BalloonPrimitive.AddQuad( Matrix.CreateRotationX(-(float)System.Math.PI / 2) * Matrix.CreateRotationY((float)System.Math.PI / 2) * Matrix.CreateScale(6.0f / Overworld.Width), Color.White, Color.White, uvs, bounds); }
public static GeometricPrimitive CreateFromChunk(VoxelChunk Chunk, WorldManager World) { DebugHelper.AssertNotNull(Chunk); DebugHelper.AssertNotNull(World); var sliceStack = new List <RawPrimitive>(); var sliceCache = new SliceCache(); int maxViewingLevel = World.Renderer.PersistentSettings.MaxViewingLevel; var terrainTileSheet = new TerrainTileSheet(512, 512, 32, 32); for (var localY = 0; localY < maxViewingLevel - Chunk.Origin.Y && localY < VoxelConstants.ChunkSizeY; ++localY) { RawPrimitive sliceGeometry = null; sliceCache.ClearSliceCache(); lock (Chunk.Data.SliceCache) { var cachedSlice = Chunk.Data.SliceCache[localY]; if (cachedSlice != null) { sliceStack.Add(cachedSlice); // Todo: Get rid of the raw primitive / geometric primitive bullshit entirely if (GameSettings.Current.GrassMotes) { Chunk.RebuildMoteLayerIfNull(localY); } continue; } sliceGeometry = new RawPrimitive(); Chunk.Data.SliceCache[localY] = sliceGeometry; } if (GameSettings.Current.CalculateRamps) { PrecomputeVoxelSlopesSlice(World.ChunkManager, Chunk, localY); } if (GameSettings.Current.GrassMotes) { Chunk.RebuildMoteLayer(localY); } DebugHelper.AssertNotNull(sliceGeometry); GenerateSliceGeometry(sliceGeometry, Chunk, localY, terrainTileSheet, World, sliceCache); sliceStack.Add(sliceGeometry); } var chunkGeo = RawPrimitive.Concat(sliceStack); var r = new GeometricPrimitive(); r.Vertices = chunkGeo.Vertices; r.VertexCount = chunkGeo.VertexCount; r.Indexes = chunkGeo.Indexes.Select(c => (ushort)c).ToArray(); r.IndexCount = chunkGeo.IndexCount; return(r); }
override public void Render(DwarfTime gameTime, ChunkManager chunks, Camera camera, SpriteBatch spriteBatch, GraphicsDevice graphicsDevice, Shader effect, bool renderingForWater) { base.Render(gameTime, chunks, camera, spriteBatch, graphicsDevice, effect, renderingForWater); if (Debugger.Switches.DrawRailNetwork) { DrawNeighborConnection(TrackAbove); DrawNeighborConnection(TrackBelow); } if (Primitive == null) { Primitive = new RawPrimitive(); var voxel = GetContainingVoxel(); AddSideQuad(voxel, new GlobalVoxelOffset(1, 0, 0), (float)Math.PI * 0.5f, new Vector3(0.45f, 0.0f, 0.0f)); AddSideQuad(voxel, new GlobalVoxelOffset(0, 0, 1), 0.0f, new Vector3(0.0f, 0.0f, 0.45f)); AddSideQuad(voxel, new GlobalVoxelOffset(-1, 0, 0), (float)Math.PI * 0.5f, new Vector3(-0.45f, 0.0f, 0.0f)); AddSideQuad(voxel, new GlobalVoxelOffset(0, 0, -1), 0.0f, new Vector3(0.0f, 0.0f, -0.45f)); } if (Primitive.VertexCount == 0) { return; } var under = new VoxelHandle(chunks, GlobalVoxelCoordinate.FromVector3(Position)); if (under.IsValid) { Color color = new Color(under.Sunlight ? 255 : 0, 255, 0); LightRamp = color; } else { LightRamp = new Color(200, 255, 0); } Color origTint = effect.VertexColorTint; if (!Active) { DoStipple(effect); } effect.VertexColorTint = VertexColor; effect.LightRamp = LightRamp; effect.World = GlobalTransform; effect.MainTexture = Sheet.GetTexture(); effect.EnableWind = false; foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Apply(); Primitive.Render(graphicsDevice); } effect.VertexColorTint = origTint; if (!Active && !String.IsNullOrEmpty(previousEffect)) { effect.CurrentTechnique = effect.Techniques[previousEffect]; } }
public void ResetPrimitive() { Primitive = null; }
override public void Render(DwarfTime gameTime, ChunkManager chunks, Camera camera, SpriteBatch spriteBatch, GraphicsDevice graphicsDevice, Shader effect, bool renderingForWater) { base.Render(gameTime, chunks, camera, spriteBatch, graphicsDevice, effect, renderingForWater); if (Debugger.Switches.DrawRailNetwork) { //Drawer3D.DrawBox(GetContainingVoxel().GetBoundingBox(), Color.White, 0.01f, true); //Drawer3D.DrawLine(GetContainingVoxel().GetBoundingBox().Center(), GlobalTransform.Translation, Color.White, 0.01f); var transform = Matrix.CreateRotationY((float)Math.PI * 0.5f * (float)Piece.Orientation) * GlobalTransform; if (Library.GetRailPiece(Piece.RailPiece).HasValue(out var piece)) { foreach (var spline in piece.SplinePoints) { for (var i = 1; i < spline.Count; ++i) { Drawer3D.DrawLine(Vector3.Transform(spline[i - 1], transform), Vector3.Transform(spline[i], transform), Color.Purple, 0.1f); } } foreach (var connection in piece.EnumerateConnections()) { Drawer3D.DrawLine(Vector3.Transform(connection.Item1, transform) + new Vector3(0.0f, 0.2f, 0.0f), Vector3.Transform(connection.Item2, transform) + new Vector3(0.0f, 0.2f, 0.0f), Color.Brown, 0.1f); } //foreach (var neighborConnection in NeighborRails) //{ // var neighbor = Manager.FindComponent(neighborConnection.NeighborID); // if (neighbor == null) // Drawer3D.DrawLine(Position, Position + Vector3.UnitY, Color.CornflowerBlue, 0.1f); // else // Drawer3D.DrawLine(Position + new Vector3(0.0f, 0.5f, 0.0f), (neighbor as Body).Position + new Vector3(0.0f, 0.5f, 0.0f), Color.Teal, 0.1f); //} } } if (!IsVisible) { return; } if (Primitive == null) { var bounds = Vector4.Zero; var uvs = Sheet.GenerateTileUVs(Frame, out bounds); if (Library.GetRailPiece(Piece.RailPiece).HasValue(out var rawPiece)) { var transform = Matrix.CreateRotationY((float)Math.PI * 0.5f * (float)Piece.Orientation); var realShape = 0; if (rawPiece.AutoSlope) { var transformedConnections = GetTransformedConnections(); var matchingNeighbor1 = NeighborRails.FirstOrDefault(n => (n.Position - transformedConnections[0].Item1 - new Vector3(0.0f, 1.0f, 0.0f)).LengthSquared() < 0.001f); var matchingNeighbor2 = NeighborRails.FirstOrDefault(n => (n.Position - transformedConnections[1].Item1 - new Vector3(0.0f, 1.0f, 0.0f)).LengthSquared() < 0.001f); if (matchingNeighbor1 != null && matchingNeighbor2 != null) { realShape = 3; } else if (matchingNeighbor1 != null) { realShape = 1; } else if (matchingNeighbor2 != null) { realShape = 2; } } Primitive = new RawPrimitive(); Primitive.AddVertex(new ExtendedVertex(Vector3.Transform(new Vector3(-0.5f, VertexHeightOffsets[realShape, 0], 0.5f), transform), Color.White, Color.White, uvs[0], bounds)); Primitive.AddVertex(new ExtendedVertex(Vector3.Transform(new Vector3(0.5f, VertexHeightOffsets[realShape, 1], 0.5f), transform), Color.White, Color.White, uvs[1], bounds)); Primitive.AddVertex(new ExtendedVertex(Vector3.Transform(new Vector3(0.5f, VertexHeightOffsets[realShape, 2], -0.5f), transform), Color.White, Color.White, uvs[2], bounds)); Primitive.AddVertex(new ExtendedVertex(Vector3.Transform(new Vector3(-0.5f, VertexHeightOffsets[realShape, 3], -0.5f), transform), Color.White, Color.White, uvs[3], bounds)); Primitive.AddIndicies(new short[] { 0, 1, 3, 1, 2, 3 }); var sideBounds = Vector4.Zero; Vector2[] sideUvs = null; sideUvs = Sheet.GenerateTileUVs(new Point(3, 4), out sideBounds); AddScaffoldGeometry(transform, sideBounds, sideUvs, -1.0f, false); if (realShape == 3) { AddScaffoldGeometry(transform, sideBounds, sideUvs, 0.0f, false); } else if (realShape == 1) { sideUvs = Sheet.GenerateTileUVs(new Point(0, 4), out sideBounds); AddScaffoldGeometry(transform, sideBounds, sideUvs, 0.0f, true); } else if (realShape == 2) { sideUvs = Sheet.GenerateTileUVs(new Point(0, 4), out sideBounds); AddScaffoldGeometry(transform, sideBounds, sideUvs, 0.0f, false); } // Todo: Make these static and avoid recalculating them constantly. var bumperBackBounds = Vector4.Zero; var bumperBackUvs = Sheet.GenerateTileUVs(new Point(0, 5), out bumperBackBounds); var bumperFrontBounds = Vector4.Zero; var bumperFrontUvs = Sheet.GenerateTileUVs(new Point(1, 5), out bumperFrontBounds); var bumperSideBounds = Vector4.Zero; var bumperSideUvs = Sheet.GenerateTileUVs(new Point(2, 5), out bumperSideBounds); foreach (var connection in GetTransformedConnections()) { var matchingNeighbor = NeighborRails.FirstOrDefault(n => (n.Position - connection.Item1).LengthSquared() < 0.001f); if (matchingNeighbor == null && rawPiece.AutoSlope) { matchingNeighbor = NeighborRails.FirstOrDefault(n => (n.Position - connection.Item1 - new Vector3(0.0f, 1.0f, 0.0f)).LengthSquared() < 0.001f); } if (matchingNeighbor == null) { var bumperOffset = connection.Item1 - GlobalTransform.Translation; var bumperGap = Vector3.Normalize(bumperOffset) * 0.1f; var bumperAngle = AngleBetweenVectors(new Vector2(bumperOffset.X, bumperOffset.Z), new Vector2(0, 0.5f)); var xDiag = bumperOffset.X <-0.001f || bumperOffset.X> 0.001f; var zDiag = bumperOffset.Z <-0.001f || bumperOffset.Z> 0.001f; if (xDiag && zDiag) { var y = bumperOffset.Y; bumperOffset *= sqrt2; bumperOffset.Y = y; var endBounds = Vector4.Zero; var endUvs = Sheet.GenerateTileUVs(new Point(6, 2), out endBounds); Primitive.AddQuad( Matrix.CreateRotationY((float)Math.PI * 1.25f) * Matrix.CreateRotationY(bumperAngle) // This offset would not be correct if diagonals could slope. * Matrix.CreateTranslation(new Vector3(Sign(bumperOffset.X), 0.0f, Sign(bumperOffset.Z))), Color.White, Color.White, endUvs, endBounds); } Primitive.AddQuad( Matrix.CreateRotationX(-(float)Math.PI * 0.5f) * Matrix.CreateTranslation(0.0f, 0.3f, -0.2f) * Matrix.CreateRotationY(bumperAngle) * Matrix.CreateTranslation(bumperOffset + bumperGap), Color.White, Color.White, bumperBackUvs, bumperBackBounds); Primitive.AddQuad( Matrix.CreateRotationX(-(float)Math.PI * 0.5f) * Matrix.CreateTranslation(0.0f, 0.3f, -0.2f) * Matrix.CreateRotationY(bumperAngle) * Matrix.CreateTranslation(bumperOffset), Color.White, Color.White, bumperFrontUvs, bumperFrontBounds); if (VoxelHelpers.FindFirstVoxelBelow(GetContainingVoxel()).RampType == RampType.None) { Primitive.AddQuad( Matrix.CreateRotationX(-(float)Math.PI * 0.5f) * Matrix.CreateRotationY(-(float)Math.PI * 0.5f) * Matrix.CreateTranslation(0.3f, 0.3f, 0.18f) * Matrix.CreateRotationY(bumperAngle) * Matrix.CreateTranslation(bumperOffset), Color.White, Color.White, bumperSideUvs, bumperSideBounds); Primitive.AddQuad( Matrix.CreateRotationX(-(float)Math.PI * 0.5f) * Matrix.CreateRotationY(-(float)Math.PI * 0.5f) * Matrix.CreateTranslation(-0.3f, 0.3f, 0.18f) * Matrix.CreateRotationY(bumperAngle) * Matrix.CreateTranslation(bumperOffset), Color.White, Color.White, bumperSideUvs, bumperSideBounds); } } } } } // Everything that draws should set it's tint, making this pointless. var under = new VoxelHandle(chunks, GlobalVoxelCoordinate.FromVector3(Position)); if (under.IsValid) { Color color = new Color(under.Sunlight ? 255 : 0, 255, 0); LightRamp = color; } else { LightRamp = new Color(200, 255, 0); } Color origTint = effect.VertexColorTint; if (!Active) { DoStipple(effect); } effect.VertexColorTint = VertexColor; effect.LightRamp = LightRamp; effect.World = GlobalTransform; effect.MainTexture = Sheet.GetTexture(); effect.EnableWind = false; foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Apply(); Primitive.Render(graphicsDevice); } effect.VertexColorTint = origTint; if (!Active) { EndDraw(effect); } }
private static void GenerateGrassFringe(RawPrimitive Into, VoxelHandle Voxel, Geo.TemplateFace Face, TerrainTileSheet TileSheet, SliceCache Cache, GrassType decalType) { for (var i = 0; i < 4; ++i) { Cache.EdgeFringeTempVerticies[i].Set = false; } if (Face.Edges != null) { for (var e = 0; e < Face.Edges.Length; ++e) { var fringeNeighbor = VoxelHelpers.GetNeighbor(Voxel, OrientationHelper.GetFaceNeighborOffset(Face.Edges[e].Orientation)); if (fringeNeighbor.IsValid) { if (fringeNeighbor.IsEmpty) { GenerateEdgeFringe(Into, Face, e, TileSheet, Cache, decalType, new Vector3(0.0f, -0.5f, 0.0f), 0.5f); } else { var above = VoxelHelpers.GetVoxelAbove(fringeNeighbor); if (above.IsValid && !above.IsEmpty) { GenerateEdgeFringe(Into, Face, e, TileSheet, Cache, decalType, new Vector3(0.0f, 0.5f, 0.0f), -0.1f); } else if (fringeNeighbor.GrassType == 0 || (fringeNeighbor.GrassType != Voxel.GrassType && Library.GetGrassType(fringeNeighbor.GrassType).FringePrecedence < decalType.FringePrecedence)) { GenerateEdgeFringe(Into, Face, e, TileSheet, Cache, decalType, new Vector3(0.0f, 0.2f, 0.0f), 0.5f); } } } } } if (Face.Corners != null) { for (var c = 0; c < Face.Corners.Length; ++c) { var cornerNeighbor = VoxelHelpers.GetNeighbor(Voxel, OrientationHelper.GetFaceNeighborOffset(Face.Edges[Face.Corners[c].EdgeA].Orientation) + OrientationHelper.GetFaceNeighborOffset(Face.Edges[Face.Corners[c].EdgeB].Orientation)); var manhattanA = VoxelHelpers.GetNeighbor(Voxel, OrientationHelper.GetFaceNeighborOffset(Face.Edges[Face.Corners[c].EdgeA].Orientation)); var manhattanB = VoxelHelpers.GetNeighbor(Voxel, OrientationHelper.GetFaceNeighborOffset(Face.Edges[Face.Corners[c].EdgeB].Orientation)); if (manhattanA.IsValid && !manhattanA.IsEmpty && manhattanA.GrassType == Voxel.GrassType) { continue; } if (manhattanB.IsValid && !manhattanB.IsEmpty && manhattanB.GrassType == Voxel.GrassType) { continue; } if (cornerNeighbor.IsValid) { if (cornerNeighbor.IsEmpty) // Todo: Do not generate fringe if horizontal neighbors are occupied. // Todo: Also - needs to use corners set by edge fringe when they are at different heights. Maybe specify which edges the corner is in between? { GenerateHangingCornerFringe(Into, Face, TileSheet, Cache, decalType, Face.Corners[c], new Vector3(0.0f, -0.5f, 0.0f)); } else { var above = VoxelHelpers.GetVoxelAbove(cornerNeighbor); if (above.IsValid && !above.IsEmpty) { } else if (cornerNeighbor.GrassType == 0 || (cornerNeighbor.GrassType != Voxel.GrassType && Library.GetGrassType(cornerNeighbor.GrassType).FringePrecedence < decalType.FringePrecedence)) { GenerateHangingCornerFringe(Into, Face, TileSheet, Cache, decalType, Face.Corners[c], new Vector3(0.0f, 0.1f, 0.0f)); } } } } } }
private static void BuildDesignationGeometry( RawPrimitive Into, VoxelHandle Voxel, SliceCache Cache, TerrainTileSheet TileSheet, WorldManager World) { // Todo: Store designations per chunk. foreach (var designation in World.PersistentData.Designations.EnumerateDesignations(Voxel).ToList()) { if ((designation.Type & World.Renderer.PersistentSettings.VisibleTypes) != designation.Type) // If hidden by player, do not draw. { return; } var designationProperties = Library.GetDesignationTypeProperties(designation.Type).Value; var designationVisible = false; if (designationProperties.DrawType == DesignationDrawType.PreviewVoxel) { designationVisible = Voxel.Coordinate.Y < World.Renderer.PersistentSettings.MaxViewingLevel; } else { designationVisible = VoxelHelpers.DoesVoxelHaveVisibleSurface(World, Voxel); } if (designationVisible && Library.GetVoxelPrimitive(Library.DesignationVoxelType).HasValue(out BoxPrimitive designationPrimitive)) { switch (designationProperties.DrawType) { case DesignationDrawType.FullBox: { var solid = TemplateSolidLibrary.GetTemplateSolid(Voxel.Type.TemplateSolid); for (var f = 0; f < solid.Faces.Count; ++f) { var face = solid.Faces[f]; if (face.CullType == Geo.FaceCullType.Cull && !IsFaceVisible(Voxel, face, World.ChunkManager, out var neighbor)) { continue; } PrepVerticies(World, Voxel, face, Cache, GetVoxelVertexExploredNeighbors(Voxel, face, Cache), TileSheet, new Point(0, 0), false, 0.02f); SetVertexTint(Cache.FaceGeometry, designationProperties.Color); AddQuad(Into, Cache.FaceGeometry, QuadIndicies); } } break; case DesignationDrawType.TopBox: { var solid = TemplateSolidLibrary.GetTemplateSolid(Voxel.Type.TemplateSolid); for (var f = 0; f < solid.Faces.Count; ++f) { var face = solid.Faces[f]; if (face.Orientation != FaceOrientation.Top) { continue; } if (face.CullType == Geo.FaceCullType.Cull && !IsFaceVisible(Voxel, face, World.ChunkManager, out var neighbor)) { continue; } PrepVerticies(World, Voxel, face, Cache, GetVoxelVertexExploredNeighbors(Voxel, face, Cache), TileSheet, new Point(0, 0), false, 0.02f); SetVertexTint(Cache.FaceGeometry, designationProperties.Color); AddQuad(Into, Cache.FaceGeometry, QuadIndicies); } } break; case DesignationDrawType.PreviewVoxel: { if (Library.GetVoxelType(designation.Tag.ToString()).HasValue(out VoxelType voxelType)) { var solid = TemplateSolidLibrary.GetTemplateSolid(voxelType.TemplateSolid); for (var f = 0; f < solid.Faces.Count; ++f) { var face = solid.Faces[f]; if (face.CullType == Geo.FaceCullType.Cull && !IsFaceVisible(Voxel, face, World.ChunkManager, out var neighbor)) { continue; } PrepVerticies(World, Voxel, face, Cache, GetVoxelVertexExploredNeighbors(Voxel, face, Cache), TileSheet, SelectTile(voxelType, face.Orientation), false, 0.0f); SetVertexTint(Cache.FaceGeometry, designationProperties.Color); AddQuad(Into, Cache.FaceGeometry, QuadIndicies); } } } break; } } } }
override public void Render(DwarfTime gameTime, ChunkManager chunks, Camera camera, SpriteBatch spriteBatch, GraphicsDevice graphicsDevice, Shader effect, bool renderingForWater) { base.Render(gameTime, chunks, camera, spriteBatch, graphicsDevice, effect, renderingForWater); if (Debugger.Switches.DrawPipeNetwork) { foreach (var neighborConnection in NeighborPipes) { var neighbor = Manager.FindComponent(neighborConnection); if (neighbor == null) { Drawer3D.DrawLine(Position, Position + Vector3.UnitY, Color.CornflowerBlue, 0.1f); } else { Drawer3D.DrawLine(Position + new Vector3(0.0f, 0.5f, 0.0f), (neighbor as GameComponent).Position + new Vector3(0.0f, 0.5f, 0.0f), new Color(SteamPressure, 0.0f, 0.0f, 1.0f), 0.1f); } } Drawer3D.DrawBox(GetBoundingBox(), Color.Red, 0.01f, false); Drawer3D.DrawLine(Position, Position + Vector3.Transform(new Vector3(1, 0, 0), Matrix.CreateRotationY((float)Math.PI / 2 * (float)Orientation)), new Color(0.0f, 1.0f, 1.0f), 0.03f); } if (!DrawPipes) { return; } if (Primitive == null) { var bounds = Vector4.Zero; var uvs = Sheet.GenerateTileUVs(new Point(0, 0), out bounds); Primitive = new RawPrimitive(); foreach (var connection in NeighborPipes) { var neighbor = Manager.FindComponent(connection) as GameComponent; if (neighbor == null) { continue; } var orientationToNeighbor = OrientationHelper.DetectOrientationFromVector(new Vector3(neighbor.Position.X - this.Position.X, 0.0f, neighbor.Position.Z - this.Position.Z)); var pipeAngle = Math.PI * 0.5f * ((float)Orientation - (float)orientationToNeighbor); Primitive.AddQuad( Matrix.CreateTranslation(0.5f, 0.0f, 0.0f) * Matrix.CreateScale(0.5f, 0.5f, 0.5f) * Matrix.CreateRotationX((float)Math.PI * 0.5f) //* Matrix.CreateTranslation(0.0f, 0.3f, -0.2f) * Matrix.CreateRotationY((float)pipeAngle), //* Matrix.CreateTranslation(bumperOffset + bumperGap), Color.White, Color.White, uvs, bounds); } } if (Primitive.VertexCount == 0) { return; } var under = new VoxelHandle(chunks, GlobalVoxelCoordinate.FromVector3(Position)); if (under.IsValid) { Color color = new Color(under.Sunlight ? 255 : 0, 255, 0); LightRamp = color; } else { LightRamp = new Color(200, 255, 0); } Color origTint = effect.VertexColorTint; if (!Active) { DoStipple(effect); } effect.VertexColorTint = VertexColor; effect.LightRamp = LightRamp; effect.World = GlobalTransform; effect.MainTexture = Sheet.GetTexture(); effect.EnableWind = false; foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Apply(); Primitive.Render(graphicsDevice); } effect.VertexColorTint = origTint; if (!Active) { EndDraw(effect); } }
private void AttachNeighbor(uint ID) { NeighborPipes.Add(ID); Primitive = null; }
private void DetachNeighbor(uint ID) { NeighborPipes.RemoveAll(connection => connection == ID); Primitive = null; }
private void CreateMesh(GraphicsDevice Device, Overworld Overworld) { var numVerts = (Overworld.Width + 1) * (Overworld.Height + 1); LandMesh = new VertexBuffer(Device, VertexPositionNormalTexture.VertexDeclaration, numVerts, BufferUsage.None); var verts = new VertexPositionNormalTexture[numVerts]; int i = 0; for (int x = 0; x <= Overworld.Width; x += 1) { for (int y = 0; y <= Overworld.Height; y += 1) { var landHeight = Overworld.Map.Height((x < Overworld.Width) ? x : x - 1, (y < Overworld.Height) ? y : y - 1); verts[i].Position = new Vector3((float)x / Overworld.Width, landHeight * HeightScale, (float)y / Overworld.Height); verts[i].TextureCoordinate = new Vector2((float)x / Overworld.Width, (float)y / Overworld.Height); var normal = new Vector3( Overworld.Map.Height(MathFunctions.Clamp(x + 1, 0, Overworld.Width - 1), MathFunctions.Clamp(y, 0, Overworld.Height - 1)) - Overworld.Height, 1.0f, Overworld.Map.Height(MathFunctions.Clamp(x, 0, Overworld.Width - 1), MathFunctions.Clamp(y + 1, 0, Overworld.Height - 1)) - Overworld.Height); normal.Normalize(); verts[i].Normal = normal; i++; } } LandMesh.SetData(verts); var indices = SetUpTerrainIndices((Overworld.Width + 1), (Overworld.Height + 1)); LandIndex = new IndexBuffer(Device, typeof(int), indices.Length, BufferUsage.None); LandIndex.SetData(indices); // Create tree mesh. TreePrimitive = new RawPrimitive(); if (IconTexture == null) { IconTexture = AssetManager.GetContentTexture("GUI\\map_icons"); } var iconSheet = new SpriteSheet(IconTexture, 16, 16); for (int x = 0; x < Overworld.Width; x += 1) { for (int y = 0; y < Overworld.Height; y += 1) { if (!MathFunctions.RandEvent(0.05f)) { continue; } var elevation = Overworld.Map.Height(x, y); if (elevation <= Overworld.GenerationSettings.SeaLevel) { continue; } if (Library.GetBiome(Overworld.Map.Map[x, y].Biome).HasValue(out var biome)) { if (biome.Icon.X > 0 || biome.Icon.Y > 0) { var bounds = Vector4.Zero; var uvs = iconSheet.GenerateTileUVs(biome.Icon, out bounds); var angle = MathFunctions.Rand() * (float)System.Math.PI; TreePrimitive.AddQuad( Matrix.CreateRotationX(-(float)System.Math.PI / 2) * Matrix.CreateRotationY(angle) * Matrix.CreateScale(2.0f / Overworld.Width) * Matrix.CreateTranslation((float)x / Overworld.Width, elevation * HeightScale + 1.0f / Overworld.Width, (float)y / Overworld.Height), Color.White, Color.White, uvs, bounds); TreePrimitive.AddQuad( Matrix.CreateRotationX(-(float)System.Math.PI / 2) * Matrix.CreateRotationY((float)System.Math.PI / 2) * Matrix.CreateRotationY(angle) * Matrix.CreateScale(2.0f / Overworld.Width) * Matrix.CreateTranslation((float)x / Overworld.Width, elevation * HeightScale + 1.0f / Overworld.Width, (float)y / Overworld.Height), Color.White, Color.White, uvs, bounds); } } } } }
public static Texture2D RenderPatternIcons(GraphicsDevice device, Microsoft.Xna.Framework.Content.ContentManager Content, Gui.JsonTileSheet Sheet) { Initialize(); var shader = new Shader(Content.Load <Effect>(ContentPaths.Shaders.TexturedShaders), true); var sqrt = (int)(Math.Ceiling(Math.Sqrt(Patterns.Count))); var width = MathFunctions.NearestPowerOf2(sqrt * Sheet.TileWidth); var fitHorizontal = width / Sheet.TileWidth; var rowCount = (int)Math.Ceiling((float)Patterns.Count / (float)fitHorizontal); var height = MathFunctions.NearestPowerOf2(rowCount * Sheet.TileHeight); RenderTarget2D toReturn = new RenderTarget2D(device, width, height, false, SurfaceFormat.Color, DepthFormat.Depth16, 16, RenderTargetUsage.PreserveContents); var tileSheet = new SpriteSheet(ContentPaths.rail_tiles, 32); device.SetRenderTarget(toReturn); device.Clear(Color.Transparent); shader.SetTexturedTechnique(); shader.MainTexture = AssetManager.GetContentTexture(ContentPaths.rail_tiles); shader.SelfIlluminationEnabled = true; shader.SelfIlluminationTexture = AssetManager.GetContentTexture(ContentPaths.Terrain.terrain_illumination); shader.EnableShadows = false; shader.EnableLighting = false; shader.ClippingEnabled = false; shader.CameraPosition = new Vector3(-0.5f, 0.5f, 0.5f); shader.VertexColorTint = Color.White; shader.LightRamp = Color.White; shader.SunlightGradient = AssetManager.GetContentTexture(ContentPaths.Gradients.sungradient); shader.AmbientOcclusionGradient = AssetManager.GetContentTexture(ContentPaths.Gradients.ambientgradient); shader.TorchlightGradient = AssetManager.GetContentTexture(ContentPaths.Gradients.torchgradient); Viewport oldview = device.Viewport; int rows = height / Sheet.TileWidth; int cols = width / Sheet.TileWidth; device.ScissorRectangle = new Rectangle(0, 0, Sheet.TileWidth, Sheet.TileHeight); device.RasterizerState = RasterizerState.CullNone; device.DepthStencilState = DepthStencilState.Default; Vector3 half = Vector3.One * 0.5f; half = new Vector3(half.X, half.Y, half.Z); foreach (EffectPass pass in shader.CurrentTechnique.Passes) { int ID = 0; foreach (var type in Patterns) { int row = ID / cols; int col = ID % cols; var xboundsMin = 0; var xboundsMax = 0; var yboundsMin = 0; var yboundsMax = 0; var primitive = new RawPrimitive(); foreach (var piece in type.Pieces) { var rawPiece = RailLibrary.GetRailPiece(piece.RailPiece); var bounds = Vector4.Zero; var uvs = tileSheet.GenerateTileUVs(rawPiece.Tile, out bounds); primitive.AddQuad( Matrix.CreateRotationY((float)Math.PI * 0.5f * (float)piece.Orientation) * Matrix.CreateTranslation(new Vector3(piece.Offset.X, 0.0f, piece.Offset.Y)), Color.White, Color.White, uvs, bounds); xboundsMin = Math.Min(xboundsMin, piece.Offset.X); xboundsMax = Math.Max(xboundsMax, piece.Offset.X); yboundsMin = Math.Min(yboundsMin, piece.Offset.Y); yboundsMax = Math.Max(yboundsMax, piece.Offset.Y); } float xSize = xboundsMax - xboundsMin + 1; float ySize = yboundsMax - yboundsMin + 1; var cameraPos = new Vector3(xboundsMin + (xSize / 2), 2.0f, yboundsMax + 1.0f); device.Viewport = new Viewport(col * Sheet.TileWidth, row * Sheet.TileHeight, Sheet.TileWidth, Sheet.TileHeight); shader.View = Matrix.CreateLookAt(cameraPos, new Vector3((xboundsMin + (xSize / 2)), 0.0f, yboundsMin), Vector3.UnitY); shader.Projection = Matrix.CreatePerspectiveFieldOfView(1.0f, 1.0f, 0.1f, 10); shader.World = Matrix.Identity; shader.CameraPosition = cameraPos; pass.Apply(); primitive.Render(device); ++ID; } } device.Viewport = oldview; device.SetRenderTarget(null); return((Texture2D)toReturn); }