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
{
///
/// 画笔功能
///
public class DrawPener : UnitySingleton
{
///
/// 笔的材质
///
public Material penMate;
///
/// 笔颜色的名称
///
public string colorName;
///
/// 最小间距
///
public float minDis = 0.01f;
///
/// 默认笔头的粗细
///
public float radius = 0.005f;
///
/// 笔的颜色
///
public Color penColor = Color.white;
///
/// 线的预制体
///
public LineSegment linePrefab;
///
/// 每根线段最多100点
///
public int maxPointOfLine = 100;
///
/// 所有线段加起来最多500个点
///
public int maxPointOfSegment = 500;
///
/// 有可能要撤销对应的组件
///
private Queue 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;
///
/// 资源的id
///
public static string artLineId = "ArtId_GameObject";
///
/// 线与对应的名字的集合
///
private Dictionary lineMap;
///
/// 请他用户的线段id
/// 仅房主使用此数据
///
private List otherUserList;
private List userList;
private DrawPlaneContainer drawPlane;
public List OtherUserList
{
get
{
if (otherUserList == null)
{
otherUserList = new List();
}
return otherUserList;
}
}
public List UserList
{
get
{
if (userList == null)
{
userList = new List();
}
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);
}
///
/// 添加老线
///
///
public void AddOldLine(LineSegment line)
{
if (line)
{
if (lineMap == null)
{
lineMap = new Dictionary();
}
if (!lineMap.ContainsKey(line.name))
{
lineMap.Add(line.name, line);
}
if (lines == null)
{
lines = new Queue();
}
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;
}
}
///
/// 抬起按钮时
///
///
///
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();
}
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;
///
/// 按下按钮时
///
///
///
private void OnKeyDownAction(InputKeyCode keyCode, InputDevicePartBase part)
{
if (lines == null)
{
lines = new Queue();
}
///当前的还存在上一个画笔
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();
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();
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())
{
}
else
{
drawPlane = null;
}
}
drawCoroutine = StartCoroutine(DrawLine(keyCode));
}
private float helpAngle = 1f;
///
/// 画线功能的实现
/// 如果画在画线板上时,不计入总点数
///
///
///
private IEnumerator DrawLine(InputKeyCode keyCode)
{
var obj = part.inputDataBase.SCPointEventData.pointerCurrentRaycast.gameObject;
currentLine = CreateLine();
currentLine.IsSingleLine = !drawPlane;
if (lineMap == null)
{
lineMap = new Dictionary();
}
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;
}
}
///
/// 创建线段
///
///
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();
//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;
}
///
/// 清除本地自己的老线段
/// 为什么不在线发送确认清除?因为延时问题造成的不流畅问题
/// 主动删除并释放本地内存,然后发送同步信息删除线段
///
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);
}
}
}
///
/// 清除指定的线,删除此线段
/// 如果此线段属于用户自己创建的,则清空对应的内存
///
///
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);
}
}
///
/// 清除所有线段
///
public void ClearAllLine(bool isClearAll = false)
{
if (UserList != null)
{
ArtInfoMgr.Instance.DelGoodsByIds(UserList);
}
if (isClearAll)
{
ClearOtherLine();
}
}
///
/// 删除
///
///
public void AddLineId(int id, bool isOther = true)
{
if (isOther)
{
OtherUserList.Add(id);
}
else
{
UserList.Add(id);
}
}
///
/// 清空其他用户的线段
///
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;
}
}
}