Added per-chunkref toggle for automatic relighting. Added manual whole-chunk relighting to chunkref, which severely improves generation speed of new chunks. Added first complete example, a "Flat Map" world generator.

This commit is contained in:
Justin Aquadro 2011-04-13 07:51:13 +00:00
parent c6ee97a53b
commit 8cb719f200
6 changed files with 319 additions and 9 deletions

View file

@ -0,0 +1,56 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C# Express 2008
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Convert", "Convert\Convert.csproj", "{5BD42656-9BCF-4C55-8272-A5D3507EFDF3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlatMap", "FlatMap\FlatMap.csproj", "{EDA894F2-00AF-456B-9D07-591ED61A9AE7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlockReplace", "BlockReplace\BlockReplace.csproj", "{6D24D262-34D3-43A6-B066-1312A0C72B16}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GiveItem", "GiveItem\GiveItem.csproj", "{426B01F4-B0C0-488E-8A5A-5531C8DFA98C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MoveSpawn", "MoveSpawn\MoveSpawn.csproj", "{15C04C0C-FD50-47E9-B62C-AA0A814189ED}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Skyscraper", "Skyscraper\Skyscraper.csproj", "{83F55F54-7253-4B4D-BC37-E9D1CB63E0B8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test\Test.csproj", "{B34A66B6-6A3B-42FC-AF39-74A30F487840}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5BD42656-9BCF-4C55-8272-A5D3507EFDF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5BD42656-9BCF-4C55-8272-A5D3507EFDF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5BD42656-9BCF-4C55-8272-A5D3507EFDF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5BD42656-9BCF-4C55-8272-A5D3507EFDF3}.Release|Any CPU.Build.0 = Release|Any CPU
{EDA894F2-00AF-456B-9D07-591ED61A9AE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EDA894F2-00AF-456B-9D07-591ED61A9AE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EDA894F2-00AF-456B-9D07-591ED61A9AE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EDA894F2-00AF-456B-9D07-591ED61A9AE7}.Release|Any CPU.Build.0 = Release|Any CPU
{6D24D262-34D3-43A6-B066-1312A0C72B16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6D24D262-34D3-43A6-B066-1312A0C72B16}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6D24D262-34D3-43A6-B066-1312A0C72B16}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6D24D262-34D3-43A6-B066-1312A0C72B16}.Release|Any CPU.Build.0 = Release|Any CPU
{426B01F4-B0C0-488E-8A5A-5531C8DFA98C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{426B01F4-B0C0-488E-8A5A-5531C8DFA98C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{426B01F4-B0C0-488E-8A5A-5531C8DFA98C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{426B01F4-B0C0-488E-8A5A-5531C8DFA98C}.Release|Any CPU.Build.0 = Release|Any CPU
{15C04C0C-FD50-47E9-B62C-AA0A814189ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{15C04C0C-FD50-47E9-B62C-AA0A814189ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
{15C04C0C-FD50-47E9-B62C-AA0A814189ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
{15C04C0C-FD50-47E9-B62C-AA0A814189ED}.Release|Any CPU.Build.0 = Release|Any CPU
{83F55F54-7253-4B4D-BC37-E9D1CB63E0B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{83F55F54-7253-4B4D-BC37-E9D1CB63E0B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{83F55F54-7253-4B4D-BC37-E9D1CB63E0B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{83F55F54-7253-4B4D-BC37-E9D1CB63E0B8}.Release|Any CPU.Build.0 = Release|Any CPU
{B34A66B6-6A3B-42FC-AF39-74A30F487840}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B34A66B6-6A3B-42FC-AF39-74A30F487840}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B34A66B6-6A3B-42FC-AF39-74A30F487840}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B34A66B6-6A3B-42FC-AF39-74A30F487840}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{EDA894F2-00AF-456B-9D07-591ED61A9AE7}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>FlatMap</RootNamespace>
<AssemblyName>FlatMap</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Substrate, Version=0.2.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\bin\Release\Substrate.dll</HintPath>
</Reference>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -0,0 +1,99 @@
using System;
using Substrate;
// FlatMap is an example of generating worlds from scratch with Substrate.
// It will produce a completely flat, solid map with grass, dirt, stone,
// and bedrock layers. On a powerful workstation, creating 400 of these
// chunks only takes a few seconds.
namespace FlatMap
{
class Program
{
static void Main (string[] args)
{
string dest = "F:\\Minecraft\\test";
int xmin = -10;
int xmax = 10;
int zmin = -10;
int zmaz = 10;
// This will instantly create any necessary directory structure
BetaWorld world = BetaWorld.Create(dest);
ChunkManager cm = world.GetChunkManager();
// We can set different world parameters
world.Level.LevelName = "Flatlands";
// We'll create chunks at chunk coordinates xmin,zmin to xmax,zmax
for (int xi = xmin; xi < xmax; xi++) {
for (int zi = zmin; zi < zmaz; zi++) {
// This line will create a default empty chunk, and create a
// backing region file if necessary (which will immediately be
// written to disk)
ChunkRef chunk = cm.CreateChunk(xi, zi);
// Auto light recalculation is horrifically bad for creating
// chunks from scratch, because we're placing thousands
// of blocks. Turn it off.
chunk.AutoRecalcLight = false;
// Set the blocks
FlatChunk(chunk, 64);
// Reset and rebuild the lighting for the entire chunk at once
chunk.RebuildBlockLight();
chunk.RebuildSkyLight();
Console.WriteLine("Built Chunk {0},{1}", chunk.X, chunk.Z);
// Save the chunk to disk so it doesn't hang around in RAM
cm.Save();
}
}
// Save all remaining data (including a default level.dat)
// If we didn't save chunks earlier, they would be saved here
world.Save();
}
static void FlatChunk (ChunkRef chunk, int height)
{
// Create bedrock
for (int y = 0; y < 2; y++) {
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
chunk.SetBlockID(x, y, z, (int)BlockType.BEDROCK);
}
}
}
// Create stone
for (int y = 2; y < height - 5; y++) {
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
chunk.SetBlockID(x, y, z, (int)BlockType.STONE);
}
}
}
// Create dirt
for (int y = height - 5; y < height - 1; y++) {
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
chunk.SetBlockID(x, y, z, (int)BlockType.DIRT);
}
}
}
// Create grass
for (int y = height - 1; y < height; y++) {
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
chunk.SetBlockID(x, y, z, (int)BlockType.GRASS);
}
}
}
}
}
}

