99 lines
3.6 KiB
C#
99 lines
3.6 KiB
C#
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<MeshRenderer>();
|
|
Bounds bounds = new Bounds(Vector3.zero, 0.000001f * Vector3.one);
|
|
if (mr != null)
|
|
bounds.Encapsulate(mr.bounds);
|
|
else
|
|
{
|
|
SkinnedMeshRenderer smr = go.GetComponent<SkinnedMeshRenderer>();
|
|
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<MeshRenderer>();
|
|
if (mr != null)
|
|
bounds.Encapsulate(mr.bounds);
|
|
else
|
|
{
|
|
SkinnedMeshRenderer smr = t.GetChild(i).GetComponent<SkinnedMeshRenderer>();
|
|
if (smr != null)
|
|
bounds.Encapsulate(smr.bounds);
|
|
}
|
|
|
|
EncapsulateChildBounds(t.GetChild(i), ref bounds);
|
|
}
|
|
}
|
|
}
|
|
} |