using System.Collections; using System.Collections.Generic; using Godot; using System; namespace Rokojori { [Tool] [GlobalClass] public partial class PointMeshBaker:Node { [Export] public Texture2D albedo; [Export] public Texture2D normal; [Export] public MeshInstance3D output; [Export] public int pixelsX; [Export] public int pixelsY; [Export] public Vector2 pivot; [Export] public Vector3 offset; [Export] public Vector3 scale; [ExportToolButton( "Bake")] public Callable BakeButton => Callable.From( () => { BakePointMesh(); } ); public void BakePointMesh() { var mg = new MeshGeometry( true, false, true, false ); mg.customMeshAttributes.Add( new MeshAttributeVector4List( 0 ) ); mg.normals = null; var albedoImage = albedo.GetImage(); var normalImage = normal.GetImage(); var index = 0; for ( int x = 0; x < pixelsX; x++ ) { for ( int y = 0; y < pixelsY; y++ ) { var fx = x / (float) pixelsX; var fy = 1f - y / (float) pixelsY; var position = new Vector3( fx - pivot.X, fy - pivot.Y, 0 ) * scale + offset; var colorPosX = Mathf.FloorToInt( fx * albedoImage.GetSize().X ); var colorPosY = Mathf.FloorToInt( fy * albedoImage.GetSize().Y ); var color = albedoImage.GetPixel( colorPosX, colorPosY ); var normalPosX = Mathf.FloorToInt( fx * normalImage.GetSize().X ); var normalPosY = Mathf.FloorToInt( fy * normalImage.GetSize().Y ); var normal = normalImage.GetPixel( normalPosX, normalPosY ); mg.AddPoint( position, color.srgbToLinear(), normal.srgbToLinear().ToVector3() * 2.0f - Vector3.One, 0 ); // this.LogInfo( "Created point at:", index, position ); index ++; } } output = output == null ? this.CreateChild() : output; output.Mesh = mg.GenerateMesh( Mesh.PrimitiveType.Points, null, false ); } } }