312 lines
7.4 KiB
C#
312 lines
7.4 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using BITKit;
|
|
using BITKit.CommandPattern;
|
|
using BITKit.Entities;
|
|
using BITKit.IO;
|
|
using Cysharp.Threading.Tasks;
|
|
using PaintIn3D;
|
|
using Unity.Mathematics;
|
|
using UnityEngine;
|
|
|
|
namespace BITFactory.Cutting
|
|
{
|
|
[Serializable]
|
|
public sealed class DIUnityCuttingTool : InjectFromDI<ICuttingTool>,ICuttingTool
|
|
{
|
|
private ICuttingTool _cuttingToolImplementation => Value;
|
|
|
|
public ICommand[] Commands => _cuttingToolImplementation.Commands;
|
|
|
|
public event Action<ICommand> OnExecute
|
|
{
|
|
add => _cuttingToolImplementation.OnExecute += value;
|
|
remove => _cuttingToolImplementation.OnExecute -= value;
|
|
}
|
|
|
|
public event Action<ICommand> OnClear
|
|
{
|
|
add => _cuttingToolImplementation.OnClear += value;
|
|
remove => _cuttingToolImplementation.OnClear -= value;
|
|
}
|
|
|
|
public event Action<ICommand> OnUndo
|
|
{
|
|
add => _cuttingToolImplementation.OnUndo += value;
|
|
remove => _cuttingToolImplementation.OnUndo -= value;
|
|
}
|
|
|
|
public event Action<ICommand[]> OnRelease
|
|
{
|
|
add => _cuttingToolImplementation.OnRelease += value;
|
|
remove => _cuttingToolImplementation.OnRelease -= value;
|
|
}
|
|
|
|
public void Execute(ICommand command)
|
|
{
|
|
_cuttingToolImplementation.Execute(command);
|
|
}
|
|
|
|
public void Undo()
|
|
{
|
|
_cuttingToolImplementation.Undo();
|
|
}
|
|
|
|
public void Undo(int count)
|
|
{
|
|
_cuttingToolImplementation.Undo(count);
|
|
}
|
|
|
|
public void Redo()
|
|
{
|
|
_cuttingToolImplementation.Redo();
|
|
}
|
|
|
|
public void Trace(ICommand command)
|
|
{
|
|
_cuttingToolImplementation.Trace(command);
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
_cuttingToolImplementation.Clear();
|
|
}
|
|
|
|
public void Rebuild() => _cuttingToolImplementation.Rebuild();
|
|
public void Release() => _cuttingToolImplementation.Release();
|
|
|
|
public void CutPlanePoint(bool preview, float3 planeNormal, float3 planePoint)
|
|
{
|
|
_cuttingToolImplementation.CutPlanePoint(preview, planeNormal, planePoint);
|
|
}
|
|
|
|
public void CutPlantSphere(bool preview, float3 planeNormal, float3 planePoint, float radius)
|
|
{
|
|
_cuttingToolImplementation.CutPlantSphere(preview, planeNormal, planePoint, radius);
|
|
}
|
|
|
|
public void CutPlaneBox(bool preview, float3 planeNormal, float3 planePoint, float3 boxSize)
|
|
{
|
|
_cuttingToolImplementation.CutPlaneBox(preview, planeNormal, planePoint, boxSize);
|
|
}
|
|
|
|
public void CutPlaneLine(bool preview, float3 planeNormal, float3[] line)
|
|
{
|
|
_cuttingToolImplementation.CutPlaneLine(preview, planeNormal, line);
|
|
}
|
|
|
|
public void FillPlanePoint(bool preview, float3 planeNormal, float3 planePoint)
|
|
{
|
|
_cuttingToolImplementation.FillPlanePoint(preview, planeNormal, planePoint);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
[CustomType(typeof(ICuttingTool),true)]
|
|
public class UnityCuttingTool : EntityBehavior,ICuttingTool
|
|
{
|
|
[SerializeField] private float defaultPointRadius = 0.1f;
|
|
|
|
[SerializeReference, SubclassSelector] private IApplicationFile applicationFile;
|
|
private P3dPaintSphere paintSphere
|
|
{
|
|
get
|
|
{
|
|
if (!_paintSphere)
|
|
{
|
|
_paintSphere = GetComponentInChildren<P3dPaintSphere>();
|
|
}
|
|
return _paintSphere;
|
|
}
|
|
}
|
|
private P3dPaintSphere _paintSphere;
|
|
|
|
private readonly CommandSequence _commands=new();
|
|
private readonly CommandSequence _executedCommands=new();
|
|
private void Awake()
|
|
{
|
|
DI.Register<ICuttingTool>(this);
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
applicationFile.DataHandle += OnDataHandle;
|
|
applicationFile.AddListener(nameof(UnityCuttingTool),OnData);
|
|
|
|
}
|
|
private void OnDisable()
|
|
{
|
|
applicationFile.DataHandle -= OnDataHandle;
|
|
applicationFile.RemoveListener(nameof(UnityCuttingTool),OnData);
|
|
}
|
|
private (string, byte[]) OnDataHandle()
|
|
{
|
|
return new(nameof(UnityCuttingTool), BITBinary.WriteAsBytes(_executedCommands));
|
|
}
|
|
private async void OnData(byte[] obj)
|
|
{
|
|
await UniTask.NextFrame();
|
|
if (destroyCancellationToken.IsCancellationRequested) return;
|
|
Clear();
|
|
var seq = BITBinary.Read<CommandSequence>(obj);
|
|
_commands.AddRange(seq);
|
|
_executedCommands.AddRange(seq);
|
|
Rebuild();
|
|
}
|
|
|
|
public void CutPlanePoint(bool preview, float3 planeNormal, float3 planePoint)
|
|
{
|
|
paintSphere.Radius = defaultPointRadius;
|
|
paintSphere.HandleHitLine(
|
|
preview,
|
|
0,
|
|
1.0f,
|
|
0,
|
|
planePoint+planeNormal*1,
|
|
planePoint-planeNormal*1,
|
|
Quaternion.LookRotation(planeNormal),true);
|
|
}
|
|
|
|
public void CutPlantSphere(bool preview, float3 planeNormal, float3 planePoint, float radius)
|
|
{
|
|
paintSphere.Radius = radius;
|
|
paintSphere.HandleHitLine(
|
|
preview,
|
|
0,
|
|
1.0f,
|
|
0,
|
|
planePoint+planeNormal*1,
|
|
planePoint-planeNormal*1,
|
|
Quaternion.LookRotation(planeNormal),true);
|
|
}
|
|
|
|
public void CutPlaneBox(bool preview, float3 planeNormal, float3 planePoint, float3 boxSize)
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
|
|
public void CutPlaneLine(bool preview, float3 planeNormal, float3[] line)
|
|
{
|
|
paintSphere.Radius = defaultPointRadius;
|
|
|
|
var lastPoint = line[0];
|
|
foreach (var pos in line)
|
|
{
|
|
paintSphere.HandleHitLine(
|
|
preview,
|
|
0,
|
|
1.0f,
|
|
0,
|
|
lastPoint,
|
|
pos,
|
|
Quaternion.LookRotation(planeNormal),true);
|
|
lastPoint = pos;
|
|
}
|
|
}
|
|
|
|
public void FillPlanePoint(bool preview, float3 planeNormal, float3 planePoint)
|
|
{
|
|
var texture = (Texture2D)_paintSphere.TargetTexture.Texture;
|
|
}
|
|
|
|
public ICommand[] Commands =>_executedCommands.ToArray();
|
|
|
|
public event Action<ICommand> OnExecute;
|
|
public event Action<ICommand> OnClear;
|
|
public event Action<ICommand> OnUndo;
|
|
public event Action<ICommand[]> OnRelease;
|
|
|
|
public void Execute(ICommand command)
|
|
{
|
|
_commands.Add(command);
|
|
OnExecute?.Invoke(command);
|
|
_executedCommands.Add(command);
|
|
|
|
ExecuteInternal(command);
|
|
}
|
|
public void Undo()
|
|
{
|
|
if(_executedCommands.Count==0)return;
|
|
var command = _executedCommands[^1];
|
|
command.Undo();
|
|
_executedCommands.RemoveAt(_executedCommands.Count-1);
|
|
|
|
OnClear?.Invoke(null);
|
|
paintSphere.TargetTexture.Clear();
|
|
|
|
foreach (var x in _executedCommands)
|
|
{
|
|
ExecuteInternal(x);
|
|
OnExecute?.Invoke(x);
|
|
}
|
|
}
|
|
public void Undo(int count)
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
public void Redo()
|
|
{
|
|
throw new System.NotImplementedException();
|
|
}
|
|
public void Trace(ICommand command)
|
|
{
|
|
var index = _commands.IndexOf(command);
|
|
|
|
paintSphere.TargetTexture.Clear();
|
|
OnClear?.Invoke(command);
|
|
|
|
_executedCommands.Clear();
|
|
_executedCommands.AddRange(_commands.GetRange(0, index));
|
|
|
|
foreach (var x in _executedCommands)
|
|
{
|
|
ExecuteInternal(x);
|
|
OnExecute?.Invoke(x);
|
|
}
|
|
|
|
}
|
|
public void Clear()
|
|
{
|
|
OnClear?.Invoke(null);
|
|
_executedCommands.Clear();
|
|
_commands.Clear();
|
|
paintSphere.TargetTexture.Clear();
|
|
}
|
|
|
|
public void Rebuild()
|
|
{
|
|
OnClear?.Invoke(null);
|
|
foreach (var x in _executedCommands)
|
|
{
|
|
ExecuteInternal(x);
|
|
OnExecute?.Invoke(x);
|
|
}
|
|
}
|
|
|
|
public void Release()
|
|
{
|
|
OnRelease?.Invoke(_executedCommands.ToArray());
|
|
}
|
|
|
|
|
|
private void ExecuteInternal(ICommand command)
|
|
{
|
|
switch (command)
|
|
{
|
|
case CuttingPointCommand cuttingPointCommand:
|
|
CutPlanePoint(false,cuttingPointCommand.PlaneNormal,cuttingPointCommand.PlanePoint);
|
|
break;
|
|
case CuttingSphereCommand sphereCommand:
|
|
CutPlantSphere(false,sphereCommand.PlaneNormal,sphereCommand.PlanePoint,sphereCommand.Radius);
|
|
break;
|
|
case CuttingLineCommand lineCommand:
|
|
CutPlaneLine(false,lineCommand.PlaneNormal,lineCommand.Line);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|