rj-action-library/Runtime/Reallusion/CCImporter.cs

269 lines
7.1 KiB
C#
Raw Normal View History

using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System;
using Godot;
using System.Threading.Tasks;
using System.Text;
namespace Rokojori.Reallusion
{
[Tool]
[GlobalClass]
public partial class CCImporter:Node
{
[Export]
public Node3D characterRoot;
[Export]
public string path;
[Export]
public CCImportConfiguration configuration;
[Export]
public bool addCCMaterialsNode = true;
[Export]
public CCImportSettings importSettings;
[Export]
public CCMaterialGenerator materialGenerator;
[ExportToolButton( "Import")]
public Callable ImportButton => Callable.From(
() =>
{
Import();
}
);
[ExportToolButton( "Set Materials")]
public Callable SetMaterialsButton => Callable.From(
() =>
{
SetMaterials();
}
);
CCImportFile importFile;
public void Import()
{
this.LogInfo( "Loading:", path );
importFile = new CCImportTool().Read( path );
var sb = new StringBuilder();
importFile.messages.ForEach(
( m )=>
{
sb.Append( m.type == MessageType.Error ? "Error: " : "Info: " );
sb.Append( m.content );
sb.Append( "\n" );
}
);
this.LogInfo( sb );
importSettings = new CCImportSettings();
importSettings.configuration = configuration;
var meshIndex = 0;
importFile.ccObject.meshes.ForEach(
( m )=>
{
var meshSettings = new CCMeshSettings();
meshSettings.meshName = m.name;
for ( int i = 0; i < m.materials.Count; i++ )
{
var materialSetting = new CCMaterialSettings();
materialSetting.meshName = m.name;
materialSetting.materialName = m.materials[ i ].name;
materialSetting.materialIndex = i;
materialSetting.materialType = m.materials[ i ].GetMaterialType();
meshSettings.materials = Arrays.AddEntry( meshSettings.materials, materialSetting );
}
importSettings.meshes = Arrays.AddEntry( importSettings.meshes, meshSettings );
meshIndex ++;
}
);
}
public void SetMaterials()
{
var meshIndex = -1;
var ccmaterials = addCCMaterialsNode ? characterRoot.GetOrCreateChild<CCMaterials>( "CC Materials" ) : null;
if ( ccmaterials != null )
{
ccmaterials.Clear();
ccmaterials.root = characterRoot;
}
for ( int i = 0; i < importSettings.meshes.Length; i++ )
{
var ms = importSettings.meshes[ i ];
for ( int j = 0; j < ms.materials.Length; j++ )
{
ms.materials[ j ].configuration = importSettings.configuration;
}
}
if ( importSettings.configuration.setRenderPrioritiesForHair )
{
var renderIndex = 0;
2025-06-27 05:12:53 +00:00
for ( int i = 0; i < importSettings.configuration.preRenderPriorityTargets.Length; i++ )
{
var target = importSettings.configuration.preRenderPriorityTargets[ i ];
var targetName = target.meshName;
var targetIndex = target.materialSurfaceIndex;
var mesh = importSettings.meshes.Find( m => m.meshName == targetName );
if ( mesh == null || targetIndex < 0 || targetIndex > mesh.materials.Length )
{
this.LogInfo( "Mesh not found:",
targetName, ":", targetIndex
);
continue;
}
var material = mesh.materials[ targetIndex ];
material.assignRenderPriority = true;
material.materialRenderPriority = renderIndex;
renderIndex++;
}
for ( int i = 0; i < importSettings.meshes.Length; i++ )
{
var ms = importSettings.meshes[ i ];
for ( int j = 0; j < ms.materials.Length; j++ )
{
if ( ms.materials[ j ].materialType.shaderType == CCMaterialType.CCShaderType.RLHair )
{
ms.materials[ j ].materialRenderPriorityIndexBack = renderIndex;
renderIndex ++;
}
}
}
for ( int i = 0; i < importSettings.meshes.Length; i++ )
{
var ms = importSettings.meshes[ i ];
for ( int j = 0; j < ms.materials.Length; j++ )
{
if ( ms.materials[ j ].materialType.shaderType == CCMaterialType.CCShaderType.RLHair )
{
ms.materials[ j ].materialRenderPriorityIndexFront = renderIndex;
renderIndex ++;
}
}
}
}
importFile.ccObject.meshes.ForEach(
( m )=>
{
meshIndex ++;
var meshSettings = importSettings.meshes[ meshIndex ];
var mesh = characterRoot.FindChild( m.name ) as MeshInstance3D;
if ( mesh == null )
{
return;
}
for ( int i = 0; i < m.materials.Count; i++ )
{
var settings = meshSettings.materials[ i ];
var material = materialGenerator == null ? m.materials[ i ].CreateMaterial( settings ) :
materialGenerator.CreateMaterial( m.materials[ i ], settings );
2025-06-27 05:12:53 +00:00
if ( settings.assignRenderPriority )
{
material.RenderPriority = settings.materialRenderPriority;
}
var overwriteMaterial = settings.configuration.GetOverwriteMaterial( m.name, i );
if ( overwriteMaterial != null )
{
material = overwriteMaterial;
}
mesh.SetSurfaceOverrideMaterial( i, material );
if ( ccmaterials == null )
{
continue;
}
if ( settings.materialType.shaderType == CCMaterialType.CCShaderType.RLHair )
{
var hairMaterial = (CustomMaterial) material;
var materials = Materials.ResolveNextPasses( material );
materials.ForEach( m =>
{
ccmaterials.hairMaterials = Arrays.AddEntry( ccmaterials.hairMaterials, m );
}
);
ccmaterials.hairSpecular.ReadFrom( hairMaterial );
ccmaterials.hairMetallic.ReadFrom( hairMaterial );
ccmaterials.hairRoughness.ReadFrom( hairMaterial );
}
else if (
settings.materialType.shaderType == CCMaterialType.CCShaderType.RLHead ||
settings.materialType.shaderType == CCMaterialType.CCShaderType.RLSkin
)
{
var skinMaterial = (CustomMaterial) material;
var materials = Materials.ResolveNextPasses( material );
materials.ForEach( m =>
{
ccmaterials.skinMaterials = Arrays.AddEntry( ccmaterials.skinMaterials, m );
}
);
ccmaterials.skinAlbedoNoise.ReadFrom( skinMaterial );
ccmaterials.skinAlbedoNoiseOffset.ReadFrom( skinMaterial );
}
}
}
);
}
}
}