rj-action-library/Runtime/Procedural/HeightMap/LODHeightMapGeometry.cs

109 lines
2.6 KiB
C#

using Godot;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class LODHeightMapGeometry:LODParent
{
[Export]
public float size = 500;
[Export]
public float height = 1000;
[Export]
public int resolution = 128;
[Export]
public float noiseScale = 0.0025f;
[Export]
public float noiseScaleAmount = 10f;
[Export]
public float noiseScale2 = 0.025f;
[Export]
public float noiseScale2Amount = 1f;
[Export]
public float noiseScale3 = 0.15f;
[Export]
public float noiseScale3Amount = 0.1f;
[Export]
public int levels = 6;
[Export]
public Material material;
public void Create()
{
var hmd = HeightMapData.Create( resolution, resolution );
var offsetX = GlobalPosition.X - size/2f;
var offsetY = GlobalPosition.Z - size/2f;
var weights = noiseScaleAmount + noiseScale2Amount + noiseScale3Amount;
for ( int i = 0; i < 128; i ++ )
{
for ( int j = 0; j < 128; j++ )
{
var x = i / (float)resolution * size + offsetX;
var y = j / (float)resolution * size + offsetY;
var v = Noise.Perlin( new Vector2( x, y ) * noiseScale ) * noiseScaleAmount ;
var v2 = Noise.Perlin( new Vector2( x, y ) * noiseScale2 ) * noiseScale2Amount;
var v3 = Noise.Perlin( new Vector2( x, y ) * noiseScale3 ) * noiseScale3Amount;
hmd.Set( i, j, ( v + v2 + v3 ) / weights );
}
}
var level = 1;
var ratio = size / resolution;
var scale = new Vector3( ratio * level, height, ratio * level );
var meshInstance3D = this.CreateChild<MeshInstance3D>();
meshInstance3D.Mesh = hmd.GenerateMeshGeometry( scale ).GenerateMesh();
Materials.Set( meshInstance3D, material );
var offset = size / -2;
meshInstance3D.Position = new Vector3( offset, 0, offset );
var levelScale = 2;
var meshes = new List<Node3D>();
meshes.Add( meshInstance3D );
while ( level < levels )
{
hmd = hmd.CreateLowerResolution();
level ++;
scale = new Vector3( ratio * levelScale , height, ratio * levelScale );
var lowMeshInstance3D = this.CreateChild<MeshInstance3D>();
lowMeshInstance3D.Mesh = hmd.GenerateMeshGeometry( scale ).GenerateMesh();
Materials.Set( lowMeshInstance3D, material );
lowMeshInstance3D.Position = new Vector3( offset, 0, offset );
levelScale *= 2;
meshes.Add( lowMeshInstance3D );
}
lods = meshes.ToArray();
}
}
}