Localization & More

This commit is contained in:
Josef 2025-01-26 10:15:28 +01:00
parent 9d1c1eb378
commit 4afa937816
16 changed files with 305 additions and 20 deletions

View File

@ -3,12 +3,22 @@ using Godot;
using System.Collections.Generic;
using System;
using System.Threading.Tasks;
using System.Reflection;
namespace Rokojori
{
public static class Nodes
{
public static void CopyData<T>( T from, T to ) where T:Node
{
var memberInfos = ReflectionHelper.GetDataMemberInfos<T>( BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly );
var memberNames = Lists.Map( memberInfos, m => m.Name );
ReflectionHelper.CopyDataMembersFromTo( from, to, memberNames );
}
public static T Find<T>( Node root, NodePathLocatorType type = NodePathLocatorType.DirectChildren, int parentOffset = 0 ) where T:Node
{
var it = root;

View File

@ -7,6 +7,7 @@ namespace Rokojori
{
public static void Overwrite<T>( List<string> overwriteProperties, T sourceResource, T targetResource ) where T:Resource
{
}
}
}

View File

@ -0,0 +1,37 @@
using Godot;
using System.Collections;
using System.Collections.Generic;
using Godot.Collections;
namespace Rokojori
{
public enum LocaleCode
{
EN,
JA,
DE,
ES,
FR,
PT,
IT,
KO,
ZH,
RU,
PL,
TU,
AR,
NL,
SV,
HI,
TH,
ID,
VI,
EL,
CS,
FI,
UK,
RO,
HU
}
}

View File

@ -0,0 +1,15 @@
using Godot;
using System.Collections;
using System.Collections.Generic;
using Godot.Collections;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class LocaleManager:Node
{
[Export]
public LocaleCode languageLocale;
}
}

View File

@ -0,0 +1,43 @@
using Godot;
using System.Collections;
using System.Collections.Generic;
using Godot.Collections;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class LocaleText:LocalizedString
{
[Export(PropertyHint.MultilineText)]
public string en;
[ExportGroup("Translations")]
[Export]
public LocaleTextEntry[] entries;
[ExportGroup("Context")]
[Export(PropertyHint.MultilineText)]
public string context;
public override string GetLocalizedString( LocaleCode localeCode )
{
if ( localeCode == LocaleCode.EN )
{
return en;
}
var entry = Arrays.Find( entries, e => e.code == localeCode );
if ( entry != null )
{
return entry.content;
}
return en;
}
}
}

View File

@ -0,0 +1,18 @@
using Godot;
using System.Collections;
using System.Collections.Generic;
using Godot.Collections;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class LocaleTextEntry:LocalizedString
{
[Export]
public LocaleCode code;
[Export(PropertyHint.MultilineText)]
public string content;
}
}

View File

@ -0,0 +1,18 @@
using Godot;
using System.Collections;
using System.Collections.Generic;
using Godot.Collections;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class LocalizedString:Resource
{
public virtual string GetLocalizedString( LocaleCode localeCode )
{
return "";
}
}
}

View File

@ -332,6 +332,11 @@ namespace Rokojori
return a.Lerp( b, lerp );
}
public static Vector3 LerpGlobalPosition( Node3D a, Node3D b, float lerp )
{
return a.GlobalPosition.Lerp( b.GlobalPosition, lerp );
}
public static Quaternion LookRotation( Vector3 direction, bool useModelFront = false )
{
if ( direction.Normalized() == Vector3.Up )

View File

@ -361,6 +361,19 @@ namespace Rokojori
return Mathf.Atan2( y1 - y0, x1 - x0 );
}
public static Curve ScaleCurve( Curve c, float scale )
{
var clone = (Curve) c.Duplicate( true );
for ( int i = 0; i < clone.PointCount; i++ )
{
var y = clone.GetPointPosition( i ).Y;
clone.SetPointValue( i, y * scale);
}
return clone;
}
public static float CurveMaximum( Curve c, int numSamples = 20 )
{
var max = 0f;

View File

@ -51,6 +51,12 @@ namespace Rokojori
[Export]
public Vector2 patchOffsetPosition = new Vector2( 0.5f, 0.5f );
[Export]
public bool centerPatch = false;
[Export]
public float centerPatchComputationHeightTreshold = 0.1f;
[ExportGroup( "Blade Triangles")]
[Export( PropertyHint.Range, "1,256")]
@ -218,6 +224,28 @@ namespace Rokojori
Vector3 _patchOffset = Vector3.Zero;
public int ComputeNumBlades()
{
if ( blades == 0 )
{
if ( bladesX < bladesZ )
{
bladesX = Mathf.Max( 1, bladesX );
}
else
{
bladesZ = Mathf.Max( 1, bladesZ );
}
}
return ( bladesX + blades ) * ( blades + bladesZ );
}
public int ComputeNumTriangles()
{
return bladeSegments * 2 * ComputeNumBlades();
}
public void CreatePatch()
{
if ( blades == 0 && bladesX == 0 && bladesZ == 0)
@ -348,7 +376,19 @@ namespace Rokojori
}
}
if ( centerPatch )
{
var f = 100000;
var h = centerPatchComputationHeightTreshold;
var box = Box3.Create( new Vector3( -f, -f, -f ), new Vector3( f, h, f ) );
mg.CenterMesh( true, false, true, box );
}
X_numTriangles = mg.indices.Count / 3;
output.Mesh = mg.GenerateMesh();
}

