Switch points generation from managed thread to unmanaged thread; Change Spline to NativeSpline; Add converter for DistributionMode and update cloner editor ui; Add MeshData type for object distribution calculation; Add ObjectDistributionSetting and ObjectDistributionCalculation(Vertex and Edge Mode);

This commit is contained in:
Misaki
2024-09-17 18:27:35 +09:00
parent 1c39403cbf
commit 0ae44d6139
23 changed files with 559 additions and 148 deletions

View File

@@ -11,7 +11,6 @@ namespace Misaki.ArtTool
public static void Initialize()
{
var boolToDisplayGroup = new ConverterGroup("BoolToDisplayConvertor");
boolToDisplayGroup.AddConverter((ref bool v) => BoolToDisplayConverter.ConvertTo(v));
boolToDisplayGroup.AddConverter((ref StyleEnum<DisplayStyle> v) => BoolToDisplayConverter.ConvertBack(v));
@@ -19,7 +18,6 @@ namespace Misaki.ArtTool
var inverseBoolToDisplayGroup = new ConverterGroup("InverseBoolToDisplayConverter");
inverseBoolToDisplayGroup.AddConverter((ref bool v) => InverseBoolToDisplayConverter.ConvertTo(v));
inverseBoolToDisplayGroup.AddConverter((ref StyleEnum<DisplayStyle> v) => InverseBoolToDisplayConverter.ConvertBack(v));
@@ -27,7 +25,6 @@ namespace Misaki.ArtTool
var float2ToVector2Group = new ConverterGroup("Float2ToVector2Converter");
float2ToVector2Group.AddConverter((ref float2 v) => Float2ToVector2Converter.ConvertTo(v));
float2ToVector2Group.AddConverter((ref Vector2 v) => Float2ToVector2Converter.ConvertBack(v));
@@ -35,11 +32,50 @@ namespace Misaki.ArtTool
var float3ToVector3Group = new ConverterGroup("Float3ToVector3Converter");
float3ToVector3Group.AddConverter((ref float3 v) => Float3ToVector3Converter.ConvertTo(v));
float3ToVector3Group.AddConverter((ref Vector3 v) => Float3ToVector3Converter.ConvertBack(v));
ConverterGroups.RegisterConverterGroup(float3ToVector3Group);
var int2ToVector2IntGroup = new ConverterGroup("int2ToVector2IntConverter");
int2ToVector2IntGroup.AddConverter((ref int2 v) => Int2ToVector2IntConverter.ConvertTo(v));
int2ToVector2IntGroup.AddConverter((ref Vector2Int v) => Int2ToVector2IntConverter.ConvertBack(v));
ConverterGroups.RegisterConverterGroup(int2ToVector2IntGroup);
var int3ToVector3IntGroup = new ConverterGroup("int3ToVector3IntConverter");
int3ToVector3IntGroup.AddConverter((ref int3 v) => Int3ToVector3IntConverter.ConvertTo(v));
int3ToVector3IntGroup.AddConverter((ref Vector3Int v) => Int3ToVector3IntConverter.ConvertBack(v));
ConverterGroups.RegisterConverterGroup(int3ToVector3IntGroup);
// Converter in ui-toolkit does not support converter parameters right now, we have to register all the types one by one
var objectModeToDisplayStyleGroup = new ConverterGroup("ObjectModeToDisplayStyleConverter");
objectModeToDisplayStyleGroup.AddConverter((ref DistributionMode v) => DistributionModeToDisplayStyleConverter.ObjectModeConvertTo(v));
var splineModeToDisplayStyleGroup = new ConverterGroup("SplineModeToDisplayStyleConverter");
splineModeToDisplayStyleGroup.AddConverter((ref DistributionMode v) => DistributionModeToDisplayStyleConverter.SplineModeConvertTo(v));
var linearModeToDisplayStyleGroup = new ConverterGroup("LinearModeToDisplayStyleConverter");
linearModeToDisplayStyleGroup.AddConverter((ref DistributionMode v) => DistributionModeToDisplayStyleConverter.LinearModeConvertTo(v));
var gridModeToDisplayStyleGroup = new ConverterGroup("GridModeToDisplayStyleConverter");
gridModeToDisplayStyleGroup.AddConverter((ref DistributionMode v) => DistributionModeToDisplayStyleConverter.GridModeConvertTo(v));
var radialModeToDisplayStyleGroup = new ConverterGroup("RadialModeToDisplayStyleConverter");
radialModeToDisplayStyleGroup.AddConverter((ref DistributionMode v) => DistributionModeToDisplayStyleConverter.RadialModeConvertTo(v));
var honeycombModeToDisplayStyleGroup = new ConverterGroup("HoneycombModeToDisplayStyleConverter");
honeycombModeToDisplayStyleGroup.AddConverter((ref DistributionMode v) => DistributionModeToDisplayStyleConverter.HoneycombModeConvertTo(v));
ConverterGroups.RegisterConverterGroup(objectModeToDisplayStyleGroup);
ConverterGroups.RegisterConverterGroup(splineModeToDisplayStyleGroup);
ConverterGroups.RegisterConverterGroup(linearModeToDisplayStyleGroup);
ConverterGroups.RegisterConverterGroup(gridModeToDisplayStyleGroup);
ConverterGroups.RegisterConverterGroup(radialModeToDisplayStyleGroup);
ConverterGroups.RegisterConverterGroup(honeycombModeToDisplayStyleGroup);
}
}
}

