Files
2026-03-04 10:03:45 +08:00

1058 lines
31 KiB
C#

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<MeshFilter>();
if (m_previewFilter == null)
{
base.gameObject.AddComponent<MeshFilter>();
m_previewFilter = GetComponent<MeshFilter>();
m_previewFilter.hideFlags = HideFlags.HideInInspector;
}
m_previewRenderer = GetComponent<MeshRenderer>();
if (m_previewRenderer == null)
{
base.gameObject.AddComponent<MeshRenderer>();
m_previewRenderer = GetComponent<MeshRenderer>();
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;
}
}
}