Skip to content

Commit

Permalink
merge: issues #1 has been fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
Morsiusiurandum authored Jul 15, 2023
2 parents 2553f48 + a10f36f commit fe2441b
Show file tree
Hide file tree
Showing 26 changed files with 1,096 additions and 174 deletions.
648 changes: 648 additions & 0 deletions .editorconfig

Large diffs are not rendered by default.

61 changes: 61 additions & 0 deletions Assets/Editor/PackageVersion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System;
using UnityEditor;
using UnityEditor.PackageManager;
using UnityEditor.PackageManager.Requests;
using UnityEngine;

public static class PackageVersion
{
private static ListRequest _request;
private static int _progressId;

/// <summary>
/// Package check will start on Editor start
/// </summary>
[InitializeOnLoadMethod]
public static void GetPackageList()
{
// List packages installed for the project
_request = Client.List();
_progressId = Progress.Start("Package version check");
//Injection update loop
EditorApplication.update += VersionCheck;
}

/// <summary>
/// Make sure the collection version conforms to the specification
/// </summary>
/// <exception cref="ArgumentOutOfRangeException">Error in Status</exception>
private static void VersionCheck()
{
switch (_request.Status)
{
case StatusCode.Success:
{
Progress.Report(_progressId, 2, 3, "Checking the version");
//version detection operation
foreach (var info in _request.Result)
if (info.name == "com.unity.collections")
Debug.Log(info.version);

Progress.Report(_progressId, 3, 3);
break;
}
case StatusCode.Failure:
{
Debug.LogWarning(_request.Error.message);
break;
}
case StatusCode.InProgress:
{
Progress.Report(_progressId, 1, 3, "Waiting package list");
return;
}
default:
throw new ArgumentOutOfRangeException();
}

Progress.Remove(_progressId);
EditorApplication.update -= VersionCheck;
}
}
3 changes: 3 additions & 0 deletions Assets/Editor/PackageVersion.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Assets/Editor/SmoothNormals.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 60 additions & 0 deletions Assets/Editor/SmoothNormals/BakeNormalJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;

internal struct BakeNormalJob : IJobParallelFor
{
[ReadOnly] private NativeArray<Vector3> _normals;
[ReadOnly] private NativeArray<Vector4> _tangents;
[ReadOnly] private NativeArray<Vector3> _vertex;
[ReadOnly] private NativeParallelMultiHashMap<Vector3, Vector3> _result;
[ReadOnly] private readonly bool _existColors;
private NativeArray<Color> _colors;

public BakeNormalJob(NativeArray<Vector3> vertex, NativeArray<Vector3> normals, NativeArray<Vector4> tangents,
NativeParallelMultiHashMap<Vector3, Vector3> result, bool existColors, NativeArray<Color> colors)
{
_normals = normals;
_tangents = tangents;
_vertex = vertex;
_result = result;
_existColors = existColors;
_colors = colors;
}

void IJobParallelFor.Execute(int index)
{
var smoothedNormals = Vector3.zero;
var vertex = _vertex[index];

foreach (var values in _result.GetValuesForKey(vertex)) smoothedNormals += values;

smoothedNormals = smoothedNormals.normalized;

var biNormal = (Vector3.Cross(_normals[index], _tangents[index]) * _tangents[index].w).normalized;

var tbn = new Matrix4x4(
_tangents[index],
biNormal,
_normals[index],
Vector4.zero);
tbn = tbn.transpose;

//Calculate the normal vector in model space
var bakedNormal = tbn.MultiplyVector(smoothedNormals).normalized;

//Remapping [-1,1] to [0,1]
var color = new Color
{
r = bakedNormal.x * 0.5f + 0.5f,
g = bakedNormal.y * 0.5f + 0.5f,
b = bakedNormal.z * 0.5f + 0.5f,
/*
* Choose a color channel
* b = _existColors ? m_Colors[index].b : 1,
*/
a = _existColors ? _colors[index].a : 1
};
_colors[index] = color;
}
}
3 changes: 3 additions & 0 deletions Assets/Editor/SmoothNormals/BakeNormalJob.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions Assets/Editor/SmoothNormals/CollectNormalJob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;

