using System; using System.Collections; using Gaia.FullSerializer; using UnityEngine; namespace Gaia { [ExecuteInEditMode] public class Stamper : MonoBehaviour { public string m_stampID = Guid.NewGuid().ToString(); public Texture2D m_stampPreviewImage; public float m_x; public float m_y = 50f; public float m_z; public float m_width = 10f; public float m_height = 10f; public float m_rotation; public bool m_stickBaseToGround = true; [fsIgnore] public GaiaResource m_resources; [fsIgnore] public float m_seaLevel; public string m_resourcesPath; public bool m_invertStamp; public bool m_normaliseStamp; public float m_baseLevel; public bool m_drawStampBase = true; public GaiaConstants.FeatureOperation m_stampOperation; public int m_smoothIterations; public float m_blendStrength = 0.5f; public float m_stencilHeight = 1f; public AnimationCurve m_heightModifier = AnimationCurve.Linear(0f, 0f, 1f, 1f); public AnimationCurve m_distanceMask = new AnimationCurve(new Keyframe(0f, 1f), new Keyframe(1f, 1f)); public GaiaConstants.ImageFitnessFilterMode m_areaMaskMode; public Texture2D m_imageMask; public bool m_imageMaskInvert; public bool m_imageMaskNormalise; public bool m_imageMaskFlip; public int m_imageMaskSmoothIterations = 3; [fsIgnore] public HeightMap m_imageMaskHM; public float m_noiseMaskSeed; public int m_noiseMaskOctaves = 8; public float m_noiseMaskPersistence = 0.25f; public float m_noiseMaskFrequency = 1f; public float m_noiseMaskLacunarity = 1.5f; public float m_noiseZoom = 10f; public bool m_alwaysShow; public bool m_showBase = true; public bool m_showSeaLevel = true; public bool m_showRulers; public bool m_showTerrainHelper; [fsIgnore] public Color m_gizmoColour = new Color(1f, 0.6f, 0f, 1f); [fsIgnore] public IEnumerator m_updateCoroutine; [fsIgnore] public float m_updateTimeAllowed = 1f / 30f; [fsIgnore] public float m_stampProgress; [fsIgnore] public bool m_stampComplete = true; [fsIgnore] public bool m_cancelStamp; [fsIgnore] public Material m_previewMaterial; private int m_featureID; private int m_scanWidth; private int m_scanDepth; private int m_scanHeight; private float m_scanResolution = 0.1f; private Bounds m_scanBounds; private UnityHeightMap m_stampHM; private GaiaWorldManager m_undoMgr; private GaiaWorldManager m_redoMgr; private MeshFilter m_previewFilter; private MeshRenderer m_previewRenderer; public void LoadStamp() { m_featureID = -1; m_scanBounds = new Bounds(base.transform.position, Vector3.one * 10f); if (m_stampPreviewImage == null) { Debug.LogWarning("Can't load feature - texture not set"); return; } m_featureID = m_stampPreviewImage.GetInstanceID(); if (!GaiaUtils.CheckValidGaiaStampPath(m_stampPreviewImage)) { Debug.LogError("The file provided is not a valid stamp. You need to drag the stamp preview from one of the directories underneath your Gaia Stamps directory."); m_featureID = -1; m_stampPreviewImage = null; return; } string gaiaStampPath = GaiaUtils.GetGaiaStampPath(m_stampPreviewImage); m_stampHM = new UnityHeightMap(gaiaStampPath); if (!m_stampHM.HasData()) { m_featureID = -1; m_stampPreviewImage = null; Debug.LogError("Was unable to load " + gaiaStampPath); return; } float[] array = new float[5]; Buffer.BlockCopy(m_stampHM.GetMetaData(), 0, array, 0, array.Length * 4); m_scanWidth = (int)array[0]; m_scanDepth = (int)array[1]; m_scanHeight = (int)array[2]; m_scanResolution = array[3]; m_baseLevel = array[4]; m_scanBounds = new Bounds(base.transform.position, new Vector3((float)m_scanWidth * m_scanResolution * m_width, (float)m_scanHeight * m_scanResolution * m_height, (float)m_scanDepth * m_scanResolution * m_width)); if (m_invertStamp) { m_stampHM.Invert(); } if (m_normaliseStamp) { m_stampHM.Normalise(); } GeneratePreviewMesh(); } public void LoadStamp(string imagePreviewPath) { LoadStamp(); } public bool LoadRuntimeStamp(TextAsset stamp) { m_stampHM = new UnityHeightMap(stamp); if (!m_stampHM.HasData()) { m_featureID = -1; m_stampPreviewImage = null; Debug.LogError("Was unable to load textasset stamp"); return false; } float[] array = new float[5]; Buffer.BlockCopy(m_stampHM.GetMetaData(), 0, array, 0, array.Length * 4); m_scanWidth = (int)array[0]; m_scanDepth = (int)array[1]; m_scanHeight = (int)array[2]; m_scanResolution = array[3]; m_baseLevel = array[4]; m_scanBounds = new Bounds(base.transform.position, new Vector3((float)m_scanWidth * m_scanResolution * m_width, (float)m_scanHeight * m_scanResolution * m_height, (float)m_scanDepth * m_scanResolution * m_width)); if (m_invertStamp) { m_stampHM.Invert(); } if (m_normaliseStamp) { m_stampHM.Normalise(); } return true; } public void InvertStamp() { m_stampHM.Invert(); GeneratePreviewMesh(); } public void NormaliseStamp() { m_stampHM.Normalise(); GeneratePreviewMesh(); } public void Stamp() { m_cancelStamp = false; m_stampComplete = false; m_stampProgress = 0f; AddToSession(GaiaOperation.OperationType.Stamp, "Stamping " + m_stampPreviewImage.name); StartCoroutine(ApplyStamp()); } public void CancelStamp() { m_cancelStamp = true; } public bool IsStamping() { return !m_stampComplete; } public void UpdateStamp() { if (m_stickBaseToGround) { AlignToGround(); } base.transform.position = new Vector3(m_x, m_y, m_z); base.transform.localScale = new Vector3(m_width, m_height, m_width); base.transform.localRotation = Quaternion.AngleAxis(m_rotation, Vector3.up); m_scanBounds.center = base.transform.position; m_scanBounds.size = new Vector3((float)m_scanWidth * m_scanResolution * m_width, (float)m_scanHeight * m_scanResolution * m_height, (float)m_scanDepth * m_scanResolution * m_width); if (m_stampHM != null) { m_stampHM.SetBoundsWU(m_scanBounds); } base.transform.hasChanged = false; } public void AlignToGround() { if (m_stampHM != null && m_stampHM.HasData()) { float num = 0f; Terrain terrain = TerrainHelper.GetTerrain(base.transform.position); if (terrain == null) { terrain = Terrain.activeTerrain; } if (terrain != null) { num = terrain.transform.position.y; } m_scanBounds.center = base.transform.position; m_scanBounds.size = new Vector3((float)m_scanWidth * m_scanResolution * m_width, (float)m_scanHeight * m_scanResolution * m_height, (float)m_scanDepth * m_scanResolution * m_width); if (terrain == null) { m_y = num + m_scanBounds.extents.y; return; } float num2 = m_scanBounds.min.y + m_scanBounds.size.y * m_baseLevel; m_y = m_scanBounds.center.y - (num2 - num); } } public bool GetHeightRange(ref float baseLevel, ref float minHeight, ref float maxHeight) { if (m_stampHM == null || !m_stampHM.HasData()) { return false; } baseLevel = m_baseLevel; m_stampHM.GetHeightRange(ref minHeight, ref maxHeight); return true; } public void FitToTerrain() { Terrain terrain = TerrainHelper.GetTerrain(base.transform.position); if (terrain == null) { terrain = TerrainHelper.GetActiveTerrain(); } if (terrain == null) { return; } Bounds bounds = default(Bounds); if (TerrainHelper.GetTerrainBounds(terrain, ref bounds)) { m_height = bounds.size.y / 100f * 2f; if (m_stampHM != null && m_stampHM.HasData()) { m_width = bounds.size.x / (float)m_stampHM.Width() * 10f; } else { m_width = m_height; } m_height *= 0.25f; m_x = bounds.center.x; m_y = bounds.center.y; m_z = bounds.center.z; m_rotation = 0f; } if (m_stickBaseToGround) { AlignToGround(); } } public bool IsFitToTerrain() { Terrain terrain = TerrainHelper.GetTerrain(base.transform.position); if (terrain == null) { terrain = Terrain.activeTerrain; } if (terrain == null || m_stampHM == null || !m_stampHM.HasData()) { Debug.LogError("Could not check if fit to terrain - no terrain present"); return false; } Bounds bounds = default(Bounds); if (TerrainHelper.GetTerrainBounds(terrain, ref bounds)) { float num = bounds.size.x / (float)m_stampHM.Width() * 10f; float x = bounds.center.x; float z = bounds.center.z; float num2 = 0f; if (num != m_width || x != m_x || z != m_z || num2 != m_rotation) { return false; } return true; } return false; } public void AddToSession(GaiaOperation.OperationType opType, string opName) { GaiaSessionManager sessionManager = GaiaSessionManager.GetSessionManager(); if (sessionManager != null && !sessionManager.IsLocked()) { GaiaOperation gaiaOperation = new GaiaOperation(); gaiaOperation.m_description = opName; gaiaOperation.m_generatedByID = m_stampID; gaiaOperation.m_generatedByName = base.transform.name; gaiaOperation.m_generatedByType = GetType().ToString(); gaiaOperation.m_isActive = true; gaiaOperation.m_operationDateTime = DateTime.Now.ToString(); gaiaOperation.m_operationType = opType; if (opType == GaiaOperation.OperationType.Stamp) { gaiaOperation.m_operationDataJson = new string[1]; gaiaOperation.m_operationDataJson[0] = SerialiseJson(); } else { gaiaOperation.m_operationDataJson = new string[0]; } sessionManager.AddOperation(gaiaOperation); } } public string SerialiseJson() { new fsSerializer().TrySerialize(this, out var data); return fsJsonPrinter.CompressedJson(data); } public void DeSerialiseJson(string json) { fsData data = fsJsonParser.Parse(json); fsSerializer obj = new fsSerializer(); Stamper instance = this; obj.TryDeserialize(data, ref instance); instance.LoadStamp(); instance.UpdateStamp(); } public void FlattenTerrain() { AddToSession(GaiaOperation.OperationType.FlattenTerrain, "Flattening terrain"); m_undoMgr = new GaiaWorldManager(Terrain.activeTerrains); m_undoMgr.LoadFromWorld(); m_redoMgr = new GaiaWorldManager(Terrain.activeTerrains); m_redoMgr.FlattenWorld(); m_redoMgr = null; } public void SmoothTerrain() { AddToSession(GaiaOperation.OperationType.SmoothTerrain, "Smoothing terrain"); m_undoMgr = new GaiaWorldManager(Terrain.activeTerrains); m_undoMgr.LoadFromWorld(); m_redoMgr = new GaiaWorldManager(Terrain.activeTerrains); m_redoMgr.SmoothWorld(); m_redoMgr = null; } public void ClearTrees() { AddToSession(GaiaOperation.OperationType.ClearTrees, "Clearing terrain trees"); TerrainHelper.ClearTrees(); } public void ClearDetails() { AddToSession(GaiaOperation.OperationType.ClearDetails, "Clearing terrain details"); TerrainHelper.ClearDetails(); } public bool CanPreview() { return m_previewRenderer != null; } public bool CurrentPreviewState() { if (m_previewRenderer != null) { return m_previewRenderer.enabled; } return false; } public void ShowPreview() { if (m_previewRenderer != null) { m_previewRenderer.enabled = true; } } public void HidePreview() { if (m_previewRenderer != null) { m_previewRenderer.enabled = false; } } public void TogglePreview() { if (m_previewRenderer != null) { m_previewRenderer.enabled = !m_previewRenderer.enabled; } } public bool CanUndo() { if (m_undoMgr == null) { return false; } return true; } public void CreateUndo() { m_undoMgr = new GaiaWorldManager(Terrain.activeTerrains); m_undoMgr.LoadFromWorld(); m_redoMgr = null; } public void Undo() { if (m_undoMgr != null) { AddToSession(GaiaOperation.OperationType.StampUndo, "Undoing stamp"); m_redoMgr = new GaiaWorldManager(Terrain.activeTerrains); m_redoMgr.LoadFromWorld(); m_undoMgr.SaveToWorld(forceWrite: true); } } public bool CanRedo() { if (m_redoMgr == null) { return false; } return true; } public void Redo() { if (m_redoMgr != null) { AddToSession(GaiaOperation.OperationType.StampRedo, "Redoing stamp"); m_redoMgr.SaveToWorld(forceWrite: true); m_redoMgr = null; } } private void OnEnable() { if (m_stampPreviewImage != null) { LoadStamp(); } } private void Start() { if (Application.isPlaying) { HidePreview(); } } public void StartEditorUpdates() { } public void StopEditorUpdates() { } private void EditorUpdate() { } private void OnDrawGizmosSelected() { DrawGizmos(isSelected: true); } private void OnDrawGizmos() { DrawGizmos(isSelected: false); } private void DrawGizmos(bool isSelected) { if (m_stampPreviewImage == null) { return; } if (base.transform.hasChanged) { m_x = base.transform.position.x; m_y = base.transform.position.y; m_z = base.transform.position.z; m_rotation = base.transform.localEulerAngles.y; if (base.transform.localScale.x != m_width || base.transform.localScale.z != m_width) { float num = Mathf.Abs(base.transform.localScale.x - m_width); float num2 = Mathf.Abs(base.transform.localScale.z - m_width); if (num > num2) { if (base.transform.localScale.x > 0f) { m_width = base.transform.localScale.x; } } else if (base.transform.localScale.z > 0f) { m_width = base.transform.localScale.z; } } if (base.transform.localScale.y != m_height && base.transform.localScale.y > 0f) { m_height = base.transform.localScale.y; } UpdateStamp(); } if (!isSelected && !m_alwaysShow) { return; } if (m_showBase) { Bounds bounds = default(Bounds); if (TerrainHelper.GetTerrainBounds(base.transform.position, ref bounds)) { bounds.center = new Vector3(bounds.center.x, m_scanBounds.min.y + m_scanBounds.size.y * m_baseLevel, bounds.center.z); bounds.size = new Vector3(bounds.size.x, 0.05f, bounds.size.z); Gizmos.color = new Color(Color.yellow.r, Color.yellow.g, Color.yellow.b, Color.yellow.a / 2f); Gizmos.DrawCube(bounds.center, bounds.size); } } if (m_resources != null) { m_seaLevel = m_resources.m_seaLevel; } if (m_showSeaLevel) { Bounds bounds2 = default(Bounds); if (TerrainHelper.GetTerrainBounds(base.transform.position, ref bounds2)) { bounds2.center = new Vector3(bounds2.center.x, m_seaLevel, bounds2.center.z); bounds2.size = new Vector3(bounds2.size.x, 0.05f, bounds2.size.z); if (isSelected) { Gizmos.color = new Color(Color.blue.r, Color.blue.g, Color.blue.b, Color.blue.a / 2f); Gizmos.DrawCube(bounds2.center, bounds2.size); } else { Gizmos.color = new Color(Color.blue.r, Color.blue.g, Color.blue.b, Color.blue.a / 4f); Gizmos.DrawCube(bounds2.center, bounds2.size); } } } if (m_showRulers) { DrawRulers(); } Matrix4x4 matrix = Gizmos.matrix; Gizmos.matrix = base.transform.localToWorldMatrix; Vector3 size = new Vector3((float)m_scanWidth * m_scanResolution, (float)m_scanHeight * m_scanResolution, (float)m_scanDepth * m_scanResolution); Gizmos.color = new Color(m_gizmoColour.r, m_gizmoColour.g, m_gizmoColour.b, m_gizmoColour.a / 2f); Gizmos.DrawWireCube(Vector3.zero, size); Gizmos.matrix = matrix; Terrain terrain = TerrainHelper.GetTerrain(base.transform.position); if (terrain != null) { Gizmos.color = Color.white; Bounds bounds3 = default(Bounds); TerrainHelper.GetTerrainBounds(terrain, ref bounds3); Gizmos.DrawWireCube(bounds3.center, bounds3.size); } } private void DrawRulers() { } public IEnumerator ApplyStamp() { UpdateStamp(); GaiaWorldManager mgr = new GaiaWorldManager(Terrain.activeTerrains); mgr.LoadFromWorld(); if (mgr.TileCount == 0) { Debug.LogError("Can not stamp without a terrain present!"); m_stampProgress = 0f; m_stampComplete = true; m_updateCoroutine = null; yield break; } CreateUndo(); if (m_areaMaskMode != GaiaConstants.ImageFitnessFilterMode.None && !LoadImageMask()) { m_stampProgress = 0f; m_stampComplete = true; m_updateCoroutine = null; yield break; } Vector3 angle = new Vector3(0f, base.transform.localRotation.eulerAngles.y, 0f); Bounds boundsWU = m_stampHM.GetBoundsWU(); Bounds bounds = default(Bounds); bounds.center = boundsWU.center; bounds.Encapsulate(RotatePointAroundPivot(new Vector3(boundsWU.min.x, boundsWU.center.y, boundsWU.min.z), boundsWU.center, angle)); bounds.Encapsulate(RotatePointAroundPivot(new Vector3(boundsWU.min.x, boundsWU.center.y, boundsWU.max.z), boundsWU.center, angle)); bounds.Encapsulate(RotatePointAroundPivot(new Vector3(boundsWU.max.x, boundsWU.center.y, boundsWU.min.z), boundsWU.center, angle)); bounds.Encapsulate(RotatePointAroundPivot(new Vector3(boundsWU.max.x, boundsWU.center.y, boundsWU.max.z), boundsWU.center, angle)); Vector3 vector = mgr.Ceil(mgr.WUtoTU(bounds.size)); Vector3 pivot = new Vector3(0.5f, 0f, 0.5f); int newSmMaxX = (int)vector.x; int newSmMaxZ = (int)vector.z; float newSmXtoNU = 1f / vector.x; float newSmZtoNU = 1f / vector.z; float xNewSMtoOrigSMScale = bounds.size.x / boundsWU.size.x; float zNewSMtoOrigSMScale = bounds.size.x / boundsWU.size.z; float scaleOffsetX = 0.5f * ((boundsWU.size.x - bounds.size.x) / boundsWU.size.x); float scaleOffsetZ = 0.5f * ((boundsWU.size.z - bounds.size.x) / boundsWU.size.z); float currentTime = Time.realtimeSinceStartup; float accumulatedTime = 0f; int currChecks = 0; int totalChecks = newSmMaxX * newSmMaxZ; Vector3 vector2 = mgr.WUtoTU(base.transform.position); Vector3 globalOffsetTU = vector2 - vector * 0.5f; Vector3 globalPositionTU = Vector3.one; globalPositionTU.y = vector2.y; float smToOrigHeightConversion = boundsWU.size.y / mgr.WorldBoundsWU.size.y; float smHeightOffset = (boundsWU.min.y - mgr.WorldBoundsWU.min.y) / mgr.WorldBoundsWU.size.y; float stencilHeightNU = m_stencilHeight / mgr.WorldBoundsWU.size.y; double rotationCosTheta = Math.Cos(Math.PI / 180.0 * (double)angle.y); double rotationSinTheta = Math.Sin(Math.PI / 180.0 * (double)angle.y); RotationProducts xRotationProducts = new RotationProducts(); RotationProducts[] zRotationProductCache = new RotationProducts[newSmMaxZ]; Vector3 vector3 = default(Vector3); for (int x = 0; x < newSmMaxX; x++) { float num = (float)x * newSmXtoNU - pivot.x; xRotationProducts.sinTheta = (double)num * rotationSinTheta; xRotationProducts.cosTheta = (double)num * rotationCosTheta; for (int z = 0; z < newSmMaxZ; z++) { m_stampProgress = (float)currChecks++ / (float)totalChecks; float realtimeSinceStartup = Time.realtimeSinceStartup; float num2 = realtimeSinceStartup - currentTime; currentTime = realtimeSinceStartup; accumulatedTime += num2; if (accumulatedTime > m_updateTimeAllowed) { accumulatedTime = 0f; yield return null; } if (m_cancelStamp) { break; } globalPositionTU.x = (float)z + globalOffsetTU.z; globalPositionTU.z = (float)x + globalOffsetTU.x; if (!mgr.InBoundsTU(globalPositionTU)) { continue; } if (zRotationProductCache[z] == null) { float num3 = (float)z * newSmZtoNU - pivot.z; zRotationProductCache[z] = new RotationProducts { sinTheta = (double)num3 * rotationSinTheta, cosTheta = (double)num3 * rotationCosTheta }; } vector3.x = (float)(xRotationProducts.cosTheta - zRotationProductCache[z].sinTheta + (double)pivot.x); vector3.z = (float)(xRotationProducts.sinTheta + zRotationProductCache[z].cosTheta + (double)pivot.z); float num4 = vector3.x * xNewSMtoOrigSMScale + scaleOffsetX; float num5 = vector3.z * zNewSMtoOrigSMScale + scaleOffsetZ; if (!(num4 < 0f) && !(num4 > 1f) && !(num5 < 0f) && !(num5 > 1f)) { float time = GaiaUtils.Math_Distance(num4, num5, pivot.x, pivot.z) * 2f; float num6 = m_distanceMask.Evaluate(time); if (m_areaMaskMode != GaiaConstants.ImageFitnessFilterMode.None && m_imageMaskHM != null) { num6 *= m_imageMaskHM[num4, num5]; } float num7 = m_heightModifier.Evaluate(m_stampHM[num4, num5]); float smHeightAdj = ((m_stampOperation == GaiaConstants.FeatureOperation.StencilHeight) ? num7 : (smHeightOffset + num7 * smToOrigHeightConversion)); float heightTU = mgr.GetHeightTU(globalPositionTU); float value = CalculateHeight(heightTU, num7, smHeightAdj, stencilHeightNU, num6); mgr.SetHeightTU(globalPositionTU, Mathf.Clamp01(value)); } } } if (!m_cancelStamp) { mgr.SaveToWorld(); } else { m_undoMgr = null; m_redoMgr = null; } m_stampProgress = 0f; m_stampComplete = true; m_updateCoroutine = null; } private void GeneratePreviewMesh() { if (m_previewMaterial == null) { m_previewMaterial = new Material(Shader.Find("Diffuse")); m_previewMaterial.color = Color.white; if (Terrain.activeTerrain != null) { GaiaSplatPrototype[] gaiaSplatPrototypes = GaiaSplatPrototype.GetGaiaSplatPrototypes(Terrain.activeTerrain); if (gaiaSplatPrototypes.Length != 0) { Texture2D texture2D = ((gaiaSplatPrototypes.Length != 4) ? gaiaSplatPrototypes[0].texture : gaiaSplatPrototypes[3].texture); GaiaUtils.MakeTextureReadable(texture2D); Texture2D texture2D2 = new Texture2D(texture2D.width, texture2D.height, TextureFormat.ARGB32, mipChain: true); texture2D2.SetPixels32(texture2D.GetPixels32()); texture2D2.wrapMode = TextureWrapMode.Repeat; texture2D2.Apply(); m_previewMaterial.mainTexture = texture2D2; m_previewMaterial.mainTextureScale = new Vector2(30f, 30f); } } m_previewMaterial.hideFlags = HideFlags.HideInInspector; m_previewMaterial.name = "StamperMaterial"; } m_previewFilter = GetComponent(); if (m_previewFilter == null) { base.gameObject.AddComponent(); m_previewFilter = GetComponent(); m_previewFilter.hideFlags = HideFlags.HideInInspector; } m_previewRenderer = GetComponent(); if (m_previewRenderer == null) { base.gameObject.AddComponent(); m_previewRenderer = GetComponent(); m_previewRenderer.hideFlags = HideFlags.HideInInspector; } m_previewRenderer.sharedMaterial = m_previewMaterial; Vector3 targetSize = new Vector3((float)m_scanWidth * m_scanResolution, (float)m_scanHeight * m_scanResolution, (float)m_scanDepth * m_scanResolution); m_previewFilter.mesh = GaiaUtils.CreateMesh(m_stampHM.Heights(), targetSize); } private bool LoadImageMask() { m_imageMaskHM = null; if (m_areaMaskMode == GaiaConstants.ImageFitnessFilterMode.None) { return false; } if (m_areaMaskMode == GaiaConstants.ImageFitnessFilterMode.ImageRedChannel || m_areaMaskMode == GaiaConstants.ImageFitnessFilterMode.ImageGreenChannel || m_areaMaskMode == GaiaConstants.ImageFitnessFilterMode.ImageBlueChannel || m_areaMaskMode == GaiaConstants.ImageFitnessFilterMode.ImageAlphaChannel || m_areaMaskMode == GaiaConstants.ImageFitnessFilterMode.ImageGreyScale) { if (m_imageMask == null) { Debug.LogError("You requested an image mask but did not supply one. Please select mask texture."); return false; } GaiaUtils.MakeTextureReadable(m_imageMask); GaiaUtils.MakeTextureUncompressed(m_imageMask); m_imageMaskHM = new HeightMap(m_imageMask.width, m_imageMask.height); for (int i = 0; i < m_imageMaskHM.Width(); i++) { for (int j = 0; j < m_imageMaskHM.Depth(); j++) { switch (m_areaMaskMode) { case GaiaConstants.ImageFitnessFilterMode.ImageGreyScale: m_imageMaskHM[i, j] = m_imageMask.GetPixel(i, j).grayscale; break; case GaiaConstants.ImageFitnessFilterMode.ImageRedChannel: m_imageMaskHM[i, j] = m_imageMask.GetPixel(i, j).r; break; case GaiaConstants.ImageFitnessFilterMode.ImageGreenChannel: m_imageMaskHM[i, j] = m_imageMask.GetPixel(i, j).g; break; case GaiaConstants.ImageFitnessFilterMode.ImageBlueChannel: m_imageMaskHM[i, j] = m_imageMask.GetPixel(i, j).b; break; case GaiaConstants.ImageFitnessFilterMode.ImageAlphaChannel: m_imageMaskHM[i, j] = m_imageMask.GetPixel(i, j).a; break; } } } } else if (m_areaMaskMode == GaiaConstants.ImageFitnessFilterMode.PerlinNoise || m_areaMaskMode == GaiaConstants.ImageFitnessFilterMode.RidgedNoise || m_areaMaskMode == GaiaConstants.ImageFitnessFilterMode.BillowNoise) { int num = 2048; int num2 = 2048; Terrain terrain = TerrainHelper.GetTerrain(base.transform.position); if (terrain == null) { terrain = Terrain.activeTerrain; } if (terrain != null) { num = terrain.terrainData.heightmapResolution; num2 = terrain.terrainData.heightmapResolution; } m_imageMaskHM = new HeightMap(num, num2); FractalGenerator fractalGenerator = new FractalGenerator(); fractalGenerator.Seed = m_noiseMaskSeed; fractalGenerator.Octaves = m_noiseMaskOctaves; fractalGenerator.Persistence = m_noiseMaskPersistence; fractalGenerator.Frequency = m_noiseMaskFrequency; fractalGenerator.Lacunarity = m_noiseMaskLacunarity; if (m_areaMaskMode == GaiaConstants.ImageFitnessFilterMode.PerlinNoise) { fractalGenerator.FractalType = FractalGenerator.Fractals.Perlin; } else if (m_areaMaskMode == GaiaConstants.ImageFitnessFilterMode.RidgedNoise) { fractalGenerator.FractalType = FractalGenerator.Fractals.RidgeMulti; } else if (m_areaMaskMode == GaiaConstants.ImageFitnessFilterMode.BillowNoise) { fractalGenerator.FractalType = FractalGenerator.Fractals.Billow; } float num3 = 1f / m_noiseZoom; for (int k = 0; k < num; k++) { for (int l = 0; l < num2; l++) { m_imageMaskHM[k, l] = fractalGenerator.GetValue((float)k * num3, (float)l * num3); } } } else { Terrain terrain2 = TerrainHelper.GetTerrain(base.transform.position); if (terrain2 == null) { terrain2 = Terrain.activeTerrain; } if (terrain2 == null) { Debug.LogError("You requested an terrain texture mask but there is no terrain."); return false; } GaiaSplatPrototype[] gaiaSplatPrototypes = GaiaSplatPrototype.GetGaiaSplatPrototypes(terrain2); switch (m_areaMaskMode) { case GaiaConstants.ImageFitnessFilterMode.TerrainTexture0: if (gaiaSplatPrototypes.Length < 1) { Debug.LogError("You requested an terrain texture mask 0 but there is no active texture in slot 0."); return false; } m_imageMaskHM = new HeightMap(terrain2.terrainData.GetAlphamaps(0, 0, terrain2.terrainData.alphamapWidth, terrain2.terrainData.alphamapHeight), 0); break; case GaiaConstants.ImageFitnessFilterMode.TerrainTexture1: if (gaiaSplatPrototypes.Length < 2) { Debug.LogError("You requested an terrain texture mask 1 but there is no active texture in slot 1."); return false; } m_imageMaskHM = new HeightMap(terrain2.terrainData.GetAlphamaps(0, 0, terrain2.terrainData.alphamapWidth, terrain2.terrainData.alphamapHeight), 1); break; case GaiaConstants.ImageFitnessFilterMode.TerrainTexture2: if (gaiaSplatPrototypes.Length < 3) { Debug.LogError("You requested an terrain texture mask 2 but there is no active texture in slot 2."); return false; } m_imageMaskHM = new HeightMap(terrain2.terrainData.GetAlphamaps(0, 0, terrain2.terrainData.alphamapWidth, terrain2.terrainData.alphamapHeight), 2); break; case GaiaConstants.ImageFitnessFilterMode.TerrainTexture3: if (gaiaSplatPrototypes.Length < 4) { Debug.LogError("You requested an terrain texture mask 3 but there is no active texture in slot 3."); return false; } m_imageMaskHM = new HeightMap(terrain2.terrainData.GetAlphamaps(0, 0, terrain2.terrainData.alphamapWidth, terrain2.terrainData.alphamapHeight), 3); break; case GaiaConstants.ImageFitnessFilterMode.TerrainTexture4: if (gaiaSplatPrototypes.Length < 5) { Debug.LogError("You requested an terrain texture mask 4 but there is no active texture in slot 4."); return false; } m_imageMaskHM = new HeightMap(terrain2.terrainData.GetAlphamaps(0, 0, terrain2.terrainData.alphamapWidth, terrain2.terrainData.alphamapHeight), 4); break; case GaiaConstants.ImageFitnessFilterMode.TerrainTexture5: if (gaiaSplatPrototypes.Length < 6) { Debug.LogError("You requested an terrain texture mask 5 but there is no active texture in slot 5."); return false; } m_imageMaskHM = new HeightMap(terrain2.terrainData.GetAlphamaps(0, 0, terrain2.terrainData.alphamapWidth, terrain2.terrainData.alphamapHeight), 5); break; case GaiaConstants.ImageFitnessFilterMode.TerrainTexture6: if (gaiaSplatPrototypes.Length < 7) { Debug.LogError("You requested an terrain texture mask 6 but there is no active texture in slot 6."); return false; } m_imageMaskHM = new HeightMap(terrain2.terrainData.GetAlphamaps(0, 0, terrain2.terrainData.alphamapWidth, terrain2.terrainData.alphamapHeight), 6); break; case GaiaConstants.ImageFitnessFilterMode.TerrainTexture7: if (gaiaSplatPrototypes.Length < 8) { Debug.LogError("You requested an terrain texture mask 7 but there is no active texture in slot 7."); return false; } m_imageMaskHM = new HeightMap(terrain2.terrainData.GetAlphamaps(0, 0, terrain2.terrainData.alphamapWidth, terrain2.terrainData.alphamapHeight), 7); break; } m_imageMaskHM.Flip(); } if (m_imageMaskSmoothIterations > 0) { m_imageMaskHM.Smooth(m_imageMaskSmoothIterations); } if (m_imageMaskFlip) { m_imageMaskHM.Flip(); } if (m_imageMaskNormalise) { m_imageMaskHM.Normalise(); } if (m_imageMaskInvert) { m_imageMaskHM.Invert(); } return true; } private float CalculateHeight(float terrainHeight, float smHeightRaw, float smHeightAdj, float stencilHeightNU, float strength) { float num = 0f; if (!m_drawStampBase && smHeightRaw < m_baseLevel) { return terrainHeight; } switch (m_stampOperation) { case GaiaConstants.FeatureOperation.RaiseHeight: if (smHeightAdj > terrainHeight) { num = (smHeightAdj - terrainHeight) * strength; terrainHeight += num; } break; case GaiaConstants.FeatureOperation.BlendHeight: num = (m_blendStrength * smHeightAdj + (1f - m_blendStrength) * terrainHeight - terrainHeight) * strength; terrainHeight += num; break; case GaiaConstants.FeatureOperation.DifferenceHeight: num = (Mathf.Abs(smHeightAdj - terrainHeight) - terrainHeight) * strength; terrainHeight += num; break; case GaiaConstants.FeatureOperation.StencilHeight: num = (terrainHeight + smHeightAdj * stencilHeightNU - terrainHeight) * strength; terrainHeight += num; break; case GaiaConstants.FeatureOperation.LowerHeight: if (smHeightAdj < terrainHeight) { num = (terrainHeight - smHeightAdj) * strength; terrainHeight -= num; } break; } return terrainHeight; } private Vector3 RotatePointAroundPivot(Vector3 point, Vector3 pivot, Vector3 angle) { Vector3 vector = point - pivot; vector = Quaternion.Euler(angle) * vector; point = vector + pivot; return point; } } }