189 lines
5.7 KiB
C#
189 lines
5.7 KiB
C#
using System.Collections.Generic;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
|
|
namespace UniGLTF
|
|
{
|
|
public static class BoneInfoDrawer
|
|
{
|
|
#region Bone
|
|
const string BONE_GIZMO = "Assets/UniGLTF/Editor/UniGLTF/Gizmo/Models/BoneGizmo.prefab";
|
|
static GameObject _bone;
|
|
static GameObject BonePrefab
|
|
{
|
|
get
|
|
{
|
|
if (_bone == null)
|
|
{
|
|
_bone = AssetDatabase.LoadAssetAtPath<GameObject>(BONE_GIZMO);
|
|
}
|
|
return _bone;
|
|
}
|
|
}
|
|
|
|
private static Mesh _boneMesh;
|
|
static Mesh BoneMesh
|
|
{
|
|
get
|
|
{
|
|
if (_boneMesh == null)
|
|
{
|
|
_boneMesh = BonePrefab.GetComponent<MeshFilter>().sharedMesh;
|
|
}
|
|
return _boneMesh;
|
|
}
|
|
}
|
|
|
|
private static Material _boneMaterial;
|
|
static Material BoneMaterial
|
|
{
|
|
get
|
|
{
|
|
if (_boneMaterial == null)
|
|
{
|
|
_boneMaterial = BonePrefab.GetComponent<MeshRenderer>().sharedMaterial;
|
|
_boneMaterial.enableInstancing = true;
|
|
}
|
|
return _boneMaterial;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Selected
|
|
const string SELECTED_BONE_GIZMO = "Assets/UniGLTF/Editor/UniGLTF/Gizmo/Models/SelectedBoneGizmo.prefab";
|
|
static GameObject _selected;
|
|
static GameObject SelectedPrefab
|
|
{
|
|
get
|
|
{
|
|
if (_selected == null)
|
|
{
|
|
_selected = AssetDatabase.LoadAssetAtPath<GameObject>(SELECTED_BONE_GIZMO);
|
|
if (_selected == null)
|
|
{
|
|
throw new System.NullReferenceException("SelectedPrefab");
|
|
}
|
|
}
|
|
return _selected;
|
|
}
|
|
}
|
|
|
|
private static Mesh _selectedBoneMesh;
|
|
static Mesh SelectedBoneMesh
|
|
{
|
|
get
|
|
{
|
|
if (_selectedBoneMesh == null)
|
|
{
|
|
_selectedBoneMesh = SelectedPrefab.GetComponent<MeshFilter>().sharedMesh;
|
|
}
|
|
return _selectedBoneMesh;
|
|
}
|
|
}
|
|
|
|
private static Material _selectedMaterial;
|
|
public static Material SelectedMaterial
|
|
{
|
|
get
|
|
{
|
|
if (_selectedMaterial == null)
|
|
{
|
|
_selectedMaterial = SelectedPrefab.GetComponent<MeshRenderer>().sharedMaterial;
|
|
_selectedMaterial.enableInstancing = true;
|
|
}
|
|
return _selectedMaterial;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Hover
|
|
const string HOVER_BONE_GIZMO = "Assets/UniGLTF/Editor/UniGLTF/Gizmo/Models/HoverBoneGizmo.prefab";
|
|
static GameObject _hover;
|
|
static GameObject HoverPrefab
|
|
{
|
|
get
|
|
{
|
|
if (_hover == null)
|
|
{
|
|
_hover = AssetDatabase.LoadAssetAtPath<GameObject>(HOVER_BONE_GIZMO);
|
|
if (_hover == null)
|
|
{
|
|
throw new System.NullReferenceException("HoverPrefab");
|
|
}
|
|
}
|
|
return _hover;
|
|
}
|
|
}
|
|
|
|
private static Mesh _hoverBoneMesh;
|
|
static Mesh HoverBoneMesh
|
|
{
|
|
get
|
|
{
|
|
if (_hoverBoneMesh == null)
|
|
{
|
|
_hoverBoneMesh = HoverPrefab.GetComponent<MeshFilter>().sharedMesh;
|
|
}
|
|
return _hoverBoneMesh;
|
|
}
|
|
}
|
|
|
|
private static Material _hoverMaterial;
|
|
public static Material HoverMaterial
|
|
{
|
|
get
|
|
{
|
|
if (_hoverMaterial == null)
|
|
{
|
|
_hoverMaterial = HoverPrefab.GetComponent<MeshRenderer>().sharedMaterial;
|
|
_hoverMaterial.enableInstancing = true;
|
|
}
|
|
return _hoverMaterial;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
public static void DrawBone(this CommandBuffer buf, BoneInfo bone, Material material)
|
|
{
|
|
var head = bone.GetHeadPosition();
|
|
var tail = bone.GetTailPosition();
|
|
|
|
var headToTail = tail - head;
|
|
var distance = headToTail.magnitude;
|
|
|
|
var matrix = Matrix4x4.TRS(
|
|
head,
|
|
Quaternion.LookRotation(headToTail, bone.GetUpVector()),
|
|
new Vector3(distance, distance, distance)
|
|
);
|
|
|
|
buf.DrawMesh(SelectedBoneMesh, matrix, material);
|
|
}
|
|
|
|
private const int MaxDrawCount = 256;
|
|
private static readonly Matrix4x4[] _maxDrawAtOnceMatrices = new Matrix4x4[MaxDrawCount];
|
|
public static void DrawBones(this CommandBuffer buf, List<BoneInfo> bones)
|
|
{
|
|
var idx = 0;
|
|
foreach (var bone in bones)
|
|
{
|
|
if (idx >= MaxDrawCount) break;
|
|
|
|
var head = bone.GetHeadPosition();
|
|
var tail = bone.GetTailPosition();
|
|
|
|
var headToTail = tail - head;
|
|
var distance = headToTail.magnitude;
|
|
|
|
_maxDrawAtOnceMatrices[idx++] = Matrix4x4.TRS(
|
|
head,
|
|
Quaternion.LookRotation(headToTail, bone.GetUpVector()),
|
|
new Vector3(distance, distance, distance)
|
|
);
|
|
}
|
|
buf.DrawMeshInstanced(BoneMesh, 0, BoneMaterial, 0, _maxDrawAtOnceMatrices);
|
|
}
|
|
}
|
|
}
|