Land Explorer in HomeCamp with boot loading, journal UI, and CDN publish tooling.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -162,120 +162,6 @@ public static class BuildCharacterAnimationLab
|
||||
EditorSceneManager.CloseScene(scene,true);
|
||||
}
|
||||
}
|
||||
public static string BuildLmGirl()
|
||||
{
|
||||
if (EditorApplication.isPlaying) throw new InvalidOperationException("Edit Mode required.");
|
||||
const string targetRoot=Root+"/LmGirl";
|
||||
const string generated=targetRoot+"/Generated";
|
||||
if (SceneManager.GetSceneByPath(targetRoot+"/LmGirlAnimationLab.unity").isLoaded)
|
||||
throw new InvalidOperationException("Open a different scene before rebuilding LmGirl; Unity cannot overwrite another loaded scene.");
|
||||
Folder(generated);
|
||||
var data=JsonConvert.DeserializeObject<Data>(File.ReadAllText(Path.Combine(Repo,"Tools/output/lmgirl_tpose_studio/rig_mixamo41/unity_review_data.json")));
|
||||
var meshes=data.variants.ToDictionary(v=>v.name,v=>MakeMesh(v,data.bones,generated));
|
||||
var website=JsonConvert.DeserializeObject<Data>(File.ReadAllText(Path.Combine(Repo,"Tools/output/lmgirl_tpose_studio/rig_mixamo41/website/unity_review_data.json")));
|
||||
meshes["mixamo"]=MakeMesh(website.variants[0],website.bones,generated);
|
||||
var gait=JsonConvert.DeserializeObject<Gait>(File.ReadAllText(Path.Combine(Repo,"Tools/output/lmgirl_tpose_studio/rig_mixamo41/gait_correction.json")));
|
||||
var walk41=MakeClip(gait.motions["tokenrig"],data.bones,generated);
|
||||
var walk33=MakeClip(gait.motions["mixamo"],website.bones,generated);
|
||||
foreach (string suffix in new[]{"base","mix"})
|
||||
{
|
||||
string path=generated+"/LmGirlTpose_"+suffix+".png";
|
||||
File.Copy(Path.Combine(Repo,"Tools/output/lmgirl_tpose_studio/xpbr/LmGirlTpose_"+suffix+".png"),path,true);
|
||||
AssetDatabase.ImportAsset(path,ImportAssetOptions.ForceSynchronousImport);
|
||||
var importer=(TextureImporter)AssetImporter.GetAtPath(path);
|
||||
importer.sRGBTexture=suffix=="base";importer.maxTextureSize=1024;
|
||||
importer.alphaIsTransparency=false;importer.SaveAndReimport();
|
||||
}
|
||||
string matPath=generated+"/LmGirlTextured.mat";
|
||||
var material=AssetDatabase.LoadAssetAtPath<Material>(matPath);
|
||||
if (!material)
|
||||
{
|
||||
material=new Material(AssetDatabase.LoadAssetAtPath<Material>(Generated+"/CharacterTextured.mat"));
|
||||
AssetDatabase.CreateAsset(material,matPath);
|
||||
}
|
||||
material.SetTexture("_MainTex",AssetDatabase.LoadAssetAtPath<Texture2D>(generated+"/LmGirlTpose_base.png"));
|
||||
material.SetTexture("_MixTex",AssetDatabase.LoadAssetAtPath<Texture2D>(generated+"/LmGirlTpose_mix.png"));
|
||||
EditorUtility.SetDirty(material);
|
||||
var uiPath=JsonUIPrefabBuilder.BuildFromJsonFile(Path.Combine(Repo,"Doc/UIPrefabCreater/UI_LmGirlAnimationLab.json"));
|
||||
if (string.IsNullOrEmpty(uiPath)) throw new InvalidOperationException("LmGirl UI conversion failed.");
|
||||
var previous=SceneManager.GetActiveScene();
|
||||
var scene=EditorSceneManager.NewScene(NewSceneSetup.EmptyScene,NewSceneMode.Additive);
|
||||
try
|
||||
{
|
||||
SceneManager.SetActiveScene(scene);
|
||||
var root=(GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath<GameObject>(Generated+"/CharacterAnimationLab.prefab"));
|
||||
PrefabUtility.UnpackPrefabInstance(root,PrefabUnpackMode.Completely,InteractionMode.AutomatedAction);
|
||||
root.name="LmGirlAnimationLab";
|
||||
var viewer=root.GetComponent<CharacterAnimationLab>();
|
||||
string[] variants={"mixamo","raw","post","local"};
|
||||
string[] labels={"Mixamo 网站 · 33 骨","TokenRig 原始 · 41 骨","体素后处理 · 41 骨","局部约束 · 41 骨"};
|
||||
var slots=viewer.actors.Select(a=>a.rig.transform.parent).ToList();
|
||||
foreach(var actor in viewer.actors)UnityEngine.Object.DestroyImmediate(actor.rig);
|
||||
slots.Add(UnityEngine.Object.Instantiate(slots[2],root.transform));
|
||||
viewer.actors=new CharacterAnimationLab.Actor[4];
|
||||
Color[] colors={new Color(.49f,.78f,.85f),new Color(.94f,.72f,.43f),new Color(.68f,.62f,.85f),new Color(.62f,.82f,.51f)};
|
||||
Quaternion Rotation(float[] q)=>new Quaternion(q[0],q[1],q[2],q[3]);
|
||||
for (int i=0;i<variants.Length;i++)
|
||||
{
|
||||
var actorData=i==0?website:data;
|
||||
var slot=slots[i];slot.localPosition=new Vector3((i-1.5f)*.83f,0,0);
|
||||
slot.name="Stage_LmGirl_"+variants[i];
|
||||
slot.GetComponentInChildren<Renderer>().sharedMaterial=Material("LmGirlPedestal"+i,colors[i],generated);
|
||||
var rig=new GameObject("Rig");rig.transform.SetParent(slot,false);rig.transform.localScale=Vector3.one*(1.55f/actorData.height);
|
||||
var bones=new Transform[actorData.bones.Length];
|
||||
for (int b=0;b<bones.Length;b++)
|
||||
{
|
||||
var go=new GameObject(actorData.bones[b].name);bones[b]=go.transform;
|
||||
go.transform.SetParent(actorData.bones[b].parent<0?rig.transform:bones[actorData.bones[b].parent],false);
|
||||
SetTRS(go.transform,actorData.bones[b].rest);
|
||||
}
|
||||
var meshGo=new GameObject("CharacterMesh");meshGo.transform.SetParent(rig.transform,false);
|
||||
var skin=meshGo.AddComponent<SkinnedMeshRenderer>();skin.sharedMesh=meshes[variants[i]];skin.bones=bones;skin.rootBone=bones[0];
|
||||
skin.sharedMaterial=material;skin.quality=SkinQuality.Auto;skin.updateWhenOffscreen=true;
|
||||
skin.localBounds=new Bounds(new Vector3(0,.75f,0),new Vector3(3,3,3));
|
||||
viewer.actors[i]=new CharacterAnimationLab.Actor{label=labels[i],rig=rig,hips=bones[0],
|
||||
rightHand=bones.First(b=>b.name=="mixamorig:RightHand"),renderer=skin,
|
||||
walkingClip=i==0?walk33:walk41,
|
||||
translationScale=actorData.translationScale,translationOffsets=actorData.translationOffsets.Select(x=>V(x)).ToArray(),
|
||||
translationDeltaRotations=actorData.translationDeltaRotations?.Select(Rotation).ToArray()??Array.Empty<Quaternion>(),
|
||||
bindRotationCorrections=actorData.bindRotationCorrections?.Select(Rotation).ToArray()??Array.Empty<Quaternion>(),
|
||||
rotationParents=actorData.rotationParents??Array.Empty<int>()};
|
||||
}
|
||||
UnityEngine.Object.DestroyImmediate(viewer.ui.gameObject);
|
||||
var ui=(GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath<GameObject>(uiPath),root.transform);
|
||||
viewer.ui=ui.transform;ui.GetComponentInChildren<AnimationLabSeekBar>().viewer=viewer;
|
||||
viewer.texturedMaterial=material;viewer.motion=0;viewer.time=10f/30;viewer.focus=-1;viewer.detail=0;viewer.yaw=0;viewer.textured=true;viewer.playing=true;
|
||||
viewer.Sample();
|
||||
RenderSettings.ambientMode=AmbientMode.Flat;RenderSettings.ambientLight=new Color(.65f,.69f,.73f);RenderSettings.fog=false;
|
||||
if (!EditorSceneManager.SaveScene(scene,targetRoot+"/LmGirlAnimationLab.unity"))
|
||||
throw new IOException("LmGirl scene was not saved.");
|
||||
PrefabUtility.SaveAsPrefabAsset(root,generated+"/LmGirlAnimationLab.prefab");
|
||||
// Keep the rejected generic-cleaning experiments inspectable as
|
||||
// persistent prefabs without promoting them to the default lineup.
|
||||
for(int b=0;b<data.bones.Length;b++)SetTRS(viewer.actors[1].renderer.bones[b],data.bones[b].rest);
|
||||
for(int b=0;b<website.bones.Length;b++)SetTRS(viewer.actors[0].renderer.bones[b],website.bones[b].rest);
|
||||
PrefabUtility.SaveAsPrefabAsset(viewer.actors[0].rig,generated+"/LmGirl_mixamo.prefab");
|
||||
foreach (string variant in new[]{"raw","post","clean","clean_eps","local"})
|
||||
{
|
||||
var actor=viewer.actors[1];actor.renderer.sharedMesh=meshes[variant];
|
||||
PrefabUtility.SaveAsPrefabAsset(actor.rig,generated+"/LmGirl_"+variant+".prefab");
|
||||
}
|
||||
AssetDatabase.SaveAssets();
|
||||
return JsonConvert.SerializeObject(new{scene=targetRoot+"/LmGirlAnimationLab.unity",visibleVariants=4,websiteBones=website.bones.Length,tokenRigBones=data.bones.Length,triangles=4999,sourceClips=viewer.clips.Select(c=>AssetDatabase.GetAssetPath(c)),walkingClips=new[]{AssetDatabase.GetAssetPath(walk33),AssetDatabase.GetAssetPath(walk41)},translationScale=data.translationScale});
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (previous.IsValid()&&previous.isLoaded)SceneManager.SetActiveScene(previous);
|
||||
EditorSceneManager.CloseScene(scene,true);
|
||||
}
|
||||
}
|
||||
public static string OpenLmGirl()
|
||||
{
|
||||
if (EditorSceneManager.GetSceneManagerSetup().Any(s=>SceneManager.GetSceneByPath(s.path).isDirty))throw new InvalidOperationException("Existing scene has unsaved changes.");
|
||||
EditorSceneManager.OpenScene(Root+"/LmGirl/LmGirlAnimationLab.unity",OpenSceneMode.Single);
|
||||
Selection.activeGameObject=UnityEngine.Object.FindObjectOfType<CharacterAnimationLab>().gameObject;
|
||||
return SceneManager.GetActiveScene().path;
|
||||
}
|
||||
public static string RefineLayout()
|
||||
{
|
||||
if (EditorApplication.isPlaying) throw new InvalidOperationException("Edit Mode required.");
|
||||
|
||||
Reference in New Issue
Block a user