View File

@@ -1,7 +1,67 @@
using UnityEngine.UIElements;
namespace Misaki.ArtTool
{
public struct DistributionModeToDisplayStyleConverter
{
public static StyleEnum<DisplayStyle> ObjectModeConvertTo(DistributionMode mode)
{
if (mode == DistributionMode.Object)
{
return DisplayStyle.Flex;
}
return DisplayStyle.None;
}
public static StyleEnum<DisplayStyle> SplineModeConvertTo(DistributionMode mode)
{
if (mode == DistributionMode.Spline)
{
return DisplayStyle.Flex;
}
return DisplayStyle.None;
}
public static StyleEnum<DisplayStyle> LinearModeConvertTo(DistributionMode mode)
{
if (mode == DistributionMode.Linear)
{
return DisplayStyle.Flex;
}
return DisplayStyle.None;
}
public static StyleEnum<DisplayStyle> GridModeConvertTo(DistributionMode mode)
{
if (mode == DistributionMode.Grid)
{
return DisplayStyle.Flex;
}
return DisplayStyle.None;
}
public static StyleEnum<DisplayStyle> RadialModeConvertTo(DistributionMode mode)
{
if (mode == DistributionMode.Radial)
{
return DisplayStyle.Flex;
}
return DisplayStyle.None;
}
public static StyleEnum<DisplayStyle> HoneycombModeConvertTo(DistributionMode mode)
{
if (mode == DistributionMode.Honeycomb)
{
return DisplayStyle.Flex;
}
return DisplayStyle.None;
}
}
}

View File

