BITFALL/Assets/GSpawn - Level Designer/Scripts/Level Design/Gizmos/Object Mirror Gizmos/ObjectMirrorGizmo.cs

1218 lines
56 KiB
C#

#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
using System;
using System.Collections.Generic;
namespace GSpawn
{
public class MirroredObjectList
{
public List<GameObject> objects = new List<GameObject>();
}
public enum MirrorGizmoMidSnapMode
{
Default = 0,
TileRuleGrid
}
public class ObjectMirrorGizmo : PluginGizmo
{
private enum PlanePatchId
{
TopLeft = 0,
TopRight,
BottomRight,
BottomLeft
}
private class MirrorPlanePatch
{
public XYQuad3D quad = new XYQuad3D();
public Color fillColor;
}
private class MirrorPlane
{
public PlaneId id;
public MirrorPlanePatch[] patches = new MirrorPlanePatch[4]
{ new MirrorPlanePatch(), new MirrorPlanePatch(), new MirrorPlanePatch(), new MirrorPlanePatch() };
public Quaternion modelRotation = Quaternion.identity;
public Vector3 modelNormal = Vector3.zero;
}
private Color[] _moveAxisColors = new Color[] { DefaultSystemValues.xAxisColor, DefaultSystemValues.yAxisColor, DefaultSystemValues.zAxisColor };
private Vector3[] _modelMoveDirs = new Vector3[] { Vector3.right, Vector3.up, Vector3.forward };
private Color[] _planeFillColors = new Color[3];
private bool[] _planeMask = new bool[3];
private Color[] _rotationHandleColors = new Color[] { DefaultSystemValues.xAxisColor, DefaultSystemValues.yAxisColor, DefaultSystemValues.zAxisColor };
private Vector3[] _rotationAxes = new Vector3[] { Vector3.right, Vector3.up, Vector3.forward };
// 1-to-1 mapping with PlanePatchId (in pairs of 2)
private Vector3[] _patchCalcAxes = new Vector3[] { Vector3.left, Vector3.up, Vector3.right, Vector3.up, Vector3.right, Vector3.down, Vector3.left, Vector3.down };
// 1-to-1 mapping with PlaneId
private MirrorPlane[] _mirrorPlanes = new MirrorPlane[]
{
new MirrorPlane(){ id = PlaneId.XY, modelRotation = Quaternion.identity, modelNormal = Vector3.forward },
new MirrorPlane(){ id = PlaneId.YZ, modelRotation = Quaternion.AngleAxis(90.0f, Vector3.up), modelNormal = Vector3.right },
new MirrorPlane(){ id = PlaneId.ZX, modelRotation = Quaternion.AngleAxis(90.0f, Vector3.right), modelNormal = Vector3.up }
};
private List<MirrorPlanePatch> _sortedPatches = new List<MirrorPlanePatch>();
private SceneRaycastFilter _snapToObjectsRaycastFilter = new SceneRaycastFilter()
{ objectTypes = GameObjectType.Mesh | GameObjectType.Terrain | GameObjectType.Sprite };
private ObjectRaycastConfig _snapToObjectsRaycastConfig = new ObjectRaycastConfig()
{ raycastPrecision = ObjectRaycastPrecision.BestFit };
private ObjectBounds.QueryConfig _mirroredBoundsQConfig = ObjectBounds.QueryConfig.defaultConfig;
private int _snapHandleId;
private int _xAxisMoveHandleId;
private int _yAxisMoveHandleId;
private int _zAxisMoveHandleId;
private int _xAxisRotationHandleId;
private int _yAxisRotationHandleId;
private int _zAxisRotationHandleId;
[SerializeField]
private MirrorGizmoMidSnapMode _midSnapMode = MirrorGizmoMidSnapMode.Default;
[NonSerialized]
private List<Vector3> _vector3Buffer = new List<Vector3>(5);
[NonSerialized]
private List<Plane> _mirrorPlaneBuffer = new List<Plane>(3);
[NonSerialized]
private List<PlaneId> _mirrorPlaneIdBuffer = new List<PlaneId>(3);
[NonSerialized]
private List<OBB> _obbBuffer = new List<OBB>(8);
[NonSerialized]
private List<Vector3Int> _vec3IntBuffer = new List<Vector3Int>();
[NonSerialized]
private List<TileRuleGridCellRange> _tileRuleGridCellRangeBuffer = new List<TileRuleGridCellRange>();
[NonSerialized]
private List<TileRuleConnectionPath> _tileRuleConnectionPathBuffer = new List<TileRuleConnectionPath>();
[NonSerialized]
private List<Symmetry.MirroredOBB> _mirroredOBBBuffer = new List<Symmetry.MirroredOBB>(8);
[NonSerialized]
private IEnumerable<GameObject> _targetObjects = null;
[NonSerialized]
private List<GameObject> _parentBuffer = new List<GameObject>();
[NonSerialized]
private ObjectMirrorGizmoSettings _sharedSettings;
[NonSerialized]
private ObjectOverlapFilter _symPairsOverlapFilter = new ObjectOverlapFilter();
[NonSerialized]
private List<GameObject> _symPairsObjectOverlapBuffer = new List<GameObject>();
[NonSerialized]
private ObjectOutline _symPairsOutline = new ObjectOutline();
public ObjectMirrorGizmoSettings sharedSettings { get { return _sharedSettings; } set { _sharedSettings = value; } }
public bool isDraggingHandles
{
get
{
int hotControl = GUIUtility.hotControl;
if (hotControl == 0) return false;
return hotControl == _snapHandleId || hotControl == _xAxisMoveHandleId || hotControl == _yAxisMoveHandleId || hotControl == _zAxisMoveHandleId ||
hotControl == _xAxisRotationHandleId || hotControl == _yAxisRotationHandleId || hotControl == _zAxisRotationHandleId;
}
}
public MirrorGizmoMidSnapMode midSnapMode { get { return _midSnapMode; } set { _midSnapMode = value; } }
public TileRuleGrid tileRuleGrid { get; set; }
public int tileRuleGridYOffset { get; set; }
public void snapToView()
{
Ray ray = new Ray(PluginCamera.camera.transform.position, PluginCamera.camera.transform.forward);
var hit = PluginScene.instance.raycastGrid(ray);
if (hit != null)
{
UndoEx.record(this);
position = PluginScene.instance.grid.snapAllAxes(hit.hitPoint);
}
else
{
UndoEx.record(this);
Sphere sphere = new Sphere(position, getRotationHandleSize());
position = PluginCamera.camera.calcSphereCenterInFrontOfCamera(sphere);
}
}
public void bindTargetObjects(IEnumerable<GameObject> targetObjects)
{
_targetObjects = targetObjects;
}
public void mirrorTargets()
{
mirrorObjects(_targetObjects);
}
public void mirrorObjectsOrganized_NoDuplicateCommand(IEnumerable<GameObject> gameObjects, List<MirroredObjectList> mirroredObjectLists)
{
mirroredObjectLists.Clear();
if (!gatherMirrorPlanes(_mirrorPlaneBuffer)) return;
if (_mirrorPlaneBuffer.Count == 0) return;
if (_mirrorPlaneBuffer.Count == 1)
{
mirroredObjectLists.Add(new MirroredObjectList());
}
else
if (_mirrorPlaneBuffer.Count == 2)
{
mirroredObjectLists.Add(new MirroredObjectList());
mirroredObjectLists.Add(new MirroredObjectList());
mirroredObjectLists.Add(new MirroredObjectList());
}
else
if (_mirrorPlaneBuffer.Count == 3)
{
mirroredObjectLists.Add(new MirroredObjectList());
mirroredObjectLists.Add(new MirroredObjectList());
mirroredObjectLists.Add(new MirroredObjectList());
mirroredObjectLists.Add(new MirroredObjectList());
mirroredObjectLists.Add(new MirroredObjectList());
mirroredObjectLists.Add(new MirroredObjectList());
mirroredObjectLists.Add(new MirroredObjectList());
}
GameObjectEx.getParents(gameObjects, _parentBuffer);
bool mirrorRotation = sharedSettings.mirrorRotation;
bool mirrorSpanning = sharedSettings.mirrorSpanning;
foreach (var parent in _parentBuffer)
{
_mirroredOBBBuffer.Clear();
OBB hierarchyWorldOBB = ObjectBounds.calcHierarchyWorldOBB(parent, _mirroredBoundsQConfig);
if (!hierarchyWorldOBB.isValid) continue;
_mirroredOBBBuffer.Add(new Symmetry.MirroredOBB() { obb = hierarchyWorldOBB, mirroredRotation = new Symmetry.MirroredRotation() { rotation = parent.transform.rotation, axesScaleSign = Vector3.one } });
for (int planeIndex = 0; planeIndex < _mirrorPlaneBuffer.Count; ++planeIndex)
{
if (!mirrorSpanning)
{
var location = Box3D.classifyAgainstPlane(hierarchyWorldOBB.center, hierarchyWorldOBB.size, hierarchyWorldOBB.rotation, _mirrorPlaneBuffer[planeIndex]);
if (location == PlaneClassifyResult.Spanning)
{
_mirroredOBBBuffer.Add(new Symmetry.MirroredOBB(OBB.getInvalid(), new Symmetry.MirroredRotation()));
continue;
}
}
int numOBBs = _mirroredOBBBuffer.Count;
for (int obbIndex = 0; obbIndex < numOBBs; ++obbIndex)
{
if (_mirroredOBBBuffer[obbIndex].obb.isValid)
{
Symmetry.MirroredOBB mirroredOBB = Symmetry.mirrorOBB(_mirroredOBBBuffer[obbIndex], mirrorRotation, _mirrorPlaneBuffer[planeIndex]);
_mirroredOBBBuffer.Add(mirroredOBB);
}
else _mirroredOBBBuffer.Add(_mirroredOBBBuffer[obbIndex]);
}
}
if (_mirroredOBBBuffer.Count != 0)
{
int listIndex = 0;
int startOBB = 1;
for (int obbIndex = startOBB; obbIndex < _mirroredOBBBuffer.Count; ++obbIndex)
{
Symmetry.MirroredOBB mirroredOBB = _mirroredOBBBuffer[obbIndex];
if (!mirroredOBB.obb.isValid)
{
++listIndex;
continue;
}
GameObject prefabAsset = parent.getOutermostPrefabAsset();
if (prefabAsset == null)
{
++listIndex;
continue;
}
GameObject mirroredObject = prefabAsset.instantiatePrefab(parent.transform.position, parent.transform.rotation, parent.transform.lossyScale);
mirroredObject.transform.parent = parent.transform.parent;
UndoEx.registerCreatedObject<GameObject>(mirroredObject);
mirroredObjectLists[listIndex++].objects.Add(mirroredObject);
Transform transform = mirroredObject.transform;
UndoEx.recordTransform(transform);
if (mirrorRotation)
{
transform.rotation = mirroredOBB.mirroredRotation.rotation;
transform.setWorldScale(Vector3.Scale(transform.lossyScale, mirroredOBB.mirroredRotation.axesScaleSign));
}
transform.position = ObjectPositionCalculator.calcRootPosition(mirroredObject, mirroredOBB.obb.center, transform.lossyScale, transform.rotation);
}
}
}
}
public void mirrorObjectsOrganized(IEnumerable<GameObject> gameObjects, List<MirroredObjectList> mirroredObjectLists)
{
mirroredObjectLists.Clear();
if (!gatherMirrorPlanes(_mirrorPlaneBuffer)) return;
if (_mirrorPlaneBuffer.Count == 0) return;
if (_mirrorPlaneBuffer.Count == 1)
{
mirroredObjectLists.Add(new MirroredObjectList());
}
else
if (_mirrorPlaneBuffer.Count == 2)
{
mirroredObjectLists.Add(new MirroredObjectList());
mirroredObjectLists.Add(new MirroredObjectList());
mirroredObjectLists.Add(new MirroredObjectList());
}
else
if (_mirrorPlaneBuffer.Count == 3)
{
mirroredObjectLists.Add(new MirroredObjectList());
mirroredObjectLists.Add(new MirroredObjectList());
mirroredObjectLists.Add(new MirroredObjectList());
mirroredObjectLists.Add(new MirroredObjectList());
mirroredObjectLists.Add(new MirroredObjectList());
mirroredObjectLists.Add(new MirroredObjectList());
mirroredObjectLists.Add(new MirroredObjectList());
}
GameObjectEx.getParents(gameObjects, _parentBuffer);
bool mirrorRotation = sharedSettings.mirrorRotation;
bool mirrorSpanning = sharedSettings.mirrorSpanning;
foreach (var parent in _parentBuffer)
{
_mirroredOBBBuffer.Clear();
OBB hierarchyWorldOBB = ObjectBounds.calcHierarchyWorldOBB(parent, _mirroredBoundsQConfig);
if (!hierarchyWorldOBB.isValid) continue;
_mirroredOBBBuffer.Add(new Symmetry.MirroredOBB() { obb = hierarchyWorldOBB, mirroredRotation = new Symmetry.MirroredRotation() { rotation = parent.transform.rotation, axesScaleSign = Vector3.one } });
for (int planeIndex = 0; planeIndex < _mirrorPlaneBuffer.Count; ++planeIndex)
{
if (!mirrorSpanning)
{
var location = Box3D.classifyAgainstPlane(hierarchyWorldOBB.center, hierarchyWorldOBB.size, hierarchyWorldOBB.rotation, _mirrorPlaneBuffer[planeIndex]);
if (location == PlaneClassifyResult.Spanning)
{
_mirroredOBBBuffer.Add(new Symmetry.MirroredOBB(OBB.getInvalid(), new Symmetry.MirroredRotation()));
continue;
}
}
int numOBBs = _mirroredOBBBuffer.Count;
for (int obbIndex = 0; obbIndex < numOBBs; ++obbIndex)
{
if (_mirroredOBBBuffer[obbIndex].obb.isValid)
{
Symmetry.MirroredOBB mirroredOBB = Symmetry.mirrorOBB(_mirroredOBBBuffer[obbIndex], mirrorRotation, _mirrorPlaneBuffer[planeIndex]);
_mirroredOBBBuffer.Add(mirroredOBB);
}
else _mirroredOBBBuffer.Add(_mirroredOBBBuffer[obbIndex]);
}
}
if (_mirroredOBBBuffer.Count != 0)
{
int listIndex = 0;
int startOBB = 1;
for (int obbIndex = startOBB; obbIndex < _mirroredOBBBuffer.Count; ++obbIndex)
{
Symmetry.MirroredOBB mirroredOBB = _mirroredOBBBuffer[obbIndex];
if (!mirroredOBB.obb.isValid)
{
++listIndex;
continue;
}
GameObject prefabAsset = parent.getOutermostPrefabAsset();
if (prefabAsset == null)
{
++listIndex;
continue;
}
GameObject mirroredObject = UnityEditorCommands.duplicate(parent);
mirroredObjectLists[listIndex++].objects.Add(mirroredObject);
Transform transform = mirroredObject.transform;
UndoEx.recordTransform(transform);
if (mirrorRotation)
{
transform.rotation = mirroredOBB.mirroredRotation.rotation;
transform.setWorldScale(Vector3.Scale(transform.lossyScale, mirroredOBB.mirroredRotation.axesScaleSign));
}
transform.position = ObjectPositionCalculator.calcRootPosition(mirroredObject, mirroredOBB.obb.center, transform.lossyScale, transform.rotation);
}
}
}
}
public void mirrorObjects(IEnumerable<GameObject> gameObjects)
{
if (!gatherMirrorPlanes(_mirrorPlaneBuffer)) return;
GameObjectEx.getParents(gameObjects, _parentBuffer);
bool mirrorRotation = sharedSettings.mirrorRotation;
bool mirrorSpanning = sharedSettings.mirrorSpanning;
foreach (var parent in _parentBuffer)
{
_mirroredOBBBuffer.Clear();
OBB hierarchyWorldOBB = ObjectBounds.calcHierarchyWorldOBB(parent, _mirroredBoundsQConfig);
if (!hierarchyWorldOBB.isValid) continue;
_mirroredOBBBuffer.Add(new Symmetry.MirroredOBB() { obb = hierarchyWorldOBB, mirroredRotation = new Symmetry.MirroredRotation() { rotation = parent.transform.rotation, axesScaleSign = Vector3.one } });
for (int planeIndex = 0; planeIndex < _mirrorPlaneBuffer.Count; ++planeIndex)
{
if (!mirrorSpanning)
{
var location = Box3D.classifyAgainstPlane(hierarchyWorldOBB.center, hierarchyWorldOBB.size, hierarchyWorldOBB.rotation, _mirrorPlaneBuffer[planeIndex]);
if (location == PlaneClassifyResult.Spanning) continue;
}
int numOBBs = _mirroredOBBBuffer.Count;
for (int obbIndex = 0; obbIndex < numOBBs; ++obbIndex)
{
Symmetry.MirroredOBB mirroredOBB = Symmetry.mirrorOBB(_mirroredOBBBuffer[obbIndex], mirrorRotation, _mirrorPlaneBuffer[planeIndex]);
_mirroredOBBBuffer.Add(mirroredOBB);
}
}
if (_mirroredOBBBuffer.Count != 0)
{
int startOBB = 1;
for (int obbIndex = startOBB; obbIndex < _mirroredOBBBuffer.Count; ++obbIndex)
{
Symmetry.MirroredOBB mirroredOBB = _mirroredOBBBuffer[obbIndex];
GameObject mirroredObject = UnityEditorCommands.duplicate(parent);
Transform transform = mirroredObject.transform;
UndoEx.recordTransform(transform);
if (mirrorRotation)
{
transform.rotation = mirroredOBB.mirroredRotation.rotation;
transform.setWorldScale(Vector3.Scale(transform.lossyScale, mirroredOBB.mirroredRotation.axesScaleSign));
}
transform.position = ObjectPositionCalculator.calcRootPosition(mirroredObject, mirroredOBB.obb.center, transform.lossyScale, transform.rotation);
}
}
}
}
public void mirrorObjects(IEnumerable<GameObject> gameObjects, MirroredObjectList mirroredObjectList, bool append)
{
if (!append) mirroredObjectList.objects.Clear();
if (!gatherMirrorPlanes(_mirrorPlaneBuffer)) return;
GameObjectEx.getParents(gameObjects, _parentBuffer);
bool mirrorRotation = sharedSettings.mirrorRotation;
bool mirrorSpanning = sharedSettings.mirrorSpanning;
foreach (var parent in _parentBuffer)
{
_mirroredOBBBuffer.Clear();
OBB hierarchyWorldOBB = ObjectBounds.calcHierarchyWorldOBB(parent, _mirroredBoundsQConfig);
if (!hierarchyWorldOBB.isValid) continue;
_mirroredOBBBuffer.Add(new Symmetry.MirroredOBB() { obb = hierarchyWorldOBB, mirroredRotation = new Symmetry.MirroredRotation() { rotation = parent.transform.rotation, axesScaleSign = Vector3.one } });
for (int planeIndex = 0; planeIndex < _mirrorPlaneBuffer.Count; ++planeIndex)
{
if (!mirrorSpanning)
{
var location = Box3D.classifyAgainstPlane(hierarchyWorldOBB.center, hierarchyWorldOBB.size, hierarchyWorldOBB.rotation, _mirrorPlaneBuffer[planeIndex]);
if (location == PlaneClassifyResult.Spanning) continue;
}
int numOBBs = _mirroredOBBBuffer.Count;
for (int obbIndex = 0; obbIndex < numOBBs; ++obbIndex)
{
Symmetry.MirroredOBB mirroredOBB = Symmetry.mirrorOBB(_mirroredOBBBuffer[obbIndex], mirrorRotation, _mirrorPlaneBuffer[planeIndex]);
_mirroredOBBBuffer.Add(mirroredOBB);
}
}
if (_mirroredOBBBuffer.Count != 0)
{
int startOBB = 1;
for (int obbIndex = startOBB; obbIndex < _mirroredOBBBuffer.Count; ++obbIndex)
{
Symmetry.MirroredOBB mirroredOBB = _mirroredOBBBuffer[obbIndex];
GameObject mirroredObject = UnityEditorCommands.duplicate(parent);
mirroredObjectList.objects.Add(mirroredObject);
Transform transform = mirroredObject.transform;
UndoEx.recordTransform(transform);
if (mirrorRotation)
{
transform.rotation = mirroredOBB.mirroredRotation.rotation;
transform.setWorldScale(Vector3.Scale(transform.lossyScale, mirroredOBB.mirroredRotation.axesScaleSign));
}
transform.position = ObjectPositionCalculator.calcRootPosition(mirroredObject, mirroredOBB.obb.center, transform.lossyScale, transform.rotation);
}
}
}
}
public void mirrorObjects_NoDuplicateCommand(IEnumerable<GameObject> gameObjects, MirroredObjectList mirroredObjectList, bool append)
{
if (!append) mirroredObjectList.objects.Clear();
if (!gatherMirrorPlanes(_mirrorPlaneBuffer)) return;
GameObjectEx.getParents(gameObjects, _parentBuffer);
bool mirrorRotation = sharedSettings.mirrorRotation;
bool mirrorSpanning = sharedSettings.mirrorSpanning;
foreach (var parent in _parentBuffer)
{
_mirroredOBBBuffer.Clear();
OBB hierarchyWorldOBB = ObjectBounds.calcHierarchyWorldOBB(parent, _mirroredBoundsQConfig);
if (!hierarchyWorldOBB.isValid) continue;
_mirroredOBBBuffer.Add(new Symmetry.MirroredOBB() { obb = hierarchyWorldOBB, mirroredRotation = new Symmetry.MirroredRotation() { rotation = parent.transform.rotation, axesScaleSign = Vector3.one } });
for (int planeIndex = 0; planeIndex < _mirrorPlaneBuffer.Count; ++planeIndex)
{
if (!mirrorSpanning)
{
var location = Box3D.classifyAgainstPlane(hierarchyWorldOBB.center, hierarchyWorldOBB.size, hierarchyWorldOBB.rotation, _mirrorPlaneBuffer[planeIndex]);
if (location == PlaneClassifyResult.Spanning) continue;
}
int numOBBs = _mirroredOBBBuffer.Count;
for (int obbIndex = 0; obbIndex < numOBBs; ++obbIndex)
{
Symmetry.MirroredOBB mirroredOBB = Symmetry.mirrorOBB(_mirroredOBBBuffer[obbIndex], mirrorRotation, _mirrorPlaneBuffer[planeIndex]);
_mirroredOBBBuffer.Add(mirroredOBB);
}
}
if (_mirroredOBBBuffer.Count != 0)
{
int startOBB = 1;
for (int obbIndex = startOBB; obbIndex < _mirroredOBBBuffer.Count; ++obbIndex)
{
GameObject prefabAsset = parent.getOutermostPrefabAsset();
if (prefabAsset == null) continue;
Symmetry.MirroredOBB mirroredOBB = _mirroredOBBBuffer[obbIndex];
GameObject mirroredObject = prefabAsset.instantiatePrefab(parent.transform.position, parent.transform.rotation, parent.transform.lossyScale);
mirroredObject.transform.parent = parent.transform.parent;
UndoEx.registerCreatedObject<GameObject>(mirroredObject);
mirroredObjectList.objects.Add(mirroredObject);
Transform transform = mirroredObject.transform;
UndoEx.recordTransform(transform);
if (mirrorRotation)
{
transform.rotation = mirroredOBB.mirroredRotation.rotation;
transform.setWorldScale(Vector3.Scale(transform.lossyScale, mirroredOBB.mirroredRotation.axesScaleSign));
}
transform.position = ObjectPositionCalculator.calcRootPosition(mirroredObject, mirroredOBB.obb.center, transform.lossyScale, transform.rotation);
}
}
}
}
public void mirrorObject_NoDuplicateCommand(GameObject gameObject, GameObject prefabAsset)
{
if (!gatherMirrorPlanes(_mirrorPlaneBuffer)) return;
bool mirrorRotation = sharedSettings.mirrorRotation;
bool mirrorSpanning = sharedSettings.mirrorSpanning;
_mirroredOBBBuffer.Clear();
OBB hierarchyWorldOBB = ObjectBounds.calcHierarchyWorldOBB(gameObject, _mirroredBoundsQConfig);
if (!hierarchyWorldOBB.isValid) return;
_mirroredOBBBuffer.Add(new Symmetry.MirroredOBB() { obb = hierarchyWorldOBB, mirroredRotation = new Symmetry.MirroredRotation() { rotation = gameObject.transform.rotation, axesScaleSign = Vector3.one } });
for (int planeIndex = 0; planeIndex < _mirrorPlaneBuffer.Count; ++planeIndex)
{
if (!mirrorSpanning)
{
var location = Box3D.classifyAgainstPlane(hierarchyWorldOBB.center, hierarchyWorldOBB.size, hierarchyWorldOBB.rotation, _mirrorPlaneBuffer[planeIndex]);
if (location == PlaneClassifyResult.Spanning) continue;
}
int numOBBs = _mirroredOBBBuffer.Count;
for (int obbIndex = 0; obbIndex < numOBBs; ++obbIndex)
{
Symmetry.MirroredOBB mirroredOBB = Symmetry.mirrorOBB(_mirroredOBBBuffer[obbIndex], mirrorRotation, _mirrorPlaneBuffer[planeIndex]);
_mirroredOBBBuffer.Add(mirroredOBB);
}
}
if (_mirroredOBBBuffer.Count != 0)
{
int startOBB = 1;
Transform sourceTransform = gameObject.transform;
for (int obbIndex = startOBB; obbIndex < _mirroredOBBBuffer.Count; ++obbIndex)
{
Symmetry.MirroredOBB mirroredOBB = _mirroredOBBBuffer[obbIndex];
GameObject mirroredObject = prefabAsset.instantiatePrefab(sourceTransform.position, sourceTransform.rotation, sourceTransform.lossyScale);
mirroredObject.transform.parent = sourceTransform.parent;
UndoEx.registerCreatedObject<GameObject>(mirroredObject);
// Note: Need to record transform for Undo/Redo. If we don't do this,
// the transform will not be restored correctly on Redo (e.g. mirroring
// while modular snap spawn mode is enabled).
Transform transform = mirroredObject.transform;
UndoEx.recordTransform(transform);
if (mirrorRotation)
{
transform.rotation = mirroredOBB.mirroredRotation.rotation;
transform.setWorldScale(Vector3.Scale(transform.lossyScale, mirroredOBB.mirroredRotation.axesScaleSign));
}
transform.position = ObjectPositionCalculator.calcRootPosition(mirroredObject, mirroredOBB.obb.center, transform.lossyScale, transform.rotation);
}
}
}
public void mirrorOBBs(List<OBB> obbs, List<OBB> mirroredOBBs)
{
mirroredOBBs.Clear();
if (!gatherMirrorPlanes(_mirrorPlaneBuffer)) return;
bool mirrorRotation = sharedSettings.mirrorRotation;
bool mirrorSpanning = sharedSettings.mirrorSpanning;
foreach (var obb in obbs)
{
_obbBuffer.Clear();
if (!obb.isValid) continue;
_obbBuffer.Add(obb);
for (int planeIndex = 0; planeIndex < _mirrorPlaneBuffer.Count; ++planeIndex)
{
if (!mirrorSpanning)
{
var location = Box3D.classifyAgainstPlane(obb.center, obb.size, obb.rotation, _mirrorPlaneBuffer[planeIndex]);
if (location == PlaneClassifyResult.Spanning) continue;
}
int numOBBs = _obbBuffer.Count;
for (int obbIndex = 0; obbIndex < numOBBs; ++obbIndex)
{
OBB mirroredOBB = Symmetry.mirrorOBB(_obbBuffer[obbIndex], mirrorRotation, _mirrorPlaneBuffer[planeIndex]);
_obbBuffer.Add(mirroredOBB);
}
}
if (_obbBuffer.Count != 0)
{
int startOBB = 1;
for (int obbIndex = startOBB; obbIndex < _obbBuffer.Count; ++obbIndex)
{
mirroredOBBs.Add(_obbBuffer[obbIndex]);
}
}
}
}
public void mirrorOBB(OBB obb, List<OBB> mirroredOBBs)
{
mirroredOBBs.Clear();
if (!gatherMirrorPlanes(_mirrorPlaneBuffer)) return;
bool mirrorRotation = sharedSettings.mirrorRotation;
bool mirrorSpanning = sharedSettings.mirrorSpanning;
_obbBuffer.Clear();
if (!obb.isValid) return;
_obbBuffer.Add(obb);
for (int planeIndex = 0; planeIndex < _mirrorPlaneBuffer.Count; ++planeIndex)
{
if (!mirrorSpanning)
{
var location = Box3D.classifyAgainstPlane(obb.center, obb.size, obb.rotation, _mirrorPlaneBuffer[planeIndex]);
if (location == PlaneClassifyResult.Spanning) continue;
}
int numOBBs = _obbBuffer.Count;
for (int obbIndex = 0; obbIndex < numOBBs; ++obbIndex)
{
OBB mirroredOBB = Symmetry.mirrorOBB(_obbBuffer[obbIndex], mirrorRotation, _mirrorPlaneBuffer[planeIndex]);
_obbBuffer.Add(mirroredOBB);
}
}
if (_obbBuffer.Count != 0)
{
int startOBB = 1;
for (int obbIndex = startOBB; obbIndex < _obbBuffer.Count; ++obbIndex)
{
mirroredOBBs.Add(_obbBuffer[obbIndex]);
}
}
}
public void mirrorTileRuleGridCellRange(TileRuleGridCellRange cellRange, List<TileRuleGridCellRange> mirroredRanges)
{
mirroredRanges.Clear();
if (tileRuleGrid == null) return;
if (!gatherMirrorPlanes(_mirrorPlaneBuffer, _mirrorPlaneIdBuffer)) return;
Vector3Int mirrorCellCoords = tileRuleGrid.mirrorGizmoCellCoords;
_tileRuleGridCellRangeBuffer.Clear();
_tileRuleGridCellRangeBuffer.Add(cellRange);
for (int planeIndex = 0; planeIndex < _mirrorPlaneBuffer.Count; ++planeIndex)
{
int numRanges = _tileRuleGridCellRangeBuffer.Count;
for (int rangeIndex = 0; rangeIndex < numRanges; ++rangeIndex)
{
var range = _tileRuleGridCellRangeBuffer[rangeIndex];
var mirroredRange = new TileRuleGridCellRange(Symmetry.mirror3DGridCell(range.min, mirrorCellCoords, _mirrorPlaneIdBuffer[planeIndex]),
Symmetry.mirror3DGridCell(range.max, mirrorCellCoords, _mirrorPlaneIdBuffer[planeIndex]));
_tileRuleGridCellRangeBuffer.Add(mirroredRange);
}
}
if (_tileRuleGridCellRangeBuffer.Count != 0)
{
int startRange = 1;
for (int rangeIndex = startRange; rangeIndex < _tileRuleGridCellRangeBuffer.Count; ++rangeIndex)
{
mirroredRanges.Add(_tileRuleGridCellRangeBuffer[rangeIndex]);
}
}
}
public void mirrorTileRuleGridCellCoords(Vector3Int cellCoords, List<Vector3Int> mirroredCoords)
{
mirroredCoords.Clear();
if (tileRuleGrid == null) return;
if (!gatherMirrorPlanes(_mirrorPlaneBuffer, _mirrorPlaneIdBuffer)) return;
Vector3Int mirrorCellCoords = tileRuleGrid.mirrorGizmoCellCoords;
if (cellCoords == mirrorCellCoords) return;
_vec3IntBuffer.Clear();
_vec3IntBuffer.Add(cellCoords);
for (int planeIndex = 0; planeIndex < _mirrorPlaneBuffer.Count; ++planeIndex)
{
int numCoords = _vec3IntBuffer.Count;
for (int coordsIndex = 0; coordsIndex < numCoords; ++coordsIndex)
{
_vec3IntBuffer.Add(Symmetry.mirror3DGridCell(_vec3IntBuffer[coordsIndex], mirrorCellCoords, _mirrorPlaneIdBuffer[planeIndex]));
}
}
if (_vec3IntBuffer.Count != 0)
{
int startCoords = 1;
for (int coordsIndex = startCoords; coordsIndex < _vec3IntBuffer.Count; ++coordsIndex)
{
mirroredCoords.Add(_vec3IntBuffer[coordsIndex]);
}
}
}
public void mirrorTileRuleConnectionPath(TileRuleConnectionPath connectionPath, List<TileRuleConnectionPath> connectionPaths)
{
if (connectionPath.cells.Count == 0) return;
connectionPaths.Clear();
if (tileRuleGrid == null) return;
if (!gatherMirrorPlanes(_mirrorPlaneBuffer, _mirrorPlaneIdBuffer)) return;
Vector3Int mirrorCellCoords = tileRuleGrid.mirrorGizmoCellCoords;
_tileRuleConnectionPathBuffer.Clear();
_tileRuleConnectionPathBuffer.Add(connectionPath);
for (int planeIndex = 0; planeIndex < _mirrorPlaneBuffer.Count; ++planeIndex)
{
int numPaths = _tileRuleConnectionPathBuffer.Count;
for (int pathIndex = 0; pathIndex < numPaths; ++pathIndex)
{
var path = _tileRuleConnectionPathBuffer[pathIndex];
var mirroredPath = new TileRuleConnectionPath();
foreach (var cell in path.cells)
{
mirroredPath.cells.Add(Symmetry.mirror3DGridCell(cell, mirrorCellCoords, _mirrorPlaneIdBuffer[planeIndex]));
}
_tileRuleConnectionPathBuffer.Add(mirroredPath);
}
}
if (_tileRuleConnectionPathBuffer.Count != 0)
{
int startPath = 1;
for (int pathIndex = startPath; pathIndex < _tileRuleConnectionPathBuffer.Count; ++pathIndex)
{
connectionPaths.Add(_tileRuleConnectionPathBuffer[pathIndex]);
}
}
}
public void drawMirroredOBBs(List<OBB> obbs)
{
Event e = Event.current;
if (e.type != EventType.Repaint) return;
HandlesEx.saveColor();
HandlesEx.saveMatrix();
HandlesEx.saveLit();
Handles.lighting = false;
foreach (var obb in obbs)
{
Handles.matrix = Matrix4x4.TRS(obb.center, obb.rotation, obb.size);
Handles.color = GizmoPrefs.instance.mirrorIndicatorFillColor;
Handles.CubeHandleCap(0, Vector3.zero, Quaternion.identity, 1.0f, e.type);
Handles.color = GizmoPrefs.instance.mirrorIndicatorWireColor;
//Handles.DrawWireCube(Vector3.zero, Vector3.one);
HandlesEx.drawUnitWireCube();
}
HandlesEx.restoreColor();
HandlesEx.restoreMatrix();
HandlesEx.restoreLit();
}
public void drawMirroredOBB(OBB obb)
{
Event e = Event.current;
if (e.type != EventType.Repaint) return;
HandlesEx.saveColor();
HandlesEx.saveMatrix();
HandlesEx.saveLit();
Handles.lighting = false;
Handles.matrix = Matrix4x4.TRS(obb.center, obb.rotation, obb.size);
Handles.color = GizmoPrefs.instance.mirrorIndicatorFillColor;
Handles.CubeHandleCap(0, Vector3.zero, Quaternion.identity, 1.0f, e.type);
Handles.color = GizmoPrefs.instance.mirrorIndicatorWireColor;
//Handles.DrawWireCube(Vector3.zero, Vector3.one);
HandlesEx.drawUnitWireCube();
HandlesEx.restoreColor();
HandlesEx.restoreMatrix();
HandlesEx.restoreLit();
}
protected override void doOnSceneGUI()
{
updateHandleIds();
drawMirrorPlanes();
drawMidSnapHandle();
drawMoveHandles();
drawRotationHandles();
drawMirroredBoxes();
if (isDraggingHandles) drawSymmetricPairHighlights();
drawUIHandles();
}
protected override void onEnable()
{
_snapToObjectsRaycastFilter.customFilter = (GameObject go) => { return go.GetComponent<ObjectSpawnGuideMono>() == null; };
}
private void updateHandleIds()
{
_snapHandleId = GUIUtility.GetControlID(FocusType.Passive);
_xAxisMoveHandleId = GUIUtility.GetControlID(FocusType.Passive);
_yAxisMoveHandleId = GUIUtility.GetControlID(FocusType.Passive);
_zAxisMoveHandleId = GUIUtility.GetControlID(FocusType.Passive);
_xAxisRotationHandleId = GUIUtility.GetControlID(FocusType.Passive);
_yAxisRotationHandleId = GUIUtility.GetControlID(FocusType.Passive);
_zAxisRotationHandleId = GUIUtility.GetControlID(FocusType.Passive);
}
private void drawUIHandles()
{
if (GizmoPrefs.instance.mirrorShowInfoText)
{
Camera camera = PluginCamera.camera;
float handleSize = HandleUtility.GetHandleSize(position);
Handles.BeginGUI();
Handles.Label(position - camera.transform.up * 1.0f * handleSize - camera.transform.right * 1.0f * handleSize,
"Position: " + position.ToString("F3"), GUIStyleDb.instance.sceneViewInfoLabel);
Handles.EndGUI();
}
}
private void drawMirrorPlanes()
{
_sortedPatches.Clear();
float quarterPlaneSize = GizmoPrefs.instance.mirrorPlaneSize * 0.25f * HandleUtility.GetHandleSize(position);
Vector2 patchSize = Vector2Ex.create(GizmoPrefs.instance.mirrorPlaneSize * 0.5f * HandleUtility.GetHandleSize(position));
_planeFillColors[0] = GizmoPrefs.instance.mirrorXYPlaneColor;
_planeFillColors[1] = GizmoPrefs.instance.mirrorYZPlaneColor;
_planeFillColors[2] = GizmoPrefs.instance.mirrorZXPlaneColor;
_planeMask[0] = sharedSettings.useXYPlane;
_planeMask[1] = sharedSettings.useYZPlane;
_planeMask[2] = sharedSettings.useZXPlane;
// Note: We need to create the plane patches first so that we
// can sort. This is necessary because we have to disable
// the depth test while drawing to allow for alpha blending.
for (int planeIndex = 0; planeIndex < _mirrorPlanes.Length; ++planeIndex)
{
if (!_planeMask[planeIndex]) continue;
var planeInfo = _mirrorPlanes[planeIndex];
Quaternion patchRotation = rotation * planeInfo.modelRotation;
// Note: Assume 1-to-1 mapping with 'PlanePatchId'
for (int patchIndex = 0; patchIndex < 4; ++patchIndex)
{
planeInfo.patches[patchIndex].fillColor = _planeFillColors[planeIndex];
XYQuad3D quad = planeInfo.patches[patchIndex].quad;
quad.rotation = patchRotation;
quad.size = patchSize;
Vector3 xAxis = patchRotation * _patchCalcAxes[patchIndex * 2];
Vector3 yAxis = patchRotation * _patchCalcAxes[patchIndex * 2 + 1];
quad.center = position + xAxis * quarterPlaneSize + yAxis * quarterPlaneSize;
// Store this patch to sort it later
_sortedPatches.Add(planeInfo.patches[patchIndex]);
}
}
var camPos = PluginCamera.camera.transform.position;
_sortedPatches.Sort(delegate (MirrorPlanePatch p0, MirrorPlanePatch p1)
{
float d0 = (camPos - p0.quad.center).magnitude;
float d1 = (camPos - p1.quad.center).magnitude;
return d1.CompareTo(d0);
});
Material material = MaterialPool.instance.simpleDiffuse;
material.setZTestEnabled(false);
material.setZWriteEnabled(false);
material.setCullModeOff();
for (int patchIndex = 0; patchIndex < _sortedPatches.Count; ++patchIndex)
{
var patch = _sortedPatches[patchIndex];
material.SetColor("_Color", patch.fillColor);
material.SetPass(0);
patch.quad.drawFilled();
material.SetColor("_Color", GizmoPrefs.instance.mirrorPlaneBorderColor);
material.SetPass(0);
patch.quad.drawWire();
}
}
private void drawMidSnapHandle()
{
EditorGUI.BeginChangeCheck();
Handles.Slider(_snapHandleId, position, rotation * Vector3.right, getSnapHandleSize(), Handles.CubeHandleCap, 0.0f);
if (EditorGUI.EndChangeCheck())
{
if (_midSnapMode == MirrorGizmoMidSnapMode.TileRuleGrid)
{
if (tileRuleGrid != null)
{
Vector3Int cellCoords;
if (tileRuleGrid.pickCellCoords(PluginCamera.camera.getCursorRay(), tileRuleGridYOffset, out cellCoords))
{
tileRuleGrid.mirrorGizmoCellCoords = cellCoords;
}
}
}
else
{
Ray ray = PluginCamera.camera.getCursorRay();
SceneRayHit rayHit = PluginScene.instance.raycastClosest(ray, _snapToObjectsRaycastFilter, _snapToObjectsRaycastConfig);
if (rayHit.anyHit)
{
if (rayHit.wasGridHit && (!rayHit.wasObjectHit || rayHit.gridHit.hitEnter < rayHit.objectHit.hitEnter))
{
var hitCell = rayHit.gridHit.hitCell;
PluginScene.instance.grid.calcCellCenterAndCorners(hitCell, true, _vector3Buffer);
var closestPtIndex = Vector3Ex.findIndexOfPointClosestToPoint(_vector3Buffer, rayHit.gridHit.hitPoint);
if (closestPtIndex >= 0)
{
UndoEx.record(this);
position = _vector3Buffer[closestPtIndex];
}
}
else
if (rayHit.wasObjectHit && (!rayHit.wasGridHit || rayHit.objectHit.hitEnter < rayHit.gridHit.hitEnter))
{
GameObjectType objectType = GameObjectDataDb.instance.getGameObjectType(rayHit.objectHit.hitObject);
position = PluginScene.instance.grid.snapAllAxes(rayHit.objectHit.hitPoint);
/*if (objectType == GameObjectType.Terrain)
{
UndoEx.record(this);
position = rayHit.objectHit.hitPoint;
}
else
{
OBB worldOBB = ObjectBounds.calcWorldOBB(rayHit.objectHit.hitObject, _snapToObjectsBoundsQConfig);
if (worldOBB.isValid)
{
Box3DFace hitFace = Box3D.findFaceClosestToPoint(rayHit.objectHit.hitPoint, worldOBB.center, worldOBB.size, worldOBB.rotation);
Box3D.calcFaceCenterAndCorners(worldOBB.center, worldOBB.size, worldOBB.rotation, hitFace, _faceCenterAndCorners);
var closestPtIndex = Vector3Ex.findIndexOfPointClosestToPoint(_faceCenterAndCorners, rayHit.objectHit.hitPoint);
if (closestPtIndex >= 0)
{
UndoEx.record(this);
position = _faceCenterAndCorners[closestPtIndex];
}
}
}*/
}
}
}
}
}
private void drawMoveHandles()
{
float offsetAlongDirection = getRotationHandleSize() + 0.2f * HandleUtility.GetHandleSize(position);
var moveSnapStep = sharedSettings.moveSnapStep;
HandlesEx.saveColor();
for (int axisIndex = 0; axisIndex < 3; ++axisIndex)
{
Handles.color = _moveAxisColors[axisIndex];
EditorGUI.BeginChangeCheck();
Vector3 direction = rotation *_modelMoveDirs[axisIndex];
Vector3 currentPosition = position + direction * offsetAlongDirection;
Vector3 newPosition = Handles.Slider(getMoveHandleId(axisIndex), currentPosition, direction, getMoveHandleSize(), Handles.ConeHandleCap, moveSnapStep[axisIndex]);
if (EditorGUI.EndChangeCheck())
{
UndoEx.record(this);
position += (newPosition - currentPosition);
}
}
HandlesEx.restoreColor();
}
private void drawRotationHandles()
{
if (!sharedSettings.hasRotationHandles) return;
var rotationSnapStep = sharedSettings.rotationSnapStep;
for (int axisIndex = 0; axisIndex < 3; ++axisIndex)
{
Handles.color = _rotationHandleColors[axisIndex];
EditorGUI.BeginChangeCheck();
Quaternion rotQuat = Handles.Disc(getRotationHandleId(axisIndex), rotation, position, rotation * _rotationAxes[axisIndex], getRotationHandleSize(), true, rotationSnapStep[axisIndex]);
if (EditorGUI.EndChangeCheck())
{
UndoEx.record(this);
rotation = rotQuat;
}
}
}
private int getMoveHandleId(int axisIndex)
{
if (axisIndex == 0) return _xAxisMoveHandleId;
else if (axisIndex == 1) return _yAxisMoveHandleId;
return _zAxisMoveHandleId;
}
private int getRotationHandleId(int axisIndex)
{
if (axisIndex == 0) return _xAxisRotationHandleId;
else if (axisIndex == 1) return _yAxisRotationHandleId;
return _zAxisRotationHandleId;
}
private void drawMirroredBoxes()
{
if (_targetObjects == null) return;
Event e = Event.current;
if (e.type != EventType.Repaint) return;
if (!gatherMirrorPlanes(_mirrorPlaneBuffer)) return;
HandlesEx.saveColor();
HandlesEx.saveMatrix();
HandlesEx.saveLit();
Handles.lighting = false;
GameObjectEx.getParents(_targetObjects, _parentBuffer);
bool mirrorRotation = sharedSettings.mirrorRotation;
bool mirrorSpanning = sharedSettings.mirrorSpanning;
foreach(var parent in _parentBuffer)
{
_obbBuffer.Clear();
OBB obb = ObjectBounds.calcHierarchyWorldOBB(parent, _mirroredBoundsQConfig);
if (!obb.isValid) continue;
_obbBuffer.Add(obb);
for (int planeIndex = 0; planeIndex < _mirrorPlaneBuffer.Count; ++planeIndex)
{
if (!mirrorSpanning)
{
var location = Box3D.classifyAgainstPlane(obb.center, obb.size, obb.rotation, _mirrorPlaneBuffer[planeIndex]);
if (location == PlaneClassifyResult.Spanning) continue;
}
int numOBBs = _obbBuffer.Count;
for (int obbIndex = 0; obbIndex < numOBBs; ++obbIndex)
{
OBB mirroredOBB = Symmetry.mirrorOBB(_obbBuffer[obbIndex], mirrorRotation, _mirrorPlaneBuffer[planeIndex]);
_obbBuffer.Add(mirroredOBB);
}
}
int startOBB = 1;
for (int obbIndex = startOBB; obbIndex < _obbBuffer.Count; ++obbIndex)
{
Handles.matrix = Matrix4x4.TRS(_obbBuffer[obbIndex].center, _obbBuffer[obbIndex].rotation, _obbBuffer[obbIndex].size);
Handles.color = GizmoPrefs.instance.mirrorIndicatorFillColor;
Handles.CubeHandleCap(0, Vector3.zero, Quaternion.identity, 1.0f, e.type);
Handles.color = GizmoPrefs.instance.mirrorIndicatorWireColor;
//Handles.DrawWireCube(Vector3.zero, Vector3.one);
HandlesEx.drawUnitWireCube();
}
}
HandlesEx.restoreColor();
HandlesEx.restoreMatrix();
HandlesEx.restoreLit();
}
private void drawSymmetricPairHighlights()
{
if (sharedSettings.useXYPlane)
drawSymmetricPairHighlights(GizmoPrefs.instance.mirrorXYPlaneColor, PlaneId.XY);
if (sharedSettings.useYZPlane)
drawSymmetricPairHighlights(GizmoPrefs.instance.mirrorYZPlaneColor, PlaneId.YZ);
if (sharedSettings.useZXPlane)
drawSymmetricPairHighlights(GizmoPrefs.instance.mirrorZXPlaneColor, PlaneId.ZX);
}
private void drawSymmetricPairHighlights(Color highlightColor, PlaneId planeId)
{
highlightColor = highlightColor.createNewAlpha(1.0f);
Vector3 obbSize = Vector3.one;
obbSize.y = GizmoPrefs.instance.mirrorSymmetricPairHighlightRadius * 2.0f;
obbSize[(2 + (int)planeId) % 3] = GizmoPrefs.instance.mirrorSymmetricPairHighlightRadius * 2.0f;
OBB overlapOBB = new OBB(position, obbSize, rotation);
Plane mirrorPlane = new Plane(rotation * _mirrorPlanes[(int)planeId].modelNormal, position);
_symPairsOverlapFilter.objectTypes = GameObjectType.Mesh | GameObjectType.Sprite;
var overlapConfig = ObjectOverlapConfig.defaultConfig;
overlapConfig.prefabMode = ObjectOverlapPrefabMode.OnlyPrefabInstanceRoot;
_symPairsOutline.objectGather.Clear();
if (PluginScene.instance.overlapBox(overlapOBB, _symPairsOverlapFilter, overlapConfig, _symPairsObjectOverlapBuffer))
{
// Identify pairs of objects that are equally spaced from the mirror plane
int numObjects = _symPairsObjectOverlapBuffer.Count;
for (int i = 0; i < numObjects; ++i)
{
GameObject firstObject = _symPairsObjectOverlapBuffer[i];
GameObject firstPrefab = firstObject.getOutermostPrefabAsset();
if (firstPrefab == null) continue;
float d0 = mirrorPlane.GetDistanceToPoint(firstObject.transform.position);
float absD0 = Mathf.Abs(d0);
for (int j = i + 1; j < numObjects; ++j)
{
GameObject secondObject = _symPairsObjectOverlapBuffer[j];
//GameObject secondPrefab = secondObject.getOutermostPrefabAsset();
//if (secondPrefab != firstPrefab) continue;
// Only proceed if they reside on different sides of the plane
float d1 = mirrorPlane.GetDistanceToPoint(secondObject.transform.position);
if (Mathf.Sign(d0) != Mathf.Sign(d1))
{
// Ensure equal distance from plane
if (Mathf.Abs(absD0 - Mathf.Abs(d1)) < 1e-5f)
{
_symPairsOutline.objectGather.Add(firstObject);
_symPairsOutline.objectGather.Add(secondObject);
}
}
}
}
_symPairsOutline.drawHandles(highlightColor);
}
}
private bool gatherMirrorPlanes(List<Plane> planes)
{
planes.Clear();
if (sharedSettings.useXYPlane)
planes.Add(new Plane(rotation * _mirrorPlanes[(int)PlaneId.XY].modelNormal, position));
if (sharedSettings.useYZPlane)
planes.Add(new Plane(rotation * _mirrorPlanes[(int)PlaneId.YZ].modelNormal, position));
if (sharedSettings.useZXPlane)
planes.Add(new Plane(rotation * _mirrorPlanes[(int)PlaneId.ZX].modelNormal, position));
return planes.Count != 0;
}
private bool gatherMirrorPlanes(List<Plane> planes, List<PlaneId> planeIds)
{
planes.Clear();
planeIds.Clear();
if (sharedSettings.useXYPlane)
{
planes.Add(new Plane(rotation * _mirrorPlanes[(int)PlaneId.XY].modelNormal, position));
planeIds.Add(PlaneId.XY);
}
if (sharedSettings.useYZPlane)
{
planes.Add(new Plane(rotation * _mirrorPlanes[(int)PlaneId.YZ].modelNormal, position));
planeIds.Add(PlaneId.YZ);
}
if (sharedSettings.useZXPlane)
{
planes.Add(new Plane(rotation * _mirrorPlanes[(int)PlaneId.ZX].modelNormal, position));
planeIds.Add(PlaneId.ZX);
}
return planes.Count != 0;
}
private float getMoveHandleSize()
{
return HandleUtility.GetHandleSize(position) * 0.20f;
}
private float getSnapHandleSize()
{
return HandleUtility.GetHandleSize(position) * 0.112f;
}
private float getRotationHandleSize()
{
return HandleUtility.GetHandleSize(position) * 1.3f;
}
}
}
#endif