WIP: apply generated world texture to tiles.

WorldChunkRefactoring
Martin Felis 2023-05-09 21:51:45 +02:00
parent 4c92a6c5c3
commit a5ce4a235d
14 changed files with 310 additions and 89 deletions

2
.gitignore vendored
View File

@ -10,3 +10,5 @@ mono_crash.*
export/html export/html
export/android export/android
assets/tmp/*

View File

@ -17,4 +17,8 @@
<ItemGroup> <ItemGroup>
<Folder Include="LocalSystems" /> <Folder Include="LocalSystems" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="scenes\Tests\HexTile3DMaterialAssign.tscn" />
</ItemGroup>
</Project> </Project>

View File

@ -22,7 +22,7 @@ compress/hdr_mode=0
compress/bptc_ldr=0 compress/bptc_ldr=0
compress/normal_map=0 compress/normal_map=0
flags/repeat=true flags/repeat=true
flags/filter=true flags/filter=false
flags/mipmaps=true flags/mipmaps=true
flags/anisotropic=false flags/anisotropic=false
flags/srgb=2 flags/srgb=2

View File

@ -0,0 +1,9 @@
[gd_resource type="ShaderMaterial" load_steps=3 format=2]
[ext_resource path="res://assets/4x4checkerColor.png" type="Texture" id=1]
[ext_resource path="res://materials/shader/HexToTexture.gdshader" type="Shader" id=2]
[resource]
shader = ExtResource( 2 )
shader_param/TextureSize = 4
shader_param/MapAlbedoTexture = ExtResource( 1 )

View File

@ -0,0 +1,82 @@
shader_type spatial;
render_mode specular_schlick_ggx, async_visible;
uniform sampler2D MapAlbedoTexture : hint_black_albedo;
uniform int TextureSize: hint_range(0, 1024, 4);
varying vec2 map_coord;
const mat2 _HexAffineInverse = mat2(vec2(1.333333, -0.6666667), vec2(0, -1.154701));
vec3 axial_to_cube(vec2 axial) {
return vec3(axial.x, axial.y, -axial.x - axial.y);
}
ivec3 round_cube_coords(vec3 cube) {
ivec3 rounded = ivec3(cube);
vec3 diffs = abs(vec3(rounded) - cube);
if (diffs.x > diffs.y && diffs.x > diffs.z) {
rounded.x = -rounded.y - rounded.z;
} else if (diffs.y > diffs.z) {
rounded.y = -rounded.x - rounded.z;
} else {
rounded.z = -rounded.x - rounded.y;
}
return rounded;
}
vec2 axial_to_offset(vec2 axial) {
ivec3 cubeCoords = round_cube_coords(axial_to_cube(axial));
int x = cubeCoords.x;
int y = cubeCoords.y;
int off_y = y + (x - (x % 1)) / 2;
return vec2(float(x), float(off_y));
}
void vertex() {
// Input:2
mat4 model_matrix = WORLD_MATRIX;
vec3 origin = vec4(WORLD_MATRIX * vec4(0, 0, 0, 1)).xyz;
vec3 axial_coords = vec3(_HexAffineInverse * origin.xz, 0);
// Output:0
map_coord = origin.xz * 1. / float(TextureSize);
map_coord = axial_to_offset(axial_coords.xy) / float(TextureSize);
}
void fragment() {
// Input:3
mat4 n_out3p0 = WORLD_MATRIX;
// TransformDecompose:5
vec3 n_out5p0 = n_out3p0[0].xyz;
vec3 n_out5p1 = n_out3p0[1].xyz;
vec3 n_out5p2 = n_out3p0[2].xyz;
vec3 n_out5p3 = n_out3p0[3].xyz;
// VectorOp:9
vec3 n_in9p1 = vec3(1.00000, 1.00000, 1.00000);
vec3 n_out9p0 = n_out5p3 * n_in9p1;
// TextureUniform:4
vec3 n_out4p0;
float n_out4p1;
{
vec4 n_tex_read = texture(MapAlbedoTexture, map_coord);
n_out4p0 = n_tex_read.rgb;
n_out4p1 = n_tex_read.a;
}
// Output:0
ALBEDO = n_out4p0;
}
void light() {
// Output:0
}

View File

@ -9,17 +9,17 @@
config_version=4 config_version=4
_global_script_classes=[ { _global_script_classes=[ {
"base": "Reference", "base": "Node",
"class": "ClickableComponent", "class": "ClickableComponent",
"language": "GDScript", "language": "GDScript",
"path": "res://components/ClickableComponent.gd" "path": "res://components/ClickableComponent.gd"
}, { }, {
"base": "Reference", "base": "KinematicBody2D",
"class": "CollisionLine", "class": "CollisionLine",
"language": "GDScript", "language": "GDScript",
"path": "res://utils/CollisionLine.gd" "path": "res://utils/CollisionLine.gd"
}, { }, {
"base": "Reference", "base": "Node",
"class": "ColorComponent", "class": "ColorComponent",
"language": "GDScript", "language": "GDScript",
"path": "res://components/ColorComponent.gd" "path": "res://components/ColorComponent.gd"
@ -54,7 +54,7 @@ _global_script_classes=[ {
"language": "GDScript", "language": "GDScript",
"path": "res://utils/SpringDamper.gd" "path": "res://utils/SpringDamper.gd"
}, { }, {
"base": "Reference", "base": "Sprite",
"class": "TintedSpriteComponent", "class": "TintedSpriteComponent",
"language": "GDScript", "language": "GDScript",
"path": "res://components/TintedSpriteComponent.gd" "path": "res://components/TintedSpriteComponent.gd"

View File

@ -30,6 +30,7 @@ public class Game : Spatial
// Resources // Resources
private PackedScene _tileHighlightScene; private PackedScene _tileHighlightScene;
private ShaderMaterial _tileMaterial;
// other members // other members
private HexGrid _hexGrid; private HexGrid _hexGrid;
@ -69,6 +70,8 @@ public class Game : Spatial
// resources // resources
_tileHighlightScene = GD.Load<PackedScene>("utils/TileHighlight.tscn"); _tileHighlightScene = GD.Load<PackedScene>("utils/TileHighlight.tscn");
_tileMaterial = GD.Load<ShaderMaterial>("materials/HexTileTextureLookup.tres");
Debug.Assert(_tileMaterial != null);
// other members // other members
_lastTile = new HexCell(); _lastTile = new HexCell();
@ -82,6 +85,7 @@ public class Game : Spatial
// connect signals // connect signals
_streamContainerArea.Connect("input_event", this, nameof(OnAreaInputEvent)); _streamContainerArea.Connect("input_event", this, nameof(OnAreaInputEvent));
_streamContainer.Connect("TileClicked", this, nameof(OnTileClicked)); _streamContainer.Connect("TileClicked", this, nameof(OnTileClicked));
_streamContainer.Connect("TileHovered", this, nameof(OnTileHovered));
_tileWorld.Connect("WorldGenerated", this, nameof(OnWorldGenerated)); _tileWorld.Connect("WorldGenerated", this, nameof(OnWorldGenerated));
_generateWorldButton.Connect("pressed", this, nameof(OnGenerateButton)); _generateWorldButton.Connect("pressed", this, nameof(OnGenerateButton));
@ -96,7 +100,7 @@ public class Game : Spatial
} }
// perform dependency injection // perform dependency injection
//_streamContainer.SetWorld(_tileWorld); //_streamContainer.SetWorld(_tileWorld);Clicked
WorldInfoComponent worldInfoComponent = _player.GetNode<WorldInfoComponent>("WorldInfo"); WorldInfoComponent worldInfoComponent = _player.GetNode<WorldInfoComponent>("WorldInfo");
if (worldInfoComponent != null) if (worldInfoComponent != null)
{ {
@ -183,11 +187,6 @@ public class Game : Spatial
{ {
HexCell cellAtCursor = _hexGrid.GetHexAt(new Vector2(position.x, position.z)); HexCell cellAtCursor = _hexGrid.GetHexAt(new Vector2(position.x, position.z));
Transform highlightTransform = Transform.Identity; Transform highlightTransform = Transform.Identity;
Vector2 cellPlaneCoords = _hexGrid.GetHexCenter(cellAtCursor);
cellPlaneCoords = _hexGrid.GetHexCenterFromOffset(cellAtCursor.OffsetCoords);
highlightTransform.origin.x = cellPlaneCoords.x;
highlightTransform.origin.z = cellPlaneCoords.y;
highlightTransform.origin.y = 0.1f;
_mouseWorldLabel.Text = position.ToString(); _mouseWorldLabel.Text = position.ToString();
_mouseTileLabel.Text = cellAtCursor.OffsetCoords.ToString(); _mouseTileLabel.Text = cellAtCursor.OffsetCoords.ToString();
@ -224,6 +223,17 @@ public class Game : Spatial
// } // }
} }
public void OnTileHovered(HexTile3D tile)
{
Transform highlightTransform = _tileHighlight.GlobalTransform;
highlightTransform.origin.x = tile.GlobalTranslation.x;
highlightTransform.origin.z = tile.GlobalTranslation.z;
highlightTransform.origin.y = 0.1f;
_mouseTileHighlight.Transform = highlightTransform;
_mouseWorldLabel.Text = tile.GlobalTranslation.ToString();
_mouseTileLabel.Text = tile.OffsetCoords.ToString();
}
public void OnEntityClicked(Entity entity) public void OnEntityClicked(Entity entity)
{ {
GD.Print("Clicked on entity at " + entity.GlobalTranslation); GD.Print("Clicked on entity at " + entity.GlobalTranslation);
@ -245,9 +255,12 @@ public class Game : Spatial
ImageTexture new_world_texture = new ImageTexture(); ImageTexture new_world_texture = new ImageTexture();
_tileWorld.Colormap.Unlock(); _tileWorld.Colormap.Unlock();
new_world_texture.CreateFromImage(_tileWorld.Colormap); new_world_texture.CreateFromImage(_tileWorld.Colormap, (uint) (Texture.FlagsEnum.Mipmaps | Texture.FlagsEnum.Repeat));
_tileWorld.Colormap.Lock(); _tileWorld.Colormap.Lock();
_worldTextureRect.Texture = new_world_texture; _worldTextureRect.Texture = new_world_texture;
_tileMaterial.Set("MapAlbedoTexture", new_world_texture);
_streamContainer.SetTileMaterial(_tileMaterial);
} }
} }

View File

@ -21,6 +21,9 @@ public class HexTile3D : Spatial
[Signal] [Signal]
delegate void TileClicked(HexTile3D tile3d); delegate void TileClicked(HexTile3D tile3d);
[Signal]
delegate void TileHovered(HexTile3D tile3d);
// other member variables // other member variables
private SpatialMaterial _undefinedMaterial; private SpatialMaterial _undefinedMaterial;
private SpatialMaterial _sandMaterial; private SpatialMaterial _sandMaterial;
@ -125,6 +128,7 @@ public class HexTile3D : Spatial
IsMouseOver = true; IsMouseOver = true;
_previousMaterial = (SpatialMaterial)_mesh.MaterialOverride; _previousMaterial = (SpatialMaterial)_mesh.MaterialOverride;
EmitSignal("TileHovered", this);
// SpatialMaterial clonedMaterial = (SpatialMaterial)_mesh.GetSurfaceMaterial(0).Duplicate(); // SpatialMaterial clonedMaterial = (SpatialMaterial)_mesh.GetSurfaceMaterial(0).Duplicate();
// clonedMaterial.AlbedoColor = new Color(1, 0, 0); // clonedMaterial.AlbedoColor = new Color(1, 0, 0);
// _mesh.MaterialOverride = clonedMaterial; // _mesh.MaterialOverride = clonedMaterial;

View File

@ -1,7 +1,7 @@
[gd_scene load_steps=7 format=2] [gd_scene load_steps=5 format=2]
[ext_resource path="res://scenes/HexTile3D.cs" type="Script" id=1] [ext_resource path="res://scenes/HexTile3D.cs" type="Script" id=1]
[ext_resource path="res://assets/4x4checkerColor.png" type="Texture" id=2] [ext_resource path="res://materials/HexTileTextureLookup.tres" type="Material" id=2]
[sub_resource type="CylinderMesh" id=6] [sub_resource type="CylinderMesh" id=6]
top_radius = 0.5 top_radius = 0.5
@ -10,76 +10,6 @@ height = 10.0
radial_segments = 6 radial_segments = 6
rings = 1 rings = 1
[sub_resource type="Shader" id=11]
code = "shader_type spatial;
render_mode specular_schlick_ggx, async_visible;
uniform sampler2D MapAlbedoTexture : hint_black_albedo;
uniform mat4 HexAffineInverse;
varying vec2 map_coord;
const mat2 _HexAffineInverse = mat2(vec2(1.333333, -0.6666667), vec2(0, -1.154701));
vec2 axial_to_offset(vec2 axial) {
ivec2 axial_i = ivec2(axial);
int x = axial_i.x;
int y = axial_i.y;
int off_y = y + (x - (x % 1)) / 2;
return vec2(float(x), float(off_y));
}
void vertex() {
// Input:2
mat4 model_matrix = WORLD_MATRIX;
vec3 origin = vec4(WORLD_MATRIX * vec4(0, 0, 0, 1)).xyz;
vec3 axial_coords = vec3(_HexAffineInverse * origin.xz, 0);
// Output:0
map_coord = origin.xz * 0.25;
map_coord = axial_to_offset(axial_coords.xy) * 0.25;
}
void fragment() {
// Input:3
mat4 n_out3p0 = WORLD_MATRIX;
// TransformDecompose:5
vec3 n_out5p0 = n_out3p0[0].xyz;
vec3 n_out5p1 = n_out3p0[1].xyz;
vec3 n_out5p2 = n_out3p0[2].xyz;
vec3 n_out5p3 = n_out3p0[3].xyz;
// VectorOp:9
vec3 n_in9p1 = vec3(1.00000, 1.00000, 1.00000);
vec3 n_out9p0 = n_out5p3 * n_in9p1;
// TextureUniform:4
vec3 n_out4p0;
float n_out4p1;
{
vec4 n_tex_read = texture(MapAlbedoTexture, map_coord);
n_out4p0 = n_tex_read.rgb;
n_out4p1 = n_tex_read.a;
}
// Output:0
ALBEDO = n_out4p0;
}
void light() {
// Output:0
}
"
[sub_resource type="ShaderMaterial" id=10]
shader = SubResource( 11 )
shader_param/HexAffineInverse = null
shader_param/MapAlbedoTexture = ExtResource( 2 )
[sub_resource type="CylinderShape" id=5] [sub_resource type="CylinderShape" id=5]
height = 1.0 height = 1.0
radius = 0.5 radius = 0.5
@ -91,7 +21,7 @@ script = ExtResource( 1 )
[node name="Mesh" type="MeshInstance" parent="."] [node name="Mesh" type="MeshInstance" parent="."]
transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0.00399733, -5, 0 ) transform = Transform( -4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0.00399733, -5, 0 )
mesh = SubResource( 6 ) mesh = SubResource( 6 )
material/0 = SubResource( 10 ) material/0 = ExtResource( 2 )
[node name="StaticBody" type="StaticBody" parent="."] [node name="StaticBody" type="StaticBody" parent="."]

View File

@ -10,11 +10,8 @@ persistence = 0.2
lacunarity = 4.0 lacunarity = 4.0
[sub_resource type="NoiseTexture" id=4] [sub_resource type="NoiseTexture" id=4]
width = 128
height = 128
seamless = true seamless = true
noise = SubResource( 3 ) noise = SubResource( 3 )
noise_offset = Vector2( 2.632, 0 )
[node name="Node2D" type="Node2D"] [node name="Node2D" type="Node2D"]
@ -30,3 +27,4 @@ size_flags_horizontal = 3
size_flags_vertical = 3 size_flags_vertical = 3
texture = SubResource( 4 ) texture = SubResource( 4 )
expand = true expand = true
stretch_mode = 5

View File

@ -22,6 +22,8 @@ public class StreamContainer : Spatial
[Signal] [Signal]
delegate void TileClicked(HexTile3D tile3d); delegate void TileClicked(HexTile3D tile3d);
[Signal]
delegate void TileHovered(HexTile3D tile3d);
// other members // other members
private Rect2 _worldRect; private Rect2 _worldRect;
@ -110,6 +112,7 @@ public class StreamContainer : Spatial
RemovedCoords.Add(tile3D.OffsetCoords); RemovedCoords.Add(tile3D.OffsetCoords);
_activeTiles.RemoveChild(tile3D); _activeTiles.RemoveChild(tile3D);
tile3D.Disconnect("TileClicked", this, nameof(OnTileClicked)); tile3D.Disconnect("TileClicked", this, nameof(OnTileClicked));
tile3D.Disconnect("TileHovered", this, nameof(OnTileHovered));
tile3D.QueueFree(); tile3D.QueueFree();
} }
} }
@ -189,6 +192,7 @@ public class StreamContainer : Spatial
tile3D.OffsetCoords = offsetCoords; tile3D.OffsetCoords = offsetCoords;
_activeTiles.AddChild(tile3D); _activeTiles.AddChild(tile3D);
tile3D.Connect("TileClicked", this, nameof(OnTileClicked)); tile3D.Connect("TileClicked", this, nameof(OnTileClicked));
tile3D.Connect("TileHovered", this, nameof(OnTileHovered));
Transform tileTransform = tile3D.Transform; Transform tileTransform = tile3D.Transform;
tileTransform.origin.y = _tileWorld.GetHeightAtOffset(offsetCoords); tileTransform.origin.y = _tileWorld.GetHeightAtOffset(offsetCoords);
@ -206,9 +210,29 @@ public class StreamContainer : Spatial
UpdateRects(_hexGrid.GetHexCenter(cell)); UpdateRects(_hexGrid.GetHexCenter(cell));
} }
public void SetTileMaterial(ShaderMaterial material)
{
foreach (Spatial node in _activeTiles.GetChildren())
{
HexTile3D tile = (HexTile3D)node;
if (tile == null)
{
continue;
}
tile.Mesh.SetSurfaceMaterial(0, material);
}
}
public void OnTileClicked(HexTile3D tile) public void OnTileClicked(HexTile3D tile)
{ {
GD.Print("Clicked on Tile at " + tile.OffsetCoords); GD.Print("Clicked on Tile at " + tile.OffsetCoords);
EmitSignal("TileClicked", tile); EmitSignal("TileClicked", tile);
} }
public void OnTileHovered(HexTile3D tile)
{
GD.Print("Hovered on Tile at " + tile.OffsetCoords);
EmitSignal("TileHovered", tile);
}
} }

View File

@ -14,7 +14,7 @@ public class TileWorld : Spatial
delegate void WorldGenerated(); delegate void WorldGenerated();
// public members // public members
public Vector2 Size = new Vector2(10, 10); public Vector2 Size = new Vector2(100, 100);
public float HeightScale = 10; public float HeightScale = 10;
public Image Heightmap; public Image Heightmap;
public Image Colormap; public Image Colormap;

View File

@ -0,0 +1,82 @@
using Godot;
using System;
using System.Diagnostics;
public class HexTile3DMaterialAssign : Spatial
{
// Declare member variables here. Examples:
// private int a = 2;
// private string b = "text";
private Button _blackWhitePatternButton;
private Button _colorPatternButton;
private Button _changeMaterialButton;
private SpinBox _textureSizeSpinBox;
private HexTile3D _hexTile;
private ShaderMaterial _customTileMaterial;
private ImageTexture _blackWhitePatternTexture;
private ImageTexture _colorPatternTexture;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
_blackWhitePatternButton = (Button)FindNode("BlackWhitePatternButton");
Debug.Assert(_blackWhitePatternButton != null);
_blackWhitePatternButton.Connect("pressed", this, nameof(OnBlackWhitePatternButton));
_colorPatternButton = (Button)FindNode("ColorPatternButton");
Debug.Assert(_colorPatternButton != null);
_colorPatternButton.Connect("pressed", this, nameof(OnColorPatternButton));
_textureSizeSpinBox = (SpinBox)FindNode("TextureSizeSpinBox");
Debug.Assert(_textureSizeSpinBox != null);
_textureSizeSpinBox.Connect("value_changed", this, nameof(OnTextureSizeChanged));
_hexTile = (HexTile3D)FindNode("HexTile3D");
Debug.Assert(_hexTile != null);
_customTileMaterial = GD.Load<ShaderMaterial>("materials/HexTileTextureLookup.tres");
_blackWhitePatternTexture = new ImageTexture();
Image image = new Image();
image.Load("assets/4x4checker.png");
_blackWhitePatternTexture.CreateFromImage(image, (uint) (Texture.FlagsEnum.Mipmaps | Texture.FlagsEnum.Repeat));
_colorPatternTexture = new ImageTexture();
image.Load("assets/4x4checkerColor.png");
_colorPatternTexture.CreateFromImage(image, (uint) (Texture.FlagsEnum.Mipmaps | Texture.FlagsEnum.Repeat));
}
public void OnBlackWhitePatternButton()
{
GD.Print("Apply Black White Pattern!");
ShaderMaterial currentMaterial = (ShaderMaterial) _hexTile.Mesh.GetSurfaceMaterial(0);
Debug.Assert(currentMaterial != null);
currentMaterial.SetShaderParam("MapAlbedoTexture", _blackWhitePatternTexture);
// _customTileMaterial.SetShaderParam("MapAlbedoTexture", _imageTexture);
// _hexTile.Mesh.SetSurfaceMaterial(0, _customTileMaterial);
}
public void OnColorPatternButton()
{
GD.Print("Apply Collor Pattern!");
ShaderMaterial currentMaterial = (ShaderMaterial) _hexTile.Mesh.GetSurfaceMaterial(0);
Debug.Assert(currentMaterial != null);
currentMaterial.SetShaderParam("MapAlbedoTexture", _colorPatternTexture);
// _customTileMaterial.SetShaderParam("MapAlbedoTexture", _imageTexture);
// _hexTile.Mesh.SetSurfaceMaterial(0, _customTileMaterial);
}
public void OnTextureSizeChanged(float value)
{
GD.Print("Texture size: " + value);
ShaderMaterial currentMaterial = (ShaderMaterial) _hexTile.Mesh.GetSurfaceMaterial(0);
Debug.Assert(currentMaterial != null);
currentMaterial.SetShaderParam("TextureSize", (int) value);
GD.Print("Texture size: " + currentMaterial.GetShaderParam("TextureSize"));
}
}

View File

@ -0,0 +1,73 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://scenes/HexTile3D.tscn" type="PackedScene" id=1]
[ext_resource path="res://scenes/tests/HexTile3DMaterialAssign.cs" type="Script" id=2]
[node name="Spatial" type="Spatial"]
script = ExtResource( 2 )
[node name="Camera" type="Camera" parent="."]
transform = Transform( 1, 0, 0, 0, 0.806713, 0.590944, 0, -0.590944, 0.806713, 0, 0.952316, 1.84927 )
[node name="Control" type="Control" parent="."]
margin_left = 5.0
margin_top = 5.0
margin_right = 40.0
margin_bottom = 40.0
[node name="HBoxContainer" type="HBoxContainer" parent="Control"]
margin_right = 40.0
margin_bottom = 40.0
custom_constants/separation = 10
[node name="BlackWhitePatternButton" type="Button" parent="Control/HBoxContainer"]
margin_right = 88.0
margin_bottom = 40.0
text = "Black White"
[node name="ColorPatternButton" type="Button" parent="Control/HBoxContainer"]
margin_left = 98.0
margin_right = 143.0
margin_bottom = 40.0
text = "Color"
[node name="TextureSizeSpinBox" type="SpinBox" parent="Control/HBoxContainer"]
margin_left = 153.0
margin_right = 227.0
margin_bottom = 40.0
[node name="HexTile3D" parent="." instance=ExtResource( 1 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.881519 )
[node name="HexTile3D2" parent="." instance=ExtResource( 1 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )
[node name="HexTile3D3" parent="." instance=ExtResource( 1 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1.76304 )
[node name="HexTile3D4" parent="." instance=ExtResource( 1 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.753439, 0, -1.31897 )
[node name="HexTile3D5" parent="." instance=ExtResource( 1 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.753439, 0, -0.437451 )
[node name="HexTile3D6" parent="." instance=ExtResource( 1 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.753439, 0, -2.20049 )
[node name="HexTile3D7" parent="." instance=ExtResource( 1 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 1.48955, 0, -0.881519 )
[node name="HexTile3D8" parent="." instance=ExtResource( 1 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 1.48955, 0, 0 )
[node name="HexTile3D9" parent="." instance=ExtResource( 1 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 1.48955, 0, -1.76304 )
[node name="HexTile3D10" parent="." instance=ExtResource( 1 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2.24298, 0, -1.31897 )
[node name="HexTile3D11" parent="." instance=ExtResource( 1 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2.24298, 0, -0.437451 )
[node name="HexTile3D12" parent="." instance=ExtResource( 1 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2.24298, 0, -2.20049 )