ZeroVR/ZeroPacientVR/Assets/Octave3D World Builder/Scripts/Objects/Object Placement/Block/ObjectPlacementBlock.cs

323 lines
12 KiB
C#

#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
using System;
using System.Collections.Generic;
namespace O3DWB
{
[Serializable]
public class ObjectPlacementBlock : IMessageListener
{
#region Private Variables
[SerializeField]
private ObjectPlacementBlockSettings _settings;
[SerializeField]
private ObjectPlacementBlockRenderSettings _renderSettings;
private ObjectPlacementBlockRenderer _renderer = new ObjectPlacementBlockRenderer();
[SerializeField]
private ObjectPlacementExtensionPlane _extensionPlane = new ObjectPlacementExtensionPlane();
[SerializeField]
private BoxFace _extensionPlaneBoxFace = BoxFace.Bottom;
private GameObject _startObject;
private ObjectPlacementBlockManualConstructionSession _manualConstructionSession = new ObjectPlacementBlockManualConstructionSession();
private List<ObjectPlacementBoxStackSegment> _segments = new List<ObjectPlacementBoxStackSegment>();
#endregion
#region Public Properties
public int NumberOfSegments { get { return _segments.Count; } }
public ObjectPlacementBlockSettings Settings
{
get
{
if (_settings == null) _settings = Octave3DWorldBuilder.ActiveInstance.CreateScriptableObject<ObjectPlacementBlockSettings>();
return _settings;
}
}
public bool IsUnderManualConstruction { get { return _manualConstructionSession.IsActive; } }
public ObjectPlacementBlockRenderSettings RenderSettings
{
get
{
if (_renderSettings == null) _renderSettings = Octave3DWorldBuilder.ActiveInstance.CreateScriptableObject<ObjectPlacementBlockRenderSettings>();
return _renderSettings;
}
}
public ObjectPlacementExtensionPlaneRenderSettings ExtensionPlaneRenderSettings { get { return _extensionPlane.RenderSettings; } }
public Plane ExtensionPlane { get { return _extensionPlane.Plane; } }
#endregion
#region Constructors
public ObjectPlacementBlock()
{
MessageListenerRegistration.PerformRegistrationForObjectPlacementBlock(this);
}
#endregion
#region Public Methods
public void RenderGizmos()
{
if (_startObject == null) CancelManualConstruction();
if (CanRenderExtensionPlane())
{
_extensionPlane.FromOrientedBoxFace(_startObject.GetHierarchyWorldOrientedBox(), _extensionPlaneBoxFace);
_extensionPlane.RenderGizmos();
}
if (CanRenderBlock()) _renderer.RenderGizmos(this);
}
public void RenderHandles()
{
if (IsUnderManualConstruction && NumberOfSegments > 0 && _segments[0].NumberOfStacks > 0 && _segments[0].GetStackByIndex(0).NumberOfBoxes > 0)
{
int numberOfObjectsAlongRight = _segments[0].NumberOfStacks;
int numberOfObjectsAlongLook = NumberOfSegments;
int numberOfObjectsAlongUp = _segments[0].GetStackByIndex(0).NumberOfBoxes;
Vector3 boxSize = _segments[0].GetStackByIndex(0).BoxSize;
Vector3 labelPosition = _segments[0].GetStackByIndex(0).GetBoxByIndex(0).Center;
int numberOfStacks = _segments[0].NumberOfStacks;
if (numberOfStacks == 1)
{
labelPosition -= _extensionPlane.RightAxis * boxSize.x;
}
else
{
Vector3 fromSecondToFirstStack= _segments[0].GetStackByIndex(0).BasePosition - _segments[0].GetStackByIndex(1).BasePosition;
fromSecondToFirstStack.Normalize();
labelPosition += fromSecondToFirstStack * boxSize.x;
}
if(NumberOfSegments == 1)
{
labelPosition -= _extensionPlane.LookAxis * boxSize.z;
}
else
{
Vector3 fromSecondToFirstSegment = _segments[0].GetStackByIndex(0).BasePosition - _segments[1].GetStackByIndex(0).BasePosition;
fromSecondToFirstSegment.Normalize();
labelPosition += fromSecondToFirstSegment * boxSize.z;
}
LabelRenderSettings labelRenderSettings = RenderSettings.ManualConstructionRenderSettings.DimensionsLabelRenderSettings;
var labelStyle = new GUIStyle("label");
labelStyle.normal.textColor = labelRenderSettings.TextColor;
if (labelRenderSettings.Bold) labelStyle.fontStyle = FontStyle.Bold;
labelStyle.fontSize = labelRenderSettings.FontSize;
string labelText = "Block dimensions: " + "(" + numberOfObjectsAlongRight + ", ";
if (Settings.ManualConstructionSettings.HeightAdjustmentSettings.HeightAdjustmentMode == ObjectPlacementBlockHeightAdjustmentMode.AutomaticRandom) labelText += "#, ";
else labelText += numberOfObjectsAlongUp + ", ";
labelText += numberOfObjectsAlongLook + ")";
Handles.BeginGUI();
GUI.Label(new Rect(0.0f, SceneViewCamera.Camera.pixelHeight - 20.0f, 300.0f, 20.0f), labelText, labelStyle);
Handles.EndGUI();
}
}
public void NextExtensionPlane()
{
if (CanActivateNextExtensionPlane())
{
_extensionPlaneBoxFace = BoxFaces.GetNext(_extensionPlaneBoxFace);
SceneView.RepaintAll();
}
}
public List<OrientedBox> GetAllOrientedBoxes()
{
var allOrientedBoxes = new List<OrientedBox>();
foreach (var segment in _segments) allOrientedBoxes.AddRange(segment.GetAllOrientedBoxes());
return allOrientedBoxes;
}
public List<ObjectPlacementBoxStackSegment> GetAllSegments()
{
return new List<ObjectPlacementBoxStackSegment>(_segments);
}
public ObjectPlacementBoxStackSegment GetSegmentByIndex(int segmentIndex)
{
return _segments[segmentIndex];
}
public void SetStartObject(GameObject startObject)
{
if (_manualConstructionSession.IsActive) return;
_startObject = startObject;
}
public void BeginManualConstruction()
{
if (CanBeginManualConstruction())
{
_manualConstructionSession.SetData(GetManualConstructionSessionData());
_manualConstructionSession.Begin();
SceneView.RepaintAll();
}
}
public List<ObjectPlacementData> EndManualConstruction()
{
if (IsUnderManualConstruction)
{
List<ObjectPlacementData> objectPlacementDataInstances = _manualConstructionSession.End();
ClearData();
return objectPlacementDataInstances;
}
else
{
ClearData();
return new List<ObjectPlacementData>();
}
}
public void CancelManualConstruction()
{
_manualConstructionSession.Cancel();
ClearData();
}
public void ManualRaise()
{
_manualConstructionSession.ManualRaiseBlock();
}
public void ManualLower()
{
_manualConstructionSession.ManualLowerBlock();
}
public void UpdateForMouseMoveEvent()
{
if (_startObject == null) CancelManualConstruction();
_manualConstructionSession.UpdateForMouseMoveEvent();
}
#endregion
#region Private Methods
private ObjectPlacementBlockManualConstructionSessionData GetManualConstructionSessionData()
{
var manualConstructionSessionData = new ObjectPlacementBlockManualConstructionSessionData();
manualConstructionSessionData.Block = this;
manualConstructionSessionData.BlockSegments = _segments;
manualConstructionSessionData.BlockExtensionPlane = _extensionPlane;
manualConstructionSessionData.StartObject = _startObject;
return manualConstructionSessionData;
}
private bool CanBeginManualConstruction()
{
return _startObject != null && !_manualConstructionSession.IsActive;
}
private bool CanRenderExtensionPlane()
{
return !IsUnderManualConstruction && _startObject != null;
}
private bool CanRenderBlock()
{
return IsUnderManualConstruction && _startObject != null;
}
private bool CanActivateNextExtensionPlane()
{
return !IsUnderManualConstruction;
}
private void ClearData()
{
_segments.Clear();
}
#endregion
#region Message Handlers
public void RespondToMessage(Message message)
{
switch (message.Type)
{
case MessageType.ObjectPlacementBlockExcludeCornersWasChanged:
RespondToMessage(message as ObjectPlacementBlockExcludeCornersWasChangedMessage);
break;
case MessageType.ObjectPlacementBlockPaddingSettingsWereChanged:
RespondToMessage(message as ObjectPlacementBlockPaddingSettingsWereChangedMessage);
break;
case MessageType.ObjectPlacementBlockAutomaticRandomHeightAdjustmentSettingsWereChanged:
RespondToMessage(message as ObjectPlacementBlockAutomaticRandomHeightAdjustmentSettingsWereChangedMessage);
break;
case MessageType.ObjectPlacementBlockHeightAdjustmentModeWasChanged:
RespondToMessage(message as ObjectPlacementBlockHeightAdjustmentModeWasChangedMessage);
break;
case MessageType.ObjectPlacementBlockSubdivisionSettingsWereChanged:
RespondToMessage(message as ObjectPlacementBlockSubdivisionSettingsWereChangedMessage);
break;
case MessageType.UndoRedoWasPerformed:
RespondToMessage(message as UndoRedoWasPerformedMessage);
break;
}
}
private void RespondToMessage(ObjectPlacementBlockExcludeCornersWasChangedMessage message)
{
if (message.BlockManualConstructionSettings == Settings.ManualConstructionSettings)
_manualConstructionSession.OnExcludeCornersSettingsChanged();
}
private void RespondToMessage(ObjectPlacementBlockPaddingSettingsWereChangedMessage message)
{
if (message.PaddingSettings == Settings.ManualConstructionSettings.PaddingSettings)
_manualConstructionSession.OnPaddingSettingsChanged();
}
private void RespondToMessage(ObjectPlacementBlockAutomaticRandomHeightAdjustmentSettingsWereChangedMessage message)
{
if (message.AutomaticRandomHeightAdjustmentSettings == Settings.ManualConstructionSettings.HeightAdjustmentSettings.AutomaticRandomHeightAdjustmentSettings)
_manualConstructionSession.OnAutomaticRandomHeightAdjustmentSettingsChanged();
}
private void RespondToMessage(ObjectPlacementBlockHeightAdjustmentModeWasChangedMessage message)
{
if (message.HeightAdjustmentSettings == Settings.ManualConstructionSettings.HeightAdjustmentSettings)
_manualConstructionSession.OnHeightAdjustmentModeChanged();
}
private void RespondToMessage(ObjectPlacementBlockSubdivisionSettingsWereChangedMessage message)
{
if (message.SubdivisionSettings == Settings.ManualConstructionSettings.SubdivisionSettings)
_manualConstructionSession.OnSubdivisionSettingsChanged();
}
private void RespondToMessage(UndoRedoWasPerformedMessage message)
{
_manualConstructionSession.OnExcludeCornersSettingsChanged();
_manualConstructionSession.OnPaddingSettingsChanged();
_manualConstructionSession.OnAutomaticRandomHeightAdjustmentSettingsChanged();
_manualConstructionSession.OnHeightAdjustmentModeChanged();
_manualConstructionSession.OnSubdivisionSettingsChanged();
}
#endregion
}
}
#endif