/ofPlanet

ofPlanetはopenFrameworksで制作されている地形生成ツールです。

Primary LanguageC++

ofPlanet User's Manual

ofPlanet is terrain generator.

ofPlanet preview

can model export in obj format, can useable in other applications.
in now, verified confirmed readable in Unity. model preview in unity

Operating Enviroment

this application was developed in Visual Studio 2017.
need "VisualStudio Redistribution Package" for run a ofPlanet.

Launch

double click to Runtime/ofPlanet.exe for launch.
need blocks.json and textures.json in Runtime/data folder.
other, need images for blocks, it is locatable for subordinate on data folder.

in defaults, because already prepared Runtime/data/blocks.json, Runtime/data/textures.json and images for blocks,
should be able to launch for only double click.

Screen Image

launch application and should be able to display like below image.

start screen

Setting

input basic setting for world.

setting screen

Size

Size is configure world size.

Biome

Biome is configure world biome.
because implemented by lua script, users can add new biome.
details is see Runtime/data/script folder.

CameraSpeed

CameraSpeed is camera spped on preview.

PlayMode

PlayMode is if toggled on, will able move by WASD key.

Parameter

Parameter is like "SerializedField" on Unity. editable to variable of current selected lua script.

設定画面

for example, below script is declare variable in first four line. above image is shown editor for this variable. editor is auto updated if changed script.

topBlock = "GrassDirt"
fillBlockDeep = "Stone"
fillBlockShallow = "Dirt"
iBaseline = 0

function start()
    return "default"
-- return "ignore"
end

function onFixHeight(y)
    if(y < iBaseline) then
        return iBaseline;
    end
    return y;
end

function onGenerateTerrain(x, y, z)
    startY = y
    setblock(x, y, z, topBlock);
    while y > 0 do
        y = y - 1
        if y < (startY - 5) then
            setblock(x, y, z, fillBlockDeep)
        else
            setblock(x, y, z, fillBlockShallow)
        end
    end
end

function onGenerateWater(x, y, z)
    setblock(x, y, z, "Water");
end

function onGenerateStructures()
end

function onGenerateCave(x, y, z, noise)
    if(noise > 0.1) then
        setblock(x, y, z, "");
    end
end

function onPostGenerate()
    print("done.")
end

textures.json

textures.json is like below.

