Files
BeatSaber/Assets/VRBeatsKit/Scripts/EzySlice/SlicedHull.cs
T
whdwo798 4dad9e5d5b feat: SongCreator 씬 완성 — Beat Sage URL 지원, info.dat 메타데이터 자동 추출
- BeatSageUploader: audio_url 지원(UploadFromUrl), PollAndDownload 공통화, ZIP 500 오류 3회 재시도
- BeatSageConverter: info.dat 파싱(SongMetadata), BPM 자동 감지 → 노트 타이밍 변환에 적용
- SongCreatorManager: title/BPM 필수 입력 제거, 난이도 4개 자동 선택, GenerateFlowFromUrl 버그 수정
- NasPublisher: audioPath null 허용(URL 흐름에서 로컬 파일 없는 경우 스킵)
- .gitignore/.gitattributes 초기 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 23:37:34 +09:00

141 lines
5.4 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace EzySlice {
/**
* The final generated data structure from a slice operation. This provides easy access
* to utility functions and the final Mesh data for each section of the HULL.
*/
public sealed class SlicedHull {
private Mesh upper_hull;
private Mesh lower_hull;
public SlicedHull(Mesh upperHull, Mesh lowerHull) {
this.upper_hull = upperHull;
this.lower_hull = lowerHull;
}
public GameObject CreateUpperHull(GameObject original) {
return CreateUpperHull(original, null);
}
public GameObject CreateUpperHull(GameObject original, Material crossSectionMat) {
GameObject newObject = CreateUpperHull();
if (newObject != null) {
newObject.transform.localPosition = original.transform.localPosition;
newObject.transform.localRotation = original.transform.localRotation;
newObject.transform.localScale = original.transform.localScale;
Material[] shared = original.GetComponent<MeshRenderer>().sharedMaterials;
Mesh mesh = original.GetComponent<MeshFilter>().sharedMesh;
// nothing changed in the hierarchy, the cross section must have been batched
// with the submeshes, return as is, no need for any changes
if (mesh.subMeshCount == upper_hull.subMeshCount) {
// the the material information
newObject.GetComponent<Renderer>().sharedMaterials = shared;
return newObject;
}
// otherwise the cross section was added to the back of the submesh array because
// it uses a different material. We need to take this into account
Material[] newShared = new Material[shared.Length + 1];
// copy our material arrays across using native copy (should be faster than loop)
System.Array.Copy(shared, newShared, shared.Length);
newShared[shared.Length] = crossSectionMat;
// the the material information
newObject.GetComponent<Renderer>().sharedMaterials = newShared;
}
return newObject;
}
public GameObject CreateLowerHull(GameObject original) {
return CreateLowerHull(original, null);
}
public GameObject CreateLowerHull(GameObject original, Material crossSectionMat) {
GameObject newObject = CreateLowerHull();
if (newObject != null) {
newObject.transform.localPosition = original.transform.localPosition;
newObject.transform.localRotation = original.transform.localRotation;
newObject.transform.localScale = original.transform.localScale;
Material[] shared = original.GetComponent<MeshRenderer>().sharedMaterials;
Mesh mesh = original.GetComponent<MeshFilter>().sharedMesh;
// nothing changed in the hierarchy, the cross section must have been batched
// with the submeshes, return as is, no need for any changes
if (mesh.subMeshCount == lower_hull.subMeshCount) {
// the the material information
newObject.GetComponent<Renderer>().sharedMaterials = shared;
return newObject;
}
// otherwise the cross section was added to the back of the submesh array because
// it uses a different material. We need to take this into account
Material[] newShared = new Material[shared.Length + 1];
// copy our material arrays across using native copy (should be faster than loop)
System.Array.Copy(shared, newShared, shared.Length);
newShared[shared.Length] = crossSectionMat;
// the the material information
newObject.GetComponent<Renderer>().sharedMaterials = newShared;
}
return newObject;
}
/**
* Generate a new GameObject from the upper hull of the mesh
* This function will return null if upper hull does not exist
*/
public GameObject CreateUpperHull() {
return CreateEmptyObject("Upper_Hull", upper_hull);
}
/**
* Generate a new GameObject from the Lower hull of the mesh
* This function will return null if lower hull does not exist
*/
public GameObject CreateLowerHull() {
return CreateEmptyObject("Lower_Hull", lower_hull);
}
public Mesh upperHull {
get { return this.upper_hull; }
}
public Mesh lowerHull {
get { return this.lower_hull; }
}
/**
* Helper function which will create a new GameObject to be able to add
* a new mesh for rendering and return.
*/
private static GameObject CreateEmptyObject(string name, Mesh hull) {
if (hull == null) {
return null;
}
GameObject newObject = new GameObject(name);
newObject.AddComponent<MeshRenderer>();
MeshFilter filter = newObject.AddComponent<MeshFilter>();
filter.mesh = hull;
return newObject;
}
}
}