internal struct CollectNormalJob : IJobParallelFor
{
// Mark read-only to improve performance
[ReadOnly] private NativeArray<Vector3> _normals, _vertex;

private NativeParallelMultiHashMap<Vector3, Vector3>.ParallelWriter _result;

public CollectNormalJob(NativeArray<Vector3> normals, NativeArray<Vector3> vertex,
NativeParallelMultiHashMap<Vector3, Vector3>.ParallelWriter result)
{
_normals = normals;
_vertex = vertex;
_result = result;
}

void IJobParallelFor.Execute(int index)
{
_result.Add(_vertex[index], _normals[index]);
}
}
3 changes: 3 additions & 0 deletions Assets/Editor/SmoothNormals/CollectNormalJob.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,111 +1,16 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using Unity.Collections;
using Unity.Jobs;
using System.IO;

internal struct CollectNormalJob : IJobParallelFor
{
// Mark read-only to improve performance
[ReadOnly] private NativeArray<Vector3> m_Normals, m_Vertex;

private NativeMultiHashMap<Vector3, Vector3>.ParallelWriter m_Result;

public CollectNormalJob(NativeArray<Vector3> normals, NativeArray<Vector3> vertex, NativeMultiHashMap<Vector3, Vector3>.ParallelWriter result)
{
m_Normals = normals;
m_Vertex = vertex;
m_Result = result;
}

void IJobParallelFor.Execute(int index)
{
m_Result.Add(m_Vertex[index], m_Normals[index]);
}
}

internal struct BakeNormalJob : IJobParallelFor
{
[ReadOnly] private NativeArray<Vector3> m_Normals;
[ReadOnly] private NativeArray<Vector4> m_Tangents;
[ReadOnly] private NativeArray<Vector3> m_Vertex;
[ReadOnly] private NativeMultiHashMap<Vector3, Vector3> m_Result;
[ReadOnly] private readonly bool m_ExistColors;
private NativeArray<Color> m_Colors;

public BakeNormalJob(NativeArray<Vector3> vertex, NativeArray<Vector3> normals, NativeArray<Vector4> tangents, NativeMultiHashMap<Vector3, Vector3> result, bool existColors, NativeArray<Color> colors)
{
m_Normals = normals;
m_Tangents = tangents;
m_Vertex = vertex;
m_Result = result;
m_ExistColors = existColors;
m_Colors = colors;
}

void IJobParallelFor.Execute(int index)
{
var smoothedNormals = Vector3.zero;
var vertex = m_Vertex[index];

foreach (var values in m_Result.GetValuesForKey(vertex))
{
smoothedNormals += values;
}

smoothedNormals = smoothedNormals.normalized;

var biNormal = (Vector3.Cross(m_Normals[index], m_Tangents[index]) * m_Tangents[index].w).normalized;

var tbn = new Matrix4x4(
m_Tangents[index],
biNormal,
m_Normals[index],
Vector4.zero);
tbn = tbn.transpose;

//Calculate the normal vector in model space
var bakedNormal = tbn.MultiplyVector(smoothedNormals).normalized;

//Remapping [-1,1] to [0,1]
var color = new Color
{
r = (bakedNormal.x * 0.5f) + 0.5f,
g = (bakedNormal.y * 0.5f) + 0.5f,
b = (bakedNormal.z * 0.5f) + 0.5f,
// b = m_ExistColors ? m_Colors[index].b : 1,
a = m_ExistColors ? m_Colors[index].a : 1
};
m_Colors[index] = color;
}
}
using UnityEditor;
using UnityEngine;

public class OutlineModelImporter : AssetPostprocessor
{
private const string Suffix = "_ol";
private const string Prefix = "smoothed_";

// Called before model import
private void OnPreprocessModel()
{
// Only smoothed_xxx can enter
if (!assetPath.Contains(Prefix)) return;

// Change the import settings
// Use Unity's own algorithm to smooth the model will force the merge of coincident vertices
var model = assetImporter as ModelImporter;
if (model == null) throw new NullReferenceException();

model.importNormals = ModelImporterNormals.Calculate;
model.normalCalculationMode = ModelImporterNormalCalculationMode.AngleWeighted;
model.normalSmoothingAngle = 180.0f;
model.importAnimation = false;
model.materialImportMode = ModelImporterMaterialImportMode.None;
Debug.Log("Temporary file created successfully");
}

// Called after the Game Object is generated
// The modification to the Game Object will affect the generated result but the reference will not be retained
private void OnPostprocessModel(GameObject modelObject)
Expand All @@ -117,22 +22,20 @@ private void OnPostprocessModel(GameObject modelObject)
var model = assetImporter as ModelImporter;
if (model == null) throw new NullReferenceException();

string srcPath = model.assetPath;
string dstPath = Path.GetDirectoryName(srcPath) + "/" + Prefix + Path.GetFileName(srcPath);
var srcPath = model.assetPath;
var dstPath = Path.GetDirectoryName(srcPath) + "/" + Prefix + Path.GetFileName(srcPath);

string copyPath = Application.dataPath + "/" + dstPath[7..];
var copyPath = Application.dataPath + "/" + dstPath[7..];
if (File.Exists(copyPath))
{
//If it exists, smooth its normal
//If the object exists, smooth its normal
var copy = AssetDatabase.LoadAssetAtPath<GameObject>(dstPath);

Dictionary<string, Mesh> originalMesh = GetMesh(modelObject);
Dictionary<string, Mesh> smoothedMesh = GetMesh(copy);
var originalMesh = GetMesh(modelObject);
var smoothedMesh = GetMesh(copy);

foreach (var (name, mesh) in originalMesh)
{
mesh.colors = ComputeSmoothedNormalByJob(smoothedMesh[Prefix + name], mesh);
}

AssetDatabase.DeleteAsset(dstPath);
AssetDatabase.Refresh();
Expand All @@ -147,10 +50,29 @@ private void OnPostprocessModel(GameObject modelObject)
}
}