View File

@ -774,6 +774,45 @@ namespace Rokojori
AddTriangle( p0, p1, p2 );
}
}
public void CenterMesh( bool onX = true, bool onY = true, bool onZ = true, Box3 centerCalcluationBox = null )
{
var offset = new Vector3( 0, 0, 0 );
var numPoints = 0;
for ( int i = 0; i < vertices.Count; i++ )
{
if ( centerCalcluationBox != null && ! centerCalcluationBox.ContainsPoint( vertices[ i ] ) )
{
continue;
}
offset += vertices[ i ];
numPoints ++;
}
offset /= numPoints;
if ( ! onX )
{
offset.X = 0;
}
if ( ! onY )
{
offset.Y = 0;
}
if ( ! onZ )
{
offset.Z = 0;
}
ApplyTranslation( - offset );
}

View File

@ -69,7 +69,7 @@ namespace Rokojori
var before = output.Count ;
output = s.Scatter( output, root );
RJLog.Log( "Processed", before, "to", output.Count );
// RJLog.Log( "Processed", before, "to", output.Count );
}
);

View File

@ -76,7 +76,7 @@ namespace Rokojori
var uniformScaleRandom = Noise.Perlin( scalePerlin + new Vector3( 100002, -10002, 1000 ) );
p.position += positionOffset * positionRandom * positionOffsetScale;
p.rotation *= Quaternion.FromEuler( rotationOffset * rotationRandom * rotationOffsetScale );
p.rotation *= Quaternion.FromEuler( rotationOffset * MathX.DegreesToRadians * rotationRandom * rotationOffsetScale );

View File

@ -36,6 +36,11 @@ namespace Rokojori
return curve.Sample( Next() );
}
public int SampleInteger( Curve curve )
{
return Mathf.RoundToInt( curve.Sample( Next() ) );
}
public float Polar()
{
return this.Next() * 2f - 1f;

View File

@ -48,6 +48,13 @@ namespace Rokojori
return -1;
}
public static T Find<T>( T[] values, Func<T,bool> predicate )
{
var entryIndex = FindIndex( values, predicate );
return entryIndex == -1 ? default(T) : values[ entryIndex ];
}
public static bool Contains <T>( T[] values, T other )
{
return Array.IndexOf( values, other ) != -1;

View File

@ -206,36 +206,70 @@ namespace Rokojori
return index == -1 ? null : fields[ index ];
}
/*public static bool HasMember( object instance, string memberName )
{
return GetFieldInfo( instance, memberName ) != null;
}*/
public static List<MemberInfo> GetDataMemberInfos<T>( object instance )
{
var list = GetDataMemberInfos( instance, BindingFlags.Instance | BindingFlags.Public );
list = Lists.Filter( list, m => IsType<T>( m ) );
return list;
}
public static bool IsType<T>( MemberInfo mi )
{
if ( mi is FieldInfo fi )
{
return fi.FieldType == typeof( T );
}
if ( mi is PropertyInfo pi )
{
return pi.PropertyType == typeof( T );
}
return false;
}
public static List<MemberInfo> GetDataMemberInfos( object instance, BindingFlags flags )
{
var list = new List<MemberInfo>();
var type = instance.GetType();
var searchType = typeof( T );
var fields = type.GetFields( BindingFlags.Public | BindingFlags.Instance );
var fields = type.GetFields( flags );
for ( int i = 0; i < fields.Length; i++ )
{
if ( fields[ i ].FieldType == searchType )
{
list.Add( fields[ i ] );
}
list.Add( fields[ i ] );
}
var properties = type.GetProperties( BindingFlags.Public | BindingFlags.Instance );
var properties = type.GetProperties( flags );
for ( int i = 0; i < properties.Length; i++ )
{
if ( properties[ i ].PropertyType == searchType )
{
list.Add( properties[ i ] );
}
list.Add( properties[ i ] );
}
return list;
}
public static List<MemberInfo> GetDataMemberInfos<T>( BindingFlags flags = defaultBindings )
{
var list = new List<MemberInfo>();
var type = typeof( T );
var fields = type.GetFields( flags );
for ( int i = 0; i < fields.Length; i++ )
{
list.Add( fields[ i ] );
}
var properties = type.GetProperties( flags | BindingFlags.GetProperty | BindingFlags.SetProperty );
for ( int i = 0; i < properties.Length; i++ )
{
list.Add( properties[ i ] );
RJLog.Log( properties[ i ].Name );
}
return list;