You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
6.3 KiB
C#
159 lines
6.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
|
|
namespace FluffyGroomingTool {
|
|
[Serializable]
|
|
public class GroomLayer : ICloneable {
|
|
[SerializeField] [Range(0f, 0.5f)] public float distanceBetweenStrands = 0.0007f;
|
|
[SerializeField] [Range(0f, 1f)] public float minHeight;
|
|
[SerializeField] [Range(0f, 4f)] public float maxHeight = 2f;
|
|
[SerializeField] [Range(0f, 1f)] public float minWidth;
|
|
[SerializeField] [Range(0f, 4f)] public float maxWidth = 0.021f;
|
|
[SerializeField] [Range(0, 1f)] public float randomRotation = 1f;
|
|
[SerializeField] public float randomHeight = 1f;
|
|
|
|
[SerializeField, HideInInspector] public ClumpGroomModifier[] clumpModifiers = new ClumpGroomModifier[0];
|
|
[SerializeField, HideInInspector] public StrandGroom[] strandsGroomOneToOne;
|
|
[SerializeField, HideInInspector] public StrandGroom[] permanentlyDeletedGrooms;
|
|
[SerializeField, HideInInspector] public HairStrand[] permanentlyDeletedStrands;
|
|
[SerializeField, HideInInspector] public bool isHidden;
|
|
[SerializeField, HideInInspector] public Texture2D maskTexture;
|
|
public bool isInApplyTextureMode { get; set; }
|
|
public ComputeBuffer strandsGroomBuffer;
|
|
public string id = Guid.NewGuid().ToString();
|
|
|
|
public GroomLayer() {
|
|
if (strandsGroomOneToOne == null) strandsGroomOneToOne = new StrandGroom[0];
|
|
}
|
|
|
|
public object Clone() {
|
|
return new GroomLayer {
|
|
distanceBetweenStrands = distanceBetweenStrands,
|
|
minHeight = minHeight,
|
|
maxHeight = maxHeight,
|
|
minWidth = minWidth,
|
|
maxWidth = maxWidth,
|
|
randomRotation = randomRotation,
|
|
randomHeight = randomHeight,
|
|
clumpModifiers = clumpModifiers.Select(e => (ClumpGroomModifier) e.Clone()).ToArray(),
|
|
strandsGroomOneToOne = strandsGroomOneToOne,
|
|
permanentlyDeletedGrooms = permanentlyDeletedGrooms,
|
|
permanentlyDeletedStrands = permanentlyDeletedStrands,
|
|
isHidden = isHidden,
|
|
maskTexture = maskTexture
|
|
};
|
|
}
|
|
|
|
public void addClumpModifier() {
|
|
var clumpSpacing = 0.05f;
|
|
|
|
if (clumpModifiers.Length > 0) {
|
|
clumpSpacing = clumpModifiers[clumpModifiers.Length - 1].clumpsSpacing / 2f;
|
|
}
|
|
|
|
var list = clumpModifiers.ToList();
|
|
list.Add(new ClumpGroomModifier() {clumpsSpacing = clumpSpacing});
|
|
clumpModifiers = list.ToArray();
|
|
}
|
|
|
|
public void copyValuesFromComputeBufferToNativeObject() {
|
|
foreach (var modifier in clumpModifiers) {
|
|
modifier.copyValuesFromComputeBufferToNativeObject();
|
|
}
|
|
|
|
if (strandsGroomBuffer != null) AsyncGPUReadback.Request(strandsGroomBuffer, OnCompleteReadback);
|
|
}
|
|
|
|
void OnCompleteReadback(AsyncGPUReadbackRequest request) {
|
|
if (request.hasError) {
|
|
Debug.Log("GPU readback error detected for Strands.");
|
|
return;
|
|
}
|
|
|
|
var persistentArray = request.ToPersistentArray<StrandGroomStruct>();
|
|
new Thread(() => {
|
|
strandsGroomOneToOne = persistentArray.Select(StrandGroom.convertFromStruct).ToArray();
|
|
persistentArray.Dispose();
|
|
}).Start();
|
|
}
|
|
|
|
public void removeClumpModifier(int index) {
|
|
clumpModifiers[index].clumpGroomBuffer.Dispose();
|
|
var list = clumpModifiers.ToList();
|
|
list.RemoveAt(index);
|
|
clumpModifiers = list.ToArray();
|
|
}
|
|
|
|
public void recreateGroomBuffer() {
|
|
strandsGroomBuffer?.Dispose();
|
|
strandsGroomBuffer = new ComputeBuffer(strandsGroomOneToOne.Length, StrandGroomStruct.size());
|
|
strandsGroomBuffer.SetData(strandsGroomOneToOne.ToList().Select(StrandGroomStruct.convertToStruct).ToArray());
|
|
}
|
|
|
|
public void disposeBuffers() {
|
|
strandsGroomBuffer?.Dispose();
|
|
strandsGroomBuffer = null;
|
|
foreach (var modifier in clumpModifiers) {
|
|
modifier.clumpGroomBuffer?.Dispose();
|
|
modifier.clumpGroomBuffer = null;
|
|
}
|
|
}
|
|
|
|
public ClumpGroomModifier getModifierById(string modifiersId) {
|
|
return clumpModifiers.FirstOrDefault(modifier => modifiersId.Equals(modifier.id));
|
|
}
|
|
|
|
public void setCardPreset() {
|
|
distanceBetweenStrands = 0.007f;
|
|
maxWidth = 0.19f;
|
|
randomRotation = 0f;
|
|
}
|
|
|
|
public StrandGroom[] getExistingGroomsAndPermanentlyDeleted() {
|
|
var allGrooms = new List<StrandGroom>();
|
|
allGrooms.AddRange(strandsGroomOneToOne);
|
|
if (permanentlyDeletedGrooms != null && permanentlyDeletedGrooms.Length > 0) {
|
|
allGrooms.AddRange(permanentlyDeletedGrooms);
|
|
}
|
|
|
|
return allGrooms.ToArray();
|
|
}
|
|
|
|
public void clearPermanentlyDeletedBackup() {
|
|
permanentlyDeletedGrooms = null;
|
|
permanentlyDeletedStrands = null;
|
|
}
|
|
|
|
public List<StrandGroom> getPermanentlyDeletedGrooms() {
|
|
return permanentlyDeletedGrooms != null ? permanentlyDeletedGrooms.ToList() : new List<StrandGroom>();
|
|
}
|
|
|
|
public List<HairStrand> getPermanentlyDeletedStrands() {
|
|
return permanentlyDeletedStrands != null ? permanentlyDeletedStrands.ToList() : new List<HairStrand>();
|
|
}
|
|
|
|
private float _tempDistanceBetweenStrands = -1;
|
|
|
|
public float TempDistanceBetweenStrands {
|
|
get {
|
|
if (_tempDistanceBetweenStrands == -1f) _tempDistanceBetweenStrands = distanceBetweenStrands;
|
|
return _tempDistanceBetweenStrands;
|
|
}
|
|
set => _tempDistanceBetweenStrands = value;
|
|
}
|
|
|
|
public static readonly float FLOAT_COMPARISON_TOLERANCE = 0.000000001f;
|
|
|
|
public bool isDistanceBetweenStrandsUndoPerformed() {
|
|
return Math.Abs(TempDistanceBetweenStrands - distanceBetweenStrands) > FLOAT_COMPARISON_TOLERANCE;
|
|
}
|
|
|
|
public bool hasClumpLayer() {
|
|
return clumpModifiers.Length > 0;
|
|
}
|
|
}
|
|
} |