mirror of
https://github.com/aelurum/AssetStudio.git
synced 2025-07-14 02:54:16 -04:00
Improve integration with Live2D assets
This commit is contained in:
9
AssetStudioUtility/CubismLive2DExtractor/BlendType.cs
Normal file
9
AssetStudioUtility/CubismLive2DExtractor/BlendType.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace CubismLive2DExtractor
|
||||
{
|
||||
public enum BlendType
|
||||
{
|
||||
Add,
|
||||
Multiply,
|
||||
Overwrite,
|
||||
}
|
||||
}
|
@ -1,24 +1,17 @@
|
||||
namespace CubismLive2DExtractor
|
||||
{
|
||||
public enum BlendType
|
||||
{
|
||||
Add,
|
||||
Multiply,
|
||||
Overwrite,
|
||||
}
|
||||
|
||||
public class CubismExpression3Json
|
||||
{
|
||||
public string Type;
|
||||
public float FadeInTime;
|
||||
public float FadeOutTime;
|
||||
public SerializableExpressionParameter[] Parameters;
|
||||
public string Type { get; set; }
|
||||
public float FadeInTime { get; set; }
|
||||
public float FadeOutTime { get; set; }
|
||||
public SerializableExpressionParameter[] Parameters { get; set; }
|
||||
|
||||
public class SerializableExpressionParameter
|
||||
{
|
||||
public string Id;
|
||||
public float Value;
|
||||
public BlendType Blend;
|
||||
public string Id { get; set; }
|
||||
public float Value { get; set; }
|
||||
public BlendType Blend { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace CubismLive2DExtractor
|
||||
{
|
||||
public sealed class AnimationCurve
|
||||
{
|
||||
public CubismKeyframeData[] m_Curve { get; set; }
|
||||
public int m_PreInfinity { get; set; }
|
||||
public int m_PostInfinity { get; set; }
|
||||
public int m_RotationOrder { get; set; }
|
||||
}
|
||||
|
||||
public sealed class CubismFadeMotion
|
||||
{
|
||||
public string m_Name { get; set; }
|
||||
public string MotionName { get; set; }
|
||||
public float FadeInTime { get; set; }
|
||||
public float FadeOutTime { get; set; }
|
||||
public string[] ParameterIds { get; set; }
|
||||
public AnimationCurve[] ParameterCurves { get; set; }
|
||||
public float[] ParameterFadeInTimes { get; set; }
|
||||
public float[] ParameterFadeOutTimes { get; set; }
|
||||
public float MotionLength { get; set; }
|
||||
|
||||
public CubismFadeMotion()
|
||||
{
|
||||
ParameterIds = Array.Empty<string>();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
namespace CubismLive2DExtractor
|
||||
{
|
||||
public class CubismKeyframeData
|
||||
{
|
||||
public float time { get; set; }
|
||||
public float value { get; set; }
|
||||
public float inSlope { get; set; }
|
||||
public float outSlope { get; set; }
|
||||
public int weightedMode { get; set; }
|
||||
public float inWeight { get; set; }
|
||||
public float outWeight { get; set; }
|
||||
|
||||
public CubismKeyframeData() { }
|
||||
|
||||
public CubismKeyframeData(ImportedKeyframe<float> keyframe)
|
||||
{
|
||||
time = keyframe.time;
|
||||
value = keyframe.value;
|
||||
inSlope = keyframe.inSlope;
|
||||
outSlope = keyframe.outSlope;
|
||||
weightedMode = 0;
|
||||
inWeight = 0;
|
||||
outWeight = 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AssetStudio;
|
||||
|
||||
namespace CubismLive2DExtractor
|
||||
{
|
||||
@ -45,9 +46,9 @@ namespace CubismLive2DExtractor
|
||||
}
|
||||
|
||||
private static void AddSegments(
|
||||
CubismKeyframeData curve,
|
||||
CubismKeyframeData preCurve,
|
||||
CubismKeyframeData nextCurve,
|
||||
Keyframe<float> curve,
|
||||
Keyframe<float> preCurve,
|
||||
Keyframe<float> nextCurve,
|
||||
SerializableCurve cubismCurve,
|
||||
bool forceBezier,
|
||||
ref int totalPointCount,
|
||||
@ -97,7 +98,7 @@ namespace CubismLive2DExtractor
|
||||
totalSegmentCount++;
|
||||
}
|
||||
|
||||
public CubismMotion3Json(CubismFadeMotion fadeMotion, HashSet<string> paramNames, HashSet<string> partNames, bool forceBezier)
|
||||
public CubismMotion3Json(CubismUnityClasses.CubismFadeMotionData fadeMotion, HashSet<string> paramNames, HashSet<string> partNames, bool forceBezier)
|
||||
{
|
||||
Version = 3;
|
||||
Meta = new SerializableMeta
|
||||
@ -151,7 +152,7 @@ namespace CubismLive2DExtractor
|
||||
else
|
||||
{
|
||||
target = paramId.ToLower().Contains("part") ? "PartOpacity" : "Parameter";
|
||||
AssetStudio.Logger.Warning($"[{fadeMotion.m_Name}] Binding error: Unable to find \"{paramId}\" among the model parts/parameters");
|
||||
Logger.Warning($"[{fadeMotion.m_Name}] Binding error: Unable to find \"{paramId}\" among the model parts/parameters");
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -178,7 +179,7 @@ namespace CubismLive2DExtractor
|
||||
var curve = fadeMotion.ParameterCurves[i].m_Curve[j];
|
||||
var preCurve = fadeMotion.ParameterCurves[i].m_Curve[j - 1];
|
||||
var next = fadeMotion.ParameterCurves[i].m_Curve.ElementAtOrDefault(j + 1);
|
||||
var nextCurve = next ?? new CubismKeyframeData();
|
||||
var nextCurve = next ?? new Keyframe<float>();
|
||||
AddSegments(curve, preCurve, nextCurve, Curves[actualCurveCount], forceBezier, ref totalPointCount, ref totalSegmentCount, ref j);
|
||||
}
|
||||
actualCurveCount++;
|
||||
@ -230,10 +231,10 @@ namespace CubismLive2DExtractor
|
||||
};
|
||||
for (var j = 1; j < track.Curve.Count; j++)
|
||||
{
|
||||
var curve = new CubismKeyframeData(track.Curve[j]);
|
||||
var preCurve = new CubismKeyframeData(track.Curve[j - 1]);
|
||||
var curve = CreateKeyFrame(track.Curve[j]);
|
||||
var preCurve = CreateKeyFrame(track.Curve[j - 1]);
|
||||
var next = track.Curve.ElementAtOrDefault(j + 1);
|
||||
var nextCurve = next != null ? new CubismKeyframeData(next) : new CubismKeyframeData();
|
||||
var nextCurve = next != null ? CreateKeyFrame(next) : new Keyframe<float>();
|
||||
AddSegments(curve, preCurve, nextCurve, Curves[i], forceBezier, ref totalPointCount, ref totalSegmentCount, ref j);
|
||||
}
|
||||
totalPointCount++;
|
||||
@ -255,5 +256,19 @@ namespace CubismLive2DExtractor
|
||||
}
|
||||
Meta.TotalUserDataSize = totalUserDataSize;
|
||||
}
|
||||
|
||||
private static Keyframe<float> CreateKeyFrame(ImportedKeyframe<float> iKeyframe)
|
||||
{
|
||||
return new Keyframe<float>
|
||||
{
|
||||
time = iKeyframe.time,
|
||||
value = iKeyframe.value,
|
||||
inSlope = iKeyframe.inSlope,
|
||||
outSlope = iKeyframe.outSlope,
|
||||
weightedMode = 0,
|
||||
inWeight = 0,
|
||||
outWeight = 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,62 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AssetStudio;
|
||||
|
||||
namespace CubismLive2DExtractor
|
||||
{
|
||||
public sealed class CubismObjectList
|
||||
{
|
||||
public static SerializedFile AssetsFile { get; set; }
|
||||
public HashSet<ObjectData> CubismExpressionObjects { get; set; }
|
||||
public HashSet<ObjectData> CubismFadeMotionObjects { get; set; }
|
||||
|
||||
public class ObjectData
|
||||
{
|
||||
private long _pathID;
|
||||
public Object Asset { get; set; }
|
||||
public int m_FileID { get; set; }
|
||||
public long m_PathID
|
||||
{
|
||||
get => _pathID;
|
||||
set
|
||||
{
|
||||
_pathID = value;
|
||||
Asset = GetObjByPathID(_pathID);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is ObjectData objectData && _pathID == objectData.m_PathID;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _pathID.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
public List<MonoBehaviour> GetFadeMotionAssetList()
|
||||
{
|
||||
return CubismFadeMotionObjects?.Where(x => x.Asset != null).Select(x => (MonoBehaviour)x.Asset).ToList();
|
||||
}
|
||||
|
||||
public List<MonoBehaviour> GetExpressionList()
|
||||
{
|
||||
return CubismExpressionObjects?.Where(x => x.Asset != null).Select(x => (MonoBehaviour)x.Asset).ToList();
|
||||
}
|
||||
|
||||
private static Object GetObjByPathID(long pathID)
|
||||
{
|
||||
var assetFileList = AssetsFile.assetsManager.assetsFileList;
|
||||
foreach (var assetFile in assetFileList)
|
||||
{
|
||||
if (assetFile.ObjectsDic.TryGetValue(pathID, out var obj))
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using AssetStudio;
|
||||
using CubismLive2DExtractor.CubismUnityClasses;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace CubismLive2DExtractor
|
||||
@ -10,20 +11,25 @@ namespace CubismLive2DExtractor
|
||||
{
|
||||
public enum CubismMonoBehaviourType
|
||||
{
|
||||
FadeController,
|
||||
FadeMotionList,
|
||||
FadeMotion,
|
||||
ExpressionController,
|
||||
ExpressionList,
|
||||
Expression,
|
||||
Physics,
|
||||
DisplayInfo,
|
||||
PosePart,
|
||||
Model,
|
||||
RenderTexture,
|
||||
}
|
||||
|
||||
public static string ParsePhysics(OrderedDictionary physicsDict)
|
||||
public static string ParsePhysics(OrderedDictionary physicsDict, float motionFps)
|
||||
{
|
||||
var cubismPhysicsRig = JsonConvert.DeserializeObject<CubismPhysics>(JsonConvert.SerializeObject(physicsDict))._rig;
|
||||
var cubismPhysicsRig = JsonConvert.DeserializeObject<CubismPhysics>(JsonConvert.SerializeObject(physicsDict)).Rig;
|
||||
|
||||
var physicsSettings = new CubismPhysics3Json.SerializablePhysicsSettings[cubismPhysicsRig.SubRigs.Length];
|
||||
for (int i = 0; i < physicsSettings.Length; i++)
|
||||
for (var i = 0; i < physicsSettings.Length; i++)
|
||||
{
|
||||
var subRigs = cubismPhysicsRig.SubRigs[i];
|
||||
physicsSettings[i] = new CubismPhysics3Json.SerializablePhysicsSettings
|
||||
@ -48,7 +54,7 @@ namespace CubismLive2DExtractor
|
||||
}
|
||||
}
|
||||
};
|
||||
for (int j = 0; j < subRigs.Input.Length; j++)
|
||||
for (var j = 0; j < subRigs.Input.Length; j++)
|
||||
{
|
||||
var input = subRigs.Input[j];
|
||||
physicsSettings[i].Input[j] = new CubismPhysics3Json.SerializableInput
|
||||
@ -63,7 +69,7 @@ namespace CubismLive2DExtractor
|
||||
Reflect = input.IsInverted
|
||||
};
|
||||
}
|
||||
for (int j = 0; j < subRigs.Output.Length; j++)
|
||||
for (var j = 0; j < subRigs.Output.Length; j++)
|
||||
{
|
||||
var output = subRigs.Output[j];
|
||||
physicsSettings[i].Output[j] = new CubismPhysics3Json.SerializableOutput
|
||||
@ -80,7 +86,7 @@ namespace CubismLive2DExtractor
|
||||
Reflect = output.IsInverted
|
||||
};
|
||||
}
|
||||
for (int j = 0; j < subRigs.Particles.Length; j++)
|
||||
for (var j = 0; j < subRigs.Particles.Length; j++)
|
||||
{
|
||||
var particles = subRigs.Particles[j];
|
||||
physicsSettings[i].Vertices[j] = new CubismPhysics3Json.SerializableVertex
|
||||
@ -94,7 +100,7 @@ namespace CubismLive2DExtractor
|
||||
}
|
||||
}
|
||||
var physicsDictionary = new CubismPhysics3Json.SerializablePhysicsDictionary[physicsSettings.Length];
|
||||
for (int i = 0; i < physicsSettings.Length; i++)
|
||||
for (var i = 0; i < physicsSettings.Length; i++)
|
||||
{
|
||||
physicsDictionary[i] = new CubismPhysics3Json.SerializablePhysicsDictionary
|
||||
{
|
||||
@ -102,6 +108,8 @@ namespace CubismLive2DExtractor
|
||||
Name = $"Dummy{i + 1}"
|
||||
};
|
||||
}
|
||||
|
||||
var fps = cubismPhysicsRig.Fps == 0 ? motionFps : cubismPhysicsRig.Fps;
|
||||
var physicsJson = new CubismPhysics3Json
|
||||
{
|
||||
Version = 3,
|
||||
@ -111,6 +119,7 @@ namespace CubismLive2DExtractor
|
||||
TotalInputCount = cubismPhysicsRig.SubRigs.Sum(x => x.Input.Length),
|
||||
TotalOutputCount = cubismPhysicsRig.SubRigs.Sum(x => x.Output.Length),
|
||||
VertexCount = cubismPhysicsRig.SubRigs.Sum(x => x.Particles.Length),
|
||||
Fps = fps == 0 ? 30f : fps,
|
||||
EffectiveForces = new CubismPhysics3Json.SerializableEffectiveForces
|
||||
{
|
||||
Gravity = cubismPhysicsRig.Gravity,
|
||||
@ -133,12 +142,21 @@ namespace CubismLive2DExtractor
|
||||
var m_Type = m_MonoBehaviour.ConvertToTypeTree(assemblyLoader);
|
||||
switch (cubismMonoBehaviourType)
|
||||
{
|
||||
case CubismMonoBehaviourType.FadeController:
|
||||
fieldName = "cubismfademotionlist";
|
||||
break;
|
||||
case CubismMonoBehaviourType.FadeMotionList:
|
||||
fieldName = "cubismfademotionobjects";
|
||||
break;
|
||||
case CubismMonoBehaviourType.FadeMotion:
|
||||
fieldName = "parameterids";
|
||||
break;
|
||||
case CubismMonoBehaviourType.ExpressionController:
|
||||
fieldName = "expressionslist";
|
||||
break;
|
||||
case CubismMonoBehaviourType.ExpressionList:
|
||||
fieldName = "cubismexpressionobjects";
|
||||
break;
|
||||
case CubismMonoBehaviourType.Expression:
|
||||
fieldName = "parameters";
|
||||
break;
|
||||
@ -151,6 +169,12 @@ namespace CubismLive2DExtractor
|
||||
case CubismMonoBehaviourType.PosePart:
|
||||
fieldName = "groupindex";
|
||||
break;
|
||||
case CubismMonoBehaviourType.Model:
|
||||
fieldName = "_moc";
|
||||
break;
|
||||
case CubismMonoBehaviourType.RenderTexture:
|
||||
fieldName = "_maintexture";
|
||||
break;
|
||||
}
|
||||
if (m_Type.m_Nodes.FindIndex(x => x.m_Name.ToLower() == fieldName) < 0)
|
||||
{
|
||||
|
@ -69,6 +69,7 @@ namespace CubismLive2DExtractor
|
||||
public int TotalInputCount;
|
||||
public int TotalOutputCount;
|
||||
public int VertexCount;
|
||||
public float Fps;
|
||||
public SerializableEffectiveForces EffectiveForces;
|
||||
public SerializablePhysicsDictionary[] PhysicsDictionary;
|
||||
}
|
||||
|
@ -1,75 +0,0 @@
|
||||
using AssetStudio;
|
||||
|
||||
namespace CubismLive2DExtractor
|
||||
{
|
||||
public class CubismPhysicsNormalizationTuplet
|
||||
{
|
||||
public float Maximum;
|
||||
public float Minimum;
|
||||
public float Default;
|
||||
}
|
||||
|
||||
public class CubismPhysicsNormalization
|
||||
{
|
||||
public CubismPhysicsNormalizationTuplet Position;
|
||||
public CubismPhysicsNormalizationTuplet Angle;
|
||||
}
|
||||
|
||||
public class CubismPhysicsParticle
|
||||
{
|
||||
public Vector2 InitialPosition;
|
||||
public float Mobility;
|
||||
public float Delay;
|
||||
public float Acceleration;
|
||||
public float Radius;
|
||||
}
|
||||
|
||||
public class CubismPhysicsOutput
|
||||
{
|
||||
public string DestinationId;
|
||||
public int ParticleIndex;
|
||||
public Vector2 TranslationScale;
|
||||
public float AngleScale;
|
||||
public float Weight;
|
||||
public CubismPhysicsSourceComponent SourceComponent;
|
||||
public bool IsInverted;
|
||||
}
|
||||
|
||||
public enum CubismPhysicsSourceComponent
|
||||
{
|
||||
X,
|
||||
Y,
|
||||
Angle,
|
||||
}
|
||||
|
||||
public class CubismPhysicsInput
|
||||
{
|
||||
public string SourceId;
|
||||
public Vector2 ScaleOfTranslation;
|
||||
public float AngleScale;
|
||||
public float Weight;
|
||||
public CubismPhysicsSourceComponent SourceComponent;
|
||||
public bool IsInverted;
|
||||
}
|
||||
|
||||
public class CubismPhysicsSubRig
|
||||
{
|
||||
public CubismPhysicsInput[] Input;
|
||||
public CubismPhysicsOutput[] Output;
|
||||
public CubismPhysicsParticle[] Particles;
|
||||
public CubismPhysicsNormalization Normalization;
|
||||
}
|
||||
|
||||
public class CubismPhysicsRig
|
||||
{
|
||||
public CubismPhysicsSubRig[] SubRigs;
|
||||
public Vector2 Gravity = new Vector2(0, -1);
|
||||
public Vector2 Wind;
|
||||
}
|
||||
|
||||
public class CubismPhysics
|
||||
{
|
||||
public string m_Name;
|
||||
public CubismPhysicsRig _rig;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
using AssetStudio;
|
||||
|
||||
namespace CubismLive2DExtractor.CubismUnityClasses
|
||||
{
|
||||
public sealed class CubismExpressionData : MonoBehaviour
|
||||
{
|
||||
public string Type { get; set; }
|
||||
public float FadeInTime { get; set; }
|
||||
public float FadeOutTime { get; set; }
|
||||
public SerializableExpressionParameter[] Parameters { get; set; }
|
||||
|
||||
public class SerializableExpressionParameter
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public float Value { get; set; }
|
||||
public BlendType Blend { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
using AssetStudio;
|
||||
|
||||
namespace CubismLive2DExtractor.CubismUnityClasses
|
||||
{
|
||||
public sealed class CubismExpressionList : MonoBehaviour
|
||||
{
|
||||
public PPtr<CubismExpressionData>[] CubismExpressionObjects { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using AssetStudio;
|
||||
|
||||
namespace CubismLive2DExtractor.CubismUnityClasses
|
||||
{
|
||||
public sealed class CubismFadeMotionData : MonoBehaviour
|
||||
{
|
||||
public string MotionName { get; set; }
|
||||
public float FadeInTime { get; set; }
|
||||
public float FadeOutTime { get; set; }
|
||||
public string[] ParameterIds { get; set; } = Array.Empty<string>();
|
||||
public AnimationCurve<float>[] ParameterCurves { get; set; }
|
||||
public float[] ParameterFadeInTimes { get; set; }
|
||||
public float[] ParameterFadeOutTimes { get; set; }
|
||||
public float MotionLength { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
using AssetStudio;
|
||||
|
||||
namespace CubismLive2DExtractor.CubismUnityClasses
|
||||
{
|
||||
public sealed class CubismFadeMotionList : MonoBehaviour
|
||||
{
|
||||
public int[] MotionInstanceIds { get; set; }
|
||||
public PPtr<CubismFadeMotionData>[] CubismFadeMotionObjects { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
using AssetStudio;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace CubismLive2DExtractor.CubismUnityClasses
|
||||
{
|
||||
public class CubismPhysicsNormalizationTuplet
|
||||
{
|
||||
public float Maximum { get; set; }
|
||||
public float Minimum { get; set; }
|
||||
public float Default { get; set; }
|
||||
}
|
||||
|
||||
public class CubismPhysicsNormalization
|
||||
{
|
||||
public CubismPhysicsNormalizationTuplet Position { get; set; }
|
||||
public CubismPhysicsNormalizationTuplet Angle { get; set; }
|
||||
}
|
||||
|
||||
public class CubismPhysicsParticle
|
||||
{
|
||||
public Vector2 InitialPosition { get; set; }
|
||||
public float Mobility { get; set; }
|
||||
public float Delay { get; set; }
|
||||
public float Acceleration { get; set; }
|
||||
public float Radius { get; set; }
|
||||
}
|
||||
|
||||
public class CubismPhysicsOutput
|
||||
{
|
||||
public string DestinationId { get; set; }
|
||||
public int ParticleIndex { get; set; }
|
||||
public Vector2 TranslationScale { get; set; }
|
||||
public float AngleScale { get; set; }
|
||||
public float Weight { get; set; }
|
||||
public CubismPhysicsSourceComponent SourceComponent { get; set; }
|
||||
public bool IsInverted { get; set; }
|
||||
}
|
||||
|
||||
public enum CubismPhysicsSourceComponent
|
||||
{
|
||||
X,
|
||||
Y,
|
||||
Angle,
|
||||
}
|
||||
|
||||
public class CubismPhysicsInput
|
||||
{
|
||||
public string SourceId { get; set; }
|
||||
public Vector2 ScaleOfTranslation { get; set; }
|
||||
public float AngleScale { get; set; }
|
||||
public float Weight { get; set; }
|
||||
public CubismPhysicsSourceComponent SourceComponent { get; set; }
|
||||
public bool IsInverted { get; set; }
|
||||
}
|
||||
|
||||
public class CubismPhysicsSubRig
|
||||
{
|
||||
public CubismPhysicsInput[] Input { get; set; }
|
||||
public CubismPhysicsOutput[] Output { get; set; }
|
||||
public CubismPhysicsParticle[] Particles { get; set; }
|
||||
public CubismPhysicsNormalization Normalization { get; set; }
|
||||
}
|
||||
|
||||
public class CubismPhysicsRig
|
||||
{
|
||||
public CubismPhysicsSubRig[] SubRigs { get; set; }
|
||||
public Vector2 Gravity { get; set; } = new Vector2(0, -1);
|
||||
public Vector2 Wind { get; set; }
|
||||
public float Fps { get; set; }
|
||||
}
|
||||
|
||||
public sealed class CubismPhysics : MonoBehaviour
|
||||
{
|
||||
[JsonProperty("_rig")]
|
||||
public CubismPhysicsRig Rig { get; set; }
|
||||
}
|
||||
}
|
@ -6,41 +6,46 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using AssetStudio;
|
||||
using CubismLive2DExtractor.CubismUnityClasses;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using static CubismLive2DExtractor.CubismParsers;
|
||||
using Object = AssetStudio.Object;
|
||||
|
||||
namespace CubismLive2DExtractor
|
||||
{
|
||||
public sealed class Live2DExtractor
|
||||
{
|
||||
private List<MonoBehaviour> Expressions { get; set; }
|
||||
public static Dictionary<MonoBehaviour, CubismModel> MocDict { get; set; }
|
||||
public static AssemblyLoader Assembly { get; set; }
|
||||
public CubismModel Model { get; set; }
|
||||
private List<MonoBehaviour> FadeMotions { get; set; }
|
||||
private List<GameObject> GameObjects { get; set; }
|
||||
private List<AnimationClip> AnimationClips { get; set; }
|
||||
private List<Texture2D> Texture2Ds { get; set; }
|
||||
private HashSet<string> EyeBlinkParameters { get; set; }
|
||||
private HashSet<string> LipSyncParameters { get; set; }
|
||||
private HashSet<string> ParameterNames { get; set; }
|
||||
private HashSet<string> PartNames { get; set; }
|
||||
private MonoBehaviour MocMono { get; set; }
|
||||
private MonoBehaviour PhysicsMono { get; set; }
|
||||
private MonoBehaviour FadeMotionLst { get; set; }
|
||||
private List<MonoBehaviour> Expressions { get; set; }
|
||||
private List<MonoBehaviour> ParametersCdi { get; set; }
|
||||
private List<MonoBehaviour> PartsCdi { get; set; }
|
||||
private List<MonoBehaviour> PoseParts { get; set; }
|
||||
private List<Texture2D> Texture2Ds { get; set; }
|
||||
public MonoBehaviour MocMono { get; set; }
|
||||
private MonoBehaviour PhysicsMono { get; set; }
|
||||
private MonoBehaviour FadeMotionLst { get; set; }
|
||||
private MonoBehaviour ExpressionLst { get; set; }
|
||||
private HashSet<string> ParameterNames { get; set; }
|
||||
private HashSet<string> PartNames { get; set; }
|
||||
private HashSet<string> EyeBlinkParameters { get; set; }
|
||||
private HashSet<string> LipSyncParameters { get; set; }
|
||||
|
||||
public Live2DExtractor(IGrouping<string, AssetStudio.Object> assets, List<AnimationClip> inClipMotions = null, List<MonoBehaviour> inFadeMotions = null, MonoBehaviour inFadeMotionLst = null)
|
||||
public Live2DExtractor(List<Object> assets, List<AnimationClip> inClipMotions = null, List<MonoBehaviour> inFadeMotions = null, MonoBehaviour inFadeMotionLst = null)
|
||||
{
|
||||
Expressions = new List<MonoBehaviour>();
|
||||
FadeMotions = inFadeMotions ?? new List<MonoBehaviour>();
|
||||
AnimationClips = inClipMotions ?? new List<AnimationClip>();
|
||||
GameObjects = new List<GameObject>();
|
||||
Texture2Ds = new List<Texture2D>();
|
||||
EyeBlinkParameters = new HashSet<string>();
|
||||
LipSyncParameters = new HashSet<string>();
|
||||
@ -50,6 +55,12 @@ namespace CubismLive2DExtractor
|
||||
ParametersCdi = new List<MonoBehaviour>();
|
||||
PartsCdi = new List<MonoBehaviour>();
|
||||
PoseParts = new List<MonoBehaviour>();
|
||||
var renderTextureSet = new HashSet<Texture2D>();
|
||||
var isRenderReadable = true;
|
||||
var searchRenderTextures = true;
|
||||
var searchModelParamCdi = true;
|
||||
var searchModelPartCdi = true;
|
||||
var searchPoseParts = true;
|
||||
|
||||
Logger.Debug("Sorting model assets..");
|
||||
foreach (var asset in assets)
|
||||
@ -63,12 +74,53 @@ namespace CubismLive2DExtractor
|
||||
{
|
||||
case "CubismMoc":
|
||||
MocMono = m_MonoBehaviour;
|
||||
Model = MocDict[MocMono];
|
||||
if (Model != null)
|
||||
{
|
||||
PhysicsMono = Model.PhysicsController;
|
||||
if (inFadeMotionLst == null && TryGetFadeList(Model.FadeController, out var fadeMono))
|
||||
{
|
||||
FadeMotionLst = inFadeMotionLst = fadeMono;
|
||||
}
|
||||
if (TryGetExpressionList(Model.ExpressionController, out var expressionMono))
|
||||
{
|
||||
ExpressionLst = expressionMono;
|
||||
}
|
||||
if (Model.RenderTextureList.Count > 0)
|
||||
{
|
||||
var renderList = Model.RenderTextureList;
|
||||
foreach (var renderMono in renderList)
|
||||
{
|
||||
if (!TryGetRenderTexture(renderMono, out var tex))
|
||||
break;
|
||||
renderTextureSet.Add(tex);
|
||||
}
|
||||
searchRenderTextures = renderTextureSet.Count == 0;
|
||||
}
|
||||
if (Model.ParamDisplayInfoList.Count > 0)
|
||||
{
|
||||
ParametersCdi = Model.ParamDisplayInfoList;
|
||||
searchModelParamCdi = false;
|
||||
}
|
||||
if (Model.PartDisplayInfoList.Count > 0)
|
||||
{
|
||||
PartsCdi = Model.PartDisplayInfoList;
|
||||
searchModelPartCdi = false;
|
||||
}
|
||||
if (Model.PosePartList.Count > 0)
|
||||
{
|
||||
PoseParts = Model.PosePartList;
|
||||
searchPoseParts = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "CubismPhysicsController":
|
||||
PhysicsMono = m_MonoBehaviour;
|
||||
if (PhysicsMono == null)
|
||||
PhysicsMono = m_MonoBehaviour;
|
||||
break;
|
||||
case "CubismExpressionData":
|
||||
Expressions.Add(m_MonoBehaviour);
|
||||
if (ExpressionLst == null)
|
||||
Expressions.Add(m_MonoBehaviour);
|
||||
break;
|
||||
case "CubismFadeMotionData":
|
||||
if (inFadeMotions == null && inFadeMotionLst == null)
|
||||
@ -107,23 +159,31 @@ namespace CubismLive2DExtractor
|
||||
}
|
||||
break;
|
||||
case "CubismDisplayInfoParameterName":
|
||||
if (m_MonoBehaviour.m_GameObject.TryGet(out _))
|
||||
if (searchModelParamCdi && m_MonoBehaviour.m_GameObject.TryGet(out _))
|
||||
{
|
||||
ParametersCdi.Add(m_MonoBehaviour);
|
||||
}
|
||||
break;
|
||||
case "CubismDisplayInfoPartName":
|
||||
if (m_MonoBehaviour.m_GameObject.TryGet(out _))
|
||||
if (searchModelPartCdi && m_MonoBehaviour.m_GameObject.TryGet(out _))
|
||||
{
|
||||
PartsCdi.Add(m_MonoBehaviour);
|
||||
}
|
||||
break;
|
||||
case "CubismPosePart":
|
||||
if (m_MonoBehaviour.m_GameObject.TryGet(out _))
|
||||
if (searchPoseParts && m_MonoBehaviour.m_GameObject.TryGet(out _))
|
||||
{
|
||||
PoseParts.Add(m_MonoBehaviour);
|
||||
}
|
||||
break;
|
||||
case "CubismRenderer":
|
||||
if (searchRenderTextures && isRenderReadable)
|
||||
{
|
||||
isRenderReadable = TryGetRenderTexture(m_MonoBehaviour, out var renderTex);
|
||||
if (isRenderReadable)
|
||||
renderTextureSet.Add(renderTex);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -133,41 +193,43 @@ namespace CubismLive2DExtractor
|
||||
AnimationClips.Add(m_AnimationClip);
|
||||
}
|
||||
break;
|
||||
case GameObject m_GameObject:
|
||||
GameObjects.Add(m_GameObject);
|
||||
break;
|
||||
case Texture2D m_Texture2D:
|
||||
Texture2Ds.Add(m_Texture2D);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (renderTextureSet.Count > 0)
|
||||
{
|
||||
Texture2Ds = renderTextureSet.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public void ExtractCubismModel(string destPath, string modelName, Live2DMotionMode motionMode, AssemblyLoader assemblyLoader, bool forceBezier = false, int parallelTaskCount = 1)
|
||||
public void ExtractCubismModel(string destPath, Live2DMotionMode motionMode, bool forceBezier = false, int parallelTaskCount = 1)
|
||||
{
|
||||
Directory.CreateDirectory(destPath);
|
||||
var modelName = Model?.Name ?? "model";
|
||||
|
||||
#region moc3
|
||||
using (var cubismModel = new CubismModel(MocMono))
|
||||
using (var cubismMoc = new CubismMoc(MocMono))
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("Model Stats:");
|
||||
sb.AppendLine($"SDK Version: {cubismModel.VersionDescription}");
|
||||
if (cubismModel.Version > 0)
|
||||
sb.AppendLine($"SDK Version: {cubismMoc.VersionDescription}");
|
||||
if (cubismMoc.Version > 0)
|
||||
{
|
||||
sb.AppendLine($"Canvas Width: {cubismModel.CanvasWidth}");
|
||||
sb.AppendLine($"Canvas Height: {cubismModel.CanvasHeight}");
|
||||
sb.AppendLine($"Center X: {cubismModel.CentralPosX}");
|
||||
sb.AppendLine($"Center Y: {cubismModel.CentralPosY}");
|
||||
sb.AppendLine($"Pixel Per Unit: {cubismModel.PixelPerUnit}");
|
||||
sb.AppendLine($"Part Count: {cubismModel.PartCount}");
|
||||
sb.AppendLine($"Parameter Count: {cubismModel.ParamCount}");
|
||||
sb.AppendLine($"Canvas Width: {cubismMoc.CanvasWidth}");
|
||||
sb.AppendLine($"Canvas Height: {cubismMoc.CanvasHeight}");
|
||||
sb.AppendLine($"Center X: {cubismMoc.CentralPosX}");
|
||||
sb.AppendLine($"Center Y: {cubismMoc.CentralPosY}");
|
||||
sb.AppendLine($"Pixel Per Unit: {cubismMoc.PixelPerUnit}");
|
||||
sb.AppendLine($"Part Count: {cubismMoc.PartCount}");
|
||||
sb.AppendLine($"Parameter Count: {cubismMoc.ParamCount}");
|
||||
Logger.Debug(sb.ToString());
|
||||
|
||||
ParameterNames = cubismModel.ParamNames;
|
||||
PartNames = cubismModel.PartNames;
|
||||
ParameterNames = cubismMoc.ParamNames;
|
||||
PartNames = cubismMoc.PartNames;
|
||||
}
|
||||
cubismModel.SaveMoc3($"{destPath}{modelName}.moc3");
|
||||
cubismMoc.SaveMoc3($"{destPath}{modelName}.moc3");
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -204,34 +266,13 @@ namespace CubismLive2DExtractor
|
||||
textures.UnionWith(textureBag);
|
||||
#endregion
|
||||
|
||||
#region physics3.json
|
||||
var isPhysicsExported = false;
|
||||
if (PhysicsMono != null)
|
||||
{
|
||||
var physicsDict = ParseMonoBehaviour(PhysicsMono, CubismMonoBehaviourType.Physics, assemblyLoader);
|
||||
if (physicsDict != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var buff = ParsePhysics(physicsDict);
|
||||
File.WriteAllText($"{destPath}{modelName}.physics3.json", buff);
|
||||
isPhysicsExported = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Warning($"Error in parsing physics data: {e.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region cdi3.json
|
||||
var isCdiExported = false;
|
||||
if (ParametersCdi.Count > 0 || PartsCdi.Count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
isCdiExported = ExportCdiJson(destPath, modelName, assemblyLoader);
|
||||
isCdiExported = ExportCdiJson(destPath, modelName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -243,26 +284,34 @@ namespace CubismLive2DExtractor
|
||||
#region motion3.json
|
||||
var motions = new SortedDictionary<string, JArray>();
|
||||
var destMotionPath = Path.Combine(destPath, "motions") + Path.DirectorySeparatorChar;
|
||||
var motionFps = 0f;
|
||||
|
||||
if (motionMode == Live2DMotionMode.MonoBehaviour && FadeMotionLst != null) //Fade motions from Fade Motion List
|
||||
{
|
||||
Logger.Debug("Motion export method: MonoBehaviour (Fade motion)");
|
||||
var fadeMotionLstDict = ParseMonoBehaviour(FadeMotionLst, CubismMonoBehaviourType.FadeMotionList, assemblyLoader);
|
||||
var fadeMotionLstDict = ParseMonoBehaviour(FadeMotionLst, CubismMonoBehaviourType.FadeMotionList, Assembly);
|
||||
if (fadeMotionLstDict != null)
|
||||
{
|
||||
CubismObjectList.AssetsFile = FadeMotionLst.assetsFile;
|
||||
var fadeMotionAssetList = JsonConvert.DeserializeObject<CubismObjectList>(JsonConvert.SerializeObject(fadeMotionLstDict)).GetFadeMotionAssetList();
|
||||
if (fadeMotionAssetList?.Count > 0)
|
||||
var cubismFadeList = JsonConvert.DeserializeObject<CubismFadeMotionList>(JsonConvert.SerializeObject(fadeMotionLstDict));
|
||||
var fadeMotionAssetList = new List<MonoBehaviour>();
|
||||
foreach (var motionPPtr in cubismFadeList.CubismFadeMotionObjects)
|
||||
{
|
||||
if (motionPPtr.TryGet<MonoBehaviour>(out var fadeMono, FadeMotionLst.assetsFile))
|
||||
{
|
||||
fadeMotionAssetList.Add(fadeMono);
|
||||
}
|
||||
}
|
||||
|
||||
if (fadeMotionAssetList.Count > 0)
|
||||
{
|
||||
FadeMotions = fadeMotionAssetList;
|
||||
Logger.Debug($"\"{FadeMotionLst.m_Name}\": found {fadeMotionAssetList.Count} motion(s)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (motionMode == Live2DMotionMode.MonoBehaviour && FadeMotions.Count > 0) //motion from MonoBehaviour
|
||||
{
|
||||
ExportFadeMotions(destMotionPath, assemblyLoader, forceBezier, motions);
|
||||
ExportFadeMotions(destMotionPath, forceBezier, motions, ref motionFps);
|
||||
}
|
||||
|
||||
if (motions.Count == 0) //motion from AnimationClip
|
||||
@ -274,16 +323,10 @@ namespace CubismLive2DExtractor
|
||||
exportMethod += "V2";
|
||||
converter = new CubismMotion3Converter(AnimationClips, PartNames, ParameterNames);
|
||||
}
|
||||
else if (GameObjects.Count > 0) //AnimationClipV1
|
||||
else if (Model?.ModelGameObject != null) //AnimationClipV1
|
||||
{
|
||||
exportMethod += "V1";
|
||||
var rootTransform = GameObjects[0].m_Transform;
|
||||
while (rootTransform.m_Father.TryGet(out var m_Father))
|
||||
{
|
||||
rootTransform = m_Father;
|
||||
}
|
||||
rootTransform.m_GameObject.TryGet(out var rootGameObject);
|
||||
converter = new CubismMotion3Converter(rootGameObject, AnimationClips);
|
||||
converter = new CubismMotion3Converter(Model.ModelGameObject, AnimationClips);
|
||||
}
|
||||
|
||||
if (motionMode == Live2DMotionMode.MonoBehaviour)
|
||||
@ -294,7 +337,7 @@ namespace CubismLive2DExtractor
|
||||
}
|
||||
Logger.Debug($"Motion export method: {exportMethod}");
|
||||
|
||||
ExportClipMotions(destMotionPath, converter, forceBezier, motions);
|
||||
ExportClipMotions(destMotionPath, converter, forceBezier, motions, ref motionFps);
|
||||
}
|
||||
|
||||
if (motions.Count == 0)
|
||||
@ -311,6 +354,30 @@ namespace CubismLive2DExtractor
|
||||
var expressions = new JArray();
|
||||
var destExpressionPath = Path.Combine(destPath, "expressions") + Path.DirectorySeparatorChar;
|
||||
|
||||
if (ExpressionLst != null) //Expressions from Expression List
|
||||
{
|
||||
Logger.Debug("Parsing expression list..");
|
||||
var expLstDict = ParseMonoBehaviour(ExpressionLst, CubismMonoBehaviourType.ExpressionList, Assembly);
|
||||
if (expLstDict != null)
|
||||
{
|
||||
var cubismExpList = JsonConvert.DeserializeObject<CubismExpressionList>(JsonConvert.SerializeObject(expLstDict));
|
||||
var expAssetList = new List<MonoBehaviour>();
|
||||
foreach (var expPPtr in cubismExpList.CubismExpressionObjects)
|
||||
{
|
||||
if (expPPtr.TryGet<MonoBehaviour>(out var expMono, ExpressionLst.assetsFile))
|
||||
{
|
||||
expAssetList.Add(expMono);
|
||||
}
|
||||
}
|
||||
|
||||
if (expAssetList.Count > 0)
|
||||
{
|
||||
Expressions = expAssetList;
|
||||
Logger.Debug($"\"{ExpressionLst.m_Name}\": found {expAssetList.Count} expression(s)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Expressions.Count > 0)
|
||||
{
|
||||
Directory.CreateDirectory(destExpressionPath);
|
||||
@ -318,7 +385,7 @@ namespace CubismLive2DExtractor
|
||||
foreach (var monoBehaviour in Expressions)
|
||||
{
|
||||
var expressionName = monoBehaviour.m_Name.Replace(".exp3", "");
|
||||
var expressionDict = ParseMonoBehaviour(monoBehaviour, CubismMonoBehaviourType.Expression, assemblyLoader);
|
||||
var expressionDict = ParseMonoBehaviour(monoBehaviour, CubismMonoBehaviourType.Expression, Assembly);
|
||||
if (expressionDict == null)
|
||||
continue;
|
||||
|
||||
@ -339,7 +406,7 @@ namespace CubismLive2DExtractor
|
||||
{
|
||||
try
|
||||
{
|
||||
isPoseExported = ExportPoseJson(destPath, modelName, assemblyLoader);
|
||||
isPoseExported = ExportPoseJson(destPath, modelName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -348,6 +415,27 @@ namespace CubismLive2DExtractor
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region physics3.json
|
||||
var isPhysicsExported = false;
|
||||
if (PhysicsMono != null)
|
||||
{
|
||||
var physicsDict = ParseMonoBehaviour(PhysicsMono, CubismMonoBehaviourType.Physics, Assembly);
|
||||
if (physicsDict != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var buff = ParsePhysics(physicsDict, motionFps);
|
||||
File.WriteAllText($"{destPath}{modelName}.physics3.json", buff);
|
||||
isPhysicsExported = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Warning($"Error in parsing physics data: {e.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region model3.json
|
||||
var groups = new List<CubismModel3Json.SerializableGroup>();
|
||||
|
||||
@ -402,20 +490,21 @@ namespace CubismLive2DExtractor
|
||||
#endregion
|
||||
}
|
||||
|
||||
private void ExportFadeMotions(string destMotionPath, AssemblyLoader assemblyLoader, bool forceBezier, SortedDictionary<string, JArray> motions)
|
||||
private void ExportFadeMotions(string destMotionPath, bool forceBezier, SortedDictionary<string, JArray> motions, ref float fps)
|
||||
{
|
||||
Directory.CreateDirectory(destMotionPath);
|
||||
foreach (var fadeMotionMono in FadeMotions)
|
||||
{
|
||||
var fadeMotionDict = ParseMonoBehaviour(fadeMotionMono, CubismMonoBehaviourType.FadeMotion, assemblyLoader);
|
||||
var fadeMotionDict = ParseMonoBehaviour(fadeMotionMono, CubismMonoBehaviourType.FadeMotion, Assembly);
|
||||
if (fadeMotionDict == null)
|
||||
continue;
|
||||
|
||||
var fadeMotion = JsonConvert.DeserializeObject<CubismFadeMotion>(JsonConvert.SerializeObject(fadeMotionDict));
|
||||
var fadeMotion = JsonConvert.DeserializeObject<CubismFadeMotionData>(JsonConvert.SerializeObject(fadeMotionDict));
|
||||
if (fadeMotion.ParameterIds.Length == 0)
|
||||
continue;
|
||||
|
||||
var motionJson = new CubismMotion3Json(fadeMotion, ParameterNames, PartNames, forceBezier);
|
||||
fps = motionJson.Meta.Fps;
|
||||
|
||||
var animName = Path.GetFileNameWithoutExtension(fadeMotion.m_Name);
|
||||
if (motions.ContainsKey(animName))
|
||||
@ -430,7 +519,7 @@ namespace CubismLive2DExtractor
|
||||
}
|
||||
}
|
||||
|
||||
private static void ExportClipMotions(string destMotionPath, CubismMotion3Converter converter, bool forceBezier, SortedDictionary<string, JArray> motions)
|
||||
private static void ExportClipMotions(string destMotionPath, CubismMotion3Converter converter, bool forceBezier, SortedDictionary<string, JArray> motions, ref float fps)
|
||||
{
|
||||
if (converter == null)
|
||||
return;
|
||||
@ -448,7 +537,8 @@ namespace CubismLive2DExtractor
|
||||
continue;
|
||||
}
|
||||
var motionJson = new CubismMotion3Json(animation, forceBezier);
|
||||
|
||||
fps = motionJson.Meta.Fps;
|
||||
|
||||
if (motions.ContainsKey(animName))
|
||||
{
|
||||
animName = $"{animName}_{animation.GetHashCode()}";
|
||||
@ -462,12 +552,12 @@ namespace CubismLive2DExtractor
|
||||
}
|
||||
}
|
||||
|
||||
private bool ExportPoseJson(string destPath, string modelName, AssemblyLoader assemblyLoader)
|
||||
private bool ExportPoseJson(string destPath, string modelName)
|
||||
{
|
||||
var groupDict = new SortedDictionary<int, List<CubismPose3Json.ControlNode>>();
|
||||
foreach (var posePartMono in PoseParts)
|
||||
{
|
||||
var posePartDict = ParseMonoBehaviour(posePartMono, CubismMonoBehaviourType.PosePart, assemblyLoader);
|
||||
var posePartDict = ParseMonoBehaviour(posePartMono, CubismMonoBehaviourType.PosePart, Assembly);
|
||||
if (posePartDict == null)
|
||||
break;
|
||||
|
||||
@ -507,7 +597,7 @@ namespace CubismLive2DExtractor
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ExportCdiJson(string destPath, string modelName, AssemblyLoader assemblyLoader)
|
||||
private bool ExportCdiJson(string destPath, string modelName)
|
||||
{
|
||||
var cdiJson = new CubismCdi3Json
|
||||
{
|
||||
@ -518,7 +608,7 @@ namespace CubismLive2DExtractor
|
||||
var parameters = new SortedSet<CubismCdi3Json.ParamGroupArray>();
|
||||
foreach (var paramMono in ParametersCdi)
|
||||
{
|
||||
var displayName = GetDisplayName(paramMono, assemblyLoader);
|
||||
var displayName = GetDisplayName(paramMono);
|
||||
if (displayName == null)
|
||||
break;
|
||||
|
||||
@ -536,7 +626,7 @@ namespace CubismLive2DExtractor
|
||||
var parts = new SortedSet<CubismCdi3Json.PartArray>();
|
||||
foreach (var partMono in PartsCdi)
|
||||
{
|
||||
var displayName = GetDisplayName(partMono, assemblyLoader);
|
||||
var displayName = GetDisplayName(partMono);
|
||||
if (displayName == null)
|
||||
break;
|
||||
|
||||
@ -557,9 +647,9 @@ namespace CubismLive2DExtractor
|
||||
return true;
|
||||
}
|
||||
|
||||
private static string GetDisplayName(MonoBehaviour cdiMono, AssemblyLoader assemblyLoader)
|
||||
private string GetDisplayName(MonoBehaviour cdiMono)
|
||||
{
|
||||
var dict = ParseMonoBehaviour(cdiMono, CubismMonoBehaviourType.DisplayInfo, assemblyLoader);
|
||||
var dict = ParseMonoBehaviour(cdiMono, CubismMonoBehaviourType.DisplayInfo, Assembly);
|
||||
if (dict == null)
|
||||
return null;
|
||||
|
||||
@ -571,5 +661,44 @@ namespace CubismLive2DExtractor
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private bool TryGetFadeList(MonoBehaviour m_MonoBehaviour, out MonoBehaviour listMono)
|
||||
{
|
||||
return TryGetAsset(m_MonoBehaviour, CubismMonoBehaviourType.FadeController, "CubismFadeMotionList", out listMono);
|
||||
}
|
||||
|
||||
private bool TryGetExpressionList(MonoBehaviour m_MonoBehaviour, out MonoBehaviour listMono)
|
||||
{
|
||||
return TryGetAsset(m_MonoBehaviour, CubismMonoBehaviourType.ExpressionController, "ExpressionsList", out listMono);
|
||||
}
|
||||
|
||||
private bool TryGetRenderTexture(MonoBehaviour m_MonoBehaviour, out Texture2D renderTex)
|
||||
{
|
||||
return TryGetAsset(m_MonoBehaviour, CubismMonoBehaviourType.RenderTexture, "_mainTexture", out renderTex);
|
||||
}
|
||||
|
||||
private bool TryGetAsset<T>(MonoBehaviour m_MonoBehaviour, CubismMonoBehaviourType cubismMonoType, string pptrField, out T result) where T : Object
|
||||
{
|
||||
result = null;
|
||||
if (m_MonoBehaviour == null)
|
||||
return false;
|
||||
|
||||
var pptrDict = (OrderedDictionary)ParseMonoBehaviour(m_MonoBehaviour, cubismMonoType, Assembly)?[pptrField];
|
||||
if (pptrDict == null)
|
||||
return false;
|
||||
|
||||
var resultPPtr = GeneratePPtr<T>(pptrDict, m_MonoBehaviour.assetsFile);
|
||||
return resultPPtr.TryGet(out result);
|
||||
}
|
||||
|
||||
private PPtr<T> GeneratePPtr<T>(OrderedDictionary pptrDict, SerializedFile assetsFile = null) where T : Object
|
||||
{
|
||||
return new PPtr<T>
|
||||
{
|
||||
m_FileID = (int)pptrDict["m_FileID"],
|
||||
m_PathID = (long)pptrDict["m_PathID"],
|
||||
AssetsFile = assetsFile
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
namespace CubismLive2DExtractor
|
||||
{
|
||||
public enum Live2DModelGroupOption
|
||||
{
|
||||
ContainerPath,
|
||||
SourceFileName,
|
||||
}
|
||||
}
|
@ -18,6 +18,45 @@ namespace AssetStudio
|
||||
var typeDefinitionConverter = new TypeDefinitionConverter(typeDef, helper, 1);
|
||||
m_Type.m_Nodes.AddRange(typeDefinitionConverter.ConvertToTypeTreeNodes());
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_Script.m_ClassName)
|
||||
{
|
||||
case "CubismModel":
|
||||
helper.AddMonoCubismModel(m_Type.m_Nodes, 1);
|
||||
break;
|
||||
case "CubismMoc":
|
||||
helper.AddMonoCubismMoc(m_Type.m_Nodes, 1);
|
||||
break;
|
||||
case "CubismFadeController":
|
||||
helper.AddMonoCubismFadeController(m_Type.m_Nodes, 1);
|
||||
break;
|
||||
case "CubismFadeMotionList":
|
||||
helper.AddMonoCubismFadeList(m_Type.m_Nodes, 1);
|
||||
break;
|
||||
case "CubismFadeMotionData":
|
||||
helper.AddMonoCubismFadeData(m_Type.m_Nodes, 1);
|
||||
break;
|
||||
case "CubismExpressionController":
|
||||
helper.AddMonoCubismExpressionController(m_Type.m_Nodes, 1);
|
||||
break;
|
||||
case "CubismExpressionList":
|
||||
helper.AddMonoCubismExpressionList(m_Type.m_Nodes, 1);
|
||||
break;
|
||||
case "CubismExpressionData":
|
||||
helper.AddMonoCubismExpressionData(m_Type.m_Nodes, 1);
|
||||
break;
|
||||
case "CubismDisplayInfoParameterName":
|
||||
helper.AddMonoCubismDisplayInfo(m_Type.m_Nodes, 1);
|
||||
break;
|
||||
case "CubismDisplayInfoPartName":
|
||||
helper.AddMonoCubismDisplayInfo(m_Type.m_Nodes, 1);
|
||||
break;
|
||||
case "CubismPosePart":
|
||||
helper.AddMonoCubismPosePart(m_Type.m_Nodes, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return m_Type;
|
||||
}
|
||||
|
@ -277,5 +277,100 @@ namespace AssetStudio
|
||||
nodes.Add(new TypeTreeNode("PropertyName", name, indent, false));
|
||||
AddString(nodes, "id", indent + 1);
|
||||
}
|
||||
|
||||
#region CubismLive2D
|
||||
public void AddMonoCubismModel(List<TypeTreeNode> nodes, int indent)
|
||||
{
|
||||
AddPPtr(nodes, "CubismMoc", "_moc", indent);
|
||||
}
|
||||
|
||||
public void AddMonoCubismMoc(List<TypeTreeNode> nodes, int indent)
|
||||
{
|
||||
nodes.Add(new TypeTreeNode("vector", "_bytes", indent, align: true));
|
||||
AddArray(nodes, indent + 2);
|
||||
nodes.Add(new TypeTreeNode("UInt8", "data", indent + 2, false));
|
||||
}
|
||||
|
||||
public void AddMonoCubismPosePart(List<TypeTreeNode> nodes, int indent)
|
||||
{
|
||||
nodes.Add(new TypeTreeNode("int", "GroupIndex", indent, false));
|
||||
nodes.Add(new TypeTreeNode("int", "PartIndex", indent, false));
|
||||
nodes.Add(new TypeTreeNode("vector", "Link", indent, align: false));
|
||||
AddArray(nodes, indent + 2);
|
||||
AddString(nodes, "data", indent + 2);
|
||||
}
|
||||
|
||||
public void AddMonoCubismDisplayInfo(List<TypeTreeNode> nodes, int indent)
|
||||
{
|
||||
AddString(nodes, "Name", indent);
|
||||
AddString(nodes, "DisplayName", indent);
|
||||
}
|
||||
|
||||
public void AddMonoCubismFadeController(List<TypeTreeNode> nodes, int indent)
|
||||
{
|
||||
AddPPtr(nodes, "CubismFadeMotionList", "CubismFadeMotionList", indent);
|
||||
}
|
||||
|
||||
public void AddMonoCubismFadeList(List<TypeTreeNode> nodes, int indent)
|
||||
{
|
||||
nodes.Add(new TypeTreeNode("vector", "MotionInstanceIds", indent, align: false));
|
||||
AddArray(nodes, indent + 2);
|
||||
nodes.Add(new TypeTreeNode("int", "data", indent + 2, align: false));
|
||||
nodes.Add(new TypeTreeNode("vector", "CubismFadeMotionObjects", indent, align: false));
|
||||
AddArray(nodes, indent + 2);
|
||||
AddPPtr(nodes, "CubismFadeMotionData", "data", indent + 2);
|
||||
}
|
||||
|
||||
public void AddMonoCubismFadeData(List<TypeTreeNode> nodes, int indent)
|
||||
{
|
||||
AddString(nodes, "MotionName", indent);
|
||||
nodes.Add(new TypeTreeNode("float", "FadeInTime", indent, false));
|
||||
nodes.Add(new TypeTreeNode("float", "FadeOutTime", indent, false));
|
||||
nodes.Add(new TypeTreeNode("vector", "ParameterIds", indent, align: false));
|
||||
AddArray(nodes, indent + 2);
|
||||
AddString(nodes, "data", indent + 2);
|
||||
nodes.Add(new TypeTreeNode("vector", "ParameterCurves", indent, align: false));
|
||||
AddArray(nodes, indent + 2);
|
||||
AddAnimationCurve(nodes, "data", indent + 2);
|
||||
nodes.Add(new TypeTreeNode("vector", "ParameterFadeInTimes", indent, align: false));
|
||||
AddArray(nodes, indent + 2);
|
||||
nodes.Add(new TypeTreeNode("float", "data", indent + 2, align: false));
|
||||
nodes.Add(new TypeTreeNode("vector", "ParameterFadeOutTimes", indent, align: false));
|
||||
AddArray(nodes, indent + 2);
|
||||
nodes.Add(new TypeTreeNode("float", "data", indent + 2, align: false));
|
||||
nodes.Add(new TypeTreeNode("float", "MotionLength", indent , align: false));
|
||||
}
|
||||
|
||||
public void AddMonoCubismExpressionController(List<TypeTreeNode> nodes, int indent)
|
||||
{
|
||||
AddPPtr(nodes, "CubismExpressionList", "ExpressionsList", indent);
|
||||
nodes.Add(new TypeTreeNode("int", "CurrentExpressionIndex", indent, false));
|
||||
}
|
||||
|
||||
public void AddMonoCubismExpressionList(List<TypeTreeNode> nodes, int indent)
|
||||
{
|
||||
nodes.Add(new TypeTreeNode("vector", "CubismExpressionObjects", indent, align: false));
|
||||
AddArray(nodes, indent + 2);
|
||||
AddPPtr(nodes, "CubismExpressionData", "data", indent + 2);
|
||||
}
|
||||
|
||||
private void AddMonoCubismExpressionParameter(List<TypeTreeNode> nodes, string name, int indent)
|
||||
{
|
||||
nodes.Add(new TypeTreeNode("SerializableExpressionParameter", name, indent, false));
|
||||
AddString(nodes, "Id", indent + 1);
|
||||
nodes.Add(new TypeTreeNode("float", "Value", indent + 1, false));
|
||||
nodes.Add(new TypeTreeNode("int", "Blend", indent + 1, false));
|
||||
}
|
||||
|
||||
public void AddMonoCubismExpressionData(List<TypeTreeNode> nodes, int indent)
|
||||
{
|
||||
AddString(nodes, "Type", indent);
|
||||
nodes.Add(new TypeTreeNode("float", "FadeInTime", indent, false));
|
||||
nodes.Add(new TypeTreeNode("float", "FadeOutTime", indent, false));
|
||||
nodes.Add(new TypeTreeNode("SerializableExpressionParameter", "Parameters", indent, align: false));
|
||||
AddArray(nodes, indent + 2);
|
||||
AddMonoCubismExpressionParameter(nodes, "data", indent + 2);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user