L3DT users' wiki
Large 3D terrain generator

Scripts > Cube wrapped heightfield

Description Apply various wrapping and blending operations to generate a heightfield that may be wrapped onto a cube (nearly) seamlessly.
Author Aaron
Created 2012/03/09
Updated 2012/03/14 — new images with better blending.
Requires L3DT v12.03 build 1 or later
Download cube_mapped_heightfield.zs

About

This script converts 4×3 aspect heightfields like this…

…into cube-wrapped maps such as this:

In principle, the above map could be 'folded' to create a 6 sided cube. With a some sort of spherical distortion calculation, this may allow spherical worlds to be generated from heightmaps.

In Sapphire, the raw (unfolded) results look like:

Note that the blending operations have some artefacts that you will need to clean up manually, including streaking near tile edges, and small steps at internal tile edges.

Script contents

// Author:  A. Torpy
// Updated: 10 Mar 2012

hvar hMap
set hMap <project.GetMap "HF">
int nx ny
set nx <map.GetWidth hMap>
set ny <map.GetHeight hMap>
assert <or nx ny> "Map not initialised"

int TileSize
set TileSize <div ny 3>
if <not <iseq 0 <mod ny TileSize>>>
  echo <strcat "Height is not divisible by 3 (" <strcat ny <strcat " % " <strcat TileSize <strcat " = " <strcat <mod ny TileSize> ")">>>>>>
  return -1
endif

if <not <iseq 4 <div nx TileSize>>>
  echo "Width must be 4/3 height"
  return -1
endif
if <not <iseq 0 <mod nx TileSize>>>
  echo "Width must be exactly 4/3 height"
  return -1
endif

int depth
set depth <div TileSize 3>
if <not <EditUI &depth "Enter blend depth">>
  return -1
endif
if <islt depth 1>
  echo "Blend depth must be greater than 0"
  return -1
endif
if <isgt depth <div TileSize 2>>
  echo <strcat "Blend depth must not be greater than TileSize/2 (i.e. " <strcat <div TileSize 2> ")">>
  return -1
endif


L3DTio_Backup.BackupMap "HF" "BoxWrap HF" 0 "view.ShowMap \"HF\""
  

int px py

int p pmax
set p 0
set pmax 3
do 

  // east/west
  calc.HF.BlendEdges hMap 0 TileSize 1 0 depth <sub nx 1> TileSize 1 2 depth TileSize 0.5 0 NULL

  // easternmost top to mid topmost (reversed)
  calc.HF.BlendEdges hMap <mul 3 TileSize> <mul 2 TileSize> 0 3 depth <mul TileSize 2> <sub ny 1> 2 3 depth TileSize 0.5 0 NULL

  // easternmost bottom to mid bottommost (reversed)
  calc.HF.BlendEdges hMap <mul 3 TileSize> TileSize 0 1 depth <mul TileSize 2> 0 2 1 depth TileSize 0.5 0 NULL

  // northwest diag
  set px TileSize
  set py <mul TileSize 2>
  calc.HF.BlendEdges hMap px py 2 3 depth px py 1 0 depth TileSize 0.5 0 NULL

  // northeast diag
  set px <mul TileSize 2>
  set py <mul TileSize 2>
  calc.HF.BlendEdges hMap px py 1 2 depth px py 0 3 depth TileSize 0.5 0 NULL

  // southeast diag
  set px <mul TileSize 2>
  set py TileSize
  calc.HF.BlendEdges hMap px py 0 1 depth px py 3 2 depth TileSize 0.5 0 NULL

  // southwest diag
  set px TileSize
  set py TileSize
  calc.HF.BlendEdges hMap px py 2 1 depth px py 3 0 depth TileSize 0.5 0 NULL

  // interior vert b/w rightmost tiles (except for last pass, where we don't want changes
  if <islt p <sub pmax 1>>
    set px <mul TileSize 3>
    set py TileSize
    calc.HF.BlendEdges hMap px py 2 1 depth px py 0 1 depth TileSize 0.5 0 NULL

    // interior of centre square, left edge
    set px TileSize
    set py TileSize
    calc.HF.BlendEdges hMap px py 1 2 depth px py 1 0 depth TileSize 0.5f 0 NULL

    // interior of centre square, right edge
    set px <mul TileSize 2>
    set py TileSize
    calc.HF.BlendEdges hMap px py 1 0 depth px py 1 2 depth TileSize 0.5f 0 NULL

    // interior of centre square, top edge
    set px TileSize
    set py <mul TileSize 2>
    calc.HF.BlendEdges hMap px py 0 1 depth px py 0 3 depth TileSize 0.5f 0 NULL

    // interior of centre square, bottom edge
    set px TileSize
    set py TileSize
    calc.HF.BlendEdges hMap px py 0 3 depth px py 0 1 depth TileSize 0.5f 0 NULL
  endif

while <islt <incr p> pmax>


// clear rects
calc.map.ZeroArea hMap 0 0 TileSize TileSize 0
calc.map.ZeroArea hMap <mul TileSize 2> 0 <mul TileSize 2> TileSize 0
calc.map.ZeroArea hMap 0 <mul TileSize 2> TileSize TileSize 0
calc.map.ZeroArea hMap <mul TileSize 2> <mul TileSize 2> <mul TileSize 2> TileSize 0

map.SetFlag hMap 5 true
view.ShowMap "HF"

return 0
 
scripts/cube_wrapped_heightfield.txt · Last modified: 2017/08/31 04:14 (external edit)
 
Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki