Added object distributuon calculationg
This commit is contained in:
@@ -9,6 +9,7 @@ using Unity.Mathematics;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Jobs;
|
||||
using UnityEngine.Profiling;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Splines;
|
||||
using Object = UnityEngine.Object;
|
||||
@@ -48,7 +49,7 @@ namespace Misaki.ArtTool
|
||||
|
||||
private bool _isPointsDirty = false;
|
||||
|
||||
private const float GIZMOS_BASE_SIZE = 0.5f;
|
||||
private const float GIZMOS_BASE_SIZE = 0.25f;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
@@ -132,6 +133,8 @@ namespace Misaki.ArtTool
|
||||
|
||||
public void GeneratePoints()
|
||||
{
|
||||
Profiler.BeginSample("GeneratePoints");
|
||||
|
||||
Clear();
|
||||
|
||||
switch (distributionMode)
|
||||
@@ -144,6 +147,7 @@ namespace Misaki.ArtTool
|
||||
}
|
||||
|
||||
objectDistributionSetting.meshData = new(inputMeshFilter, Allocator.TempJob);
|
||||
_pointSize = objectDistributionSetting.DistributionCount;
|
||||
|
||||
break;
|
||||
case DistributionMode.Spline:
|
||||
@@ -176,21 +180,15 @@ namespace Misaki.ArtTool
|
||||
break;
|
||||
}
|
||||
|
||||
// Allocate a empty native spline to avoid job error
|
||||
if (distributionMode != DistributionMode.Spline)
|
||||
{
|
||||
splineDistributionSetting.nativeSpline = new(new List<BezierKnot>(), false, transform.localToWorldMatrix, Allocator.TempJob);
|
||||
}
|
||||
// Allocate a empty native collection to avoid job error
|
||||
EnsureNativeCollectionValid();
|
||||
|
||||
if (_pointSize == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_points == null || _pointSize > _points.Length)
|
||||
{
|
||||
_points = _pointPool.Rent(_pointSize);
|
||||
}
|
||||
_points = _pointPool.Rent(_pointSize);
|
||||
|
||||
foreach (var effectorData in effectors)
|
||||
{
|
||||
@@ -198,38 +196,6 @@ namespace Misaki.ArtTool
|
||||
}
|
||||
|
||||
var worldMatrix = transform.localToWorldMatrix;
|
||||
//Parallel.For(0, _pointSize, i =>
|
||||
////for (var i = 0; i < _pointSize; i++)
|
||||
//{
|
||||
// var pointMatrix = float4x4.identity;
|
||||
// var isValid = true;
|
||||
// switch (distributionMode)
|
||||
// {
|
||||
// case DistributionMode.Object:
|
||||
// break;
|
||||
// case DistributionMode.Spline:
|
||||
// Distribution.SplineDistribution(i, _pointSize, splineDistributionSetting, out pointMatrix, out isValid);
|
||||
// break;
|
||||
// case DistributionMode.Linear:
|
||||
// Distribution.LinearDistribution(i, linearDistributionSetting, out pointMatrix, out isValid);
|
||||
// break;
|
||||
// case DistributionMode.Grid:
|
||||
// Distribution.GridDistribution(i, gridDistributionSetting, out pointMatrix, out isValid);
|
||||
// break;
|
||||
// case DistributionMode.Radial:
|
||||
// break;
|
||||
// case DistributionMode.Honeycomb:
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
|
||||
// pointMatrix = math.mul(worldMatrix, pointMatrix);
|
||||
|
||||
// _points[i].matrix = pointMatrix;
|
||||
// _points[i].isValid = isValid;
|
||||
// //}
|
||||
//});
|
||||
|
||||
// Since NativeSpline is not available in managed thread, we have to use jobs
|
||||
var pointsArray = new NativeArray<PointData>(_points.Length, Allocator.TempJob);
|
||||
@@ -240,6 +206,7 @@ namespace Misaki.ArtTool
|
||||
|
||||
distributionMode = distributionMode,
|
||||
|
||||
objectDistributionSetting = objectDistributionSetting,
|
||||
splineDistributionSetting = splineDistributionSetting,
|
||||
linearDistributionSetting = linearDistributionSetting,
|
||||
gridDistributionSetting = gridDistributionSetting,
|
||||
@@ -259,7 +226,7 @@ namespace Misaki.ArtTool
|
||||
// Switch to managed thread for effectors because of interface
|
||||
Parallel.For(0, _pointSize, i =>
|
||||
{
|
||||
for (var e = 0; e < effectors.Count; e++)
|
||||
for (var e = effectors.Count - 1; e >= 0; e--)
|
||||
{
|
||||
if (!effectors[e].enable)
|
||||
{
|
||||
@@ -281,6 +248,21 @@ namespace Misaki.ArtTool
|
||||
});
|
||||
|
||||
_isPointsDirty = false;
|
||||
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
private void EnsureNativeCollectionValid()
|
||||
{
|
||||
if (distributionMode != DistributionMode.Spline)
|
||||
{
|
||||
splineDistributionSetting.nativeSpline = new(new List<BezierKnot>(), false, transform.localToWorldMatrix, Allocator.TempJob);
|
||||
}
|
||||
|
||||
if (distributionMode != DistributionMode.Object)
|
||||
{
|
||||
objectDistributionSetting.meshData = new MeshData(Allocator.TempJob);
|
||||
}
|
||||
}
|
||||
|
||||
public void InstantiateGameObjectOnPoints()
|
||||
|
||||
@@ -48,8 +48,15 @@ namespace Misaki.ArtTool
|
||||
|
||||
public virtual void Initialize()
|
||||
{
|
||||
for (var i = 0; i < fieldDataList.Count; i++)
|
||||
var fieldCount = fieldDataList.Count;
|
||||
for (var i = fieldCount - 1; i >= 0; i--)
|
||||
{
|
||||
var fieldData = fieldDataList[i];
|
||||
if (fieldData.field == null || !fieldData.enable || fieldData.opacity <= 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
fieldDataList[i].field.Initialize();
|
||||
}
|
||||
|
||||
@@ -62,16 +69,16 @@ namespace Misaki.ArtTool
|
||||
{
|
||||
var weight = 1.0f;
|
||||
var fieldCount = fieldDataList.Count;
|
||||
for (var i = 0; i < fieldCount; i++)
|
||||
for (var i = fieldCount - 1; i >= 0; i--)
|
||||
{
|
||||
var fieldData = fieldDataList[i];
|
||||
if (!fieldData.enable || fieldData.opacity <= 0.0f)
|
||||
if (fieldData.field == null || !fieldData.enable || fieldData.opacity <= 0.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//weight = math.lerp(weight, fieldData.field.Operate(worldPosition), fieldData.opacity);
|
||||
weight = FieldHelper.BlendField(weight, fieldData.field.Operate(worldPosition), fieldData.opacity, fieldData.blending);
|
||||
var bValue = fieldData.field.Operate(worldPosition, weight);
|
||||
weight = FieldHelper.BlendField(weight, bValue, fieldData.opacity, fieldData.blending);
|
||||
}
|
||||
|
||||
weight *= strength;
|
||||
|
||||
@@ -6,29 +6,13 @@ namespace Misaki.ArtTool
|
||||
{
|
||||
public abstract class FieldBase : MonoBehaviour
|
||||
{
|
||||
public RemappingSetting remappingSetting = new();
|
||||
|
||||
public EventHandler propertyChanged;
|
||||
|
||||
public virtual void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
public abstract float Operate(float3 position);
|
||||
|
||||
protected float Remapping(float weight)
|
||||
{
|
||||
if (!remappingSetting.enable)
|
||||
{
|
||||
return weight;
|
||||
}
|
||||
|
||||
weight = math.saturate(weight / (1.0f - remappingSetting.innerOffset));
|
||||
weight = math.lerp(remappingSetting.min, remappingSetting.max, weight);
|
||||
weight = remappingSetting.invert ? 1.0f - weight : weight;
|
||||
weight *= remappingSetting.strength;
|
||||
return weight;
|
||||
}
|
||||
public abstract float Operate(float3 position, float weight);
|
||||
|
||||
private void Update()
|
||||
{
|
||||
|
||||
28
Runtime/Cloner/Contracts/Field/IFieldLayer.cs
Normal file
28
Runtime/Cloner/Contracts/Field/IFieldLayer.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace Misaki.ArtTool
|
||||
{
|
||||
public interface IFieldLayer
|
||||
{
|
||||
public EventHandler PropertyChanged
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public virtual void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual float Operate(float3 position)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
public virtual float Operate(float weight)
|
||||
{
|
||||
return weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Runtime/Cloner/Contracts/Field/IFieldLayer.cs.meta
Normal file
2
Runtime/Cloner/Contracts/Field/IFieldLayer.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1155a51cb3c944442b68146ffde0edc8
|
||||
15
Runtime/Cloner/Contracts/Field/ModifierBase.cs
Normal file
15
Runtime/Cloner/Contracts/Field/ModifierBase.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace Misaki.ArtTool.Packages
|
||||
{
|
||||
public abstract class ModifierBase : IFieldLayer
|
||||
{
|
||||
public EventHandler PropertyChanged
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public abstract float Operate(float weight);
|
||||
}
|
||||
}
|
||||
2
Runtime/Cloner/Contracts/Field/ModifierBase.cs.meta
Normal file
2
Runtime/Cloner/Contracts/Field/ModifierBase.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f0813bb760ec42440a4ebe667f0339cc
|
||||
@@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using Unity.Mathematics;
|
||||
using Unity.Mathematics;
|
||||
using Random = Unity.Mathematics.Random;
|
||||
|
||||
namespace Misaki.ArtTool
|
||||
{
|
||||
@@ -7,7 +7,74 @@ namespace Misaki.ArtTool
|
||||
{
|
||||
public static void ObjectDistribution(int index, ObjectDistributionSetting setting, out float4x4 localMatrix, out bool isValid)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var random = new Random();
|
||||
if (index > uint.MaxValue - setting.seed)
|
||||
{
|
||||
random = Random.CreateFromIndex(setting.seed - (uint)index);
|
||||
}
|
||||
else
|
||||
{
|
||||
random = Random.CreateFromIndex(setting.seed + (uint)index);
|
||||
}
|
||||
|
||||
var position = float3.zero;
|
||||
var forwardDirection = new float3(0.0f, 0.0f, 1.0f);
|
||||
var upDirection = new float3(0.0f, 1.0f, 0.0f);
|
||||
isValid = false;
|
||||
|
||||
switch (setting.mode)
|
||||
{
|
||||
case ObjectDistributionMode.Surface:
|
||||
break;
|
||||
case ObjectDistributionMode.Volume:
|
||||
|
||||
var meshScale = setting.meshData.worldMatrix.GetScale();
|
||||
var meshPosition = setting.meshData.worldMatrix.c3.xyz;
|
||||
|
||||
position = random.NextFloat3(-setting.meshData.bounds.extents * meshScale + meshPosition, setting.meshData.bounds.extents * meshScale + meshPosition);
|
||||
|
||||
var isInsideMesh = ShapeHelper.IsPointInsideMesh(position, ref setting.meshData);
|
||||
while (!isInsideMesh)
|
||||
{
|
||||
position = random.NextFloat3(-setting.meshData.bounds.extents * meshScale + meshPosition, setting.meshData.bounds.extents * meshScale + meshPosition);
|
||||
isInsideMesh = ShapeHelper.IsPointInsideMesh(position, ref setting.meshData);
|
||||
}
|
||||
isValid = true;
|
||||
break;
|
||||
|
||||
case ObjectDistributionMode.Vertex:
|
||||
if (ShapeHelper.GetMeshVertexPosition(index, ref setting.meshData, out var vertexPosition))
|
||||
{
|
||||
position = vertexPosition;
|
||||
isValid = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case ObjectDistributionMode.Edge:
|
||||
if (ShapeHelper.GetMeshEdgePosition(index, ref setting.meshData, out var edgePosition, out var edgeForward, out var edgeUp))
|
||||
{
|
||||
position = edgePosition;
|
||||
forwardDirection = edgeForward;
|
||||
upDirection = edgeUp;
|
||||
isValid = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case ObjectDistributionMode.PolygonCenter:
|
||||
if (ShapeHelper.GetMeshPolygonPosition(index, ref setting.meshData, out var polygonPosition))
|
||||
{
|
||||
position = polygonPosition;
|
||||
isValid = true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
var rotation = quaternion.LookRotationSafe(forwardDirection, upDirection);
|
||||
|
||||
localMatrix = float4x4.TRS(position, rotation, new float3(1.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,8 @@ namespace Misaki.ArtTool
|
||||
[ExecuteInEditMode]
|
||||
public class LinearField : FieldBase
|
||||
{
|
||||
public RemappingSetting remappingSetting = new();
|
||||
|
||||
public float length = 1.0f;
|
||||
|
||||
private float3 fieldForward;
|
||||
@@ -17,13 +19,13 @@ namespace Misaki.ArtTool
|
||||
fieldPosition = transform.position;
|
||||
}
|
||||
|
||||
public override float Operate(float3 position)
|
||||
public override float Operate(float3 position, float weight)
|
||||
{
|
||||
var plane = new Unity.Mathematics.Geometry.Plane(fieldForward, fieldPosition);
|
||||
var distance = plane.SignedDistanceToPoint(position) / length;
|
||||
var weight = math.saturate(distance / 2.0f + 0.5f);
|
||||
|
||||
weight = Remapping(weight);
|
||||
weight = math.saturate(distance / 2.0f + 0.5f);
|
||||
weight = FieldHelper.ApplyRemapping(weight, ref remappingSetting);
|
||||
|
||||
return weight;
|
||||
}
|
||||
|
||||
8
Runtime/Cloner/Fields/ModifierLayer.meta
Normal file
8
Runtime/Cloner/Fields/ModifierLayer.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e7afadfcd369f5a4385b23c090665f74
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
14
Runtime/Cloner/Fields/ModifierLayer/Clamp.cs
Normal file
14
Runtime/Cloner/Fields/ModifierLayer/Clamp.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace Misaki.ArtTool
|
||||
{
|
||||
public class Clamp : FieldBase
|
||||
{
|
||||
public float2 minMax;
|
||||
|
||||
public override float Operate(float3 position, float weight)
|
||||
{
|
||||
return math.clamp(weight, minMax.x, minMax.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Runtime/Cloner/Fields/ModifierLayer/Clamp.cs.meta
Normal file
2
Runtime/Cloner/Fields/ModifierLayer/Clamp.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 315e5886979edba429c781f6a8a0a0cc
|
||||
@@ -5,6 +5,8 @@ namespace Misaki.ArtTool
|
||||
{
|
||||
public class SphereField : FieldBase
|
||||
{
|
||||
public RemappingSetting remappingSetting = new();
|
||||
|
||||
public float radius = 1.0f;
|
||||
|
||||
private float3 fieldPosition;
|
||||
@@ -14,10 +16,10 @@ namespace Misaki.ArtTool
|
||||
fieldPosition = transform.position;
|
||||
}
|
||||
|
||||
public override float Operate(float3 position)
|
||||
public override float Operate(float3 position, float weight)
|
||||
{
|
||||
var weight = ShapeHelper.Linear01DistanceToSphereCenter(position, fieldPosition, radius);
|
||||
weight = Remapping(weight);
|
||||
weight = ShapeHelper.Linear01DistanceToSphereCenter(position, fieldPosition, radius);
|
||||
weight = FieldHelper.ApplyRemapping(weight, ref remappingSetting);
|
||||
|
||||
return weight;
|
||||
}
|
||||
|
||||
@@ -52,5 +52,19 @@ namespace Misaki.ArtTool
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static float ApplyRemapping(float weight, ref RemappingSetting remappingSetting)
|
||||
{
|
||||
if (!remappingSetting.enable)
|
||||
{
|
||||
return weight;
|
||||
}
|
||||
|
||||
weight = math.saturate(weight / (1.0f - remappingSetting.innerOffset));
|
||||
weight = math.lerp(remappingSetting.min, remappingSetting.max, weight);
|
||||
weight = remappingSetting.invert ? 1.0f - weight : weight;
|
||||
weight *= remappingSetting.strength;
|
||||
return weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace Misaki.ArtTool
|
||||
{
|
||||
internal static partial class ShapeHelper
|
||||
{
|
||||
internal static float3 GetCubePosition(int index, int3 size)
|
||||
internal static float3 GetCubePosition(int index, float3 size)
|
||||
{
|
||||
float3 localPosition;
|
||||
var yIndex = index / (size.x * size.z);
|
||||
@@ -13,38 +13,96 @@ namespace Misaki.ArtTool
|
||||
var xIndex = remain % size.x;
|
||||
|
||||
localPosition = new float3(xIndex, yIndex, zIndex);
|
||||
localPosition -= (float3)(size - 1) * 0.5f;
|
||||
localPosition -= (size - 1) * 0.5f;
|
||||
return localPosition;
|
||||
}
|
||||
|
||||
internal static bool GetMeshVertexPosition(int index, MeshData meshData, out float3 position)
|
||||
internal static bool GetMeshVertexPosition(int index, ref MeshData meshData, out float3 position)
|
||||
{
|
||||
position = float3.zero;
|
||||
|
||||
if (!meshData.vertices.IsCreated || meshData.vertices.Length <= index)
|
||||
{
|
||||
position = float3.zero;
|
||||
return false;
|
||||
}
|
||||
|
||||
position = meshData.vertices[index];
|
||||
var meshScale = meshData.worldMatrix.GetScale();
|
||||
var meshPosition = meshData.worldMatrix.c3.xyz;
|
||||
|
||||
if (index >= meshData.vertices.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
position = meshData.vertices[index] * meshScale + meshPosition;
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool GetMeshEdgePosition(int index, MeshData meshData, out float3 position)
|
||||
internal static bool GetMeshEdgePosition(int index, ref MeshData meshData, out float3 position, out float3 forwardDirection, out float3 upDirection)
|
||||
{
|
||||
if (!meshData.edges.IsCreated || meshData.edges.Length <= index)
|
||||
position = float3.zero;
|
||||
forwardDirection = new float3(0.0f, 0.0f, 1.0f);
|
||||
upDirection = new float3(0.0f, 1.0f, 0.0f);
|
||||
|
||||
if (!meshData.edges.IsCreated || index >= meshData.edges.Length)
|
||||
{
|
||||
position = float3.zero;
|
||||
return false;
|
||||
}
|
||||
|
||||
var edge = meshData.edges[index];
|
||||
if (meshData.vertices.Length <= edge.x || meshData.vertices.Length <= edge.y)
|
||||
if (edge.x >= meshData.vertices.Length || edge.y >= meshData.vertices.Length)
|
||||
{
|
||||
position = float3.zero;
|
||||
return false;
|
||||
}
|
||||
|
||||
position = (meshData.vertices[edge.x] + meshData.vertices[edge.y]) / 2.0f;
|
||||
var meshScale = meshData.worldMatrix.GetScale();
|
||||
var meshPosition = meshData.worldMatrix.c3.xyz;
|
||||
|
||||
var a = meshData.vertices[edge.x] * meshScale + meshPosition;
|
||||
var b = meshData.vertices[edge.y] * meshScale + meshPosition;
|
||||
|
||||
position = (a + b) / 2.0f;
|
||||
forwardDirection = a - b;
|
||||
|
||||
var interpNormal = math.normalize(meshData.normals[edge.x] + meshData.normals[edge.y]);
|
||||
upDirection = math.normalize(math.cross(interpNormal, new float3(1.0f, 0.0f, 0.0f)));
|
||||
|
||||
if (math.all(upDirection <= float3.zero))
|
||||
{
|
||||
upDirection = math.normalize(math.cross(interpNormal, new float3(0.0f, 0.0f, 1.0f)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool GetMeshPolygonPosition(int index, ref MeshData meshData, out float3 position)
|
||||
{
|
||||
position = float3.zero;
|
||||
|
||||
if (!meshData.edges.IsCreated || meshData.edges.Length <= index)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var meshScale = meshData.worldMatrix.GetScale();
|
||||
var meshPosition = meshData.worldMatrix.c3.xyz;
|
||||
|
||||
var triangleIndex = index * 3;
|
||||
|
||||
if (triangleIndex >= meshData.triangles.Length - 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var pointIndexA = meshData.triangles[triangleIndex];
|
||||
var pointIndexB = meshData.triangles[triangleIndex + 1];
|
||||
var pointIndexC = meshData.triangles[triangleIndex + 2];
|
||||
|
||||
var a = meshData.vertices[pointIndexA] * meshScale + meshPosition;
|
||||
var b = meshData.vertices[pointIndexB] * meshScale + meshPosition;
|
||||
var c = meshData.vertices[pointIndexC] * meshScale + meshPosition;
|
||||
|
||||
position = (a + b + c) / 3.0f;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,15 +41,17 @@ namespace Misaki.ArtTool
|
||||
return withinRadius && withinHeight;
|
||||
}
|
||||
|
||||
internal static bool IsPointInsideMesh(float3 pointPosition, float3 meshPosition, MeshData meshData)
|
||||
internal static bool IsPointInsideMesh(float3 pointPosition, ref MeshData meshData)
|
||||
{
|
||||
var windingNumber = 0;
|
||||
var meshScale = meshData.worldMatrix.GetScale();
|
||||
var meshPosition = meshData.worldMatrix.c3.xyz;
|
||||
|
||||
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]];
|
||||
var v1 = meshData.vertices[meshData.triangles[i]] * meshScale + meshPosition;
|
||||
var v2 = meshData.vertices[meshData.triangles[i + 1]] * meshScale + meshPosition;
|
||||
var v3 = meshData.vertices[meshData.triangles[i + 2]] * meshScale + meshPosition;
|
||||
|
||||
if (IsPointInsideTriangle(pointPosition, v1, v2, v3))
|
||||
{
|
||||
@@ -57,9 +59,10 @@ namespace Misaki.ArtTool
|
||||
}
|
||||
}
|
||||
|
||||
return windingNumber % 2 != 0;
|
||||
return windingNumber % 2 == 0;
|
||||
}
|
||||
|
||||
//TODO: Fix it
|
||||
private static bool IsPointInsideTriangle(float3 point, float3 a, float3 b, float3 c)
|
||||
{
|
||||
var v0 = c - a;
|
||||
@@ -76,7 +79,7 @@ namespace Misaki.ArtTool
|
||||
var u = (dot11 * dot02 - dot01 * dot12) * invDenom;
|
||||
var v = (dot00 * dot12 - dot01 * dot02) * invDenom;
|
||||
|
||||
return (u >= 0) && (v >= 0) && (u + v < 1.0f);
|
||||
return (u >= 0) && (v >= 0) && (u + v < 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
using Unity.Burst;
|
||||
using Unity.Collections;
|
||||
using Unity.Jobs;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Misaki.ArtTool
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[BurstCompile]
|
||||
public struct PointsGenerationJob : IJobParallelForBatch
|
||||
{
|
||||
public float4x4 worldMatrix;
|
||||
@@ -13,6 +13,7 @@ namespace Misaki.ArtTool
|
||||
|
||||
public DistributionMode distributionMode;
|
||||
|
||||
public ObjectDistributionSetting objectDistributionSetting;
|
||||
public SplineDistributionSetting splineDistributionSetting;
|
||||
public LinearDistributionSetting linearDistributionSetting;
|
||||
public GridDistributionSetting gridDistributionSetting;
|
||||
@@ -29,6 +30,7 @@ namespace Misaki.ArtTool
|
||||
switch (distributionMode)
|
||||
{
|
||||
case DistributionMode.Object:
|
||||
Distribution.ObjectDistribution(i, objectDistributionSetting, out pointMatrix, out isValid);
|
||||
break;
|
||||
case DistributionMode.Spline:
|
||||
Distribution.SplineDistribution(i, pointSize, splineDistributionSetting, out pointMatrix, out isValid);
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using Unity.Burst;
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine.Jobs;
|
||||
|
||||
namespace Misaki.ArtTool
|
||||
{
|
||||
[BurstCompile]
|
||||
public struct TransformAccessJob : IJobParallelForTransform
|
||||
{
|
||||
[ReadOnly]
|
||||
|
||||
@@ -7,8 +7,40 @@ namespace Misaki.ArtTool
|
||||
{
|
||||
public MeshData meshData;
|
||||
public ObjectDistributionMode mode;
|
||||
public int count;
|
||||
public uint count;
|
||||
public uint seed;
|
||||
public bool alignNormal;
|
||||
|
||||
public int DistributionCount
|
||||
{
|
||||
get
|
||||
{
|
||||
var result = 0;
|
||||
switch (mode)
|
||||
{
|
||||
case ObjectDistributionMode.Surface:
|
||||
case ObjectDistributionMode.Volume:
|
||||
result = (int)count;
|
||||
break;
|
||||
|
||||
case ObjectDistributionMode.Vertex:
|
||||
result = meshData.vertexCount;
|
||||
break;
|
||||
|
||||
case ObjectDistributionMode.Edge:
|
||||
result = meshData.edges.Length;
|
||||
break;
|
||||
|
||||
case ObjectDistributionMode.PolygonCenter:
|
||||
result = meshData.triangles.Length / 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,4 +8,4 @@ namespace Misaki.ArtTool
|
||||
public bool enable = true;
|
||||
public EffectorBase effector;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,14 +8,33 @@ namespace Misaki.ArtTool
|
||||
public struct MeshData : IDisposable
|
||||
{
|
||||
public Bounds bounds;
|
||||
|
||||
[ReadOnly]
|
||||
public NativeArray<int> triangles;
|
||||
public NativeArray<float4> tangents;
|
||||
[ReadOnly]
|
||||
public NativeArray<float3> normals;
|
||||
[ReadOnly]
|
||||
public NativeArray<float3> vertices;
|
||||
[ReadOnly]
|
||||
public NativeList<int2> edges;
|
||||
|
||||
public int vertexCount;
|
||||
|
||||
public float4x4 worldMatrix;
|
||||
|
||||
public MeshData(Allocator allocator)
|
||||
{
|
||||
bounds = default;
|
||||
|
||||
triangles = new(0, allocator);
|
||||
normals = new(0, allocator);
|
||||
vertices = new(0, allocator);
|
||||
edges = new(0, allocator);
|
||||
|
||||
vertexCount = 0;
|
||||
worldMatrix = float4x4.identity;
|
||||
}
|
||||
|
||||
public MeshData(MeshFilter meshFilter, Allocator allocator)
|
||||
{
|
||||
var mesh = meshFilter.sharedMesh;
|
||||
@@ -28,10 +47,10 @@ namespace Misaki.ArtTool
|
||||
triangles[i] = mesh.triangles[i];
|
||||
}
|
||||
|
||||
tangents = new(mesh.tangents.Length, allocator);
|
||||
for (var i = 0; i < tangents.Length; i++)
|
||||
normals = new(mesh.tangents.Length, allocator);
|
||||
for (var i = 0; i < normals.Length; i++)
|
||||
{
|
||||
tangents[i] = mesh.tangents[i];
|
||||
normals[i] = mesh.normals[i];
|
||||
}
|
||||
|
||||
vertices = new(mesh.vertices.Length, allocator);
|
||||
@@ -68,7 +87,7 @@ namespace Misaki.ArtTool
|
||||
public void Dispose()
|
||||
{
|
||||
triangles.Dispose();
|
||||
tangents.Dispose();
|
||||
normals.Dispose();
|
||||
vertices.Dispose();
|
||||
edges.Dispose();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user