private static void DrawEntityDesignations(WorldManager World, DesignationSet Set) { // Todo: Can this be drawn by the entity, allowing it to be properly frustrum culled? // - Need to add a 'gestating' entity state to the alive/dead/active mess. foreach (var entity in Set.EnumerateEntityDesignations()) { if ((entity.Type & World.Renderer.PersistentSettings.VisibleTypes) == entity.Type) { var props = Library.GetDesignationTypeProperties(entity.Type).Value; // Todo: More consistent drawing? if (entity.Type == DesignationType.Craft) { entity.Body.SetFlagRecursive(GameComponent.Flag.Visible, true); if (!entity.Body.Active) { entity.Body.SetVertexColorRecursive(props.Color); } } else { var box = entity.Body.GetBoundingBox(); _addBox(box.Min, box.Max - box.Min, props.Color, props.LineWidth, false); entity.Body.SetVertexColorRecursive(props.Color); } } else if (entity.Type == DesignationType.Craft) // Make the ghost object invisible if these designations are turned off. { entity.Body.SetFlagRecursive(GameComponent.Flag.Visible, false); } } }
private static void BuildVoxelGeometry( RawPrimitive Into, int X, int Y, int Z, VoxelChunk Chunk, //BoxPrimitive BedrockModel, Cache Cache, DesignationSet Designations, WorldManager World) { var v = VoxelHandle.UnsafeCreateLocalHandle(Chunk, new LocalVoxelCoordinate(X, Y, Z)); if (!v.IsValid || !v.IsVisible) { return; // How did this even get called then?? } BuildDesignationGeometry(Into, Chunk, Cache, Designations, World, v); if ((v.IsExplored && v.IsEmpty)) { return; } if (!v.IsExplored && v.Sunlight) { return; } if (Library.GetVoxelPrimitive(v.Type).HasValue(out BoxPrimitive primitive)) { BuildVoxelGeometryFromPrimitive(Into, Chunk, Cache, v, primitive); } }
public static void Render( GraphicsDevice Device, Shader Effect, OrbitCamera Camera, DesignationSet Designations, WorldManager World) { lock (renderLock) { Drawer3D.Effect = Effect; Drawer3D.Camera = Camera; var colorModulation = Math.Abs(Math.Sin(DwarfTime.LastTime.TotalGameTime.TotalSeconds * 2.0f)); DrawEntityDesignations(World, Designations); foreach (var box in Boxes) { _addBox(box.RealBox.Min, box.RealBox.Max - box.RealBox.Min, box.Color, box.Thickness, box.Warp); } foreach (var segment in Segments) { _addLineSegment(segment.A, segment.B, segment.Color, segment.Thickness, false); } _flush(); Boxes.Clear(); Segments.Clear(); } }
public static void Render( GraphicsDevice Device, Shader Effect, OrbitCamera Camera, DesignationDrawer DesignationDrawer, DesignationSet Designations, WorldManager World) { lock (renderLock) { Drawer3D.Effect = Effect; Drawer3D.Camera = Camera; var colorModulation = Math.Abs(Math.Sin(DwarfTime.LastTime.TotalGameTime.TotalSeconds * 2.0f)); DesignationDrawer.DrawHilites( World, Designations, _addBox, (pos, type) => { Effect.MainTexture = AssetManager.GetContentTexture(ContentPaths.Terrain.terrain_tiles); Effect.LightRamp = Color.White; // Todo: Alpha pulse Effect.VertexColorTint = new Color(0.1f, 0.9f, 1.0f, 1.0f); var prevTechnique = Effect.CurrentTechnique; Effect.CurrentTechnique = Effect.Techniques[Shader.Technique.Stipple]; var pos_distorted = pos + Vector3.Up * 0.15f + VertexNoise.GetNoiseVectorFromRepeatingTexture(pos + Vector3.One * 0.5f); Effect.World = Matrix.CreateTranslation(pos_distorted); foreach (EffectPass pass in Effect.CurrentTechnique.Passes) { pass.Apply(); VoxelLibrary.GetPrimitive(type).Render(Device); } Effect.LightRamp = Color.White; Effect.VertexColorTint = Color.White; Effect.World = Matrix.Identity; Effect.CurrentTechnique = prevTechnique; }); foreach (var box in Boxes) { _addBox(box.RealBox.Min, box.RealBox.Max - box.RealBox.Min, box.Color, box.Thickness, box.Warp); } foreach (var segment in Segments) { _addLineSegment(segment.A, segment.B, segment.Color, segment.Thickness, false); } _flush(); Boxes.Clear(); Segments.Clear(); } }
private static void BuildVoxelGeometry( RawPrimitive Into, int X, int Y, int Z, VoxelChunk Chunk, BoxPrimitive BedrockModel, Cache Cache, DesignationSet Designations, WorldManager World) { var v = VoxelHandle.UnsafeCreateLocalHandle(Chunk, new LocalVoxelCoordinate(X, Y, Z)); if (!v.IsValid || !v.IsVisible) { return; // How did this even get called then?? } BuildDesignationGeometry(Into, Chunk, Cache, Designations, World, v); if ((v.IsExplored && v.IsEmpty)) { return; } var primitive = Library.GetVoxelPrimitive(v.Type); if (v.IsExplored && primitive == null) { return; } if (!v.IsExplored && v.Sunlight) { return; } if (primitive == null) { primitive = BedrockModel; } var tint = v.Type.Tint; var uvs = primitive.UVs; if (v.Type.HasTransitionTextures && v.IsExplored) { uvs = ComputeTransitionTexture(new VoxelHandle(v.Chunk.Manager, v.Coordinate)); } BuildVoxelTopFaceGeometry(Into, Chunk, Cache, primitive, v, uvs, 0); for (int i = 1; i < 6; i++) { BuildVoxelFaceGeometry(Into, Chunk, Cache, primitive, v, tint, uvs, Matrix.Identity, i, true); } }
public void DrawHilites( WorldManager World, DesignationSet Set, Action <Vector3, Vector3, Color, float, bool> DrawBoxCallback, Action <Vector3, VoxelType> DrawPhantomCallback) { var colorModulation = Math.Abs(Math.Sin(DwarfTime.LastTime.TotalGameTime.TotalSeconds * 2.0f)); foreach (var properties in DesignationProperties) { properties.Value.ModulatedColor = new Color( (byte)(MathFunctions.Clamp((float)(properties.Value.Color.R * colorModulation + 50), 0.0f, 255.0f)), (byte)(MathFunctions.Clamp((float)(properties.Value.Color.G * colorModulation + 50), 0.0f, 255.0f)), (byte)(MathFunctions.Clamp((float)(properties.Value.Color.B * colorModulation + 50), 0.0f, 255.0f)), 255); } // Todo: Can this be drawn by the entity, allowing it to be properly frustrum culled? // - Need to add a 'gestating' entity state to the alive/dead/active mess. foreach (var entity in Set.EnumerateEntityDesignations()) { if ((entity.Type & VisibleTypes) == entity.Type) { var props = DefaultProperties; if (DesignationProperties.ContainsKey(entity.Type)) { props = DesignationProperties[entity.Type]; } // Todo: More consistent drawing? if (entity.Type == DesignationType.Craft) { entity.Body.SetFlagRecursive(GameComponent.Flag.Visible, true); if (!entity.Body.Active) { entity.Body.SetVertexColorRecursive(props.ModulatedColor); } } else { var box = entity.Body.GetBoundingBox(); DrawBoxCallback(box.Min, box.Max - box.Min, props.ModulatedColor, props.LineWidth, false); entity.Body.SetVertexColorRecursive(props.ModulatedColor); } } else if (entity.Type == DesignationType.Craft) // Make the ghost object invisible if these designations are turned off. { entity.Body.SetFlagRecursive(GameComponent.Flag.Visible, false); } } }
private static void BuildSliceGeometry( VoxelChunk chunk, BoxPrimitive bedrockModel, Cache Cache, int LocalY, RawPrimitive sliceGeometry, DesignationSet DesignationSet, WorldManager World) { for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x) { for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z) { BuildVoxelGeometry(sliceGeometry, x, LocalY, z, chunk, bedrockModel, Cache, DesignationSet, World); } } }
public void Rebuild(GraphicsDevice g) { if (g == null || g.IsDisposed) { return; } VoxelListPrimitive primitive = new VoxelListPrimitive(); DesignationSet designations = null; if (Manager.World.Master != null) { designations = Manager.World.PlayerFaction.Designations; } primitive.InitializeFromChunk(this, designations, Manager.World.DesignationDrawer, Manager.World); // TODO: Move to main thread! var changedMessage = new Message(Message.MessageType.OnChunkModified, "Chunk Modified"); foreach (var c in Manager.World.EnumerateIntersectingObjects(GetBoundingBox(), CollisionType.Both)) { c.ReceiveMessageRecursive(changedMessage); } }
private static void BuildDesignationGeometry(RawPrimitive Into, VoxelChunk Chunk, Cache Cache, DesignationSet Designations, WorldManager World, VoxelHandle v) { var designations = Designations == null ? new List <DesignationSet.VoxelDesignation>() : Designations.EnumerateDesignations(v).ToList(); int maxViewingLevel = World.Renderer.PersistentSettings.MaxViewingLevel; foreach (var designation in designations) { if ((designation.Type & World.Renderer.PersistentSettings.VisibleTypes) == designation.Type) { var props = Library.GetDesignationTypeProperties(designation.Type); var designationVisible = false; if (designation.Type == DesignationType.Put) { designationVisible = v.Coordinate.Y < maxViewingLevel; } else { designationVisible = VoxelHelpers.DoesVoxelHaveVisibleSurface(World, v); } if (designationVisible) { var desPrim = Library.GetVoxelPrimitive(Library.DesignationVoxelType); switch (props.DrawType) { case DrawBoxType.FullBox: for (int i = 0; i < 6; i++) { BuildVoxelFaceGeometry(Into, Chunk, Cache, desPrim, v, props.Color, desPrim.UVs, DesignationTransform, i, false); } break; case DrawBoxType.TopBox: BuildVoxelFaceGeometry(Into, Chunk, Cache, desPrim, v, props.Color, desPrim.UVs, DesignationTransform, 0, false); break; case DrawBoxType.PreviewVoxel: { var previewPrim = Library.GetVoxelPrimitive(Library.GetVoxelType(designation.Tag.ToString())); var offsetMatrix = Matrix.Identity; if (!v.IsEmpty) { offsetMatrix = Matrix.CreateTranslation(0.0f, 0.1f, 0.0f); } for (int i = 0; i < 6; i++) { BuildVoxelFaceGeometry(Into, Chunk, Cache, previewPrim, v, props.Color, previewPrim.UVs, offsetMatrix, i, false); } } break; } } } } }
public void InitializeFromChunk(VoxelChunk chunk, DesignationSet DesignationSet, WorldManager World) { DebugHelper.AssertNotNull(chunk); DebugHelper.AssertNotNull(DesignationSet); DebugHelper.AssertNotNull(World); BoxPrimitive bedrockModel = Library.GetVoxelPrimitive("Bedrock"); var sliceStack = new List <RawPrimitive>(); var cache = new Cache(); int maxViewingLevel = World.Renderer.PersistentSettings.MaxViewingLevel; for (var localY = 0; localY < maxViewingLevel - chunk.Origin.Y && localY < VoxelConstants.ChunkSizeY; ++localY) // Todo: Only iterate inside the chunk. { RawPrimitive sliceGeometry = null; lock (chunk.Data.SliceCache) { var cachedSlice = chunk.Data.SliceCache[localY]; if (cachedSlice != null) { cache.Clear(); sliceStack.Add(cachedSlice); if (GameSettings.Default.GrassMotes) { chunk.RebuildMoteLayerIfNull(localY); } continue; } sliceGeometry = new RawPrimitive { Vertices = null, Indexes = null }; chunk.Data.SliceCache[localY] = sliceGeometry; } if (GameSettings.Default.CalculateRamps) { UpdateCornerRamps(World.ChunkManager, chunk, localY); UpdateNeighborEdgeRamps(World.ChunkManager, chunk, localY); } if (GameSettings.Default.GrassMotes) { chunk.RebuildMoteLayer(localY); } DebugHelper.AssertNotNull(sliceGeometry); BuildSliceGeometry(chunk, bedrockModel, cache, localY, sliceGeometry, DesignationSet, World); sliceStack.Add(sliceGeometry); } var combinedGeometry = RawPrimitive.Concat(sliceStack); Vertices = combinedGeometry.Vertices; VertexCount = combinedGeometry.VertexCount; Indexes = combinedGeometry.Indexes.Select(s => (ushort)s).ToArray(); IndexCount = combinedGeometry.IndexCount; }
public void DrawHilites( DesignationSet Set, Action <Vector3, Vector3, Color, float, bool> DrawBoxCallback, Action <Vector3, VoxelType> DrawPhantomCallback) { var colorModulation = Math.Abs(Math.Sin(DwarfTime.LastTime.TotalGameTime.TotalSeconds * 2.0f)); foreach (var properties in DesignationProperties) { properties.Value.ModulatedColor = new Color( (byte)(MathFunctions.Clamp((float)(properties.Value.Color.R * colorModulation + 50), 0.0f, 255.0f)), (byte)(MathFunctions.Clamp((float)(properties.Value.Color.G * colorModulation + 50), 0.0f, 255.0f)), (byte)(MathFunctions.Clamp((float)(properties.Value.Color.B * colorModulation + 50), 0.0f, 255.0f)), 255); } foreach (var voxel in Set.EnumerateDesignations()) { if ((voxel.Type & VisibleTypes) == voxel.Type) { var props = DefaultProperties; if (DesignationProperties.ContainsKey(voxel.Type)) { props = DesignationProperties[voxel.Type]; } var v = voxel.Voxel.Coordinate.ToVector3(); if (props.Icon != null) { Drawer2D.DrawSprite(props.Icon, v + Vector3.One * 0.5f, Vector2.One * 0.5f, Vector2.Zero, new Color(255, 255, 255, 100)); } if (voxel.Type == DesignationType.Put) // Hate this. { DrawPhantomCallback(v, VoxelLibrary.GetVoxelType((voxel.Tag as short?).Value)); } else { DrawBoxCallback(v, Vector3.One, props.ModulatedColor, props.LineWidth, true); } } } foreach (var entity in Set.EnumerateEntityDesignations()) { if ((entity.Type & VisibleTypes) == entity.Type) { var props = DefaultProperties; if (DesignationProperties.ContainsKey(entity.Type)) { props = DesignationProperties[entity.Type]; } entity.Body.SetTintRecursive(props.ModulatedColor); // Todo: More consistent drawing? if (entity.Type == DesignationType.Craft) { entity.Body.SetFlagRecursive(GameComponent.Flag.Visible, true); } else { var box = entity.Body.GetBoundingBox(); DrawBoxCallback(box.Min, box.Max - box.Min, props.ModulatedColor, props.LineWidth, false); } if (props.Icon != null) { Drawer2D.DrawSprite(props.Icon, entity.Body.Position + Vector3.One * 0.5f, Vector2.One * 0.5f, Vector2.Zero, new Color(255, 255, 255, 100)); } } else if (entity.Type == DesignationType.Craft) // Make the ghost object invisible if these designations are turned off. { entity.Body.SetFlagRecursive(GameComponent.Flag.Visible, false); } } }
private static void BuildDesignationGeometry(RawPrimitive Into, VoxelChunk Chunk, Cache Cache, DesignationSet Designations, WorldManager World, VoxelHandle v) { // Todo: Store designations per chunk. foreach (var designation in Designations == null ? new List <DesignationSet.VoxelDesignation>() : Designations.EnumerateDesignations(v).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 (designation.Type == DesignationType.Put) { designationVisible = v.Coordinate.Y < World.Renderer.PersistentSettings.MaxViewingLevel; } else { designationVisible = VoxelHelpers.DoesVoxelHaveVisibleSurface(World, v); } if (designationVisible && Library.GetVoxelPrimitive(Library.DesignationVoxelType).HasValue(out BoxPrimitive designationPrimitive)) { switch (designationProperties.DrawType) { case DesignationDrawType.FullBox: for (int i = 0; i < 6; i++) { BuildVoxelFaceGeometry(Into, Chunk, Cache, designationPrimitive, v, designationProperties.Color, designationPrimitive.UVs, DesignationTransform, (BoxFace)i, false); } break; case DesignationDrawType.TopBox: BuildVoxelFaceGeometry(Into, Chunk, Cache, designationPrimitive, v, designationProperties.Color, designationPrimitive.UVs, DesignationTransform, 0, false); break; case DesignationDrawType.PreviewVoxel: { if (Library.GetVoxelType(designation.Tag.ToString()).HasValue(out VoxelType voxelType) && Library.GetVoxelPrimitive(voxelType).HasValue(out BoxPrimitive previewPrimitive)) { var offsetMatrix = Matrix.Identity; if (!v.IsEmpty) { offsetMatrix = Matrix.CreateTranslation(0.0f, 0.1f, 0.0f); } for (int i = 0; i < 6; i++) { BuildVoxelFaceGeometry(Into, Chunk, Cache, previewPrimitive, v, designationProperties.Color, previewPrimitive.UVs, offsetMatrix, (BoxFace)i, false); } } } break; } } } }