@@ -0,0 +1,31 @@
using Unity.Mathematics;
using UnityEngine;
namespace Misaki.ArtTool
{
public struct Int2ToVector2IntConverter
{
public static Vector2Int ConvertTo(int2 value)
{
return new Vector2Int(value.x, value.y);
}
public static int2 ConvertBack(Vector2Int value)
{
return new int2(value.x, value.y);
}
}
public struct Int3ToVector3IntConverter
{
public static Vector3Int ConvertTo(int3 value)
{
return new Vector3Int(value.x, value.y, value.z);
}
public static int3 ConvertBack(Vector3Int value)
{
return new int3(value.x, value.y, value.z);
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: c271b5a6b3fadff498bc8f938e501eee

View File

@@ -31,7 +31,7 @@ namespace Misaki.ArtTool
rotation = Quaternion.LookRotation(matrix.c2.xyz / scale.z, matrix.c1.xyz / scale.y);
}
internal static void DecomposeMatrixListAsSpan(in IList<Matrix4x4> matrixList, Span<Vector3> positions, Span<Quaternion> rotations, Span<Vector3> scales)
internal static void DecomposeMatrixListAsSpan(in List<Matrix4x4> matrixList, Span<Vector3> positions, Span<Quaternion> rotations, Span<Vector3> scales)
{
if (matrixList.Count != positions.Length || matrixList.Count != rotations.Length || matrixList.Count != scales.Length)
{

View File

@@ -1,55 +0,0 @@
using System;
using System.Runtime.CompilerServices;
using Unity.Mathematics;
using UnityEngine;
namespace Misaki.ArtTool
{
internal static class ShapeHelper
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static float Linear01DistanceToSphereCenter(float3 pointPosition, float3 spherePosition, float3 sphereSize)
{
var x = (pointPosition.x - spherePosition.x) / sphereSize.x;
var y = (pointPosition.y - spherePosition.y) / sphereSize.y;
var z = (pointPosition.z - spherePosition.z) / sphereSize.z;
var normalizedDistance = math.sqrt(x * x + y * y + z * z);
return math.saturate(normalizedDistance);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool IsInsideSphere(float3 pointPosition, float3 spherePosition, float3 sphereSize)
{
sphereSize /= 2.0f;
var x = (pointPosition.x - spherePosition.x) / sphereSize.x;
var y = (pointPosition.y - spherePosition.y) / sphereSize.y;
var z = (pointPosition.z - spherePosition.z) / sphereSize.z;
return (x * x + y * y + z * z) <= 1.0f;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static bool IsInsideCylinder(float3 pointPosition, float3 cylinderPosition, float3 cylinderSize)
{
cylinderSize /= 2.0f;
var dx = (pointPosition.x - cylinderPosition.x) / cylinderSize.x;
var dz = (pointPosition.z - cylinderPosition.z) / cylinderSize.z;
var distanceSquared = dx * dx + dz * dz;
var withinRadius = distanceSquared <= 1.0f;
var withinHeight = pointPosition.y >= (cylinderPosition.y - cylinderSize.y) && pointPosition.y <= (cylinderPosition.y + cylinderSize.y);
return withinRadius && withinHeight;
}
internal static bool IsInsideMesh(float3 pointPosition, float3 meshPosition, Mesh mesh)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,51 @@
using Unity.Mathematics;
namespace Misaki.ArtTool
{
internal static partial class ShapeHelper
{
internal static float3 GetCubePosition(int index, int3 size)
{
float3 localPosition;
var yIndex = index / (size.x * size.z);
var remain = index % (size.x * size.z);
var zIndex = remain / size.x;
var xIndex = remain % size.x;
localPosition = new float3(xIndex, yIndex, zIndex);
localPosition -= (float3)(size - 1) * 0.5f;
return localPosition;
}
internal static bool GetMeshVertexPosition(int index, MeshData meshData, out float3 position)
{
if (!meshData.vertices.IsCreated || meshData.vertices.Length <= index)
{
position = float3.zero;
return false;
}
position = meshData.vertices[index];
return true;
}
internal static bool GetMeshEdgePosition(int index, MeshData meshData, out float3 position)
{
if (!meshData.edges.IsCreated || meshData.edges.Length <= index)
{
position = float3.zero;
return false;
}
var edge = meshData.edges[index];
if (meshData.vertices.Length <= edge.x || meshData.vertices.Length <= edge.y)
{
position = float3.zero;
return false;
}
position = (meshData.vertices[edge.x] + meshData.vertices[edge.y]) / 2.0f;
return true;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 36c7b9b7309ef1c4681c47a09154d5e1

View File

@@ -0,0 +1,82 @@
using Unity.Mathematics;
namespace Misaki.ArtTool
{
internal static partial class ShapeHelper
{
internal static float Linear01DistanceToSphereCenter(float3 pointPosition, float3 spherePosition, float3 sphereSize)
{
var x = (pointPosition.x - spherePosition.x) / sphereSize.x;
var y = (pointPosition.y - spherePosition.y) / sphereSize.y;
var z = (pointPosition.z - spherePosition.z) / sphereSize.z;
var normalizedDistance = math.sqrt(x * x + y * y + z * z);
return math.saturate(normalizedDistance);
}
internal static bool IsPointInsideSphere(float3 pointPosition, float3 spherePosition, float3 sphereSize)
{
sphereSize /= 2.0f;
var x = (pointPosition.x - spherePosition.x) / sphereSize.x;
var y = (pointPosition.y - spherePosition.y) / sphereSize.y;
var z = (pointPosition.z - spherePosition.z) / sphereSize.z;
return (x * x + y * y + z * z) <= 1.0f;
}
internal static bool IsPointInsideCylinder(float3 pointPosition, float3 cylinderPosition, float3 cylinderSize)
{
cylinderSize /= 2.0f;
var dx = (pointPosition.x - cylinderPosition.x) / cylinderSize.x;
var dz = (pointPosition.z - cylinderPosition.z) / cylinderSize.z;
var distanceSquared = dx * dx + dz * dz;
var withinRadius = distanceSquared <= 1.0f;
var withinHeight = pointPosition.y >= (cylinderPosition.y - cylinderSize.y) && pointPosition.y <= (cylinderPosition.y + cylinderSize.y);
return withinRadius && withinHeight;
}
internal static bool IsPointInsideMesh(float3 pointPosition, float3 meshPosition, MeshData meshData)
{
var windingNumber = 0;
for (var i = 0; i < meshData.triangles.Length; i += 3)
{
var v1 = meshData.vertices[meshData.triangles[i]];
var v2 = meshData.vertices[meshData.triangles[i + 1]];
var v3 = meshData.vertices[meshData.triangles[i + 2]];
if (IsPointInsideTriangle(pointPosition, v1, v2, v3))
{
windingNumber++;
}
}
return windingNumber % 2 != 0;
}
private static bool IsPointInsideTriangle(float3 point, float3 a, float3 b, float3 c)
{
var v0 = c - a;
var v1 = b - a;
var v2 = point - a;
var dot00 = math.dot(v0, v0);
var dot01 = math.dot(v0, v1);
var dot02 = math.dot(v0, v2);
var dot11 = math.dot(v1, v1);
var dot12 = math.dot(v1, v2);
var invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
var u = (dot11 * dot02 - dot01 * dot12) * invDenom;
var v = (dot00 * dot12 - dot01 * dot02) * invDenom;
return (u >= 0) && (v >= 0) && (u + v < 1.0f);
}
}
}