Transform/Grass Udpate
This commit is contained in:
parent
4f496cc7cc
commit
7de06b4bcd
|
@ -226,6 +226,18 @@ namespace Rokojori
|
|||
return CreateChildIn<T>( parent, name );
|
||||
}
|
||||
|
||||
public static T GetOrCreateChild<T>( this Node parent, string name = null ) where T:Node,new()
|
||||
{
|
||||
var child = Nodes.GetDirectChild<T>( parent );
|
||||
|
||||
if ( child == null )
|
||||
{
|
||||
child = parent.CreateChild<T>( name );
|
||||
}
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
public static T CreateChildLocal3D<T>( this Node parent, Vector3 position, Quaternion? rotation, string name = null ) where T:Node3D,new()
|
||||
{
|
||||
var c = CreateChildIn<T>( parent, name );
|
||||
|
|
|
@ -78,6 +78,11 @@ namespace Rokojori
|
|||
return new Vector3( v.X, 0, v.Y );
|
||||
}
|
||||
|
||||
public static Vector3 XY( Vector2 v )
|
||||
{
|
||||
return new Vector3( v.X, v.Y, 0.0f );
|
||||
}
|
||||
|
||||
public static float Dot( Vector3 a, Vector3 b )
|
||||
{
|
||||
return a.Dot( b );
|
||||
|
@ -487,6 +492,25 @@ namespace Rokojori
|
|||
node.LookAt( forward + node.GlobalPosition, up );
|
||||
}
|
||||
|
||||
public static bool IsZero( this Quaternion q )
|
||||
{
|
||||
return q.X == 0 && q.Y == 0 && q.Z == 0 && q.W == 0;
|
||||
}
|
||||
|
||||
public static bool IsValid( this Quaternion q )
|
||||
{
|
||||
return ! ( q.IsFinite() || q.IsZero() );
|
||||
}
|
||||
|
||||
public static Quaternion GetNormalized( this Quaternion q )
|
||||
{
|
||||
if ( q.IsValid() )
|
||||
{
|
||||
return Quaternion.Identity;
|
||||
}
|
||||
|
||||
return q.Normalized();
|
||||
}
|
||||
|
||||
public static Quaternion GetDifference( this Quaternion q, Quaternion other )
|
||||
{
|
||||
|
|
|
@ -13,6 +13,11 @@ namespace Rokojori
|
|||
[Export]
|
||||
public float yawOffset = 0;
|
||||
|
||||
[Export]
|
||||
public MeshAxisSubDivider uSubDivisions;
|
||||
[Export]
|
||||
public MeshAxisSubDivider vSubDivisions;
|
||||
|
||||
public override int GetNumViews()
|
||||
{
|
||||
return useDoubleSidedMaterial ? 1 : 2;
|
||||
|
@ -45,6 +50,7 @@ namespace Rokojori
|
|||
|
||||
var angle = yawOffset;
|
||||
|
||||
|
||||
for ( int i = 0; i < numTextures; i++ )
|
||||
{
|
||||
var index = i;
|
||||
|
@ -54,8 +60,15 @@ namespace Rokojori
|
|||
|
||||
var uv = TextureMerger.GetUVRectangle( textureAlignment, index, true );
|
||||
|
||||
|
||||
var q = new MeshGeometry();
|
||||
q.AddQuad( bakerCameras[ index ].viewSettings.bakingRotation, outputScale, uv.min, uv.max );
|
||||
var transform3D = Math3D.TRS( Vector3.Zero, bakerCameras[ index ].viewSettings.bakingRotation, Vector3.One * outputScale );
|
||||
|
||||
|
||||
var uDivisions = MeshAxisSubDivider.GetSubDivisionsU( uSubDivisions, transform3D );
|
||||
var vDivisions = MeshAxisSubDivider.GetSubDivisionsV( vSubDivisions, transform3D );
|
||||
|
||||
q.AddQuadWithCustomDivisions( bakerCameras[ index ].viewSettings.bakingRotation, outputScale, uv.min, uv.max, uDivisions, vDivisions );
|
||||
|
||||
mg.Add( q );
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
|
||||
namespace Rokojori
|
||||
{
|
||||
[Tool]
|
||||
[GlobalClass]
|
||||
public partial class GridSubDivider:MeshAxisSubDivider
|
||||
{
|
||||
[Export]
|
||||
public int numSubDivisions = 1;
|
||||
|
||||
public override List<float> GetSubDivisions( Transform3D quadTransform, Axis axis )
|
||||
{
|
||||
var list = new List<float>();
|
||||
|
||||
for ( int i = 0; i < numSubDivisions; i++ )
|
||||
{
|
||||
float s = (float)( i + 1f ) / (float)( numSubDivisions + 1f );
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
uid://h3oc6p4vkn8o
|
|
@ -0,0 +1,64 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
|
||||
namespace Rokojori
|
||||
{
|
||||
[Tool]
|
||||
[GlobalClass]
|
||||
public partial class ManualAbsoluteSubDivider:MeshAxisSubDivider
|
||||
{
|
||||
public enum SourceAxis
|
||||
{
|
||||
X,
|
||||
Y,
|
||||
Z
|
||||
}
|
||||
|
||||
[Export]
|
||||
public SourceAxis sourceAxis;
|
||||
|
||||
[Export]
|
||||
public float[] subDivisions;
|
||||
|
||||
public override List<float> GetSubDivisions( Transform3D quadTransform, Axis axis )
|
||||
{
|
||||
var min = GetWorldMin( quadTransform );
|
||||
var max = GetWorldMax( quadTransform );
|
||||
|
||||
var minV = min.X;
|
||||
var maxV = max.X;
|
||||
|
||||
if ( SourceAxis.Y == sourceAxis )
|
||||
{
|
||||
minV = min.Y;
|
||||
maxV = max.Y;
|
||||
}
|
||||
if ( SourceAxis.Z == sourceAxis )
|
||||
{
|
||||
minV = min.Z;
|
||||
maxV = max.Z;
|
||||
}
|
||||
|
||||
var list = new List<float>();
|
||||
|
||||
for ( int i = 0; i < subDivisions.Length; i++ )
|
||||
{
|
||||
var mapped = MathX.Normalize( list[ i ], minV, maxV );
|
||||
|
||||
if ( mapped <= 0 || mapped >= 1 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
list.Add( mapped );
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
uid://b8lfjqpaqj8px
|
|
@ -0,0 +1,23 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
|
||||
namespace Rokojori
|
||||
{
|
||||
[Tool]
|
||||
[GlobalClass]
|
||||
public partial class ManualRelativeSubDivider:MeshAxisSubDivider
|
||||
{
|
||||
[Export]
|
||||
public float[] subDivisions;
|
||||
|
||||
public override List<float> GetSubDivisions( Transform3D quadTransform, Axis axis )
|
||||
{
|
||||
return Lists.From( subDivisions );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
uid://bf5p6mxka0yen
|
|
@ -0,0 +1,65 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
|
||||
namespace Rokojori
|
||||
{
|
||||
[Tool]
|
||||
[GlobalClass]
|
||||
public partial class MeshAxisSubDivider:Resource
|
||||
{
|
||||
public enum Axis
|
||||
{
|
||||
U,
|
||||
V
|
||||
}
|
||||
|
||||
public virtual List<float> GetSubDivisions( Transform3D quadTransform, Axis axis )
|
||||
{
|
||||
return new List<float>();
|
||||
}
|
||||
|
||||
public Vector3 GetWorldMin( Transform3D worldTransform )
|
||||
{
|
||||
return worldTransform * new Vector3( -0.5f, -0.5f, 0.0f);
|
||||
}
|
||||
|
||||
public Vector3 GetWorldMax( Transform3D worldTransform )
|
||||
{
|
||||
return worldTransform * new Vector3( 0.5f, 0.5f, 0.0f);
|
||||
}
|
||||
|
||||
public Vector3 AxisToVector( Axis a, float t = 1)
|
||||
{
|
||||
var d = Mathf.Lerp( -0.5f, 0.5f, t );
|
||||
var v = Axis.U == a ? new Vector3( d, 0, 0 ) : new Vector3( 0, d, 0 );
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
public static List<float> GetSubDivisions( MeshAxisSubDivider divider, Transform3D quadTransform, Axis axis )
|
||||
{
|
||||
if ( divider == null )
|
||||
{
|
||||
return new List<float>(){};
|
||||
}
|
||||
|
||||
return divider.GetSubDivisions( quadTransform, axis );
|
||||
}
|
||||
|
||||
public static List<float> GetSubDivisionsU( MeshAxisSubDivider divider, Transform3D quadTransform )
|
||||
{
|
||||
return GetSubDivisions( divider, quadTransform, Axis.U );
|
||||
}
|
||||
|
||||
public static List<float> GetSubDivisionsV( MeshAxisSubDivider divider, Transform3D quadTransform )
|
||||
{
|
||||
return GetSubDivisions( divider, quadTransform, Axis.V );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
uid://bv6l2kx1pkyf1
|
|
@ -36,14 +36,19 @@ namespace Rokojori
|
|||
material.SetShaderParameter( "isFullSphere", octahedralFullSphere );
|
||||
material.SetShaderParameter( "imposterFrames", Vector2.One * octahedralSides );
|
||||
|
||||
Materials.Set( mb.X_outputMesh, material );
|
||||
// Materials.Set( mb.X_outputMesh, material );
|
||||
|
||||
|
||||
MaterialSurfaceContainer.SetMaterialInSlot( mb.X_outputMesh, MaterialSlot.MeshSurface, material );
|
||||
}
|
||||
|
||||
public override void AssignMaterial( List<_XX_BakingPass> passes )
|
||||
{
|
||||
var mb = multiBaker;
|
||||
|
||||
var material = Materials.Get<ShaderMaterial>( mb.X_outputMesh );
|
||||
// var material = Materials.Get<ShaderMaterial>( mb.X_outputMesh );
|
||||
|
||||
var material = MaterialSurfaceContainer.GetMaterialInSlot<ShaderMaterial>( mb.X_outputMesh, MaterialSlot.MeshSurface );
|
||||
|
||||
if ( material == null )
|
||||
{
|
||||
|
|
|
@ -33,13 +33,16 @@ namespace Rokojori
|
|||
material.CullMode = BaseMaterial3D.CullModeEnum.Disabled;
|
||||
}
|
||||
|
||||
Materials.Set( mb.X_outputMesh, material );
|
||||
MaterialSurfaceContainer.SetMaterialInSlot( mb.X_outputMesh, MaterialSlot.MeshSurface, material );
|
||||
|
||||
// Materials.Set( mb.X_outputMesh, material );
|
||||
}
|
||||
|
||||
public override void AssignMaterial( List<_XX_BakingPass> passes )
|
||||
{
|
||||
var mb = multiBaker;
|
||||
var material = Materials.Get<StandardMaterial3D>( mb.X_outputMesh );
|
||||
// var material = Materials.Get<StandardMaterial3D>( mb.X_outputMesh );
|
||||
var material = MaterialSurfaceContainer.GetMaterialInSlot<StandardMaterial3D>( mb.X_outputMesh, MaterialSlot.MeshSurface );
|
||||
|
||||
|
||||
material.AlbedoTexture = _XX_BakingPass.Get( passes, BakingTargetType.Albedo, BakingTargetType.Lit );
|
||||
|
|
|
@ -7,8 +7,6 @@ using System;
|
|||
|
||||
namespace Rokojori
|
||||
{
|
||||
public abstract class MaterialSurfaceContainer
|
||||
{
|
||||
public enum MaterialSlot
|
||||
{
|
||||
None,
|
||||
|
@ -18,6 +16,10 @@ namespace Rokojori
|
|||
Overlay
|
||||
}
|
||||
|
||||
public abstract class MaterialSurfaceContainer
|
||||
{
|
||||
|
||||
|
||||
protected Node3D _owner;
|
||||
protected int _surfaceIndex;
|
||||
public int surfaceIndex => _surfaceIndex;
|
||||
|
@ -29,7 +31,7 @@ namespace Rokojori
|
|||
}
|
||||
|
||||
public abstract MaterialSlot GetActiveMaterialSlot();
|
||||
public abstract Material GetMaterialInSlot( MaterialSlot slot );
|
||||
public abstract T GetMaterialInSlot<T>( MaterialSlot slot ) where T:Material;
|
||||
public abstract void SetMaterialInSlot( MaterialSlot slot, Material material );
|
||||
|
||||
public void SetActiveMaterial( Material material )
|
||||
|
@ -37,9 +39,9 @@ namespace Rokojori
|
|||
SetMaterialInSlot( GetActiveMaterialSlot(), material );
|
||||
}
|
||||
|
||||
public Material GetActiveMaterial()
|
||||
public T GetActiveMaterial<T>() where T:Material
|
||||
{
|
||||
return GetMaterialInSlot( GetActiveMaterialSlot() );
|
||||
return (T)GetMaterialInSlot<T>( GetActiveMaterialSlot() );
|
||||
}
|
||||
|
||||
protected abstract void _MakeUnique( bool materials );
|
||||
|
@ -86,7 +88,48 @@ namespace Rokojori
|
|||
|
||||
public abstract int numSurfaces { get; }
|
||||
|
||||
public static void SetMaterialInSlot( Node3D owner, MaterialSlot slot, Material material, int surfaceIndex = 0 )
|
||||
{
|
||||
var mc = From( owner, surfaceIndex );
|
||||
|
||||
if ( mc == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mc.SetMaterialInSlot( slot, material );
|
||||
}
|
||||
|
||||
public static T GetMaterialInSlot<T>( Node3D owner, MaterialSlot slot, int surfaceIndex = 0 ) where T:Material
|
||||
{
|
||||
var mc = From( owner, surfaceIndex );
|
||||
|
||||
if ( mc == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return mc.GetMaterialInSlot<T>( slot );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static MaterialSurfaceContainer From( Node3D owner, int surfaceIndex = -1 )
|
||||
{
|
||||
if ( owner is MeshInstance3D mesh )
|
||||
{
|
||||
return new MeshSurfaceContainer( mesh, surfaceIndex );
|
||||
}
|
||||
|
||||
if ( owner is MultiMeshInstance3D multi )
|
||||
{
|
||||
return new MultiMeshSurfaceContainer( multi, surfaceIndex );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class MaterialSurfaceContainer<T>:MaterialSurfaceContainer where T:Node3D
|
||||
|
@ -102,26 +145,26 @@ namespace Rokojori
|
|||
|
||||
public override int numSurfaces => node == null || node.Mesh == null ? -1 : node.Mesh.GetSurfaceCount();
|
||||
|
||||
public override MeshSurfaceContainer.MaterialSlot GetActiveMaterialSlot()
|
||||
public override MaterialSlot GetActiveMaterialSlot()
|
||||
{
|
||||
if ( node.MaterialOverride != null )
|
||||
{
|
||||
return MeshSurfaceContainer.MaterialSlot.Override;
|
||||
return MaterialSlot.Override;
|
||||
}
|
||||
|
||||
if ( node.Mesh == null || surfaceIndex == -1 )
|
||||
{
|
||||
return MeshSurfaceContainer.MaterialSlot.None;
|
||||
return MaterialSlot.None;
|
||||
}
|
||||
|
||||
if ( node.GetSurfaceOverrideMaterial( surfaceIndex ) != null )
|
||||
{
|
||||
return MeshSurfaceContainer.MaterialSlot.MeshSurfaceOverride;
|
||||
return MaterialSlot.MeshSurfaceOverride;
|
||||
}
|
||||
|
||||
var material = node.Mesh.SurfaceGetMaterial( surfaceIndex );
|
||||
|
||||
return material == null ? MeshSurfaceContainer.MaterialSlot.None : MeshSurfaceContainer.MaterialSlot.MeshSurface;
|
||||
return material == null ? MaterialSlot.None : MaterialSlot.MeshSurface;
|
||||
}
|
||||
|
||||
public override void SetMaterialInSlot( MaterialSlot slot, Material material )
|
||||
|
@ -149,7 +192,7 @@ namespace Rokojori
|
|||
}
|
||||
}
|
||||
|
||||
public override Material GetMaterialInSlot( MaterialSlot slot )
|
||||
public override T GetMaterialInSlot<T>( MaterialSlot slot )
|
||||
{
|
||||
if ( MaterialSlot.None == slot )
|
||||
{
|
||||
|
@ -157,19 +200,19 @@ namespace Rokojori
|
|||
}
|
||||
else if ( MaterialSlot.MeshSurface == slot )
|
||||
{
|
||||
return node.Mesh.SurfaceGetMaterial( surfaceIndex );
|
||||
return (T) node.Mesh.SurfaceGetMaterial( surfaceIndex );
|
||||
}
|
||||
else if ( MaterialSlot.MeshSurfaceOverride == slot )
|
||||
{
|
||||
return node.GetSurfaceOverrideMaterial( surfaceIndex );
|
||||
return (T) node.GetSurfaceOverrideMaterial( surfaceIndex );
|
||||
}
|
||||
else if ( MaterialSlot.Override == slot )
|
||||
{
|
||||
return node.MaterialOverride;
|
||||
return (T) node.MaterialOverride;
|
||||
}
|
||||
else if ( MaterialSlot.Overlay == slot )
|
||||
{
|
||||
return node.MaterialOverlay;
|
||||
return (T) node.MaterialOverlay;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -210,22 +253,22 @@ namespace Rokojori
|
|||
public override int numSurfaces => node == null || node.Multimesh == null || node.Multimesh.Mesh == null ? -1 :
|
||||
node.Multimesh.Mesh.GetSurfaceCount();
|
||||
|
||||
public override MeshSurfaceContainer.MaterialSlot GetActiveMaterialSlot()
|
||||
public override MaterialSlot GetActiveMaterialSlot()
|
||||
{
|
||||
if ( node.MaterialOverride != null )
|
||||
{
|
||||
return MeshSurfaceContainer.MaterialSlot.Override;
|
||||
return MaterialSlot.Override;
|
||||
}
|
||||
|
||||
if ( node.Multimesh == null || node.Multimesh.Mesh == null || surfaceIndex == -1 )
|
||||
{
|
||||
return MeshSurfaceContainer.MaterialSlot.None;
|
||||
return MaterialSlot.None;
|
||||
}
|
||||
|
||||
|
||||
var material = node.Multimesh.Mesh.SurfaceGetMaterial( surfaceIndex );
|
||||
|
||||
return material == null ? MeshSurfaceContainer.MaterialSlot.None : MeshSurfaceContainer.MaterialSlot.MeshSurface;
|
||||
return material == null ? MaterialSlot.None : MaterialSlot.MeshSurface;
|
||||
}
|
||||
|
||||
public override void SetMaterialInSlot( MaterialSlot slot, Material material )
|
||||
|
@ -249,7 +292,7 @@ namespace Rokojori
|
|||
}
|
||||
}
|
||||
|
||||
public override Material GetMaterialInSlot( MaterialSlot slot )
|
||||
public override T GetMaterialInSlot<T>( MaterialSlot slot )
|
||||
{
|
||||
if ( MaterialSlot.None == slot )
|
||||
{
|
||||
|
@ -257,15 +300,15 @@ namespace Rokojori
|
|||
}
|
||||
else if ( MaterialSlot.MeshSurface == slot )
|
||||
{
|
||||
return node.Multimesh.Mesh.SurfaceGetMaterial( surfaceIndex );
|
||||
return (T) node.Multimesh.Mesh.SurfaceGetMaterial( surfaceIndex );
|
||||
}
|
||||
else if ( MaterialSlot.Override == slot )
|
||||
{
|
||||
return node.MaterialOverride;
|
||||
return (T) node.MaterialOverride;
|
||||
}
|
||||
else if ( MaterialSlot.Overlay == slot )
|
||||
{
|
||||
return node.MaterialOverlay;
|
||||
return (T) node.MaterialOverlay;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
uid://bk3iamd4q3siu
|
|
@ -48,7 +48,7 @@ namespace Rokojori
|
|||
}
|
||||
|
||||
[Export]
|
||||
public TextureSizeMode textureSizeMode = TextureSizeMode.Custom;
|
||||
public TextureSizeMode textureSizeMode = TextureSizeMode.KeepOriginal;
|
||||
|
||||
[Export]
|
||||
public Vector2I customTextureSize = new Vector2I( 1024, 1024 );
|
||||
|
@ -111,14 +111,8 @@ namespace Rokojori
|
|||
|
||||
await CombineMaterials();
|
||||
|
||||
if ( combineMeshes )
|
||||
{
|
||||
await CombineMeshes();
|
||||
}
|
||||
else
|
||||
{
|
||||
await ReassignMaterials();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -176,6 +170,12 @@ namespace Rokojori
|
|||
if ( type == null )
|
||||
{
|
||||
type = MaterialType.From( m );
|
||||
|
||||
if ( type == null )
|
||||
{
|
||||
this.LogInfo( "Invalid Type:", m);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( type == null )
|
||||
|
@ -337,47 +337,6 @@ namespace Rokojori
|
|||
return outputMaterial;
|
||||
}
|
||||
|
||||
async Task ReassignMaterials()
|
||||
{
|
||||
if ( outputContainer == null )
|
||||
{
|
||||
outputContainer = this.CreateChild<Node3D>();
|
||||
}
|
||||
|
||||
outputContainer.DestroyChildren();
|
||||
|
||||
foreach ( var n in sourceNodes )
|
||||
{
|
||||
var root = n.DeepCopyTo( outputContainer );
|
||||
var materialContainers = MeshExtractor.ExtractMaterialContainersInHierarchy( root, null, true );
|
||||
|
||||
materialContainers.ForEach(
|
||||
mc =>
|
||||
{
|
||||
mc.MakeUnique( false );
|
||||
mc.ForAllSurfaces(
|
||||
( surface )=>
|
||||
{
|
||||
var slot = surface.GetActiveMaterialSlot();
|
||||
|
||||
if ( MaterialSurfaceContainer.MaterialSlot.None == slot )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var material = surface.GetActiveMaterial();
|
||||
|
||||
if ( _combinedMaterials.ContainsKey( material ) )
|
||||
{
|
||||
surface.SetActiveMaterial( _combinedMaterials[ material ] );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async Task CombineMeshes()
|
||||
{
|
||||
var arrayMesh = new ArrayMesh();
|
||||
|
@ -390,14 +349,27 @@ namespace Rokojori
|
|||
|
||||
var outputMaterials = new List<Material>();
|
||||
|
||||
if ( ! combineMeshes )
|
||||
{
|
||||
if ( outputContainer == null )
|
||||
{
|
||||
outputContainer = this.CreateChild<Node3D>();
|
||||
}
|
||||
|
||||
outputContainer.DestroyChildren();
|
||||
}
|
||||
|
||||
_materials.ForEach(
|
||||
( m )=>
|
||||
{
|
||||
var isCombinedMaterial = _combinedMaterials.ContainsKey( m );
|
||||
var usedMaterial = isCombinedMaterial ? _combinedMaterials[ m ] : m;
|
||||
|
||||
Transform2D? uvTransform = _uvTransform.ContainsKey( m ) ? _uvTransform[ m ] : null;
|
||||
|
||||
var surfaces = _materiaList[ m ];
|
||||
|
||||
this.LogInfo( "Combining for Material", m, surfaces.Count, "meshes" );
|
||||
this.LogInfo( "Combining for Material", "combined?:",isCombinedMaterial,"material:", usedMaterial, surfaces.Count, "meshes" );
|
||||
|
||||
var meshGeometry = new MeshGeometry();
|
||||
|
||||
|
@ -414,32 +386,54 @@ namespace Rokojori
|
|||
|
||||
var trsf = s.transform;
|
||||
|
||||
if ( combineMeshes )
|
||||
{
|
||||
if ( pivot != null )
|
||||
{
|
||||
trsf.Origin -= pivot.GlobalPosition;
|
||||
}
|
||||
|
||||
smg.ApplyTransform( trsf );
|
||||
}
|
||||
|
||||
|
||||
meshGeometry.Add( smg );
|
||||
|
||||
if ( isCombinedMaterial && ! combineMeshes )
|
||||
{
|
||||
meshGeometry.GenerateMesh( Mesh.PrimitiveType.Triangles, arrayMesh );
|
||||
arrayMesh.SurfaceSetMaterial( index, usedMaterial );
|
||||
|
||||
var meshInstance = outputContainer.CreateChild<MeshInstance3D>();
|
||||
meshInstance.Mesh = arrayMesh;
|
||||
|
||||
meshInstance.GlobalTransform = trsf;
|
||||
|
||||
meshGeometry = new MeshGeometry();
|
||||
arrayMesh = new ArrayMesh();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
var isCombinedMaterial = _combinedMaterials.ContainsKey( m );
|
||||
|
||||
if ( isCombinedMaterial )
|
||||
|
||||
if ( isCombinedMaterial && combineMeshes )
|
||||
{
|
||||
this.LogInfo( "Add material groups", m );
|
||||
combined.Add( _combinedMaterials[ m ], meshGeometry );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
outputMaterials.Add( usedMaterial );
|
||||
|
||||
if ( combineMeshes )
|
||||
{
|
||||
meshGeometry.GenerateMesh( Mesh.PrimitiveType.Triangles, arrayMesh );
|
||||
arrayMesh.SurfaceSetMaterial( index, usedMaterial );
|
||||
|
||||
|
||||
arrayMesh.SurfaceSetMaterial( index, m );
|
||||
outputMaterials.Add( m );
|
||||
index ++;
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
|
@ -468,17 +462,20 @@ namespace Rokojori
|
|||
|
||||
this.LogInfo( "Processing done, adding outputs", arrayMesh.GetSurfaceCount() );
|
||||
|
||||
this.outputMaterials = outputMaterials.ToArray();
|
||||
|
||||
if ( combineMeshes )
|
||||
{
|
||||
if ( outputMesh == null )
|
||||
{
|
||||
this.LogInfo( "Created outputMesh");
|
||||
outputMesh = this.CreateChild<MeshInstance3D>();
|
||||
}
|
||||
|
||||
|
||||
this.outputMaterials = outputMaterials.ToArray();
|
||||
|
||||
outputMesh.Mesh = arrayMesh;
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -158,14 +158,14 @@ namespace Rokojori
|
|||
return list;
|
||||
}
|
||||
|
||||
public static List<Transformable<MeshSurface>> ExtractSurfaces( Node n, List<Transformable<MeshSurface>> list = null, bool trackOwners = false )
|
||||
public static List<Transformable<MeshSurface>> ExtractSurfaces( Node n, List<Transformable<MeshSurface>> list = null )
|
||||
{
|
||||
list = list == null ? new List<Transformable<MeshSurface>>() : list;
|
||||
|
||||
|
||||
if ( n is MeshInstance3D mi )
|
||||
{
|
||||
var owner = trackOwners ? mi : null;
|
||||
var owner = mi;
|
||||
var mesh = mi.Mesh;
|
||||
|
||||
|
||||
|
@ -189,7 +189,7 @@ namespace Rokojori
|
|||
|
||||
if ( n is MultiMeshInstance3D mmi )
|
||||
{
|
||||
var owner = trackOwners ? mmi : null;
|
||||
var owner = mmi;
|
||||
var mm = mmi.Multimesh;
|
||||
|
||||
for ( var j = 0; j < mm.InstanceCount; j++ )
|
||||
|
|
|
@ -660,6 +660,21 @@ namespace Rokojori
|
|||
AddTriangle( va, vb, vc, n, n, n, uv, uv, uv );
|
||||
}
|
||||
|
||||
public void AddQuad(
|
||||
VertexAttributes a,
|
||||
VertexAttributes b,
|
||||
VertexAttributes c,
|
||||
VertexAttributes d
|
||||
)
|
||||
{
|
||||
AddQuad(
|
||||
a.position, b.position, c.position, d.position,
|
||||
(Vector3) a.normal, (Vector3) b.normal, (Vector3) c.normal, (Vector3) d.normal,
|
||||
(Vector2) a.uv, (Vector2) b.uv, (Vector2) c.uv, (Vector2) d.uv
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public void AddQuad(
|
||||
Vector3 va, Vector3 vb, Vector3 vc, Vector3 vd,
|
||||
Vector3 na, Vector3 nb, Vector3 nc, Vector3 nd,
|
||||
|
@ -667,6 +682,18 @@ namespace Rokojori
|
|||
)
|
||||
{
|
||||
|
||||
/*
|
||||
|
||||
0:a -- 1:b
|
||||
| |
|
||||
2:c -- 3:d
|
||||
|
||||
faces:
|
||||
1: 0 1 2
|
||||
2: 2 3 0
|
||||
|
||||
*/
|
||||
|
||||
var index = vertices.Count;
|
||||
|
||||
Lists.Add( vertices, va, vb, vc, vd );
|
||||
|
@ -675,8 +702,10 @@ namespace Rokojori
|
|||
|
||||
Lists.Add( indices, index, index + 1, index + 2 );
|
||||
Lists.Add( indices, index + 2, index + 3, index );
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void AddQuad( Quaternion rotation, float size, Box2 rectangle )
|
||||
{
|
||||
AddQuad( rotation, size, rectangle.min, rectangle.max );
|
||||
|
@ -702,6 +731,112 @@ namespace Rokojori
|
|||
}
|
||||
}
|
||||
|
||||
public void AddQuadWithCustomDivisions( Quaternion rotation, float size, Vector2 uv00, Vector2 uv11, List<float> uDivisions, List<float> vDivisions )
|
||||
{
|
||||
if ( uDivisions.Count == 0 && vDivisions.Count == 0 )
|
||||
{
|
||||
AddQuad( rotation, size, uv00, uv11 );
|
||||
return;
|
||||
}
|
||||
|
||||
var l = size * 0.5f;
|
||||
|
||||
var normal = Vector3.Back * rotation;
|
||||
var points = new List<Vector3>
|
||||
{
|
||||
new Vector3( l, -l, 0 ), new Vector3( -l, -l, 0 ),
|
||||
new Vector3( -l, l, 0 ), new Vector3( l, l, 0 )
|
||||
};
|
||||
|
||||
for ( int i = 0; i < points.Count; i++ )
|
||||
{
|
||||
points[ i ] = points[ i ] * rotation;
|
||||
}
|
||||
|
||||
var uv10 = new Vector2( uv11.X, uv00.Y );
|
||||
var uv01 = new Vector2( uv00.X, uv11.Y );
|
||||
|
||||
var v10 = VertexAttributes.Create( points[ 0 ], uv10, normal );
|
||||
var v00 = VertexAttributes.Create( points[ 1 ], uv00, normal );
|
||||
var v01 = VertexAttributes.Create( points[ 2 ], uv01, normal );
|
||||
var v11 = VertexAttributes.Create( points[ 3 ], uv11, normal );
|
||||
|
||||
var uSegments = new List<float>();
|
||||
uSegments.Add( 0 );
|
||||
uSegments.AddRange( uDivisions );
|
||||
uSegments.Add( 1 );
|
||||
|
||||
var vSegments = new List<float>();
|
||||
vSegments.Add( 0 );
|
||||
vSegments.AddRange( vDivisions );
|
||||
vSegments.Add( 1 );
|
||||
|
||||
for ( int i = 0; i < ( uSegments.Count - 1 ); i++ )
|
||||
{
|
||||
var i0 = uSegments[ i ];
|
||||
var i1 = uSegments[ i + 1 ];
|
||||
|
||||
var t0 = v10.Lerp( v00, i0 );
|
||||
var t1 = v10.Lerp( v00, i1 );
|
||||
|
||||
var b0 = v01.Lerp( v11, i0 );
|
||||
var b1 = v01.Lerp( v11, i1 );
|
||||
|
||||
|
||||
for ( int j = 0; j < ( vSegments.Count - 1 ); j++ )
|
||||
{
|
||||
var j0 = vSegments[ j ];
|
||||
var j1 = vSegments[ j + 1 ];
|
||||
|
||||
var tb00 = t0.Lerp( b0, j0 );
|
||||
var tb10 = t1.Lerp( b1, j0 );
|
||||
|
||||
var tb01 = t0.Lerp( b0, j1 );
|
||||
var tb11 = t1.Lerp( b1, j1 );
|
||||
|
||||
AddQuad( tb10, tb00, tb01, tb11 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void AddQuadSubdivided( Quaternion rotation, float size, Vector2 uv00, Vector2 uv11, int uDivisions = 0, int vDivisions = 0 )
|
||||
{
|
||||
uDivisions = Mathf.Max( 0, uDivisions );
|
||||
vDivisions = Mathf.Max( 0, vDivisions );
|
||||
|
||||
if ( uDivisions == 0 && vDivisions == 0 )
|
||||
{
|
||||
AddQuad( rotation, size, uv00, uv11 );
|
||||
return;
|
||||
}
|
||||
|
||||
var mg = CreateFromUVFunction(
|
||||
( uv ) =>
|
||||
{
|
||||
var xy = uv * size - Vector2.One * size / 2f;
|
||||
|
||||
var pose = new Pose();
|
||||
pose.position = Math3D.XY( xy );
|
||||
pose.rotation = rotation;
|
||||
|
||||
return pose;
|
||||
|
||||
},
|
||||
|
||||
uDivisions + 2, vDivisions + 2
|
||||
);
|
||||
|
||||
var uvTransform = new Transform2D();
|
||||
uvTransform.Origin = uv00;
|
||||
uvTransform = uvTransform.ScaledLocal( uv11 - uv00 );
|
||||
|
||||
mg.ApplyUVTransform( uvTransform );
|
||||
|
||||
Add( mg );
|
||||
}
|
||||
|
||||
public void AddQuad( Quaternion rotation, float size, Vector2 uv00, Vector2 uv11 )
|
||||
{
|
||||
var l = size * 0.5f;
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
|
||||
|
||||
namespace Rokojori
|
||||
{
|
||||
public class VertexAttributes
|
||||
{
|
||||
public Vector3 position;
|
||||
public Vector3? normal;
|
||||
public Vector2? uv;
|
||||
public Vector2? uv2 = null;
|
||||
public Color? color = null;
|
||||
|
||||
public static VertexAttributes Create( Vector3 position, Vector2 uv, Vector3 normal )
|
||||
{
|
||||
var va = new VertexAttributes();
|
||||
va.position = position;
|
||||
va.uv = uv;
|
||||
va.normal = normal;
|
||||
return va;
|
||||
}
|
||||
|
||||
public VertexAttributes Lerp( VertexAttributes other, float t )
|
||||
{
|
||||
var lerped = new VertexAttributes();
|
||||
|
||||
lerped.position = position.Lerp( other.position, t );
|
||||
|
||||
if ( normal != null )
|
||||
{
|
||||
lerped.normal = ((Vector3)normal).Lerp( (Vector3)other.normal, t );
|
||||
}
|
||||
|
||||
if ( uv != null )
|
||||
{
|
||||
lerped.uv = ((Vector2)uv).Lerp( (Vector2)other.uv, t );
|
||||
}
|
||||
|
||||
if ( uv2 != null )
|
||||
{
|
||||
lerped.uv2 = ((Vector2)uv2).Lerp( (Vector2)other.uv2, t );
|
||||
}
|
||||
|
||||
if ( color != null )
|
||||
{
|
||||
lerped.color = ((Color)color).Lerp( (Color)other.color, t );
|
||||
}
|
||||
|
||||
return lerped;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
uid://sskx2gnmrilv
|
|
@ -50,11 +50,11 @@ namespace Rokojori
|
|||
|
||||
if ( useGlobalRotation )
|
||||
{
|
||||
Math3D.SetGlobalRotationTo( node3D, rotation.Normalized() );
|
||||
Math3D.SetGlobalRotationTo( node3D, rotation.GetNormalized() );
|
||||
}
|
||||
else
|
||||
{
|
||||
node3D.Quaternion = rotation;
|
||||
node3D.Quaternion = rotation.GetNormalized();
|
||||
}
|
||||
|
||||
node3D.Scale = scale;
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace Rokojori
|
|||
|
||||
public void CopyFromSampled( TextureCombinerBuffer source, int x, int y, int w, int h )
|
||||
{
|
||||
RJLog.Log( "Copy Sampled", x,y, w, h );
|
||||
// RJLog.Log( "Copy Sampled", x,y, w, h );
|
||||
|
||||
for ( int i = 0; i < w; i ++ )
|
||||
{
|
||||
|
@ -92,7 +92,7 @@ namespace Rokojori
|
|||
var mergeSize = new Vector2( w, h );
|
||||
var gridSize = (Vector2I)( mergeSize / alignment );
|
||||
|
||||
RJLog.Log( "GridMerge" );
|
||||
// RJLog.Log( "GridMerge" );
|
||||
|
||||
for ( int i = 0; i < textures.Count; i++ )
|
||||
{
|
||||
|
@ -101,7 +101,7 @@ namespace Rokojori
|
|||
positions.Add( position );
|
||||
sizes.Add( gridSize );
|
||||
|
||||
RJLog.Log( i, position, gridSize );
|
||||
// RJLog.Log( i, position, gridSize );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
vec4 quaternionFromMatrix( mat3 m )
|
||||
{
|
||||
vec4 qa = vec4( 0.0, 0.0, 0.0, 1.0 );
|
||||
|
||||
float trace = m[ 0 ][ 0 ] + m[ 1 ][ 1 ] + m[ 2 ][ 2 ];
|
||||
|
||||
if ( trace > 0.0 )
|
||||
{
|
||||
|
||||
float s = 0.5 / sqrt( trace + 1.0 );
|
||||
|
||||
qa.w = 0.25 / s;
|
||||
qa.x = ( m[ 1 ][ 2 ] - m[ 2 ][ 1 ] ) * s;
|
||||
qa.y = ( m[ 2 ][ 0 ] - m[ 0 ][ 2 ] ) * s;
|
||||
qa.z = ( m[ 0 ][ 1 ] - m[ 1 ][ 0 ] ) * s;
|
||||
|
||||
}
|
||||
else if ( m[ 0 ][ 0 ] > m[ 1 ][ 1 ] && m[ 0 ][ 0 ] > m[ 2 ][ 2 ] )
|
||||
{
|
||||
|
||||
float s = 2.0 * sqrt( 1.0 + m[ 0 ][ 0 ] - m[ 1 ][ 1 ] - m[ 2 ][ 2 ] );
|
||||
|
||||
qa.w = ( m[ 1 ][ 2 ] - m[ 2 ][ 1 ] ) / s;
|
||||
qa.x = 0.25 * s;
|
||||
qa.y = ( m[ 1 ][ 0 ] + m[ 0 ][ 1 ] ) / s;
|
||||
qa.z = ( m[ 2 ][ 0 ] + m[ 0 ][ 2 ] ) / s;
|
||||
}
|
||||
else if ( m[ 1 ][ 1 ] > m[ 2 ][ 2 ] )
|
||||
{
|
||||
|
||||
float s = 2.0 * sqrt( 1.0 + m[ 1 ][ 1 ] - m[ 0 ][ 0 ] - m[ 2 ][ 2 ] );
|
||||
|
||||
qa.w = ( m[ 2 ][ 0 ] - m[ 0 ][ 2 ] ) / s;
|
||||
qa.x = ( m[ 1 ][ 0 ] + m[ 0 ][ 1 ] ) / s;
|
||||
qa.y = 0.25 * s;
|
||||
qa.z = ( m[ 2 ][ 1 ] + m[ 1 ][ 2 ] ) / s;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
float s = 2.0 * sqrt( 1.0 + m[ 2 ][ 2 ] - m[ 0 ][ 0 ] - m[ 1 ][ 1 ] );
|
||||
|
||||
qa.w = ( m[ 0 ][ 1 ] - m[ 1 ][ 0 ] ) / s;
|
||||
qa.x = ( m[ 2 ][ 0 ] + m[ 0 ][ 2 ] ) / s;
|
||||
qa.y = ( m[ 2 ][ 1 ] + m[ 1 ][ 2 ] ) / s;
|
||||
qa.z = 0.25 * s;
|
||||
}
|
||||
|
||||
return qa;
|
||||
}
|
||||
|
||||
vec4 quaternionMultiply( vec4 a, vec4 b )
|
||||
{
|
||||
|
||||
// from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm
|
||||
|
||||
float qax = a.x;
|
||||
float qay = a.y;
|
||||
float qaz = a.z;
|
||||
float qaw = a.w;
|
||||
|
||||
float qbx = b.x;
|
||||
float qby = b.y;
|
||||
float qbz = b.z;
|
||||
float qbw = b.w;
|
||||
|
||||
vec4 q = vec4( 0.0, 0.0, 0.0, 0.0 );
|
||||
|
||||
q.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
|
||||
q.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
|
||||
q.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
|
||||
q.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
vec4 quaternionSlerp( vec4 qa, vec4 qb, float t )
|
||||
{
|
||||
if ( t == 0.0 )
|
||||
{
|
||||
return qa;
|
||||
}
|
||||
|
||||
if ( t == 1.0 )
|
||||
{
|
||||
return qb;
|
||||
}
|
||||
|
||||
float x = qa.x;
|
||||
float y = qa.y;
|
||||
float z = qa.z;
|
||||
float w = qa.w;
|
||||
|
||||
|
||||
float cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z;
|
||||
|
||||
if ( cosHalfTheta < 0.0 )
|
||||
{
|
||||
qa.w = - qb.w;
|
||||
qa.x = - qb.x;
|
||||
qa.y = - qb.y;
|
||||
qa.z = - qb.z;
|
||||
|
||||
cosHalfTheta = - cosHalfTheta;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
qa = qb;
|
||||
}
|
||||
|
||||
if ( cosHalfTheta >= 1.0 )
|
||||
{
|
||||
|
||||
qa.w = w;
|
||||
qa.x = x;
|
||||
qa.y = y;
|
||||
qa.z = z;
|
||||
|
||||
return qa;
|
||||
}
|
||||
|
||||
float sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta;
|
||||
|
||||
if ( sqrSinHalfTheta <= 0.000001 )
|
||||
{
|
||||
|
||||
float s = 1.0 - t;
|
||||
|
||||
qa.w = s * w + t * qa.w;
|
||||
qa.x = s * x + t * qa.x;
|
||||
qa.y = s * y + t * qa.y;
|
||||
qa.z = s * z + t * qa.z;
|
||||
|
||||
qa = normalize( qa );
|
||||
|
||||
return qa;
|
||||
|
||||
}
|
||||
|
||||
float sinHalfTheta = sqrt( sqrSinHalfTheta );
|
||||
float halfTheta = atan( sinHalfTheta, cosHalfTheta );
|
||||
float ratioA = sin( ( 1.0 - t ) * halfTheta ) / sinHalfTheta;
|
||||
float ratioB = sin( t * halfTheta ) / sinHalfTheta;
|
||||
|
||||
qa.w = ( w * ratioA + qa.w * ratioB );
|
||||
qa.x = ( x * ratioA + qa.x * ratioB );
|
||||
qa.y = ( y * ratioA + qa.y * ratioB );
|
||||
qa.z = ( z * ratioA + qa.z * ratioB );
|
||||
|
||||
return qa;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
uid://c6trfbv30psqx
|
|
@ -1,3 +1,4 @@
|
|||
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Quaternion.gdshaderinc"
|
||||
|
||||
vec3 applyMatrix( vec3 v, mat4 m )
|
||||
{
|
||||
|
@ -43,7 +44,7 @@ vec3 localToViewDirection( vec3 local, mat3 _MODELVIEW_NORMAL_MATRIX )
|
|||
vec3 worldToLocal( vec3 world, mat4 _MODEL_MATRIX )
|
||||
{
|
||||
mat4 inversedMatrix = inverse( _MODEL_MATRIX );
|
||||
return applyMatrix( world, inv );
|
||||
return applyMatrix( world, inversedMatrix );
|
||||
}
|
||||
|
||||
vec3 worldToLocalDirection( vec3 world, mat4 _MODEL_MATRIX )
|
||||
|
@ -142,9 +143,14 @@ vec2 worldToScreen( vec3 world, mat4 _VIEW_MATRIX, mat4 _PROJECTION_MATRIX )
|
|||
}
|
||||
|
||||
|
||||
vec3 extractScale( mat3 _MODEL_NORMAL_MATRIX )
|
||||
vec3 extractTranslation( mat4 matrix )
|
||||
{
|
||||
mat3 m = _MODEL_NORMAL_MATRIX;
|
||||
return vec3( matrix[ 3 ][ 0 ], matrix[ 3 ][ 1 ], matrix[ 3 ][ 2 ] );
|
||||
}
|
||||
|
||||
vec3 extractScale( mat3 matrix )
|
||||
{
|
||||
mat3 m = matrix;
|
||||
|
||||
float x = length( vec3( m[ 0 ][ 0 ], m[ 1 ][ 0 ], m[ 2 ][ 0 ] ) );
|
||||
float y = length( vec3( m[ 0 ][ 1 ], m[ 1 ][ 1 ], m[ 2 ][ 1 ] ) );
|
||||
|
@ -153,6 +159,48 @@ vec3 extractScale( mat3 _MODEL_NORMAL_MATRIX )
|
|||
return vec3( x, y, z );
|
||||
}
|
||||
|
||||
vec3 extractScale( mat4 matrix )
|
||||
{
|
||||
mat4 m = matrix;
|
||||
|
||||
float x = length( vec3( m[ 0 ][ 0 ], m[ 1 ][ 0 ], m[ 2 ][ 0 ] ) );
|
||||
float y = length( vec3( m[ 0 ][ 1 ], m[ 1 ][ 1 ], m[ 2 ][ 1 ] ) );
|
||||
float z = length( vec3( m[ 0 ][ 2 ], m[ 1 ][ 2 ], m[ 2 ][ 2 ] ) );
|
||||
|
||||
return vec3( x, y, z );
|
||||
}
|
||||
|
||||
mat3 extractRotationMatrix( mat4 m )
|
||||
{
|
||||
vec3 x = normalize( m[ 0 ].xyz );
|
||||
vec3 y = normalize( m[ 1 ].xyz );
|
||||
vec3 z = normalize( m[ 2 ].xyz );
|
||||
|
||||
return mat3( x, y, z );
|
||||
}
|
||||
|
||||
vec4 extractQuaternion( mat4 m )
|
||||
{
|
||||
mat3 rotationMatrix = extractRotationMatrix( m );
|
||||
|
||||
return quaternionFromMatrix( rotationMatrix );
|
||||
}
|
||||
|
||||
float extractRotationX( mat4 matrix )
|
||||
{
|
||||
return atan( matrix[2][1], matrix[2][2] );
|
||||
}
|
||||
|
||||
float extractRotationY( mat4 matrix )
|
||||
{
|
||||
return atan(-matrix[2][0], sqrt(matrix[2][1] * matrix[2][1] + matrix[2][2] * matrix[2][2]));
|
||||
}
|
||||
|
||||
float extractRotationZ( mat4 matrix )
|
||||
{
|
||||
return atan(matrix[1][0], matrix[0][0]);
|
||||
}
|
||||
|
||||
vec2 tilingOffset( vec2 uv, vec4 tilingOffset )
|
||||
{
|
||||
uv *= tilingOffset.xy;
|
||||
|
@ -378,13 +426,15 @@ mat4 identity_m4()
|
|||
mat4 translate_m4( vec3 translation )
|
||||
{
|
||||
return mat4(
|
||||
vec4( 1, 0, 0, translation.x ),
|
||||
vec4( 0, 1, 0, translation.y ),
|
||||
vec4( 0, 0, 1, translation.z ),
|
||||
vec4( 0, 0, 0, 1 )
|
||||
vec4( 1, 0, 0, 0 ),
|
||||
vec4( 0, 1, 0, 0 ),
|
||||
vec4( 0, 0, 1, 0 ),
|
||||
vec4( translation.x , translation.y, translation.z, 1 )
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
mat4 scale_m4( vec3 scale )
|
||||
{
|
||||
return mat4(
|
||||
|
@ -403,8 +453,8 @@ mat4 rotationX_m4( float radiansAngle )
|
|||
|
||||
return mat4(
|
||||
vec4( 1, 0, 0, 0 ),
|
||||
vec4( 0, c, -s, 0 ),
|
||||
vec4( 0, s, c, 0 ),
|
||||
vec4( 0, c, s, 0 ),
|
||||
vec4( 0, -s, c, 0 ),
|
||||
vec4( 0, 0, 0, 1 )
|
||||
);
|
||||
}
|
||||
|
@ -415,9 +465,9 @@ mat4 rotationY_m4( float radiansAngle )
|
|||
float s = sin( radiansAngle );
|
||||
|
||||
return mat4(
|
||||
vec4( c, 0, s, 0 ),
|
||||
vec4( c, 0,-s, 0 ),
|
||||
vec4( 0, 1, 0, 0 ),
|
||||
vec4( -s, 0, c, 0 ),
|
||||
vec4( s, 0, c, 0 ),
|
||||
vec4( 0, 0, 0, 1 )
|
||||
);
|
||||
}
|
||||
|
@ -428,9 +478,81 @@ mat4 rotationZ_m4( float radiansAngle )
|
|||
float s = sin( radiansAngle );
|
||||
|
||||
return mat4(
|
||||
vec4( c, -s, 0, 0 ),
|
||||
vec4( s, c, 0, 0 ),
|
||||
vec4( c, s, 0, 0 ),
|
||||
vec4(-s, c, 0, 0 ),
|
||||
vec4( 0, 0, 1, 0 ),
|
||||
vec4( 0, 0, 0, 1 )
|
||||
);
|
||||
}
|
||||
|
||||
mat3 quaternionToRotationMatrix( vec4 q )
|
||||
{
|
||||
float x = q.x;
|
||||
float y = q.y;
|
||||
float z = q.z;
|
||||
float w = q.w;
|
||||
|
||||
float x2 = x + x;
|
||||
float y2 = y + y;
|
||||
float z2 = z + z;
|
||||
|
||||
float xx = x * x2;
|
||||
float xy = x * y2;
|
||||
float xz = x * z2;
|
||||
|
||||
float yy = y * y2;
|
||||
float yz = y * z2;
|
||||
float zz = z * z2;
|
||||
|
||||
float wx = w * x2;
|
||||
float wy = w * y2;
|
||||
float wz = w * z2;
|
||||
|
||||
|
||||
mat3 matrix = mat3(
|
||||
|
||||
vec3(
|
||||
( 1.0 - ( yy + zz ) ),
|
||||
( xy + wz ),
|
||||
( xz - wy )
|
||||
),
|
||||
|
||||
vec3(
|
||||
( xy - wz ),
|
||||
( 1.0 - ( xx + zz ) ),
|
||||
( yz + wx )
|
||||
),
|
||||
|
||||
vec3(
|
||||
( xz + wy ),
|
||||
( yz - wx ),
|
||||
( 1.0 - ( xx + yy ) )
|
||||
)
|
||||
);
|
||||
|
||||
return matrix;
|
||||
|
||||
}
|
||||
|
||||
mat4 TRS( vec3 translation, vec4 rotation, vec3 scale )
|
||||
{
|
||||
return translate_m4( translation ) * mat4( quaternionToRotationMatrix( rotation ) ) * scale_m4( scale );
|
||||
}
|
||||
|
||||
mat4 mixTRS( mat4 a, mat4 b, float t )
|
||||
{
|
||||
vec3 oA = extractTranslation( a );
|
||||
vec3 oB = extractTranslation( b );
|
||||
|
||||
vec3 sA = extractScale( a );
|
||||
vec3 sB = extractScale( b );
|
||||
|
||||
vec4 rA = extractQuaternion( a );
|
||||
vec4 rB = extractQuaternion( b );
|
||||
|
||||
vec3 o = mix( oA, oB, t );
|
||||
vec3 s = mix( sA, sB, t );
|
||||
vec4 r = quaternionSlerp( rA, rB, t );
|
||||
|
||||
return TRS( o, r, s );
|
||||
}
|
|
@ -28,7 +28,7 @@ leftButton = ExtResource("4_nn62x")
|
|||
rightButton = ExtResource("7_r8nl0")
|
||||
upButton = ExtResource("9_sydsp")
|
||||
downButton = ExtResource("2_jknb0")
|
||||
moveSpeed = 1.0
|
||||
moveSpeed = 10.0
|
||||
mouseMovementEnabled = true
|
||||
minimizeDistanceOnMovement = true
|
||||
mouseMovementYawSpeed = 0.2
|
||||
|
|
Loading…
Reference in New Issue