848 lines
36 KiB
C#
848 lines
36 KiB
C#
using FIMSpace.FEditor;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
|
|
namespace FIMSpace.FProceduralAnimation
|
|
{
|
|
public partial class LegsAnimatorEditor
|
|
{
|
|
public bool IsSceneViewVisible { get { return SceneView.lastActiveSceneView != null; } }
|
|
public SceneView ScView { get { return SceneView.lastActiveSceneView; } }
|
|
|
|
public void SceneHelper_FocusOnInSceneView(Transform t, float scale = 1f)
|
|
{
|
|
if (t == null) return;
|
|
SceneView.lastActiveSceneView.Frame(new Bounds(t.position, Vector3.one * scale * 0.6f), false);
|
|
}
|
|
|
|
public Transform SceneHelper_FocusOnBone = null;
|
|
|
|
void SceneHelper_DrawBoneFocus()
|
|
{
|
|
if (SceneHelper_FocusOnBone == null) return;
|
|
|
|
Vector3 bonePos = SceneHelper_FocusOnBone.position;
|
|
Vector3 lookDir = ScView.camera.transform.position - bonePos;
|
|
Quaternion cameraLook = Quaternion.identity;
|
|
if (lookDir != Vector3.zero) cameraLook = Quaternion.LookRotation(lookDir);
|
|
|
|
float sideOff = Get.Util_SideMul(SceneHelper_FocusOnBone);
|
|
|
|
Handles.color = new Color(0.4f, 1f, 0.65f, 0.5f);
|
|
|
|
float avLength = 0f;
|
|
for (int c = 0; c < SceneHelper_FocusOnBone.childCount; c++)
|
|
{
|
|
Vector3 childPos = SceneHelper_FocusOnBone.GetChild(c).position;
|
|
FGUI_Handles.DrawBoneHandle(bonePos, childPos, 1f);
|
|
avLength += Vector3.Distance(childPos, bonePos);
|
|
}
|
|
|
|
if (SceneHelper_FocusOnBone.childCount > 0) avLength /= (float)SceneHelper_FocusOnBone.childCount;
|
|
else avLength = 0.65f;
|
|
|
|
//Handles.color = new Color(0.4f, 1f, 0.65f, 0.2f);
|
|
Handles.DrawWireDisc(bonePos, cameraLook * Vector3.forward, avLength * 0.3f);
|
|
|
|
// Draw children
|
|
Handles.color = new Color(0.4f, 1f, 0.65f, 0.125f);
|
|
for (int c = 0; c < SceneHelper_FocusOnBone.childCount; c++)
|
|
{
|
|
Transform child = SceneHelper_FocusOnBone.GetChild(c);
|
|
|
|
for (int i = 0; i < child.childCount; i++)
|
|
{
|
|
Vector3 childPos = child.GetChild(i).position;
|
|
FGUI_Handles.DrawBoneHandle(child.position, childPos, 0.2f);
|
|
}
|
|
}
|
|
|
|
Handles.color = new Color(0.7f, 0.7f, 0.7f, 0.25f);
|
|
float off = Mathf.Lerp(editorScaleRef, avLength, 0.4f);
|
|
lookDir.y = 0f; lookDir.Normalize();
|
|
cameraLook = ScView.camera.transform.rotation;
|
|
Vector3 helperPos = bonePos + cameraLook * Vector3.right * sideOff * off * 0.8f + Vector3.up * off * 0.2f;
|
|
Handles.DrawLine(bonePos, helperPos);
|
|
|
|
Handles.color = Color.white;
|
|
Handles.Label(helperPos + Vector3.up * off * 0.08f, SceneHelper_FocusOnBone.name, FGUI_Resources.HeaderStyle);
|
|
|
|
}
|
|
|
|
void SceneHelper_DrawHipsHubs()
|
|
{
|
|
if (Get.Hips == null) return;
|
|
if (Get.ExtraHipsHubs == null) return;
|
|
if (Get.ExtraHipsHubs.Count == 0) return;
|
|
|
|
for (int i = 0; i < Get.ExtraHipsHubs.Count; i++)
|
|
{
|
|
if (Get.ExtraHipsHubs[i] == null) continue;
|
|
|
|
Handles.SphereHandleCap(0, Get.ExtraHipsHubs[i].position, Quaternion.identity, editorScaleRef * 0.1f, EventType.Repaint);
|
|
|
|
if (!Get.LegsInitialized)
|
|
{
|
|
Handles.DrawAAPolyLine(2, Get.Hips.position, Get.ExtraHipsHubs[i].position);
|
|
}
|
|
else
|
|
{
|
|
if (Get.HipsHubs[i].HubBackBones?.Count > 0)
|
|
{
|
|
Handles.DrawAAPolyLine(2, Get.ExtraHipsHubs[i].position, Get.HipsHubs[i].HubBackBones[0].bone.position, Get.HipsHubs[i].HubBackBones[0].bone.position + Get.Up * editorScaleRef * 0.1f);
|
|
|
|
for (int b = 1; b < Get.HipsHubs[i].HubBackBones.Count; b++)
|
|
{
|
|
Handles.DrawAAPolyLine(2, Get.HipsHubs[i].HubBackBones[b - 1].bone.position, Get.HipsHubs[i].HubBackBones[b].bone.position, Get.HipsHubs[i].HubBackBones[b].bone.position + Get.Up * editorScaleRef * 0.1f);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void SceneHelper_DrawLegStartBoneSelector(LegsAnimator.Leg leg, float drawScale, Transform legsHub)
|
|
{
|
|
if (legsHub == null) return;
|
|
|
|
for (int c = 0; c < legsHub.childCount; c++)
|
|
{
|
|
Transform cc = legsHub.GetChild(c);
|
|
bool should = Util_Leg_ShouldDraw(cc);
|
|
|
|
if (should)
|
|
Handles.color = new Color(0.4f, 1f, 0.65f, 0.225f);
|
|
else
|
|
Handles.color = new Color(0.4f, 0.4f, 0.4f, 0.225f);
|
|
|
|
Vector3 childPos = cc.position;
|
|
FGUI_Handles.DrawBoneHandle(legsHub.position, childPos, 1f);
|
|
|
|
if (!should) continue;
|
|
|
|
|
|
if (cc.childCount > 0)
|
|
{
|
|
float hSize = HandleUtility.GetHandleSize(childPos);
|
|
if (hSize > 0.01f)
|
|
{
|
|
float scaler = 1f / hSize;
|
|
float mouseOnDistance = Vector2.Distance(Event.current.mousePosition, HandleUtility.WorldToGUIPoint(childPos));
|
|
if (mouseOnDistance < 2.85f * scaler) FGUI_Handles.DrawBoneHandle(childPos, cc.GetChild(0).position, .7f);
|
|
//if ( c == 0) UnityEngine.Debug.Log("scaler = " + hSize); //UnityEngine.Debug.Log("drawScale = " + editorScaleRef + " : mouse pos = " + Event.current.mousePosition + " : wpoint =" + HandleUtility.WorldToGUIPoint(childPos) + "mose distance = " + mouseOnDistance);
|
|
}
|
|
}
|
|
|
|
if (Handles.Button(childPos, Quaternion.identity, drawScale, drawScale, Handles.CircleHandleCap))
|
|
{
|
|
leg.BoneStart = cc;
|
|
}
|
|
|
|
Util_DrawBoneIndicator(cc, drawScale);
|
|
}
|
|
}
|
|
|
|
|
|
void SceneHelper_DrawLegSelectorHelper()
|
|
{
|
|
if (Get.LegsInitialized) return;
|
|
if (_selected_leg < 0) return;
|
|
if (Get.Hips == null) return;
|
|
|
|
//SceneHelper_FocusOnBone = null;
|
|
Get.User_RefreshHelperVariablesOnParametersChange();
|
|
|
|
if (Get.Legs.ContainsIndex(_selected_leg) == false)
|
|
{
|
|
_selected_leg = -1;
|
|
return;
|
|
}
|
|
|
|
Quaternion viewRot = ScView.camera.transform.rotation;
|
|
var leg = Get.Legs[_selected_leg];
|
|
|
|
float drawScaleRaw = editorScaleRef * 0.06f;
|
|
float drawScale = drawScaleRaw;
|
|
|
|
if (leg.BoneStart == null)
|
|
{
|
|
|
|
#region Start bone selector
|
|
|
|
Handles.BeginGUI();
|
|
GUI.Label(new Rect(0, 10, Screen.width, 40), "Select Start Leg Bone", FGUI_Resources.HeaderStyleBig);
|
|
Handles.EndGUI();
|
|
|
|
SceneHelper_DrawLegStartBoneSelector(leg, drawScaleRaw, Get.Hips);
|
|
|
|
for (int i = 0; i < Get.ExtraHipsHubs.Count; i++)
|
|
{
|
|
SceneHelper_DrawLegStartBoneSelector(leg, drawScaleRaw, Get.ExtraHipsHubs[i]);
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
else
|
|
{
|
|
Handles.BeginGUI();
|
|
|
|
float sideWidth = Mathf.Max(180, Screen.width * 0.33f);
|
|
|
|
GUI.Label(new Rect(0, 10, Screen.width, 40), leg.BoneStart.name.ToUpper() + " - Side: " + leg.Side.ToString(), FGUI_Resources.HeaderStyle);
|
|
|
|
if (leg.BoneStart && leg.BoneMid && leg.BoneEnd)
|
|
{
|
|
GUI.color = Color.black;
|
|
GUI.Box(new Rect(5, 8, sideWidth + 35, 124), GUIContent.none, FGUI_Resources.HeaderBoxStyleH);
|
|
GUI.Box(new Rect(5, 8, sideWidth + 35, 124), GUIContent.none, FGUI_Resources.HeaderBoxStyleH);
|
|
GUI.color = Color.white;
|
|
|
|
//GUI.color = new Color(1f, 1f, 1f, 0.8f);
|
|
GUI.color = Color.white * 1.4f;
|
|
|
|
if (GUI.Button(new Rect(20, 22, 22, 19), new GUIContent(FGUI_Resources.TexTargetingIcon, "Ping start leg in the hierarchy to easily find other legs 'Top Bones'"), FGUI_Resources.ButtonStyle)) { PingObject(leg.BoneStart); }
|
|
GUI.Label(new Rect(20, 12, sideWidth, 40), "Use " + leg.BoneStart.name + " setup for:", EditorStyles.centeredGreyMiniLabel);
|
|
|
|
if (GUI.Button(new Rect(20, 46, sideWidth, 32), "Try Automatically Setup\nRest Of The Legs in Hips", FGUI_Resources.ButtonStyle))
|
|
{
|
|
Get.Setup_TryAutoLegsSetup(leg, Get.Hips);
|
|
_selected_leg = -1;
|
|
}
|
|
|
|
GUI.Label(new Rect(20, 72, sideWidth, 40), "Apply Auto-Setup for Selective Leg Bone:", EditorStyles.centeredGreyMiniLabel);
|
|
EditorGUIUtility.labelWidth = 96;
|
|
Transform toSetup = (Transform)EditorGUI.ObjectField(new Rect(20, 104, sideWidth, 20), new GUIContent("Leg Top Bone", "Drag & Drop there leg start/thigh bone from hierarchy window to try automatically set it up with the same patter as the first bone was set up."), null, typeof(Transform), true);
|
|
if (toSetup != null) { Get.Setup_TryAutoLegSetup(leg, toSetup); _selected_leg = Get.Legs.Count - 1; }
|
|
|
|
EditorGUIUtility.labelWidth = 0;
|
|
|
|
GUI.color = Color.white;
|
|
}
|
|
|
|
|
|
Handles.EndGUI();
|
|
|
|
|
|
Vector3 buttonOff = ScView.camera.transform.rotation * Vector3.right * Get.Util_SideMul(leg.BoneStart) * drawScale * 0.8f;
|
|
//Vector3.up * drawScale
|
|
if (Util_DrawButton(new GUIContent(Tex_smLegStart), buttonOff + leg.BoneStart.position + 2f * LabelIndicatorHelperOffset(leg.BoneStart, drawScale, false, true), 1f, false))
|
|
{ PingObject(leg.BoneStart); }
|
|
Util_DrawBoneIndicator(leg.BoneStart, drawScale * 1.65f, true, "", false, true);
|
|
|
|
Handles.color = new Color(0.5f, 1f, 0.55f, 0.75f);
|
|
if (leg.BoneMid != null) FGUI_Handles.DrawBoneHandle(leg.BoneStart.position, leg.BoneMid.position, 1f);
|
|
else Util_DrawChildBoneOf(leg.BoneStart, 0.6f);
|
|
|
|
Transform legBone = leg.BoneStart;
|
|
|
|
|
|
// Drawing buttons for target bones to be selected
|
|
if (leg.BoneMid == null || leg.BoneEnd == null)
|
|
{
|
|
int i = 1;
|
|
while (legBone.childCount > 0)
|
|
{
|
|
legBone = Get.Finders_GetRelevantChildOf(legBone);
|
|
|
|
bool already = false;
|
|
for (int l = 0; l < Get.Legs.Count; l++)
|
|
{
|
|
var lg = Get.Legs[l];
|
|
if (lg.BoneStart == legBone) { already = true; break; }
|
|
if (lg.BoneMid == legBone) { already = true; break; }
|
|
if (lg.BoneEnd == legBone) { already = true; break; }
|
|
}
|
|
|
|
if (already) continue;
|
|
|
|
Util_DrawLegSegmentSelectorButton(leg, legBone, drawScale, i % 2 == 0, true);
|
|
i += 1;
|
|
}
|
|
}
|
|
|
|
|
|
// Drawing icons of already choosen leg bones
|
|
if (leg.BoneMid != null)
|
|
{
|
|
Util_DrawBoneIndicator(leg.BoneMid, drawScale * 1.65f, true, "", true, true);
|
|
|
|
Handles.color = new Color(0.35f, .925f, 0.65f, 0.65f);
|
|
FGUI_Handles.DrawBoneHandle(leg.BoneMid.position, leg.BoneMid.position, 1f);
|
|
if (Util_DrawButton(new GUIContent(Tex_smLegMid), buttonOff + leg.BoneMid.position + 1.7f * LabelIndicatorHelperOffset(leg.BoneMid, drawScale, true, true), 1f, false))
|
|
{ PingObject(leg.BoneMid); }
|
|
|
|
if (leg.BoneEnd != null) FGUI_Handles.DrawBoneHandle(leg.BoneMid.position, leg.BoneEnd.position, 1f);
|
|
else Util_DrawChildBoneOf(leg.BoneMid, 0.6f);
|
|
}
|
|
|
|
if (leg.BoneEnd != null)
|
|
{
|
|
Util_DrawBoneIndicator(leg.BoneEnd, drawScale * 1.65f, true, "", false, true);
|
|
|
|
Handles.color = new Color(0.1f, .8f, 0.9f, 0.65f);
|
|
if (leg.BoneMid) FGUI_Handles.DrawBoneHandle(leg.BoneMid.position, leg.BoneEnd.position, 1f);
|
|
if (Util_DrawButton(new GUIContent(Tex_smLegEnd), buttonOff + leg.BoneEnd.position + 2f * LabelIndicatorHelperOffset(leg.BoneEnd, drawScale, false, true), 1f, false))
|
|
{ PingObject(leg.BoneEnd); }
|
|
|
|
Util_DrawChildBoneOf(leg.BoneEnd, 0.6f);
|
|
}
|
|
|
|
//Transform lastP = AnimationTools.SkeletonRecognize.GetBottomMostChildTransform(leg.BoneStart);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (leg.OppositeLegIndex != -1)
|
|
if (Get.Legs.ContainsIndex(leg.OppositeLegIndex))
|
|
{
|
|
var oppositeLeg = Get.Legs[leg.OppositeLegIndex];
|
|
|
|
if (oppositeLeg != null)
|
|
{
|
|
Handles.color = new Color(0.7f, 0.7f, 0.2f, 0.25f);
|
|
SceneHelper_Leg_DrawBones(oppositeLeg);
|
|
|
|
Handles.color = new Color(1f, 1f, 1f, 0.4f);
|
|
SceneHelper_DrawLegAsLines(oppositeLeg);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void SceneHelper_DrawLegAsLines(LegsAnimator.Leg leg, float lineWidth = 4f)
|
|
{
|
|
if (leg.BoneStart == null) return;
|
|
if (leg.BoneMid == null) return;
|
|
Handles.DrawAAPolyLine(lineWidth, leg.BoneStart.position, leg.BoneMid.position);
|
|
if (leg.BoneEnd == null) return;
|
|
Handles.DrawAAPolyLine(lineWidth, leg.BoneMid.position, leg.BoneEnd.position);
|
|
}
|
|
|
|
void SceneHelper_DrawScaleReference()
|
|
{
|
|
float rScale = editorScaleRef;
|
|
Handles.color = new Color(0.3f, 0.9f, 0.35f, 0.55f);
|
|
|
|
Vector3 offsetSide = Get.transform.right * rScale * 0.8f;
|
|
Vector3 offsetForw = Get.transform.forward * rScale * 0.2f;
|
|
Vector3 sidePos = Get.transform.position + offsetSide;
|
|
Vector3 sidePosU = Get.transform.position + offsetSide + Get.Up * editorScaleRef;
|
|
|
|
Handles.DrawAAPolyLine(2f + rScale, sidePos + offsetForw, sidePos - offsetForw);
|
|
Handles.DrawAAPolyLine(2f + rScale, sidePosU + offsetForw, sidePosU - offsetForw);
|
|
Handles.DrawAAPolyLine(2f + rScale, sidePos, sidePosU);
|
|
|
|
if (Application.isPlaying == false)
|
|
Handles.Label(sidePos, new GUIContent(" [i]", "Scale reference height. It should be about half of the height of the chracter, if it's two-legs character.\nIf it's quadruped/spider, it should be around height of hips of the creature."));
|
|
}
|
|
|
|
|
|
void SceneHelper_DrawRaycastingCastRange()
|
|
{
|
|
if (Get.RaycastStyle == LegsAnimator.ERaycastStyle.NoRaycasting) return;
|
|
|
|
float rScale = Get.ScaleReference;
|
|
Handles.color = new Color(0.3f, 0.9f, 0.35f, 0.65f);
|
|
|
|
Vector3 offsetSide = -Get.transform.right * rScale * 0.8f;
|
|
Vector3 offsetRight = Get.transform.right * rScale * 0.2f;
|
|
Vector3 sidePos = Get.Hips.position + offsetSide;
|
|
Vector3 grnd = Get.BaseTransform.position;
|
|
|
|
if (Get.RaycastStartHeight == LegsAnimator.ERaycastStartHeight.StaticScaleReference)
|
|
{
|
|
sidePos = Get.transform.position + offsetSide + Get.transform.up * Get.ScaleReference * Get.RaycastStartHeightMul;
|
|
}
|
|
else
|
|
{
|
|
grnd = Get.Hips.position;
|
|
grnd = Get.BaseTransform.InverseTransformPoint(grnd);
|
|
grnd.y = 0f;
|
|
grnd = Get.BaseTransform.TransformPoint(grnd);
|
|
}
|
|
|
|
Vector3 sidePosGrnd = grnd + offsetSide;
|
|
Vector3 sidePosArr = Vector3.LerpUnclamped(sidePos, sidePosGrnd, 0.8f);
|
|
|
|
if (Get.RaycastStyle != LegsAnimator.ERaycastStyle.AlongBones)
|
|
{
|
|
Handles.DrawDottedLine(sidePos, Get.Hips.position, 3f);
|
|
Handles.DrawWireDisc(sidePos, Get.Up, rScale * 0.2f);
|
|
Handles.DrawWireDisc(sidePosGrnd, Get.Up, rScale * 0.2f);
|
|
}
|
|
|
|
if (Get.RaycastStyle == LegsAnimator.ERaycastStyle.StraightDown)
|
|
{
|
|
Handles.DrawAAPolyLine(2f + rScale, sidePos, sidePosGrnd);
|
|
Handles.DrawAAPolyLine(2f + rScale, sidePosGrnd, sidePosArr + offsetRight);
|
|
Handles.DrawAAPolyLine(2f + rScale, sidePosGrnd, sidePosArr - offsetRight);
|
|
}
|
|
|
|
if (Get.RaycastStyle != LegsAnimator.ERaycastStyle.StraightDown && Get.RaycastStyle != LegsAnimator.ERaycastStyle.AlongBones)
|
|
{
|
|
Handles.DrawAAPolyLine(2f + rScale, Get.Hips.position, sidePosGrnd);
|
|
Vector3 dir = sidePosGrnd - Get.Hips.position;
|
|
Quaternion towards = Quaternion.LookRotation(dir, Get.Up);
|
|
Handles.DrawAAPolyLine(2f + rScale, sidePosGrnd, sidePosGrnd - dir * 0.1f + towards * Vector3.up * Get.ScaleReference * 0.125f);
|
|
Handles.DrawAAPolyLine(2f + rScale, sidePosGrnd, sidePosGrnd - dir * 0.1f + towards * Vector3.down * Get.ScaleReference * 0.125f);
|
|
}
|
|
|
|
Vector3 castEnd = sidePosGrnd;
|
|
castEnd += -Get.Up * rScale * Get.CastDistance;
|
|
|
|
if (Get.RaycastStyle != LegsAnimator.ERaycastStyle.OriginToFoot && Get.RaycastStyle != LegsAnimator.ERaycastStyle.AlongBones)
|
|
{
|
|
Handles.DrawDottedLine(sidePosGrnd, castEnd, 3f);
|
|
Handles.DrawWireDisc(castEnd, Get.Up, rScale * 0.2f);
|
|
}
|
|
|
|
if (Get.RaycastStyle == LegsAnimator.ERaycastStyle.AlongBones)
|
|
{
|
|
if (Get.Legs.Count > 0)
|
|
{
|
|
for (int i = 0; i < Get.Legs.Count; i++)
|
|
{
|
|
if (Get.Legs[i].BoneStart && Get.Legs[i].BoneMid && Get.Legs[i].BoneEnd)
|
|
{
|
|
Handles.DrawAAPolyLine(Get.Legs[i].BoneStart.position, Get.Legs[i].BoneMid.position, Get.Legs[i].BoneEnd.position);
|
|
Handles.DrawDottedLine(Get.Legs[i].BoneEnd.position, Get.Legs[i].BoneEnd.position - Get.Up * rScale * Get.CastDistance, 3f);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void SceneHelper_DrawGlueFloorLevel()
|
|
{
|
|
Handles.matrix = Get.BaseTransform.localToWorldMatrix;
|
|
float f = Get.ScaleReferenceNoScale;
|
|
float h = Get.GluingFloorLevelUseOnMoving ? Mathf.Lerp(Get.GluingFloorLevel, Get.GluingFloorLevelOnMoving, Get.IsMovingBlend) : Get.GluingFloorLevel;
|
|
Vector3 a = new Vector3(f, h, f);
|
|
Vector3 b = new Vector3(f, h, -f);
|
|
Vector3 c = new Vector3(-f, h, -f);
|
|
Vector3 d = new Vector3(-f, h, f);
|
|
Handles.DrawAAPolyLine(3f, a, b, c, d, a);
|
|
Handles.matrix = Matrix4x4.identity;
|
|
}
|
|
|
|
|
|
void SceneHelper_DrawRaycastingStepDown()
|
|
{
|
|
if (Get.RaycastStyle == LegsAnimator.ERaycastStyle.NoRaycasting) return;
|
|
|
|
float rScale = Get.ScaleReference;
|
|
Handles.color = new Color(0.6f, 0.4f, 0.1f, 0.4f);
|
|
|
|
Vector3 hipsPos = Get.Hips.position;
|
|
if (Get.LegsInitialized)
|
|
{
|
|
hipsPos = Get.RootToWorldSpace(Get.HipsSetup.InitHipsPositionRootSpace);
|
|
}
|
|
|
|
Vector3 offsetSide = Get.transform.right * rScale * 0.8f;
|
|
Vector3 offsetRight = Get.transform.right * rScale * 0.2f;
|
|
Vector3 offsetForw = Get.transform.forward * rScale * 0.2f;
|
|
Vector3 sidePos = hipsPos + offsetSide;
|
|
|
|
Vector3 bodyEnd = sidePos;
|
|
bodyEnd += -Get.Up * rScale * Get.BodyStepDown;
|
|
|
|
float hipsToGround = Get.HipsToGroundDistance();
|
|
if (Get.LegsInitialized) hipsToGround = Get.HipsSetup.InitialHipsHeightLocal * Get.BaseTransform.lossyScale.y;
|
|
|
|
Vector3 bodyEndLeg = bodyEnd - Get.Up * hipsToGround;
|
|
|
|
if (Get.BodyStepDown > 0f)
|
|
{
|
|
Handles.DrawDottedLine(sidePos, hipsPos, 3f);
|
|
Handles.SphereHandleCap(0, sidePos, Quaternion.identity, rScale * 0.1f, EventType.Repaint);
|
|
|
|
|
|
Handles.DrawAAPolyLine(2f + rScale, sidePos, bodyEnd);
|
|
Handles.DrawWireDisc(bodyEnd, Get.Up, rScale * 0.2f);
|
|
|
|
Handles.DrawAAPolyLine(3f + rScale, bodyEnd + offsetRight, bodyEndLeg + offsetRight, bodyEndLeg + offsetRight + offsetForw);
|
|
Handles.DrawAAPolyLine(3f + rScale, bodyEnd - offsetRight, bodyEndLeg - offsetRight, bodyEndLeg - offsetRight + offsetForw);
|
|
}
|
|
|
|
if (Get.MaxBodyStepUp > 0f)
|
|
{
|
|
Vector3 bodyUpper = sidePos + offsetSide;
|
|
bodyUpper += Get.Up * rScale * Get.MaxBodyStepUp;
|
|
Handles.DrawDottedLine(bodyUpper, sidePos + offsetSide, 3f);
|
|
Handles.DrawDottedLine(sidePos + offsetSide, sidePos, 3f);
|
|
|
|
Handles.SphereHandleCap(0, bodyUpper, Quaternion.identity, rScale * 0.1f, EventType.Repaint);
|
|
bodyEndLeg = bodyUpper - Get.Up * hipsToGround;
|
|
Handles.DrawWireDisc(bodyUpper, Get.Up, rScale * 0.2f);
|
|
|
|
Handles.DrawAAPolyLine(3f + rScale, bodyUpper + offsetRight, bodyEndLeg + offsetRight, bodyEndLeg + offsetRight + offsetForw);
|
|
Handles.DrawAAPolyLine(3f + rScale, bodyUpper - offsetRight, bodyEndLeg - offsetRight, bodyEndLeg - offsetRight + offsetForw);
|
|
}
|
|
|
|
}
|
|
|
|
protected void SceneHelper_DrawExtraControll()
|
|
{
|
|
Handles.matrix = Get.BaseTransform.localToWorldMatrix;
|
|
|
|
//if (Get.FloorLevel != 0f)
|
|
{
|
|
float planeScale = Get.ScaleReference * 0.425f;
|
|
float yl = Get.GluingFloorLevel;
|
|
|
|
Handles.color = new Color(0.4f, 0.45f, 1f, 0.5f);
|
|
|
|
Handles.DrawAAPolyLine(2, new Vector3(-planeScale, yl, -planeScale),
|
|
new Vector3(planeScale, yl, -planeScale),
|
|
new Vector3(planeScale, yl, planeScale),
|
|
new Vector3(-planeScale, yl, planeScale),
|
|
new Vector3(-planeScale, yl, -planeScale));
|
|
|
|
planeScale *= 0.5f;
|
|
Handles.color *= 0.75f;
|
|
Handles.DrawWireDisc(Vector3.zero, Get.Up, planeScale);
|
|
Handles.DrawLine(new Vector3(0f, yl, planeScale), new Vector3(0f, yl, -planeScale));
|
|
Handles.DrawLine(new Vector3(planeScale, yl, 0f), new Vector3(-planeScale, yl, 0f));
|
|
}
|
|
|
|
Handles.matrix = Matrix4x4.identity;
|
|
}
|
|
|
|
void SceneHelper_DrawRaycastingPreview(Color baseColor)
|
|
{
|
|
if (Application.isPlaying == false) return;
|
|
|
|
float scaleRefSm = Get.ScaleReference * 0.1f;
|
|
|
|
Handles.color = baseColor;
|
|
for (int l = 0; l < Get.Legs.Count; l++)
|
|
{
|
|
var leg = Get.Legs[l];
|
|
|
|
if (!leg.RaycastHitted)
|
|
{
|
|
Handles.DrawWireDisc(leg.BoneEnd.position, Get.Up, scaleRefSm);
|
|
break;
|
|
}
|
|
|
|
RaycastHit hit = leg.LastGroundHit;
|
|
|
|
Handles.DrawWireDisc(hit.point, hit.normal, scaleRefSm);
|
|
Handles.DrawLine(hit.point, hit.point + hit.normal * scaleRefSm);
|
|
Handles.SphereHandleCap(0, hit.point + hit.normal * scaleRefSm, Quaternion.identity, scaleRefSm * 0.5f, EventType.Repaint);
|
|
}
|
|
}
|
|
|
|
|
|
void SceneHelper_DrawFeetLength()
|
|
{
|
|
//if (_setupik_selected_leg < 0)
|
|
// Handles.color = Color.green * 0.9f;
|
|
//else
|
|
// Handles.color = Color.green * 0.4f;
|
|
|
|
//for (int l = 0; l < Get.Legs.Count; l++)
|
|
//{
|
|
// var leg = Get.Legs[l];
|
|
// if (leg.BoneEnd == null) continue;
|
|
|
|
// Vector3 heelStart = leg.BoneEnd.TransformPoint(leg.AnkleToHeel);
|
|
// Vector3 footEnd = leg.BoneEnd.TransformPoint(leg.AnkleToFeetEnd);
|
|
// Vector3 toEnd = footEnd - heelStart;
|
|
// Vector3 right = leg.BoneEnd.TransformDirection(leg.AnkleRight).normalized * toEnd.magnitude * 0.4f;
|
|
// Vector3 end = footEnd + toEnd * Get.FeetLengthAdjust;
|
|
|
|
// Handles.DrawAAPolyLine(3f, heelStart + right, end + right, end - right, heelStart - right);
|
|
//}
|
|
}
|
|
|
|
void SceneHelper_DrawIKSetup(Color mainColor, int selected)
|
|
{
|
|
float scaleRef = Get.ScaleReference;
|
|
float scaleRefShort = Get.ScaleReference * 0.2f;
|
|
float scaleRefShort2 = scaleRefShort * 0.25f;
|
|
|
|
for (int i = 0; i < Get.Legs.Count; i++)
|
|
{
|
|
var leg = Get.Legs[i];
|
|
if (leg.HasAllBonesSet() == false) continue;
|
|
|
|
bool isSel = selected == i;
|
|
if (selected < -1) isSel = true;
|
|
|
|
Handles.color = mainColor * (isSel ? 1f : 0.5f);
|
|
Handles.DrawLine(leg.BoneStart.position, Get.Hips.position);
|
|
FGUI_Handles.DrawBoneHandle(leg.BoneStart.position, leg.BoneMid.position, 0.6f);
|
|
FGUI_Handles.DrawBoneHandle(leg.BoneMid.position, leg.BoneEnd.position, 0.6f);
|
|
|
|
Vector3 heel = leg.BoneEnd.TransformPoint(leg.AnkleToHeel);
|
|
|
|
if (Get.AnimateFeet)
|
|
{
|
|
Handles.color = mainColor * (isSel ? 0.8f : 0.3f);
|
|
|
|
//Vector3 heelForw = heel + leg.BoneEnd.TransformDirection(leg.AnkleForward * scaleRefShort);
|
|
Vector3 footEnd = leg.BoneEnd.TransformPoint(leg.AnkleToFeetEnd);
|
|
Vector3 heelForw = footEnd + (footEnd - heel) * Get.FeetLengthAdjust;
|
|
|
|
Vector3 heelUp = heelForw + leg.BoneEnd.TransformDirection(leg.AnkleUp * scaleRefShort2);
|
|
|
|
Handles.DrawAAPolyLine(2 + scaleRef, leg.BoneEnd.position, heel, heelForw, heelUp, leg.BoneEnd.position);
|
|
Handles.DrawAAPolyLine(2 + scaleRef, heelForw, heel + leg.BoneEnd.TransformDirection(leg.AnkleRight * scaleRefShort2), heel - leg.BoneEnd.TransformDirection(leg.AnkleRight * scaleRefShort2), heelForw);
|
|
|
|
scaleRefShort2 *= 2f;
|
|
Vector3 feetEnd = Vector3.LerpUnclamped(heel, heelForw, leg.FootMiddlePosition);
|
|
Handles.DrawAAPolyLine(2 + scaleRef, feetEnd - Get.BaseTransform.right * scaleRefShort2, feetEnd + Get.BaseTransform.right * scaleRefShort2);
|
|
Handles.DrawAAPolyLine(2 + scaleRef, feetEnd, heel);
|
|
}
|
|
else
|
|
{
|
|
Handles.DrawAAPolyLine(2 + scaleRef, leg.BoneEnd.position, heel);
|
|
|
|
Handles.color *= 0.6f;
|
|
Handles.DrawWireDisc(heel, Get.Up, scaleRefShort2);
|
|
|
|
if (isSel && selected > -2)
|
|
{
|
|
Handles.color *= 0.7f;
|
|
Handles.DrawWireDisc(leg.BoneEnd.position, Get.Up, scaleRefShort2);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void SceneHelper_DrawDefinedBones(Color? customColor = null)
|
|
{
|
|
if (_selected_leg >= 0) return;
|
|
if (Get.Hips == null) return;
|
|
|
|
Handles.color = new Color(0.25f, 0.9f, 0.7f, 0.8f);
|
|
if (customColor != null) Handles.color = customColor.Value;
|
|
|
|
for (int i = 0; i < Get.Legs.Count; i++)
|
|
{
|
|
var leg = Get.Legs[i];
|
|
SceneHelper_Leg_DrawBones(leg);
|
|
}
|
|
|
|
if (SceneHelper_FocusOnBone == null)
|
|
{
|
|
Handles.SphereHandleCap(0, Get.Hips.position, Quaternion.identity, editorScaleRef * 0.07f, EventType.Repaint);
|
|
}
|
|
}
|
|
|
|
|
|
void SceneHelper_DrawDefinedBonesHipsLink(Color? customColor = null)
|
|
{
|
|
if (_selected_leg >= 0) return;
|
|
if (Get.Hips == null) return;
|
|
|
|
Handles.color = new Color(0.3f, 0.9f, 0.75f, 0.4f);
|
|
if (customColor != null) Handles.color = customColor.Value;
|
|
|
|
for (int i = 0; i < Get.Legs.Count; i++)
|
|
{
|
|
var leg = Get.Legs[i];
|
|
if (leg.BoneEnd == null) continue;
|
|
Handles.DrawDottedLine(leg.BoneEnd.position, Get.Hips.position, 3f);
|
|
}
|
|
|
|
}
|
|
|
|
void SceneHelper_Leg_DrawBones(LegsAnimator.Leg leg)
|
|
{
|
|
if (leg.BoneStart)
|
|
{
|
|
if (leg.BoneMid) FGUI_Handles.DrawBoneHandle(leg.BoneStart.position, leg.BoneMid.position);
|
|
else Util_DrawChildBoneOf(leg.BoneStart);
|
|
|
|
Handles.DrawDottedLine(leg.BoneStart.position, Get.Hips.position, 2f);
|
|
}
|
|
|
|
if (leg.BoneMid)
|
|
{
|
|
if (leg.BoneEnd) FGUI_Handles.DrawBoneHandle(leg.BoneMid.position, leg.BoneEnd.position);
|
|
else Util_DrawChildBoneOf(leg.BoneMid);
|
|
}
|
|
|
|
if (leg.BoneEnd)
|
|
{
|
|
Util_DrawChildBoneOf(leg.BoneEnd);
|
|
}
|
|
}
|
|
|
|
|
|
void Util_DrawLegSegmentSelectorButton(LegsAnimator.Leg leg, Transform t, float drawScale, bool mirror = false, bool upMode = false)
|
|
{
|
|
Handles.color = new Color(0.4f, 1f, 0.65f, 0.3f);
|
|
Util_DrawChildBoneOf(t.parent, 0.4f);
|
|
|
|
float mul = 1f;
|
|
if (leg.BoneMid == t || leg.BoneEnd == t) mul = -1f;
|
|
|
|
Util_DrawBoneIndicator(t, drawScale * mul * 0.7f, false, mul == -1f ? "Change" : "", mirror, upMode);
|
|
|
|
Vector3 off = LabelIndicatorHelperOffset(t, drawScale, mirror) * 0.6f;
|
|
float hSize = HandleUtility.GetHandleSize(t.position);
|
|
float scaler = 1f / hSize;
|
|
|
|
if (leg.BoneMid == null)
|
|
{
|
|
Handles.color = new Color(1f, 1f, 1f, 1f);
|
|
if (Util_DrawButton(new GUIContent(Tex_LegMid), t.position + off * 0.2f, 1f))
|
|
{
|
|
leg.BoneMid = t;
|
|
OnChange();
|
|
}
|
|
|
|
}
|
|
|
|
if (leg.BoneEnd == null && leg.BoneMid != null)
|
|
{
|
|
Handles.color = new Color(1f, 1f, 1f, 1f);
|
|
if (Util_DrawButton(new GUIContent(Tex_LegEnd), t.position + off * 0.2f, 1f, true, new Vector2(1, 0)))
|
|
{
|
|
leg.BoneEnd = t;
|
|
leg.DefineLegSide(Get);
|
|
leg.RefreshLegAnkleToHeelAndFeetAndAxes(Get.BaseTransform);
|
|
OnChange();
|
|
}
|
|
}
|
|
|
|
|
|
if (hSize > 0.01f)
|
|
{
|
|
float mouseOnDistance = 1000f;
|
|
|
|
int sel = 0;
|
|
if (leg.BoneMid == null)
|
|
{
|
|
mouseOnDistance = Vector2.Distance(Event.current.mousePosition, HandleUtility.WorldToGUIPoint(t.position /*+ off*/));
|
|
sel = 1;
|
|
}
|
|
else
|
|
if (leg.BoneEnd == null)
|
|
{
|
|
float dist2 = Vector2.Distance(Event.current.mousePosition, HandleUtility.WorldToGUIPoint(t.position /*+ off + ScView.camera.transform.rotation * Vector3.right * drawScale * 1.25f*/));
|
|
if (dist2 < mouseOnDistance) { mouseOnDistance = dist2; sel = 2; }
|
|
}
|
|
|
|
if (mouseOnDistance < 1f * scaler)
|
|
{
|
|
Util_DrawChildBoneOf(t, .6f);
|
|
|
|
if (t.childCount > 0)
|
|
if (sel > 0)
|
|
{
|
|
string label = sel == 1 ? "? Is it Lower Leg ?" : "? IS it Foot Bone ?";
|
|
Vector3 labelPos = Vector3.Lerp(t.position, t.GetChild(0).position, 0.35f);
|
|
labelPos += ScView.camera.transform.rotation * Vector3.right * drawScale * 0.15f;
|
|
Handles.Label(labelPos, label, EditorStyles.boldLabel);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void Util_DrawBoneIndicator(Transform b, float drawScale, bool drawSphere = false, string customString = "", bool mirror = false, bool upMode = false)
|
|
{
|
|
if (b == null) return;
|
|
|
|
Handles.color = new Color(0.6f, 0.6f, 0.7f, 0.65f);
|
|
|
|
if (drawSphere)
|
|
{
|
|
Handles.SphereHandleCap(0, b.position, Quaternion.identity, drawScale * 0.5f, EventType.Repaint);
|
|
}
|
|
|
|
Vector3 labelPos = b.position + LabelIndicatorHelperOffset(b, drawScale, mirror, upMode);
|
|
labelPos += Vector3.up * drawScale * 0.4f;
|
|
|
|
Handles.DrawLine(b.position, labelPos);
|
|
Handles.color = Color.white;
|
|
Handles.Label(labelPos + Vector3.up * drawScale * 0.5f, string.IsNullOrEmpty(customString) ? b.name : customString);
|
|
}
|
|
|
|
|
|
Vector3 LabelIndicatorHelperOffset(Transform b, float drawScale, bool mirror = false, bool upMode = false)
|
|
{
|
|
if (upMode) return ScView.camera.transform.rotation * new Vector3(mirror ? 0.2f : -.2f, mirror ? 0.8f : -0.8f, 0.3f) * Get.Util_SideMul(b) * drawScale * 3f;
|
|
|
|
return ScView.camera.transform.rotation * new Vector3(mirror ? 0.9f : -.8f, 0.33f, 0f) * Get.Util_SideMul(b) * drawScale * 3f;
|
|
}
|
|
|
|
void Util_DrawChildBoneOf(Transform t, float fatness = 1f)
|
|
{
|
|
if (t.childCount <= 0) return;
|
|
FGUI_Handles.DrawBoneHandle(t.position, Get.Finders_GetRelevantChildOf(t).position, fatness);
|
|
}
|
|
|
|
|
|
bool Util_Leg_ShouldDraw(Transform t)
|
|
{
|
|
//if (t == SceneHelper_FocusOnBone) return false;
|
|
|
|
for (int i = 0; i < Get.Legs.Count; i++)
|
|
{
|
|
var leg = Get.Legs[i];
|
|
if (leg.BoneStart == t) return false;
|
|
if (leg.BoneMid == t) return false;
|
|
if (leg.BoneEnd == t) return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static GUIStyle ButtonStyle { get { if (__buttStyleHard != null) return __buttStyleHard; __buttStyleHard = new GUIStyle(EditorStyles.miniButton); __buttStyleHard.fixedHeight = 0; __buttStyleHard.padding = new RectOffset(3, 3, 3, 3); __buttStyleHard.normal.background = Resources.Load<Texture2D>("Fimp/Backgrounds/FbuttonH"); __buttStyleHard.hover.background = Resources.Load<Texture2D>("Fimp/FbuttonHover"); __buttStyleHard.focused.background = __buttStyleHard.hover.background; __buttStyleHard.active.background = Resources.Load<Texture2D>("Fimp/Backgrounds/ButtonStyle"); return __buttStyleHard; } }
|
|
private static GUIStyle __buttStyleHard = null;
|
|
|
|
bool Util_DrawButton(GUIContent content, Vector3 pos, float size, bool buttonBG = true, Vector2? rectOffset = null)
|
|
{
|
|
float sc = HandleUtility.GetHandleSize(pos);
|
|
float hSize = Mathf.Sqrt(size) * 32 - sc * 16;
|
|
|
|
if (hSize > 0f)
|
|
{
|
|
Handles.BeginGUI();
|
|
Vector2 pos2D = HandleUtility.WorldToGUIPoint(pos);
|
|
float hhSize = hSize / 2f;
|
|
|
|
GUIStyle style = buttonBG ? ButtonStyle : EditorStyles.label;
|
|
|
|
if (rectOffset != null) pos2D += rectOffset.Value * hSize;
|
|
|
|
if (GUI.Button(new Rect(pos2D.x - hhSize, pos2D.y - hhSize, hSize, hSize), content, style))
|
|
{
|
|
Handles.EndGUI();
|
|
return true;
|
|
}
|
|
|
|
Handles.EndGUI();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
Color Util_IndexColor(int index, float s = 0.3f, float v = 0.45f, float hueOff = 0f, float hueMul = 1f)
|
|
{
|
|
float h = ((float)index * 0.1f * hueMul + 0.2f + hueOff) % 1;
|
|
return Color.HSVToRGB(h, s, v);
|
|
}
|
|
|
|
void PingObject(UnityEngine.Object g)
|
|
{
|
|
EditorGUIUtility.PingObject(g);
|
|
}
|
|
|
|
}
|
|
|
|
} |