// 27 Slicer
// Copyright 2021 Deftly Games
// https://slicer.deftly.games/
using Slicer.Core;
using System;
using UnityEngine;
namespace Slicer
{
///
/// MeshDetails is used to keep track of information about a single Mesh that is being sliced.
///
[Serializable]
public class MeshDetails : Details
{
///
/// The MeshFilter on the GameObject being tracked by this details object.
///
public MeshFilter MeshFilter;
///
/// The Original Mesh on the GameObject being tracked by this details object.
///
///
/// This is the original mesh that is used as the basis for slicing when is called.
///
public Mesh OriginalSharedMesh;
///
/// The Modified Mesh on the GameObject being tracked by this details object.
///
///
/// This is the mesh that is sliced when is called.
///
public Mesh SlicedMesh;
///
/// The MeshRenderer on the GameObject being tracked by this details object.
///
public MeshRenderer MeshRenderer;
///
/// The Bounds of the mesh before it is sliced, in local space of the parent SlicerComponent.
///
public Bounds? OriginalBounds;
///
/// The hash of the Verts after slicing.
///
///
/// This is set to the value of when Vert Slicing is being skipped.
///
[SerializeField]
public Hash128 SlicedVertHash;
///
/// The hash of the UVs after slicing.
///
///
/// This is set to the value of when UV Slicing is being skipped.
///
[SerializeField]
public Hash128 SlicedUvHash;
///
public override void Destroy()
{
DestroySlicedMesh();
}
///
/// Destroys the Sliced Mesh
///
public void DestroySlicedMesh()
{
if (SlicedMesh == null)
{
return;
}
SlicerController.SafeDestroy(SlicedMesh);
}
///
public override void DisableSlicing()
{
if (MeshFilter != null && MeshFilter.sharedMesh == SlicedMesh)
{
MeshFilter.sharedMesh = OriginalSharedMesh;
}
}
///
public override void EnableSlicing()
{
if (MeshFilter != null && SlicedMesh != null)
{
MeshFilter.sharedMesh = SlicedMesh;
}
}
///
public override void FinalizeSlicing()
{
EnableSlicing();
if (Application.isPlaying && SlicerConfiguration.UseFinalizedSlicedMeshComponent)
{
var finalizedSlicedMesh = MeshFilter.gameObject.AddComponent();
finalizedSlicedMesh.SlicedMesh = SlicedMesh;
}
if (SlicerConfiguration.OptimizeFinalizedSlicedMesh)
{
SlicedMesh.Optimize();
// upload the mesh if it has been optimized
SlicedMesh.UploadMeshData(SlicerConfiguration.SetFinalizedSlicedMeshToBeNoLongerReadable);
}
else if (SlicerConfiguration.SetFinalizedSlicedMeshToBeNoLongerReadable)
{
// If we are not optimizing the mesh, only upload if the user has enabled the setting to set meshes to be no longer readable
SlicedMesh.UploadMeshData(true);
}
}
///
/// Resets the mesh hashes
///
public void ResetHashes()
{
SlicedVertHash = HashUtility.CalculateHash(Time.frameCount * 3);
SlicedUvHash = HashUtility.CalculateHash(Time.frameCount * 5);
}
///
public override Hash128 CalculateHash()
{
var hash = base.CalculateHash();
if (OriginalSharedMesh != null)
{
var tempHash = HashUtility.CalculateHash(OriginalSharedMesh);
HashUtility.AppendHash(tempHash, ref hash);
}
if (SlicedMesh != null)
{
var tempHash = HashUtility.CalculateHash(SlicedMesh);
HashUtility.AppendHash(tempHash, ref hash);
}
if (MeshFilter != null)
{
if (MeshFilter.sharedMesh != null)
{
var tempHash = HashUtility.CalculateHash(MeshFilter.sharedMesh);
HashUtility.AppendHash(tempHash, ref hash);
}
}
if (MeshRenderer != null)
{
var tempHash = HashUtility.CalculateHash(MeshRenderer.enabled, 5);
HashUtility.AppendHash(tempHash, ref hash);
foreach (var material in MeshRenderer.sharedMaterials)
{
if (material != null)
{
var matHash = HashUtility.CalculateHash(material);
HashUtility.AppendHash(matHash, ref hash);
var mainTexture = material.mainTexture;
if (mainTexture != null)
{
var mainTextureHash = HashUtility.CalculateHash(mainTexture);
var wrapModeUHash = HashUtility.CalculateHash(mainTexture.wrapModeU);
var wrapModeVHash = HashUtility.CalculateHash(mainTexture.wrapModeV);
HashUtility.AppendHash(mainTextureHash, wrapModeUHash, wrapModeVHash, ref hash);
}
}
}
}
return hash;
}
}
}