{
  "baseDirectory": "image/block",
  "textures": [
    {
      "baseFileName": "DirtBlock",
      "mappingRule": {
        "all": "Side"
      },
      "reference": "DirtBlock"
    }
    ...
}

baseDirectory

baseDirectory is directory for put on textures.

textures

textures is array for texture definition.

baseFileName

baseFileName is base of texture name. because block is structured six side plane, need each sides resolve texture. for example, baseFileName of texture list below is Dirt_.

  • Dirt_Top.png
  • Dirt_Bottom.png
  • Dirt_Left.png
  • Dirt_Right.png
  • Dirt_Front.png
  • Dirt_Back.png

resolve by add mappingRule to this string.

mappingRule

mappingRule is define texture bound sides plane.
useable keys is next: "all", "top", "bottom", "left", "right", "front", "back"

reference

reference is define name of texture set.

blocks.json

blocks.json is like below.

{
  "blocks": [
    {
      "reference": "Dirt",
      "texture": "DirtBlock"
    },
    以下略...
}

reference

reference is define name of block.

texture

texture is define texture set for corresponding to block.

shape

omitted in above examples, can specificate block shapes.
in now, supported half block like minecraft.
not only, Y axis half block, can create X axis half block and Z axis half block.
using default block shape if omitt shape property.
below is example for define shape.

......
    {
      "reference": "StoneTopSlab",
      "texture": "StoneBlock",
      "shape": "TopSlab"
    },
    {
      "reference": "StoneBottomSlab",
      "texture": "StoneBlock",
      "shape": "BottomSlab"
    },
    {
      "reference": "StoneLeftSlab",
      "texture": "StoneBlock",
      "shape": "LeftSlab"
    },
    {
      "reference": "StoneRightSlab",
      "texture": "StoneBlock",
      "shape": "RightSlab"
    },
    {
      "reference": "StoneFrontSlab",
      "texture": "StoneBlock",
      "shape": "FrontSlab"
    },
    {
      "reference": "StoneBackSlab",
      "texture": "StoneBlock",
      "shape": "BackSlab"
    },
......

textures.json & blocks.json

translate at later, because this section is not so important.
この2つのファイルが間接参照を多用したデータ構造になっているのは意図的なものです。
テクスチャのみ/ブロックのみをあとから簡単に差し替えることが可能です。

Exporter

Exporter is window for export terrain. in now, supported .bmp, .json and .obj.

export screen

Developer's Manual

Build

need openFrameworks for build this project.
and, this project must be located on below directory.

your_dir/of_v0.10.1_vs2017_release/apps/myApps/ofPlanet

and, need next addons:

and, need "lua.dll" for "ofPlanet\bin".
will auto installed lua at opened this project by nuget.
will installed "lua.dll" is together at this time.
must be this "lua.dll" is copy to "ofPlanet\bin".

Lua Script

in principle, all lua script is put on Runtime/data/script.

  • if you have ofPlanet.exe is located on Runtime

LUA Manual

Callback Functions

in internal, generate terrain by call lua from C++.
however, stylized processes is execute on C++.
example, perlin noise generation... binding block to texture...
what to do on lua script side is below list.

  • filtering noise value.
  • put blocks using noise value.
  • generate structures using weighting table.
  • generate caves using noise value.

start -> mode

write initialize code in this function.
only once called on terrain generation.

also, should be return either value.

  • "default"
    • call all callback functions.
  • "ignore"
    • call "onPostGenerate" only.

onFixHeight(y) -> y

y: noise value. biger than -1 and smaller than 1.
will called in each XZ point, filtering noise value.

onGenerateTerrain(x, y, z) -> void

x, y, z: destination point. called on each XZ points, after filter a noise.
put ground surface blocks.

onGenerateStructures() -> void

called on after "onGenerateTerrain".
generate structure if needed.

onGenerateCave(x, y, z, noise) -> void

x, y, z: destination point. noise: noise value. biger than -1 and smaller than 1.
called on after "onGenerateStructures".
generate cave if needed.

onPostGenerate -> void

called on end of terrain generation.

Function

setblock(x, y, z, name)

overwrite block in specific point.
delete block if block name is "".

putblock(x, y, z, name)

put block if nothing block on point.

getblock(x, y, z) -> name

returns block located on point.

setblockrange(minX, minY, minZ, maxX, maxY, maxZ, name)

fill to range using block.

putblockrange(minX, minY, minZ, maxX, maxY, maxZ, name)

fill to range using block.
however, skip if already existing block.

replaceblockrange(minX, minY, minZ, maxX, maxY, maxZ, oldName, newName)

replace blcok in range.

getxsize() -> xsize

returns X axis in world size.

getysize() -> ysize

returns Y axis in world size.

getzsize() -> zsize

returns Z axis in world size.

newstruct(name, format)

link a structure and name.
below is example.

function start()
    newstruct("AAA",[[
,,
,Wood,
,,

,,
,Wood,
,,

,,
,Wood,
,,

,,
,Wood,
,,

Leaf,Leaf,Leaf
Leaf,Leaf,Leaf
Leaf,Leaf,Leaf

Leaf,Leaf,Leaf
Leaf,Leaf,Leaf
Leaf,Leaf,Leaf

Leaf,Leaf,Leaf
Leaf,Leaf,Leaf
Leaf,Leaf,Leaf
]]) 
    return "default"
-- return "ignore"
end
  • example for tree generation.

translate at later. 1つの文字列の中に複数のCSVを格納するようなイメージです。空行がCSV間の区切りとなります。
下に定義されたものほど実際に構造物を生成したときに上の方(+Y)に生成されます。
また、指定されるブロック名は blocks.jsonreference と同じ名前である必要があります。
なにもない場合は ,, のように隙間をあけずにカンマを打てばOKです。

genstruct(addWeight, limitWeight, name)

generate structure using weighting table.

expandstruct(x, y, z, name)

generate structure at specific point.

setweight(x, y, z, weight, name)

overwrite weighting on specific point.

getweight(x, y, z, name)

returns weighting on specific point.

setweightrange(minX, minY, minZ, maxX, maxY, maxZ, weight, name)

overwrite weighting for specific range.

Other

Block Specification Method

use reference attribute from blocks.json.

Numeric Type

translate at later. Luaには実数型と整数型の区別がありません。
しかし、Luaのある変数が整数(integer)として使用されることが想定されているなら、
ofPlanetはその変数に対して小数部分を編集できないエディターを提供するべきです。
この区別をつけるため、ofPlanetは変数名にプレフィックスiのついた変数を特別扱いします。
iが付く場合には小数部分を編集できないスライダーUIを提供し、それ以外の場合では小数部分まで編集できてしまうスライダーUIを提供します。

Weighting Algorithm

translate at later. v0.3からは、重み付けによる構造物の生成がサポートされるようになりました。
構造物を生成できる場所を検索するときに、ただ単にブロックがそこにあるかどうかだけでなく、
その座標の重み付けがしきい値を超えるかどうかも加味して検索します。
例えば、構造物を配置することができる十分なスペースがあって、構造物を生成したときに
構造物と重なるブロックが1つも存在しなくても、その座標の重み付けが十分に高いと生成できないと判断されます。

重み付けのテーブルは構造物が生成されたときに自動的に構造物を配置した中心から放射状に拡散します。
つまり、強い重み付けを与えて構造物を生成すればその構造物の生成頻度を下げることができます。
ofPlanetでは構造物それぞれが内部的に別々の重み付けテーブルを持っているので、
ある構造物Aの生成によって別の構造物Bの生成頻度が下がることはありません。

また、構造物を生成せずとも重み付けを操作できる関数を用意しています。
これを使えば高いところだけ構造物を少なくすることも可能です。

JSON Format

format of json obtained by output.

{
    "cell": [
        {
            "block": "Stone",
            "x": 0,
            "y": 0,
            "z": 0,
        }
        ...
    ],
    "worldSize": {
        "x": 128,
        "y": 64,
        "z": 128,
    }
}

OBJ Format

  • Coordinate system(Up=Z+ Right=X+ Front=Y+)
  • Rotateion Mode: XYZ Euler Angle

License

this application was implemented by below libraries.

Asset

this application is include below assets.