rj-action-library/Runtime/Procedural/MeshGeometry.cs

294 lines
6.8 KiB
C#
Raw Normal View History

2024-08-11 17:38:06 +00:00
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
namespace Rokojori
{
public class MeshGeometry
{
public List<Vector3> vertices;
public List<int> indices;
public List<Vector3> normals;
public List<Vector2> uvs;
public List<Vector2> uv2s;
public List<Color> colors;
public int numTriangles => indices.Count / 3;
public void ForEachTriangle( Action<int,int,int,int> callback )
{
var index = 0;
for ( int i = 0; i < indices.Count; i += 3 )
{
var a = indices[ i + 0 ];
var b = indices[ i + 1 ];
var c = indices[ i + 2 ];
callback( index, a, b, c );
index ++;
}
}
public MeshGeometry UniqueTriangles()
{
var mg = new MeshGeometry();
mg.Initialize( true, true, colors != null, uv2s != null );
if ( colors != null )
{
mg.colors = new List<Color>();
}
if ( uv2s != null )
{
mg.uv2s = new List<Vector2>();
}
ForEachTriangle(
( index, a, b, c )=>
{
var vA = vertices[ a ];
var vB = vertices[ b ];
var vC = vertices[ c ];
var uvA = uvs[ a ];
var uvB = uvs[ b ];
var uvC = uvs[ c ];
var nA = normals[ a ];
var nB = normals[ b ];
var nC = normals[ c ];
mg.AddTriangle(
vA, vB, vC,
nA, nB, nC,
uvA, uvB, uvC
);
if ( colors != null )
{
Lists.Add( mg.colors, colors[ a ], colors[ b ], colors[ c ] );
}
if ( uv2s != null )
{
Lists.Add( mg.uv2s, uv2s[ a ], uv2s[ b ], uv2s[ c ] );
}
}
);
return mg;
}
public void SetTriangleUVs( int triangleIndex, Vector2 uv )
{
var i = triangleIndex * 3;
var a = indices[ i + 0 ];
var b = indices[ i + 1 ];
var c = indices[ i + 2 ];
uvs[ a ] = uv;
uvs[ b ] = uv;
uvs[ c ] = uv;
}
public void SetTriangleNormal( int triangleIndex, Vector3 normal )
{
var i = triangleIndex * 3;
var a = indices[ i + 0 ];
var b = indices[ i + 1 ];
var c = indices[ i + 2 ];
normals[ a ] = normal;
normals[ b ] = normal;
normals[ c ] = normal;
}
public void SetTriangleColor( int triangleIndex, Color color )
{
var i = triangleIndex * 3;
var a = indices[ i + 0 ];
var b = indices[ i + 1 ];
var c = indices[ i + 2 ];
colors[ a ] = color;
colors[ b ] = color;
colors[ c ] = color;
}
2024-08-11 17:38:06 +00:00
public void Initialize( bool normals = true, bool uvs = true, bool colors = false, bool uvs2 = false)
{
this.vertices = new List<Vector3>();
this.indices = new List<int>();
this.normals = normals ? new List<Vector3>() : null;
this.uvs = uvs ? new List<Vector2>() : null;
this.uv2s = uvs2 ? new List<Vector2>() : null;
this.colors = colors ? new List<Color>() : null;
}
2024-08-11 17:38:06 +00:00
public void AddTriangle(
Vector3 va, Vector3 vb, Vector3 vc,
Vector3 na, Vector3 nb, Vector3 nc,
Vector2 uva, Vector2 uvb, Vector2 uvc
)
{
var index = vertices.Count;
Lists.Add( vertices, va, vb, vc );
Lists.Add( normals, na, nb, nc );
Lists.Add( uvs, uva, uvb, uvc );
Lists.Add( indices, index, index + 1, index + 2 );
}
2024-08-11 17:38:06 +00:00
public void AddTriangle(
Vector3 va, Vector3 vb, Vector3 vc,
Vector2 uva, Vector2 uvb, Vector2 uvc
)
{
var n = Vector3.Up;
AddTriangle( va, vb, vc,
n, n, n,
uva, uvb, uvc );
}
public void AddTriangle( Vector3 va, Vector3 vb, Vector3 vc )
{
var n = Vector3.Up;
var uv = Vector2.Zero;
AddTriangle( va, vb, vc, n, n, n, uv, uv, uv );
}
public void AddQuad(
Vector3 va, Vector3 vb, Vector3 vc, Vector3 vd,
Vector3 na, Vector3 nb, Vector3 nc, Vector3 nd,
Vector2 uva, Vector2 uvb, Vector2 uvc, Vector2 uvd
)
{
AddTriangle( va, vb, vc, na, nb, nc, uva, uvb, uvc );
AddTriangle( vc, vd, va, nc, nd, na, uvc, uvd, uva );
}
2024-08-11 17:38:06 +00:00
public void AddQuad(
Vector3 va, Vector3 vb, Vector3 vc, Vector3 vd,
Vector2 uva, Vector2 uvb, Vector2 uvc, Vector2 uvd
)
{
AddTriangle( va, vb, vc, uva, uvb, uvc );
AddTriangle( vc, vd, va, uvc, uvd, uva );
}
public void AddQuad( Vector3 va, Vector3 vb, Vector3 vc, Vector3 vd )
2024-08-11 17:38:06 +00:00
{
AddQuad(
va, vb, vc, vd,
new Vector2( 0, 0 ),
new Vector2( 0, 1 ),
new Vector2( 1, 1 ),
new Vector2( 1, 0 )
);
2024-08-11 17:38:06 +00:00
}
public void AddQuad( Vector3 offset, float size )
{
var center = new Vector3( 0.5f, 0.5f, 0 );
/*
[-0.5, -0.5] [0.5, -0.5 ]
[-0.5, 0.5] [0.5, 0.5 ]
*/
AddQuad(
new Vector3( -0.5f, -0.5f, 0 ) * size + offset ,
new Vector3( -0.5f, 0.5f, 0 ) * size + offset ,
new Vector3( 0.5f, 0.5f, 0 ) * size + offset ,
new Vector3( 0.5f, -0.5f, 0 ) * size + offset
);
}
public void AddConvex2( Convex2 convex )
2024-08-11 17:38:06 +00:00
{
var points = convex.points;
var tris = points.Count - 2;
for ( int i = 0; i < tris; i++ )
{
var p0 = Math3D.XYasXZ( points[ 0 ] );
var p1 = Math3D.XYasXZ( points[ i + 1 ] );
var p2 = Math3D.XYasXZ( points[ i + 2 ] );
AddTriangle( p0, p1, p2 );
}
2024-08-11 17:38:06 +00:00
}
2024-08-11 17:38:06 +00:00
public ArrayMesh GenerateMesh( Mesh.PrimitiveType type = Mesh.PrimitiveType.Triangles, ArrayMesh arrayMesh = null )
2024-08-11 17:38:06 +00:00
{
if ( arrayMesh == null )
{
arrayMesh = new ArrayMesh();
}
var surfaceArray = new Godot.Collections.Array();
surfaceArray.Resize( (int) Mesh.ArrayType.Max );
if ( vertices != null && vertices.Count != 0 )
2024-08-11 17:38:06 +00:00
{
surfaceArray[ (int) Mesh.ArrayType.Vertex ] = vertices.ToArray();
}
if ( normals != null && normals.Count != 0 )
2024-08-11 17:38:06 +00:00
{
surfaceArray[ (int) Mesh.ArrayType.Normal ] = normals.ToArray();
}
if ( uvs != null && uvs.Count != 0 )
2024-08-11 17:38:06 +00:00
{
surfaceArray[ (int) Mesh.ArrayType.TexUV ] = uvs.ToArray();
}
if ( uv2s != null && uv2s.Count != 0 )
2024-08-11 17:38:06 +00:00
{
surfaceArray[ (int) Mesh.ArrayType.TexUV2 ] = uv2s.ToArray();
}
if ( colors != null && colors.Count != 0 )
2024-08-11 17:38:06 +00:00
{
surfaceArray[ (int) Mesh.ArrayType.Color ] = colors.ToArray();
}
if ( indices != null && indices.Count != 0 )
2024-08-11 17:38:06 +00:00
{
surfaceArray[ (int) Mesh.ArrayType.Index ] = indices.ToArray();
}
arrayMesh.AddSurfaceFromArrays( Mesh.PrimitiveType.Triangles, surfaceArray );
return arrayMesh;
}
}
}