123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528 |
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using XRTool.Util;
- using SC.XR.Unity.Module_InputSystem;
- using System;
- using System.Linq;
- using ShadowStudio.Model;
- using UnityEngine.EventSystems;
- using TriLib.Extras;
- namespace ShadowStudio.Tool
- {
- /// <summary>
- /// 画笔功能
- /// </summary>
- public class DrawPener : UnitySingleton<DrawPener>
- {
- /// <summary>
- /// 笔的材质
- /// </summary>
- public Material penMate;
- /// <summary>
- /// 笔颜色的名称
- /// </summary>
- public string colorName;
- /// <summary>
- /// 最小间距
- /// </summary>
- public float minDis = 0.01f;
- /// <summary>
- /// 默认笔头的粗细
- /// </summary>
- public float radius = 0.005f;
- /// <summary>
- /// 笔的颜色
- /// </summary>
- public Color penColor = Color.white;
- /// <summary>
- /// 线的预制体
- /// </summary>
- public LineSegment linePrefab;
- /// <summary>
- /// 每根线段最多100点
- /// </summary>
- public int maxPointOfLine = 100;
- /// <summary>
- /// 所有线段加起来最多500个点
- /// </summary>
- public int maxPointOfSegment = 500;
- /// <summary>
- /// 有可能要撤销对应的组件
- /// </summary>
- private Queue<LineSegment> lines;
- private LineSegment currentLine;
- private Coroutine drawCoroutine;
- private InputDevicePartBase part;
- private Vector3 lastPosition = Vector3.zero;
- public string defaultShader = "Mixed Reality Toolkit/Standard";
- private int currentPoint;
- /// <summary>
- /// 资源的id
- /// </summary>
- public static string artLineId = "ArtId_GameObject";
- /// <summary>
- /// 线与对应的名字的集合
- /// </summary>
- private Dictionary<string, LineSegment> lineMap;
- /// <summary>
- /// 请他用户的线段id
- /// 仅房主使用此数据
- /// </summary>
- private List<int> otherUserList;
- private List<int> userList;
- private DrawPlaneContainer drawPlane;
- public List<int> OtherUserList
- {
- get
- {
- if (otherUserList == null)
- {
- otherUserList = new List<int>();
- }
- return otherUserList;
- }
- }
- public List<int> UserList
- {
- get
- {
- if (userList == null)
- {
- userList = new List<int>();
- }
- return userList;
- }
- }
- public LineSegment GetLine(string lineName)
- {
- if (lineMap != null && lineMap.ContainsKey(lineName))
- {
- return lineMap[lineName];
- }
- return null;
- }
- protected override void Awake()
- {
- base.Awake();
- DisActiveDrawPen();
- }
- public void ActiveDrawPen()
- {
- gameObject.SetActive(true);
- }
- /// <summary>
- /// 添加老线
- /// </summary>
- /// <param name="line"></param>
- public void AddOldLine(LineSegment line)
- {
- if (line)
- {
- if (lineMap == null)
- {
- lineMap = new Dictionary<string, LineSegment>();
- }
- if (!lineMap.ContainsKey(line.name))
- {
- lineMap.Add(line.name, line);
- }
- if (lines == null)
- {
- lines = new Queue<LineSegment>();
- }
- if (line.Line.positionCount > 0 && !lines.Contains(line))
- {
- currentPoint += line.Line.positionCount;
- lines.Enqueue(line);
- }
- }
- }
- public void DisActiveDrawPen()
- {
- gameObject.SetActive(false);
- }
- public void OnEnable()
- {
- DispatcherBase.KeyDownDelegateRegister(OnKeyDownAction);
- DispatcherBase.KeyUpDelegateRegister(OnKeyUpAction);
- //caoting 2021/6/11 合并新的sdk
- if (SCInputModule.Instance)
- {
- SCInputModule.Instance.CanDrag = false;
- }
- }
- private void OnDisable()
- {
- DispatcherBase.KeyDownDelegateUnRegister(OnKeyDownAction);
- DispatcherBase.KeyUpDelegateUnRegister(OnKeyUpAction);
- //caoting 2021/6/11 合并新的sdk
- if (SCInputModule.Instance)
- {
- SCInputModule.Instance.CanDrag = true;
- }
- }
- /// <summary>
- /// 抬起按钮时
- /// </summary>
- /// <param name="keyCode"></param>
- /// <param name="part"></param>
- private void OnKeyUpAction(InputKeyCode keyCode, InputDevicePartBase part)
- {
- drawPlane = null;
- lastPosition = Vector3.zero;
- ClearPen();
- isHandlerobj = false;
- distance = 0;
- isNoCheck = false;
- }
- public void ClearPen()
- {
- if (drawCoroutine != null)
- {
- StopCoroutine(drawCoroutine);
- }
- drawCoroutine = null;
- if (lines == null)
- {
- lines = new Queue<LineSegment>();
- }
- if (currentLine)
- {
- if (currentLine.Line.positionCount > 1)
- {
- if (!lines.Contains(currentLine))
- {
- currentLine.StopSyn();
- lines.Enqueue(currentLine);
- }
- }
- else
- {
- Destroy(currentLine.gameObject);
- }
- }
- currentLine = null;
- }
- private bool isHandlerobj;
- private bool isNoCheck;
- private float distance;
- /// <summary>
- /// 按下按钮时
- /// </summary>
- /// <param name="keyCode"></param>
- /// <param name="part"></param>
- private void OnKeyDownAction(InputKeyCode keyCode, InputDevicePartBase part)
- {
- if (lines == null)
- {
- lines = new Queue<LineSegment>();
- }
- ///当前的还存在上一个画笔
- if (currentLine || drawCoroutine != null || this.part != part)
- {
- ClearPen();
- }
- ///当大于线段时,清除掉相关的线段
- while (currentPoint >= maxPointOfSegment - maxPointOfLine)
- {
- ClearOldLine();
- }
- this.part = part;
- var tmp = part.inputDataBase.SCPointEventData.pointerCurrentRaycast.gameObject;
- if (tmp)
- {
- ///如果点击了某个UI按钮,触发对应的点击事件,不绘制图形
- var tmpbutton = tmp.GetComponentInParent<IPointerClickHandler>();
- if (tmpbutton != null)
- {
- if (!isNoCheck)
- {
- isHandlerobj = true;
- if (isHandlerobj)
- {
- if (distance == 0)
- {
- distance = GetDis();
- }
- }
- }
- //tmpbutto n.OnPointerClick(part.inputDataBase.SCPointEventData);
- //return;
- }
- var downHandler = tmp.GetComponentInParent<IPointerDownHandler>();
- if (downHandler != null)
- {
- if (!isNoCheck)
- {
- isHandlerobj = true;
- if (isHandlerobj)
- {
- if (distance == 0)
- {
- distance = GetDis();
- }
- }
- }
- //downHandler.OnPointerDown(part.inputDataBase.SCPointEventData);
- //return;
- }
- ///在画板上绘制
- else if (drawPlane = tmp.GetComponentInParent<DrawPlaneContainer>())
- {
- }
- else
- {
- drawPlane = null;
- }
- }
- drawCoroutine = StartCoroutine(DrawLine(keyCode));
- }
- private float helpAngle = 1f;
- /// <summary>
- /// 画线功能的实现
- /// 如果画在画线板上时,不计入总点数
- /// </summary>
- /// <param name="keyCode"></param>
- /// <returns></returns>
- private IEnumerator DrawLine(InputKeyCode keyCode)
- {
- var obj = part.inputDataBase.SCPointEventData.pointerCurrentRaycast.gameObject;
- currentLine = CreateLine();
- currentLine.IsSingleLine = !drawPlane;
- if (lineMap == null)
- {
- lineMap = new Dictionary<string, LineSegment>();
- }
- if (!lineMap.ContainsKey(currentLine.name))
- {
- lineMap.Add(currentLine.name, currentLine);
- }
- yield return currentLine;
- Vector3 pointPos = part.detectorBase.pointerBase.cursorBase.transform.position;
- //Vector3 pointPos = part.pointerBase.cursorBase.transform.position;
- if (API_Module_InputSystem.InputDeviceStatus(InputDeviceType.KS))
- {
- pointPos = API_Module_InputSystem_KS.KSPosition(API_Module_InputSystem_KS.GCType.Right);
- pointPos += API_Module_InputSystem_KS.KSTransform(API_Module_InputSystem_KS.GCType.Right).forward.normalized * SystemSettingMgr.Instance.settings.RayDis;
- }
- if (lastPosition != Vector3.zero)
- {
- GameNode.Instance.SetParent(ObjNode.World, currentLine.transform,
- GameNode.Instance.LocalPosition(ObjNode.World, lastPosition, 1), Vector3.zero, Vector3.one, true);
- currentLine.AddPosition(lastPosition);
- currentPoint++;
- }
- else
- {
- GameNode.Instance.SetParent(ObjNode.World, currentLine.transform,
- GameNode.Instance.LocalPosition(ObjNode.World, pointPos, 1), Vector3.zero, Vector3.one, true);
- }
- while (currentLine && part)
- {
- //if (obj != part.inputDataBase.SCPointEventData.pointerCurrentRaycast.gameObject)
- //{
- // OnKeyUpAction(keyCode, part);
- // yield break;
- //}
- Vector3 posks = part.detectorBase.pointerBase.cursorBase.transform.position;
- if (API_Module_InputSystem.InputDeviceStatus(InputDeviceType.KS))
- {
- posks = API_Module_InputSystem_KS.KSPosition(API_Module_InputSystem_KS.GCType.Right);
- posks += API_Module_InputSystem_KS.KSTransform(API_Module_InputSystem_KS.GCType.Right).forward.normalized * SystemSettingMgr.Instance.settings.RayDis;
- }
- if (currentLine.Line.positionCount < 1 || Vector3.Distance(posks, pointPos) >= (obj ? (minDis / 5f) : minDis))
- {
- bool addPoint = true;
- if (currentLine.Line.positionCount > 1)
- {
- Vector3 lastDir = currentLine.transform.TransformPoint(currentLine.Line.GetPosition(currentLine.Line.positionCount - 1)) -
- currentLine.transform.TransformPoint(currentLine.Line.GetPosition(currentLine.Line.positionCount - 2));
- Vector3 curDir = posks -
- currentLine.transform.TransformPoint(currentLine.Line.GetPosition(currentLine.Line.positionCount - 1));
- if (Vector3.Angle(lastDir, curDir) < helpAngle)
- {
- UnityLog.Instance.Log(Vector3.Angle(lastDir, curDir), 4);
- addPoint = false;
- if (isHandlerobj)
- {
- pointPos = GameSession.Instance.GetHeadForwadPos(distance, false);
- currentLine.SetPosition(pointPos);
- }
- else
- {
- currentLine.SetPosition(posks);
- }
- }
- }
- if (addPoint)
- {
- if (isHandlerobj)
- {
- pointPos = GameSession.Instance.GetHeadForwadPos(distance, false);
- }
- else
- {
- pointPos = posks;
- }
- currentLine.AddPosition(pointPos);
- currentPoint++;
- }
- }
- if (currentLine.Line.positionCount >= maxPointOfLine)
- {
- lastPosition = pointPos;
- isNoCheck = true;
- OnKeyDownAction(keyCode, part);
- yield break;
- }
- yield return new WaitForFixedUpdate();
- //part.inputDataBase.SCPointEventData.pointerCurrentRaycast.gameObject;
- //part.pointerBase.cursorBase.transform.position;
- }
- }
- /// <summary>
- /// 创建线段
- /// </summary>
- /// <returns></returns>
- public LineSegment CreateLine()
- {
- LineSegment line;
- var lineName = UnityEngine.Random.Range(100000000, 999999999).ToString(); // DateTime.Now.ToString("MMddHHmmssf");
- if (linePrefab)
- {
- line = Instantiate(linePrefab);
- line.name = lineName;
- }
- else
- {
- GameObject obj = new GameObject(lineName, typeof(LineRenderer));
- line = obj.AddComponent<LineSegment>();
- //if (!line.Line.sharedMaterial)
- //{
- // line.Line.sharedMaterial = penMate;
- //}
- }
- if (line)
- {
- ///如果设置了默认的材质,则使用默认材质
- if (penMate)
- {
- line.SetLine(penMate);
- }
- line.SetLine(penColor, radius, colorName);
- }
- line.Line.positionCount = 0;
- line.Line.useWorldSpace = false;
- ///如果存在物体,则改变对齐模式,使线段看起来平整圆滑
- if (part != null && part.inputDataBase.SCPointEventData.pointerCurrentRaycast.gameObject)
- {
- line.Line.alignment = LineAlignment.TransformZ;
- }
- GameNode.Instance.SetParent(ObjNode.World, line.transform,
- Vector3.zero, Vector3.zero, Vector3.one, true);
- return line;
- }
- /// <summary>
- /// 清除本地自己的老线段
- /// 为什么不在线发送确认清除?因为延时问题造成的不流畅问题
- /// 主动删除并释放本地内存,然后发送同步信息删除线段
- /// </summary>
- public void ClearOldLine()
- {
- ///如果此条线段尚未同步,则禁止本地删除
- if (lines.Count > 0)
- {
- var line = lines.Dequeue();
- if (line)
- {
- currentPoint -= line.Line.positionCount;
- lineMap.Remove(line.name);
- ///删除线段
- line.DelLine();
- Destroy(line.gameObject);
- }
- }
- }
- /// <summary>
- /// 清除指定的线,删除此线段
- /// 如果此线段属于用户自己创建的,则清空对应的内存
- /// </summary>
- /// <param name="line"></param>
- public void ClearOldLine(LineSegment line)
- {
- if (line)
- {
- if (lineMap != null && lineMap.ContainsKey(line.name))
- {
- currentPoint -= line.Line.positionCount;
- lineMap.Remove(line.name);
- }
- Destroy(line.gameObject);
- }
- }
- /// <summary>
- /// 清除所有线段
- /// </summary>
- public void ClearAllLine(bool isClearAll = false)
- {
- if (UserList != null)
- {
- ArtInfoMgr.Instance.DelGoodsByIds(UserList);
- }
- if (isClearAll)
- {
- ClearOtherLine();
- }
- }
- /// <summary>
- /// 删除
- /// </summary>
- /// <param name="id"></param>
- public void AddLineId(int id, bool isOther = true)
- {
- if (isOther)
- {
- OtherUserList.Add(id);
- }
- else
- {
- UserList.Add(id);
- }
- }
- /// <summary>
- /// 清空其他用户的线段
- /// </summary>
- public void ClearOtherLine()
- {
- ArtInfoMgr.Instance.DelGoodsByIds(OtherUserList);
- }
- public float GetDis()
- {
- Vector3 posks = part.detectorBase.pointerBase.cursorBase.transform.position;
- if (API_Module_InputSystem.InputDeviceStatus(InputDeviceType.KS))
- {
- posks = API_Module_InputSystem_KS.KSPosition(API_Module_InputSystem_KS.GCType.Right);
- posks += API_Module_InputSystem_KS.KSTransform(API_Module_InputSystem_KS.GCType.Right).forward.normalized * SystemSettingMgr.Instance.settings.RayDis;
- }
- float dis= Vector3.Distance(posks, GameSession.Instance.gameHead.position);
- return dis;
- }
- }
- }
|