Finished the code for radial distribution
This commit is contained in:
@@ -12,14 +12,62 @@ namespace Misaki.ArtTool
|
||||
var zIndex = remain / size.x;
|
||||
var xIndex = remain % size.x;
|
||||
|
||||
localPosition = new float3(xIndex, yIndex, zIndex);
|
||||
localPosition = new float3((int)xIndex, (int)yIndex, (int)zIndex);
|
||||
localPosition -= (size - 1) * 0.5f;
|
||||
return localPosition;
|
||||
}
|
||||
|
||||
internal static bool GetMeshVertexPosition(int index, ref MeshData meshData, out float3 position)
|
||||
internal static float4x4 GetRadialMatrix(int index, RadialDistributionSetting setting)
|
||||
{
|
||||
position = float3.zero;
|
||||
var staringAngle = math.radians(setting.angleMinMax.x);
|
||||
var totalAngle = math.TAU / (360.0f / setting.angleMinMax.y) - staringAngle;
|
||||
var angleStep = totalAngle / setting.count;
|
||||
|
||||
var angle = index * angleStep + staringAngle;
|
||||
var x = math.cos(-angle) * setting.radius;
|
||||
var y = math.sin(-angle) * setting.radius;
|
||||
|
||||
var position = float3.zero;
|
||||
switch (setting.plane)
|
||||
{
|
||||
case PlaneDirection.XY:
|
||||
position = new float3(x, y, 0);
|
||||
break;
|
||||
case PlaneDirection.ZY:
|
||||
position = new float3(0, x, y);
|
||||
break;
|
||||
case PlaneDirection.XZ:
|
||||
position = new float3(x, 0, y);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
var rotation = quaternion.identity;
|
||||
if (setting.align)
|
||||
{
|
||||
switch (setting.plane)
|
||||
{
|
||||
case PlaneDirection.XY:
|
||||
rotation = quaternion.EulerXYZ(0.0f, 0.0f, angle);
|
||||
break;
|
||||
case PlaneDirection.ZY:
|
||||
rotation = quaternion.EulerXYZ(angle, 0.0f, 0.0f);
|
||||
break;
|
||||
case PlaneDirection.XZ:
|
||||
rotation = quaternion.EulerXYZ(0.0f, angle, 0.0f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return float4x4.TRS(position, rotation, new float3(1.0f));
|
||||
}
|
||||
|
||||
internal static bool TryGetMeshVertexMatrix(int index, bool alignNormal, ref MeshData meshData, out float4x4 outMatrix)
|
||||
{
|
||||
outMatrix = float4x4.identity;
|
||||
|
||||
if (!meshData.vertices.IsCreated || meshData.vertices.Length <= index)
|
||||
{
|
||||
@@ -27,22 +75,32 @@ namespace Misaki.ArtTool
|
||||
}
|
||||
|
||||
var meshScale = meshData.worldMatrix.GetScale();
|
||||
var meshPosition = meshData.worldMatrix.c3.xyz;
|
||||
var meshPosition = meshData.worldMatrix.GetPosition();
|
||||
|
||||
if (index >= meshData.vertices.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
position = meshData.vertices[index] * meshScale + meshPosition;
|
||||
var position = meshData.vertices[index] * meshScale + meshPosition;
|
||||
|
||||
var rotation = quaternion.identity;
|
||||
if (alignNormal)
|
||||
{
|
||||
var upDirection = meshData.normals[index];
|
||||
var forwardDirection = math.normalize(math.cross(upDirection, new float3(-1.0f, 0.0f, 0.0f)));
|
||||
|
||||
rotation = quaternion.LookRotation(forwardDirection, upDirection);
|
||||
}
|
||||
|
||||
outMatrix = float4x4.TRS(position, rotation, new float3(1.0f));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool GetMeshEdgePosition(int index, ref MeshData meshData, out float3 position, out float3 forwardDirection, out float3 upDirection)
|
||||
internal static bool TryGetMeshEdgeMatrix(int index, bool alignNormal, ref MeshData meshData, out float4x4 outMatrix)
|
||||
{
|
||||
position = float3.zero;
|
||||
forwardDirection = new float3(0.0f, 0.0f, 1.0f);
|
||||
upDirection = new float3(0.0f, 1.0f, 0.0f);
|
||||
outMatrix = float4x4.identity;
|
||||
|
||||
if (!meshData.edges.IsCreated || index >= meshData.edges.Length)
|
||||
{
|
||||
@@ -55,38 +113,38 @@ namespace Misaki.ArtTool
|
||||
return false;
|
||||
}
|
||||
|
||||
var a = meshData.vertices[edge.x];
|
||||
var b = meshData.vertices[edge.y];
|
||||
|
||||
var position = (a + b) / 2.0f;
|
||||
var forwardDirection = math.normalize(a - b);
|
||||
|
||||
var meshScale = meshData.worldMatrix.GetScale();
|
||||
var meshPosition = meshData.worldMatrix.c3.xyz;
|
||||
var meshPosition = meshData.worldMatrix.GetPosition();
|
||||
position = position * meshScale + meshPosition;
|
||||
|
||||
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))
|
||||
var rotation = quaternion.identity;
|
||||
if (alignNormal)
|
||||
{
|
||||
upDirection = math.normalize(math.cross(interpNormal, new float3(0.0f, 0.0f, 1.0f)));
|
||||
var upDirection = math.normalize(meshData.normals[edge.x] + meshData.normals[edge.y]);
|
||||
rotation = quaternion.LookRotation(forwardDirection, upDirection);
|
||||
}
|
||||
|
||||
outMatrix = float4x4.TRS(position, rotation, new float3(1.0f));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool GetMeshPolygonPosition(int index, ref MeshData meshData, out float3 position)
|
||||
//TODO : interpolate normal based on distance
|
||||
internal static bool TryGetMeshPolygonMatrix(int index, bool alignNormal, ref MeshData meshData, out float4x4 outMatrix)
|
||||
{
|
||||
position = float3.zero;
|
||||
outMatrix = float4x4.identity;
|
||||
|
||||
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)
|
||||
@@ -94,15 +152,110 @@ namespace Misaki.ArtTool
|
||||
return false;
|
||||
}
|
||||
|
||||
var pointIndexA = meshData.triangles[triangleIndex];
|
||||
var pointIndexB = meshData.triangles[triangleIndex + 1];
|
||||
var pointIndexC = meshData.triangles[triangleIndex + 2];
|
||||
var vertexIndexA = meshData.triangles[triangleIndex];
|
||||
var vertexIndexB = meshData.triangles[triangleIndex + 1];
|
||||
var vertexIndexC = 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;
|
||||
var a = meshData.vertices[vertexIndexA];
|
||||
var b = meshData.vertices[vertexIndexB];
|
||||
var c = meshData.vertices[vertexIndexC];
|
||||
|
||||
position = (a + b + c) / 3.0f;
|
||||
var position = (a + b + c) / 3.0f;
|
||||
|
||||
var meshScale = meshData.worldMatrix.GetScale();
|
||||
var meshPosition = meshData.worldMatrix.GetPosition();
|
||||
position = position * meshScale + meshPosition;
|
||||
|
||||
var rotation = quaternion.identity;
|
||||
if (alignNormal)
|
||||
{
|
||||
var upDirection = math.normalize(meshData.normals[vertexIndexA] + meshData.normals[vertexIndexB] + meshData.normals[vertexIndexC]);
|
||||
var forwardDirection = math.normalize(math.cross(upDirection, new float3(-1.0f, 0.0f, 0.0f)));
|
||||
|
||||
rotation = quaternion.LookRotation(forwardDirection, upDirection);
|
||||
}
|
||||
|
||||
outMatrix = float4x4.TRS(position, rotation, new float3(1.0f));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO : interpolate normal based on distance
|
||||
internal static bool TryGetMatrixOnMeshSurface(int index, uint seed, bool alignNormal, ref MeshData meshData, out float4x4 outMatrix)
|
||||
{
|
||||
outMatrix = float4x4.identity;
|
||||
|
||||
if (!meshData.areas.IsCreated || !meshData.vertices.IsCreated || !meshData.triangles.IsCreated)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var random = Random.CreateFromIndex(seed + (uint)index);
|
||||
var randomValue = random.NextFloat(meshData.totalArea);
|
||||
|
||||
var triangleIndex = -1;
|
||||
for (var j = 0; j < meshData.areas.Length; j++)
|
||||
{
|
||||
if (randomValue <= meshData.areas[j])
|
||||
{
|
||||
triangleIndex = j * 3;
|
||||
break;
|
||||
}
|
||||
randomValue -= meshData.areas[j];
|
||||
}
|
||||
|
||||
if (triangleIndex >= meshData.triangles.Length - 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var vertexIndexA = meshData.triangles[triangleIndex];
|
||||
var vertexIndexB = meshData.triangles[triangleIndex + 1];
|
||||
var vertexIndexC = meshData.triangles[triangleIndex + 2];
|
||||
|
||||
var a = meshData.vertices[vertexIndexA];
|
||||
var b = meshData.vertices[vertexIndexB];
|
||||
var c = meshData.vertices[vertexIndexC];
|
||||
|
||||
var r1 = math.sqrt(random.NextFloat());
|
||||
var r2 = random.NextFloat();
|
||||
|
||||
var position = (1 - r1) * a + (r1 * (1 - r2)) * b + (r1 * r2) * c;
|
||||
|
||||
var meshScale = meshData.worldMatrix.GetScale();
|
||||
var meshPosition = meshData.worldMatrix.GetPosition();
|
||||
position = position * meshScale + meshPosition;
|
||||
|
||||
var rotation = quaternion.identity;
|
||||
if (alignNormal)
|
||||
{
|
||||
var upDirection = math.normalize(meshData.normals[vertexIndexA] + meshData.normals[vertexIndexB] + meshData.normals[vertexIndexC]);
|
||||
var forwardDirection = math.normalize(math.cross(upDirection, new float3(-1.0f, 0.0f, 0.0f)));
|
||||
|
||||
rotation = quaternion.LookRotation(forwardDirection, upDirection);
|
||||
}
|
||||
|
||||
outMatrix = float4x4.TRS(position, rotation, new float3(1.0f));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool TryGetPositionInMeshVolume(int index, uint seed, ref MeshData meshData, out float4x4 outMatrix)
|
||||
{
|
||||
var random = Random.CreateFromIndex(seed + (uint)index);
|
||||
var meshScale = meshData.worldMatrix.GetScale();
|
||||
var meshPosition = meshData.worldMatrix.GetPosition();
|
||||
|
||||
var volumePosition = random.NextFloat3(-meshData.bounds.extents * meshScale + meshPosition, meshData.bounds.extents * meshScale + meshPosition);
|
||||
|
||||
var isInsideMesh = IsPointInsideMesh(volumePosition, ref meshData);
|
||||
while (!isInsideMesh)
|
||||
{
|
||||
volumePosition = random.NextFloat3(-meshData.bounds.extents * meshScale + meshPosition, meshData.bounds.extents * meshScale + meshPosition);
|
||||
isInsideMesh = IsPointInsideMesh(volumePosition, ref meshData);
|
||||
}
|
||||
|
||||
outMatrix = float4x4.TRS(volumePosition, quaternion.identity, new float3(1.0f));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user