using UnityEngine; namespace NBF { public class ModelViewerUtils { public static ModelViewerSettings InitSetting(GameObject go, ModelViewerSettings settings) { if (settings.objectPosition.magnitude < 0.0001f) settings.objectPosition = Vector3.zero; //---Zero the GameObject euler angles if they're very small in magnitude---// settings.objectRotation = go.transform.eulerAngles; if (settings.objectRotation.magnitude < 0.0001f) settings.objectRotation = Vector3.zero; //---Set the object scale variable---// settings.objectScale = go.transform.localScale; //将默认对象位置设为使其位于图标中心的位置 Bounds bounds = GetObjectBounds(go); settings.objectPosition = GetObjectAutoOffset(bounds); // 将默认的相机设置调整为适合图标渲染中对象的呈现效果 float camAuto = GetCameraAuto(bounds); settings.cameraSize = camAuto; settings.cameraPosition = Vector3.one * camAuto; return settings; } public static Bounds GetObjectBounds(GameObject go) { // 在将其位置归零之前先保存其位置信息 Vector3 prefabPos = go.transform.position; go.transform.position = Vector3.zero; // 创建一个边界对象,并将对象网格的边界进行封装。 MeshRenderer mr = go.GetComponent(); Bounds bounds = new Bounds(Vector3.zero, 0.000001f * Vector3.one); if (mr != null) bounds.Encapsulate(mr.bounds); else { SkinnedMeshRenderer smr = go.GetComponent(); if (smr != null) bounds.Encapsulate(smr.bounds); } //同时将对象的子对象的范围也进行封装起来 EncapsulateChildBounds(go.transform, ref bounds); //将预制物的位置重置为存储的值 go.transform.position = prefabPos; return bounds; } public static Vector3 GetObjectAutoOffset(Bounds bounds) { //将偏移量应用到图标对象的位置上 return -bounds.center; } public static float GetCameraAuto(Bounds bounds) { //---Scale camera size and position so that the object fits in the render---// Matrix4x4 trs = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0, 45, 0), 1.05f * Vector3.one); Vector3 corner = new Vector3(bounds.extents.x, bounds.extents.y, bounds.extents.z); corner = trs * corner; Vector2 refB2 = new Vector2(0.74f, 0.53f); Vector2 b2 = refB2 * corner.magnitude; return b2.magnitude; } public static void EncapsulateChildBounds(Transform t, ref Bounds bounds) { // 遍历所有子对象,封装边界 MeshRenderer mr; for (int i = 0; i < t.childCount; i++) { mr = t.GetChild(i).GetComponent(); if (mr != null) bounds.Encapsulate(mr.bounds); else { SkinnedMeshRenderer smr = t.GetChild(i).GetComponent(); if (smr != null) bounds.Encapsulate(smr.bounds); } EncapsulateChildBounds(t.GetChild(i), ref bounds); } } } }