// Called before model import
private void OnPreprocessModel()
{
// Only smoothed_xxx can enter
if (!assetPath.Contains(Prefix)) return;

// Change the import settings
// Use Unity's own algorithm to smooth the model will force the merge of coincident vertices
var model = assetImporter as ModelImporter;
if (model == null) throw new NullReferenceException();

model.importNormals = ModelImporterNormals.Calculate;
model.normalCalculationMode = ModelImporterNormalCalculationMode.AngleWeighted;
model.normalSmoothingAngle = 180.0f;
model.importAnimation = false;
model.materialImportMode = ModelImporterMaterialImportMode.None;
Debug.Log("Temporary file created successfully");
}

/// <summary>
/// Get all meshes in the model and children,MeshFilter and SkinnedMesh
/// Get all meshes in the model and children,MeshFilter and SkinnedMesh
/// </summary>
/// <param name="go">target model</param>
/// <param name="go">Target model</param>
/// <returns>The meshes dictionary </returns>
private Dictionary<string, Mesh> GetMesh(GameObject go)
{
Expand All @@ -170,35 +92,37 @@ private Color[] ComputeSmoothedNormalByJob(Mesh smoothedMesh, Mesh originalMesh)
var smoothedMeshVertexCount = smoothedMesh.vertexCount;
var originalMeshVertexCount = originalMesh.vertexCount;

// original data
// Original data
var originalNormals = new NativeArray<Vector3>(originalMesh.normals, Allocator.Persistent);
var originalVertices = new NativeArray<Vector3>(originalMesh.vertices, Allocator.Persistent);
var originalTangents = new NativeArray<Vector4>(originalMesh.tangents, Allocator.Persistent);
var originalColors = new NativeArray<Color>(originalMeshVertexCount, Allocator.Persistent);
var existColors = originalMesh.colors.Length == originalMeshVertexCount;
if (existColors) originalColors.CopyFrom(originalMesh.colors);

// smoothed data
// Smoothed data
var smoothedNormals = new NativeArray<Vector3>(smoothedMesh.normals, Allocator.Persistent);
var smoothedVertices = new NativeArray<Vector3>(smoothedMesh.vertices, Allocator.Persistent);
var targetNormals = new NativeArray<Vector3>(smoothedMeshVertexCount, Allocator.Persistent);

//result data
var result = new NativeMultiHashMap<Vector3, Vector3>(originalMeshVertexCount * 3, Allocator.Persistent);
// Result data
var result =
new NativeParallelMultiHashMap<Vector3, Vector3>(originalMeshVertexCount * 3, Allocator.Persistent);
var resultParallel = result.AsParallelWriter();

var collectNormalJob = new CollectNormalJob(smoothedNormals, smoothedVertices, resultParallel);
var normalBakeJob = new BakeNormalJob(originalVertices, originalNormals, originalTangents, result, existColors, originalColors);
var normalBakeJob = new BakeNormalJob(originalVertices, originalNormals, originalTangents, result, existColors,
originalColors);

//Job execution
// Job execution
normalBakeJob.Schedule(originalMeshVertexCount, 100,
collectNormalJob.Schedule(smoothedMeshVertexCount, 100)).Complete();

// Copy result
var resultColors = new Color[originalColors.Length];
originalColors.CopyTo(resultColors);

// release memory
// Release memory
smoothedNormals.Dispose();
smoothedVertices.Dispose();
targetNormals.Dispose();
Expand Down
File renamed without changes.
Loading

0 comments on commit fe2441b

Please sign in to comment.