View file

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("FlatMap")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("FlatMap")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("588c8d46-5ffb-4593-b48a-9529cf6fcede")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -19,6 +19,8 @@ namespace Substrate
private bool _dirty; private bool _dirty;
private bool _autoLight = true;
public int X public int X
{ {
get { return _container.ChunkGlobalX(_cx); } get { return _container.ChunkGlobalX(_cx); }
@ -29,8 +31,6 @@ namespace Substrate
get { return _container.ChunkGlobalZ(_cz); } get { return _container.ChunkGlobalZ(_cz); }
} }
public int LocalX public int LocalX
{ {
get { return _container.ChunkLocalX(_cx); } get { return _container.ChunkLocalX(_cx); }
@ -41,6 +41,12 @@ namespace Substrate
get { return _container.ChunkLocalZ(_cz); } get { return _container.ChunkLocalZ(_cz); }
} }
public bool AutoRecalcLight
{
get { return _autoLight; }
set { _autoLight = value; }
}
public ChunkRef (IChunkContainer container, IChunkCache cache, int cx, int cz) public ChunkRef (IChunkContainer container, IChunkCache cache, int cx, int cz)
{ {
_container = container; _container = container;
@ -268,14 +274,16 @@ namespace Substrate
if (GetChunk().SetBlockID(lx, ly, lz, id)) { if (GetChunk().SetBlockID(lx, ly, lz, id)) {
MarkDirty(); MarkDirty();
BlockInfo info2 = GetChunk().GetBlockInfo(lx, ly, lz); if (_autoLight) {
if (info1.Luminance != info2.Luminance || info1.Opacity != info2.Opacity) { BlockInfo info2 = GetChunk().GetBlockInfo(lx, ly, lz);
UpdateBlockLight(lx, ly, lz); if (info1.Luminance != info2.Luminance || info1.Opacity != info2.Opacity) {
} UpdateBlockLight(lx, ly, lz);
}
if (info1.Opacity != info2.Opacity) { if (info1.Opacity != info2.Opacity) {
_update.Enqueue(new BlockKey(lx, ly, lz)); _update.Enqueue(new BlockKey(lx, ly, lz));
UpdateSkyLight(); UpdateSkyLight();
}
} }
return true; return true;
@ -430,6 +438,48 @@ namespace Substrate
private BitArray _lightbit; private BitArray _lightbit;
private Queue<BlockKey> _update; private Queue<BlockKey> _update;
public void RebuildBlockLight ()
{
for (int x = 0; x < XDim; x++) {
for (int z = 0; z < ZDim; z++) {
for (int y = 0; y < YDim; y++) {
BlockInfo info = GetBlockInfo(x, y, z);
if (info == null || info.Luminance == 0) {
SetBlockLight(x, y, z, 0);
}
else {
SetBlockLight(x, y, z, Math.Max(info.Luminance - info.Opacity, 0));
QueueRelight(new BlockKey(x, y, z));
}
}
}
}
UpdateBlockLight();
}
public void RebuildSkyLight ()
{
for (int x = 0; x < XDim; x++) {
for (int z = 0; z < ZDim; z++) {
int height = GetHeight(x, z);
for (int y = 0; y < YDim; y++) {
if (y > height) {
SetBlockLight(x, y, z, BlockInfo.MAX_LUMINANCE);
}
else if (y < height) {
SetBlockLight(x, y, z, 0);
}
else {
QueueRelight(new BlockKey(x, y, z));
}
}
}
}
UpdateSkyLight();
}
private void UpdateBlockLight (int lx, int ly, int lz) private void UpdateBlockLight (int lx, int ly, int lz)
{ {
BlockKey primary = new BlockKey(lx, ly, lz); BlockKey primary = new BlockKey(lx, ly, lz);
@ -442,6 +492,11 @@ namespace Substrate
QueueRelight(new BlockKey(lx, ly, lz - 1)); QueueRelight(new BlockKey(lx, ly, lz - 1));
QueueRelight(new BlockKey(lx, ly, lz + 1)); QueueRelight(new BlockKey(lx, ly, lz + 1));
UpdateBlockLight();
}
private void UpdateBlockLight ()
{
while (_update.Count > 0) { while (_update.Count > 0) {
BlockKey k = _update.Dequeue(); BlockKey k = _update.Dequeue();
int index = LightBitmapIndex(k); int index = LightBitmapIndex(k);

View file

@ -17,6 +17,8 @@ namespace Substrate
{ {
string WorldPath { get; } string WorldPath { get; }
Level Level { get; }
IBlockManager GetBlockManager (); IBlockManager GetBlockManager ();
IBlockManager GetBlockManager (int dim); IBlockManager GetBlockManager (int dim);
@ -171,6 +173,11 @@ namespace Substrate
get { return _path; } get { return _path; }
} }
public Level Level
{
get { return _level; }
}
IBlockManager INBTWorld.GetBlockManager () IBlockManager INBTWorld.GetBlockManager ()
{ {
return GetBlockManager(); return GetBlockManager();
@ -370,6 +377,11 @@ namespace Substrate
get { return _path; } get { return _path; }
} }
public Level Level
{
get { return _level; }
}
IBlockManager INBTWorld.GetBlockManager () IBlockManager INBTWorld.GetBlockManager ()
{ {
return GetBlockManager(); return GetBlockManager();