#define PreviewObjectHide using UnityEngine; using UnityEngine.Assertions; using UnityEditor; using System; using System.IO; using System.Collections.Generic; namespace VoxelImporter { public class VoxelEditorCommon { public VoxelBase objectTarget { get; private set; } public VoxelBaseCore objectCore { get; private set; } public Material vertexColorMaterial { get; private set; } public Material vertexColorTransparentMaterial { get; private set; } public Material vertexColorTransparentZwriteMaterial { get; private set; } public Material unlitColorMaterial { get; private set; } public Material unlitTextureMaterial { get; private set; } public Texture2D blackTransparentTexture { get; private set; } public List editorRectList { get; private set; } #region GUIStyle public GUIStyle guiStyleAlphaBox { get; private set; } public GUIStyle guiStyleToggleLeft { get; private set; } public GUIStyle guiStyleToggleRight { get; private set; } public GUIStyle guiStyleLabel { get; private set; } public GUIStyle guiStyleActiveButton { get; private set; } #endregion //Animation private float animationTime; public float AnimationPower { get { return 1f - ((Mathf.Cos((Time.realtimeSinceStartup - animationTime) * Mathf.PI * 2f) + 1f) / 2f); } } #region SelectionRect public struct SelectionRect { public void Reset() { Enable = false; start = IntVector2.zero; end = IntVector2.zero; } public void SetStart(IntVector2 add) { Enable = true; start = add; end = add; } public void SetEnd(IntVector2 add) { end = add; } public bool Enable { get; private set; } public int SizeX { get { return max.x - min.x + 1; } } public int SizeY { get { return max.y - min.y + 1; } } public IntVector2 min { get { return IntVector2.Min(start, end); } } public IntVector2 max { get { return IntVector2.Max(start, end); } } public Rect rect { get { return new Rect(min.x, min.y, max.x - min.x, max.y - min.y); } } public IntVector2 start; public IntVector2 end; } public SelectionRect selectionRect; #endregion //Tool public static Tool lastTool; //Fill public long fillVoxelDataLastTimeTicks; public DataTable3> fillVoxelTable; public DataTable3 fillVoxelFaceAreaTable; public DataTable3>> fillVoxelFaceTable; public DataTable3> fillVoxelFaceFaceAreaTable; //Mesh public Mesh[] silhouetteMesh; public Mesh[] previewMesh; public Mesh[] cursorMesh; #region Icon public GameObject iconRoot; public RenderTexture iconTexture; public GameObject iconModel; public MeshRenderer iconModelRenderer; public GameObject iconCamera; public Camera iconCameraCamera; #endregion public VoxelEditorCommon(VoxelBase objectTarget, VoxelBaseCore objectCore) { this.objectTarget = objectTarget; this.objectCore = objectCore; vertexColorMaterial = new Material(Shader.Find("Voxel Importer/VertexColor")); vertexColorMaterial.hideFlags = HideFlags.DontSave; vertexColorTransparentMaterial = new Material(Shader.Find("Voxel Importer/VertexColor-Transparent")); vertexColorTransparentMaterial.hideFlags = HideFlags.DontSave; vertexColorTransparentZwriteMaterial = new Material(Shader.Find("Voxel Importer/VertexColor-Transparent-Zwrite")); vertexColorTransparentZwriteMaterial.hideFlags = HideFlags.DontSave; unlitColorMaterial = new Material(Shader.Find("Voxel Importer/Unlit/Color")); unlitColorMaterial.hideFlags = HideFlags.DontSave; unlitTextureMaterial = new Material(Shader.Find("Voxel Importer/Unlit/Transparent")); unlitTextureMaterial.hideFlags = HideFlags.DontSave; blackTransparentTexture = CreateColorTexture(new Color(0, 0, 0, 0.3f)); editorRectList = new List(); animationTime = Time.realtimeSinceStartup; } public void ClearCache() { ClearSilhouetteMeshMesh(); ClearPreviewMesh(); ClearCursorMesh(); fillVoxelTable = null; fillVoxelFaceAreaTable = null; fillVoxelFaceTable = null; fillVoxelFaceFaceAreaTable = null; } public Texture2D CreateColorTexture(Color color) { Texture2D tex = new Texture2D(4, 4); tex.hideFlags = HideFlags.DontSave; for (int x = 0; x < tex.width; x++) { for (int y = 0; y < tex.height; y++) { tex.SetPixel(x, y, color); } } tex.Apply(); return tex; } public Texture2D LoadTexture2DAssetAtPath(string path) { var result = AssetDatabase.LoadAssetAtPath(path); if (result == null) { var fileName = Path.GetFileName(path); var guids = AssetDatabase.FindAssets("t:Texture2D"); for (int i = 0; i < guids.Length; i++) { var assetPath = AssetDatabase.GUIDToAssetPath(guids[i]); if (Path.GetFileName(assetPath) == fileName) { if (assetPath.IndexOf("VoxelImporter") >= 0) { result = AssetDatabase.LoadAssetAtPath(assetPath); break; } } } } return result; } public void ClearSilhouetteMeshMesh() { if (silhouetteMesh != null) { for (int i = 0; i < silhouetteMesh.Length; i++) { MonoBehaviour.DestroyImmediate(silhouetteMesh[i]); } silhouetteMesh = null; } } public void ClearPreviewMesh() { if (previewMesh != null) { for (int i = 0; i < previewMesh.Length; i++) { MonoBehaviour.DestroyImmediate(previewMesh[i]); } previewMesh = null; } } public void ClearCursorMesh() { if (cursorMesh != null) { for (int i = 0; i < cursorMesh.Length; i++) { MonoBehaviour.DestroyImmediate(cursorMesh[i]); } cursorMesh = null; } } public bool CheckMousePositionEditorRects() { for (int i = 0; i < editorRectList.Count; i++) { if (editorRectList[i].Contains(Event.current.mousePosition)) { return false; } } return true; } public IntVector3? GetMousePositionVoxel() { IntVector3? result = null; if (objectCore.voxelData == null || objectTarget.voxelData.voxels == null) return result; if (!CheckMousePositionEditorRects()) return result; Ray localRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); { Matrix4x4 mat = objectTarget.transform.worldToLocalMatrix; localRay.direction = mat.MultiplyVector(localRay.direction); localRay.origin = mat.MultiplyPoint(localRay.origin); } { var boundsBase = objectCore.GetVoxelBounds(IntVector3.zero); float lengthMin = float.MaxValue; for (int i = 0; i < objectTarget.voxelData.voxels.Length; i++) { if (objectTarget.voxelData.voxels[i].visible == 0) continue; Vector3 position = new Vector3(objectTarget.voxelData.voxels[i].x, objectTarget.voxelData.voxels[i].y, objectTarget.voxelData.voxels[i].z); Vector3 offset = Vector3.Scale(position, objectTarget.importScale); var bounds = boundsBase; bounds.center += offset; float length; if (bounds.IntersectRay(localRay, out length)) { if (!result.HasValue || length < lengthMin) { result = objectTarget.voxelData.voxels[i].position; lengthMin = length; } } } } return result; } public bool GetMousePositionVoxelFace(out IntVector3 result, out VoxelBase.Face face) { result = IntVector3.zero; face = 0; if (objectCore.voxelData == null || objectTarget.voxelData.voxels == null) return false; if (!CheckMousePositionEditorRects()) return false; Ray localRay = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); { Matrix4x4 mat = objectTarget.transform.worldToLocalMatrix; localRay.direction = mat.MultiplyVector(localRay.direction); localRay.origin = mat.MultiplyPoint(localRay.origin); } { var boundsBase = objectCore.GetVoxelBounds(IntVector3.zero); float lengthMin = float.MaxValue; for (int i = 0; i < objectTarget.voxelData.voxels.Length; i++) { if (objectTarget.voxelData.voxels[i].visible == 0) continue; Vector3 position = new Vector3(objectTarget.voxelData.voxels[i].x, objectTarget.voxelData.voxels[i].y, objectTarget.voxelData.voxels[i].z); Vector3 offset = Vector3.Scale(position, objectTarget.importScale); var bounds = boundsBase; bounds.center += offset; float length; if (bounds.IntersectRay(localRay, out length)) { if (length < lengthMin) { result = objectTarget.voxelData.voxels[i].position; lengthMin = length; #region Face { const float Threshold = 0.001f; var posP = localRay.GetPoint(length); if (Mathf.Abs(bounds.min.x - posP.x) < Threshold) face = VoxelBase.Face.left; else if (Mathf.Abs(bounds.max.x - posP.x) < Threshold) face = VoxelBase.Face.right; else if (Mathf.Abs(bounds.min.y - posP.y) < Threshold) face = VoxelBase.Face.down; else if (Mathf.Abs(bounds.max.y - posP.y) < Threshold) face = VoxelBase.Face.up; else if (Mathf.Abs(bounds.min.z - posP.z) < Threshold) face = VoxelBase.Face.back; else if (Mathf.Abs(bounds.max.z - posP.z) < Threshold) face = VoxelBase.Face.forward; else Assert.IsTrue(false); } #endregion } } } } return face != 0; } private void CheckFillVoxelTableCheck() { if (fillVoxelDataLastTimeTicks != objectTarget.voxelData.updateVoxelTableLastTimeTicks) { fillVoxelTable = null; fillVoxelFaceAreaTable = null; fillVoxelFaceTable = null; fillVoxelFaceFaceAreaTable = null; fillVoxelDataLastTimeTicks = objectTarget.voxelData.updateVoxelTableLastTimeTicks; } } public List GetFillVoxel(IntVector3 pos) { if (objectTarget.voxelData == null) return null; if (objectTarget.voxelData.VoxelTableContains(pos) < 0) return null; CheckFillVoxelTableCheck(); if (fillVoxelTable == null) { fillVoxelTable = new DataTable3>(objectTarget.voxelData.voxelSize.x, objectTarget.voxelData.voxelSize.y, objectTarget.voxelData.voxelSize.z); } if (!fillVoxelTable.Contains(pos)) { List searchList = new List(); int posPalette = 0; var doneTable = new FlagTable3(objectTarget.voxelData.voxelSize.x, objectTarget.voxelData.voxelSize.y, objectTarget.voxelData.voxelSize.z); { var index = objectTarget.voxelData.VoxelTableContains(pos); posPalette = objectTarget.voxelData.voxels[index].palette; searchList.Clear(); searchList.Add(pos); doneTable.Set(pos, true); } var result = new List(); for (int j = 0; j < searchList.Count; j++) { var p = searchList[j]; var index = objectTarget.voxelData.VoxelTableContains(p); if (index < 0) continue; if (objectTarget.voxelData.voxels[index].palette == posPalette) { result.Add(p); for (int x = p.x - 1; x <= p.x + 1; x++) { for (int y = p.y - 1; y <= p.y + 1; y++) { for (int z = p.z - 1; z <= p.z + 1; z++) { if (x >= 0 && y >= 0 && z >= 0 && x < objectTarget.voxelData.voxelSize.x && y < objectTarget.voxelData.voxelSize.y && z < objectTarget.voxelData.voxelSize.z && !doneTable.Get(x, y, z)) { doneTable.Set(x, y, z, true); var indexTmp = objectTarget.voxelData.VoxelTableContains(x, y, z); if (indexTmp >= 0 && objectTarget.voxelData.voxels[indexTmp].palette == posPalette) searchList.Add(new IntVector3(x, y, z)); } } } } } } for (int j = 0; j < result.Count; j++) { fillVoxelTable.Set(result[j], result); } } var fillVoxel = fillVoxelTable.Get(pos); return fillVoxel; } public VoxelData.FaceAreaTable GetFillVoxelFaceAreaTable(IntVector3 pos) { if (objectTarget.voxelData == null) return null; if (objectTarget.voxelData.VoxelTableContains(pos) < 0) return null; CheckFillVoxelTableCheck(); if (fillVoxelFaceAreaTable == null) { fillVoxelFaceAreaTable = new DataTable3(objectTarget.voxelData.voxelSize.x, objectTarget.voxelData.voxelSize.y, objectTarget.voxelData.voxelSize.z); } if (!fillVoxelFaceAreaTable.Contains(pos)) { var list = GetFillVoxel(pos); if (list == null) return null; var voxels = new List(); for (int i = 0; i < list.Count; i++) { var index = objectTarget.voxelData.VoxelTableContains(list[i]); var voxel = objectTarget.voxelData.voxels[index]; voxel.palette = -1; voxels.Add(voxel); } var faceAreaTable = objectCore.Edit_CreateMeshOnly_FaceArea(voxels, true); for (int i = 0; i < list.Count; i++) { fillVoxelFaceAreaTable.Set(list[i], faceAreaTable); } } var fillVoxelFaceArea = fillVoxelFaceAreaTable.Get(pos); return fillVoxelFaceArea; } public List GetFillVoxelFace(IntVector3 pos, VoxelBase.Face face) { if (objectTarget.voxelData == null) return null; if (objectTarget.voxelData.VoxelTableContains(pos) < 0) return null; CheckFillVoxelTableCheck(); if (fillVoxelFaceTable == null) { fillVoxelFaceTable = new DataTable3>>(objectTarget.voxelData.voxelSize.x, objectTarget.voxelData.voxelSize.y, objectTarget.voxelData.voxelSize.z); } if (!fillVoxelFaceTable.Contains(pos) || !fillVoxelFaceTable.Get(pos).ContainsKey((int)face)) { List searchList = new List(); var doneTable = new FlagTable3(objectTarget.voxelData.voxelSize.x, objectTarget.voxelData.voxelSize.y, objectTarget.voxelData.voxelSize.z); { searchList.Clear(); searchList.Add(pos); doneTable.Set(pos, true); } var result = new List(); for (int j = 0; j < searchList.Count; j++) { var p = searchList[j]; var index = objectTarget.voxelData.VoxelTableContains(p); if (index < 0) continue; if ((objectTarget.voxelData.voxels[index].visible & face) != 0) { result.Add(p); int xOffset = (face & (VoxelBase.Face.up | VoxelBase.Face.down | VoxelBase.Face.forward | VoxelBase.Face.back)) != 0 ? 1 : 0; int yOffset = (face & (VoxelBase.Face.right | VoxelBase.Face.left | VoxelBase.Face.forward | VoxelBase.Face.back)) != 0 ? 1 : 0; int zOffset = (face & (VoxelBase.Face.right | VoxelBase.Face.left | VoxelBase.Face.up | VoxelBase.Face.down)) != 0 ? 1 : 0; for (int x = p.x - xOffset; x <= p.x + xOffset; x++) { for (int y = p.y - yOffset; y <= p.y + yOffset; y++) { for (int z = p.z - zOffset; z <= p.z + zOffset; z++) { if (x >= 0 && y >= 0 && z >= 0 && x < objectTarget.voxelData.voxelSize.x && y < objectTarget.voxelData.voxelSize.y && z < objectTarget.voxelData.voxelSize.z && !doneTable.Get(x, y, z)) { doneTable.Set(x, y, z, true); var indexTmp = objectTarget.voxelData.VoxelTableContains(x, y, z); if (indexTmp >= 0) searchList.Add(new IntVector3(x, y, z)); } } } } } } Dictionary> data; if (fillVoxelFaceTable.Contains(pos)) data = fillVoxelFaceTable.Get(pos); else data = new Dictionary>(); data[(int)face] = result; fillVoxelFaceTable.Set(pos, data); for (int j = 0; j < result.Count; j++) { if (fillVoxelFaceTable.Contains(result[j])) data = fillVoxelFaceTable.Get(result[j]); else data = new Dictionary>(); data[(int)face] = result; fillVoxelFaceTable.Set(result[j], data); } } var fillVoxel = fillVoxelFaceTable.Get(pos)[(int)face]; return fillVoxel; } public VoxelData.FaceAreaTable GetFillVoxelFaceFaceAreaTable(IntVector3 pos, VoxelBase.Face face) { if (objectTarget.voxelData == null) return null; if (objectTarget.voxelData.VoxelTableContains(pos) < 0) return null; CheckFillVoxelTableCheck(); if (fillVoxelFaceFaceAreaTable == null) { fillVoxelFaceFaceAreaTable = new DataTable3>(objectTarget.voxelData.voxelSize.x, objectTarget.voxelData.voxelSize.y, objectTarget.voxelData.voxelSize.z); } if (!fillVoxelFaceFaceAreaTable.Contains(pos) || !fillVoxelFaceFaceAreaTable.Get(pos).ContainsKey((int)face)) { var list = GetFillVoxelFace(pos, face); if (list == null) return null; var voxels = new List(); for (int i = 0; i < list.Count; i++) { var index = objectTarget.voxelData.VoxelTableContains(list[i]); var voxel = objectTarget.voxelData.voxels[index]; voxel.palette = -1; voxel.visible = face; voxels.Add(voxel); } var faceAreaTable = objectCore.Edit_CreateMeshOnly_FaceArea(voxels, true); Dictionary data; if (fillVoxelFaceFaceAreaTable.Contains(pos)) data = fillVoxelFaceFaceAreaTable.Get(pos); else data = new Dictionary(); data[(int)face] = faceAreaTable; fillVoxelFaceFaceAreaTable.Set(pos, data); for (int i = 0; i < list.Count; i++) { if (fillVoxelFaceFaceAreaTable.Contains(list[i])) data = fillVoxelFaceFaceAreaTable.Get(list[i]); else data = new Dictionary(); data[(int)face] = faceAreaTable; fillVoxelFaceFaceAreaTable.Set(list[i], data); } } var fillVoxelFaceArea = fillVoxelFaceFaceAreaTable.Get(pos)[(int)face]; return fillVoxelFaceArea; } public struct VertexPower { public IntVector3 position; public float power; } public List GetMousePositionVertex(float radius) { List result = new List(); if (objectTarget.voxelData == null || objectTarget.voxelData.voxels == null) return result; if (!CheckMousePositionEditorRects()) return result; var boundsList = new List(); var vertexList = new List(); { Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); ray.origin = objectTarget.transform.worldToLocalMatrix.MultiplyPoint3x4(ray.origin); ray.direction = objectTarget.transform.worldToLocalMatrix.MultiplyVector(ray.direction); bool[,,] doneTable = new bool[objectTarget.voxelData.voxelSize.x + 1, objectTarget.voxelData.voxelSize.y + 1, objectTarget.voxelData.voxelSize.z + 1]; { Ray rayRadius = HandleUtility.GUIPointToWorldRay(new Vector2(Event.current.mousePosition.x + radius, Event.current.mousePosition.y)); rayRadius.origin = objectTarget.transform.worldToLocalMatrix.MultiplyPoint3x4(rayRadius.origin); rayRadius.direction = objectTarget.transform.worldToLocalMatrix.MultiplyVector(rayRadius.direction); Func AddVertex = (pos) => { if (doneTable[pos.x, pos.y, pos.z]) return true; doneTable[pos.x, pos.y, pos.z] = true; var posL = objectCore.GetVoxelRatePosition(pos, Vector3.zero); var posP = ray.origin + ray.direction * Vector3.Dot(posL - ray.origin, ray.direction); var posR = rayRadius.origin + rayRadius.direction * (Vector3.Dot(posP - rayRadius.origin, rayRadius.direction)); var distanceL = (posL - posP).sqrMagnitude; var distanceR = (posR - posP).sqrMagnitude; if (distanceL < distanceR) { vertexList.Add(new VertexPower() { position = pos, power = distanceL / distanceR }); return true; } return false; }; for (int i = 0; i < objectTarget.voxelData.voxels.Length; i++) { if (objectTarget.voxelData.voxels[i].visible == 0) continue; var pos = objectTarget.voxelData.voxels[i].position; bool enable = false; if ((objectTarget.voxelData.voxels[i].visible & (VoxelBase.Face.left | VoxelBase.Face.down | VoxelBase.Face.back)) != 0) if (AddVertex(new IntVector3(pos.x, pos.y, pos.z))) enable = true; if ((objectTarget.voxelData.voxels[i].visible & (VoxelBase.Face.right | VoxelBase.Face.down | VoxelBase.Face.back)) != 0) if (AddVertex(new IntVector3(pos.x + 1, pos.y, pos.z))) enable = true; if ((objectTarget.voxelData.voxels[i].visible & (VoxelBase.Face.left | VoxelBase.Face.up | VoxelBase.Face.back)) != 0) if (AddVertex(new IntVector3(pos.x, pos.y + 1, pos.z))) enable = true; if ((objectTarget.voxelData.voxels[i].visible & (VoxelBase.Face.left | VoxelBase.Face.down | VoxelBase.Face.forward)) != 0) if (AddVertex(new IntVector3(pos.x, pos.y, pos.z + 1))) enable = true; if ((objectTarget.voxelData.voxels[i].visible & (VoxelBase.Face.right | VoxelBase.Face.up | VoxelBase.Face.back)) != 0) if (AddVertex(new IntVector3(pos.x + 1, pos.y + 1, pos.z))) enable = true; if ((objectTarget.voxelData.voxels[i].visible & (VoxelBase.Face.right | VoxelBase.Face.down | VoxelBase.Face.forward)) != 0) if (AddVertex(new IntVector3(pos.x + 1, pos.y, pos.z + 1))) enable = true; if ((objectTarget.voxelData.voxels[i].visible & (VoxelBase.Face.left | VoxelBase.Face.up | VoxelBase.Face.forward)) != 0) if (AddVertex(new IntVector3(pos.x, pos.y + 1, pos.z + 1))) enable = true; if ((objectTarget.voxelData.voxels[i].visible & (VoxelBase.Face.right | VoxelBase.Face.up | VoxelBase.Face.forward)) != 0) if (AddVertex(new IntVector3(pos.x + 1, pos.y + 1, pos.z + 1))) enable = true; if (enable) { if ((ray.direction.x < 0f && ((objectTarget.voxelData.voxels[i].visible & VoxelBase.Face.right) != 0)) || (ray.direction.x > 0f && ((objectTarget.voxelData.voxels[i].visible & VoxelBase.Face.left) != 0)) || (ray.direction.y < 0f && ((objectTarget.voxelData.voxels[i].visible & VoxelBase.Face.up) != 0)) || (ray.direction.y > 0f && ((objectTarget.voxelData.voxels[i].visible & VoxelBase.Face.down) != 0)) || (ray.direction.z < 0f && ((objectTarget.voxelData.voxels[i].visible & VoxelBase.Face.forward) != 0)) || (ray.direction.z > 0f && ((objectTarget.voxelData.voxels[i].visible & VoxelBase.Face.back) != 0))) { boundsList.Add(objectCore.GetVoxelBounds(pos)); } } } } } { for (int i = 0; i < vertexList.Count; i++) { var pos = objectCore.GetVoxelRatePosition(vertexList[i].position, Vector3.zero); Ray ray = HandleUtility.GUIPointToWorldRay(HandleUtility.WorldToGUIPoint(objectTarget.transform.localToWorldMatrix.MultiplyPoint3x4(pos))); ray.origin = objectTarget.transform.worldToLocalMatrix.MultiplyPoint3x4(ray.origin); ray.direction = objectTarget.transform.worldToLocalMatrix.MultiplyVector(ray.direction); float length = (pos - ray.origin).magnitude - 0.1f; bool enable = true; for (int j = 0; j < boundsList.Count; j++) { float distance; if (boundsList[j].IntersectRay(ray, out distance)) { if (distance < length) { enable = false; break; } } } if (enable) { result.Add(vertexList[i]); } } } return result; } public List GetSelectionRectVoxel() { List result = new List(); if (selectionRect.Enable && objectTarget.voxelData != null && objectTarget.voxelData.voxels != null) { var localToWorldMatrix = objectTarget.transform.localToWorldMatrix; for (int i = 0; i < objectTarget.voxelData.voxels.Length; i++) { var local = objectCore.GetVoxelCenterPosition(objectTarget.voxelData.voxels[i].position); var world = localToWorldMatrix.MultiplyPoint(local); var screen = HandleUtility.WorldToGUIPoint(world); if (selectionRect.rect.Contains(screen)) { result.Add(objectTarget.voxelData.voxels[i].position); } } } return result; } public Dictionary GetSelectionRectVoxelFace() { Dictionary result = new Dictionary(); if (selectionRect.Enable && objectTarget.voxelData != null && objectTarget.voxelData.vertexList != null) { var localToWorldMatrix = objectTarget.transform.localToWorldMatrix; FlagTable3 containsTable = new FlagTable3(objectTarget.voxelData.voxelSize.x + 1, objectTarget.voxelData.voxelSize.y + 1, objectTarget.voxelData.voxelSize.z + 1); for (int i = 0; i < objectTarget.voxelData.vertexList.Count; i++) { var local = objectCore.GetVoxelRatePosition(objectTarget.voxelData.vertexList[i], Vector3.zero); var world = localToWorldMatrix.MultiplyPoint3x4(local); var screen = HandleUtility.WorldToGUIPoint(world); if (selectionRect.rect.Contains(screen)) containsTable.Set(objectTarget.voxelData.vertexList[i], true); } containsTable.AllAction((x, y, z) => { Action AddFace = (xx, yy, zz, face) => { var pos = new IntVector3(xx, yy, zz); var index = objectTarget.voxelData.VoxelTableContains(pos); if (index < 0) return; if ((objectTarget.voxelData.voxels[index].visible & face) == 0) return; VoxelBase.Face combineFace; if (!result.TryGetValue(pos, out combineFace)) { result.Add(pos, face); } else { combineFace |= face; result[pos] = combineFace; } }; #region Left if (containsTable.Get(x, y + 1, z) && containsTable.Get(x, y, z + 1) && containsTable.Get(x, y + 1, z + 1)) { AddFace(x, y, z, VoxelBase.Face.left); AddFace(x - 1, y, z, VoxelBase.Face.right); } #endregion #region Down if (containsTable.Get(x + 1, y, z) && containsTable.Get(x, y, z + 1) && containsTable.Get(x + 1, y, z + 1)) { AddFace(x, y, z, VoxelBase.Face.down); AddFace(x, y - 1, z, VoxelBase.Face.up); } #endregion #region Back if (containsTable.Get(x + 1, y, z) && containsTable.Get(x, y + 1, z) && containsTable.Get(x + 1, y + 1, z)) { AddFace(x, y, z, VoxelBase.Face.back); AddFace(x, y, z - 1, VoxelBase.Face.forward); } #endregion }); } return result; } public List GetSelectionRectVertex() { List result = new List(); if (selectionRect.Enable && objectTarget.voxelData != null && objectTarget.voxelData.vertexList != null) { var localToWorldMatrix = objectTarget.transform.localToWorldMatrix; for (int i = 0; i < objectTarget.voxelData.vertexList.Count; i++) { var local = objectCore.GetVoxelRatePosition(objectTarget.voxelData.vertexList[i], Vector3.zero); var world = localToWorldMatrix.MultiplyPoint3x4(local); var screen = HandleUtility.WorldToGUIPoint(world); if (selectionRect.rect.Contains(screen)) { result.Add(objectTarget.voxelData.vertexList[i]); } } } return result; } public Rect ResizeSceneViewRect(Rect rect) { var sv = SceneView.currentDrawingSceneView; if (rect.x + rect.width >= sv.position.width) rect.x -= (rect.x + rect.width) - sv.position.width; if (rect.y + rect.height >= sv.position.height) rect.y -= (rect.y + rect.height) - sv.position.height; if (rect.x < 0) rect.x -= rect.x; if (rect.y < 0) rect.y -= rect.y; return rect; } public void GUIStyleReady() { if (guiStyleAlphaBox == null) guiStyleAlphaBox = new GUIStyle(GUI.skin.box); guiStyleAlphaBox.normal.textColor = Color.white; guiStyleAlphaBox.fontStyle = FontStyle.Bold; guiStyleAlphaBox.alignment = TextAnchor.UpperCenter; guiStyleAlphaBox.normal.background = blackTransparentTexture; if (guiStyleToggleLeft == null) guiStyleToggleLeft = new GUIStyle(GUI.skin.toggle); guiStyleToggleLeft.normal.textColor = Color.white; guiStyleToggleLeft.onNormal.textColor = Color.white; guiStyleToggleLeft.hover.textColor = Color.white; guiStyleToggleLeft.onHover.textColor = Color.white; guiStyleToggleLeft.focused.textColor = Color.white; guiStyleToggleLeft.onFocused.textColor = Color.white; guiStyleToggleLeft.active.textColor = Color.white; guiStyleToggleLeft.onActive.textColor = Color.white; if (guiStyleToggleRight == null) guiStyleToggleRight = new GUIStyle(GUI.skin.toggle); guiStyleToggleRight.normal.textColor = Color.white; guiStyleToggleRight.onNormal.textColor = Color.white; guiStyleToggleRight.hover.textColor = Color.white; guiStyleToggleRight.onHover.textColor = Color.white; guiStyleToggleRight.focused.textColor = Color.white; guiStyleToggleRight.onFocused.textColor = Color.white; guiStyleToggleRight.active.textColor = Color.white; guiStyleToggleRight.onActive.textColor = Color.white; guiStyleToggleRight.padding.left = 2; guiStyleToggleRight.overflow.left = -149; if (guiStyleLabel == null) guiStyleLabel = new GUIStyle(GUI.skin.label); guiStyleLabel.normal.textColor = Color.white; if (guiStyleActiveButton == null) guiStyleActiveButton = new GUIStyle(GUI.skin.button); guiStyleActiveButton.normal = guiStyleActiveButton.active; } #region Icon public void InitializeIcon() { const string IconRootObjectName = "Tmp#VoxelImporterIcon"; { var objects = Resources.FindObjectsOfTypeAll(); for (int i = 0; i < objects.Length; i++) { if (objects[i].name == IconRootObjectName) iconRoot = objects[i]; } } if (iconRoot == null) { #if PreviewObjectHide iconRoot = UnityEditor.EditorUtility.CreateGameObjectWithHideFlags(IconRootObjectName, HideFlags.HideAndDontSave); #else iconRoot = new GameObject(IconRootObjectName); iconRoot.hideFlags = HideFlags.DontSave; #endif } iconRoot.SetActive(false); int blankLayer; for (blankLayer = 31; blankLayer > 0; blankLayer--) { if (string.IsNullOrEmpty(LayerMask.LayerToName(blankLayer))) break; } if (blankLayer < 0) blankLayer = 31; iconRoot.layer = blankLayer; iconTexture = new RenderTexture(128, 128, 16, RenderTextureFormat.ARGB32); iconTexture.hideFlags = HideFlags.DontSave; iconTexture.Create(); CreateIconObject(); } public void CreateIconObject(Transform transform = null, Mesh mesh = null, Material[] materials = null) { if (iconRoot == null) return; if (transform != null) { iconRoot.transform.position = transform.position; iconRoot.transform.rotation = transform.rotation; iconRoot.transform.localScale = Vector3.one; } else { iconRoot.transform.position = Vector3.zero; iconRoot.transform.rotation = Quaternion.identity; iconRoot.transform.localScale = Vector3.one; } { const string IconModelName = "IconModel"; var iconModelTransform = iconRoot.transform.Find(IconModelName); if (iconModelTransform != null) iconModel = iconModelTransform.gameObject; if (iconModel == null) { #if PreviewObjectHide iconModel = UnityEditor.EditorUtility.CreateGameObjectWithHideFlags(IconModelName, HideFlags.HideAndDontSave); #else iconModel = new GameObject(IconModelName); iconModel.hideFlags = HideFlags.DontSave; #endif } iconModel.transform.SetParent(iconRoot.transform); iconModel.transform.localPosition = new Vector3(0f, 0f, 0f); iconModel.layer = iconRoot.layer; MeshFilter meshFilter = iconModel.GetComponent(); if (meshFilter == null) meshFilter = iconModel.AddComponent(); meshFilter.sharedMesh = mesh; iconModelRenderer = iconModel.GetComponent(); if (iconModelRenderer == null) iconModelRenderer = iconModel.AddComponent(); if (materials != null) iconModelRenderer.sharedMaterials = materials; } { const string IconCameraName = "IconCamera"; var iconCameraTransform = iconRoot.transform.Find(IconCameraName); if (iconCameraTransform != null) iconCamera = iconCameraTransform.gameObject; if (iconCamera == null) { #if PreviewObjectHide iconCamera = UnityEditor.EditorUtility.CreateGameObjectWithHideFlags(IconCameraName, HideFlags.HideAndDontSave); #else iconCamera = new GameObject(IconCameraName); iconCamera.hideFlags = HideFlags.DontSave; #endif iconCameraCamera = iconCamera.AddComponent(); } else { iconCameraCamera = iconCamera.GetComponent(); } iconCamera.transform.SetParent(iconRoot.transform); iconCamera.layer = iconRoot.layer; if (mesh != null) { var rot = Quaternion.AngleAxis(180f, Vector3.up); iconCamera.transform.localRotation = rot; iconCamera.transform.localPosition = mesh.bounds.center + iconCamera.transform.worldToLocalMatrix.MultiplyVector(iconCamera.transform.forward) * mesh.bounds.size.z * 5f; } else { iconCamera.transform.localPosition = Vector3.zero; iconCamera.transform.localRotation = Quaternion.identity; } iconCameraCamera.orthographic = true; if (mesh != null) { iconCameraCamera.orthographicSize = Mathf.Max(mesh.bounds.size.x, Mathf.Max(mesh.bounds.size.y, mesh.bounds.size.z)) * 0.6f; iconCameraCamera.farClipPlane = Mathf.Max(mesh.bounds.size.x, Mathf.Max(mesh.bounds.size.y, mesh.bounds.size.z)) * 5f; } iconCameraCamera.clearFlags = CameraClearFlags.Color; iconCameraCamera.backgroundColor = new Color(0f, 0f, 0f, 0f); iconCameraCamera.cullingMask = 1 << iconRoot.layer; iconCameraCamera.targetTexture = iconTexture; } } public bool IsReadyIcon() { return iconRoot != null && iconModelRenderer != null && iconModelRenderer.sharedMaterials != null; } public Texture2D IconObjectRender() { if (iconRoot == null) return null; Texture2D tex = null; iconRoot.SetActive(true); iconCameraCamera.Render(); { RenderTexture save = RenderTexture.active; RenderTexture.active = iconTexture; tex = new Texture2D(iconTexture.width, iconTexture.height, TextureFormat.ARGB32, iconTexture.useMipMap); tex.hideFlags = HideFlags.DontSave; tex.ReadPixels(new Rect(0, 0, iconTexture.width, iconTexture.height), 0, 0); tex.Apply(); RenderTexture.active = save; } iconRoot.SetActive(false); return tex; } #endregion } }