|
|
|
|
/******************************************************************************/
|
|
|
|
|
/*
|
|
|
|
|
Project - MudBun
|
|
|
|
|
Publisher - Long Bunny Labs
|
|
|
|
|
http://LongBunnyLabs.com
|
|
|
|
|
Author - Ming-Lun "Allen" Chou
|
|
|
|
|
http://AllenChou.net
|
|
|
|
|
*/
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
namespace MudBun
|
|
|
|
|
{
|
|
|
|
|
public class GizmosUtil
|
|
|
|
|
{
|
|
|
|
|
public static readonly Color OutlineDefault = new Color(1.0f, 1.0f, 1.0f, 0.5f);
|
|
|
|
|
public static readonly Color OutlineSelected = new Color(1.0f, 0.7f, 0.1f, 0.5f);
|
|
|
|
|
public static readonly Color Transparent = new Color(1.0f, 1.0f, 1.0f, 0.0f);
|
|
|
|
|
|
|
|
|
|
public static void DrawLine(Vector3 a, Vector3 b)
|
|
|
|
|
{
|
|
|
|
|
Gizmos.DrawLine(a, b);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void DrawCircle(float radius, Vector3 center, Quaternion rotation)
|
|
|
|
|
{
|
|
|
|
|
int numSegments = 32;
|
|
|
|
|
float t = 0.0f;
|
|
|
|
|
float dt = MathUtil.TwoPi / numSegments;
|
|
|
|
|
Vector3 prev = center + rotation * new Vector3(radius, 0.0f, 0.0f);
|
|
|
|
|
for (int i = 0; i < numSegments; ++i)
|
|
|
|
|
{
|
|
|
|
|
t += dt;
|
|
|
|
|
Vector3 curr = center + rotation * new Vector3(radius * Mathf.Cos(t), 0.0f, radius * Mathf.Sin(t));
|
|
|
|
|
DrawLine(prev, curr);
|
|
|
|
|
prev = curr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void DrawWireBox(Vector3 center, Vector3 size, Quaternion rotation)
|
|
|
|
|
{
|
|
|
|
|
Matrix4x4 prevMatrix = Gizmos.matrix;
|
|
|
|
|
Gizmos.matrix *= Matrix4x4.TRS(center, rotation, size);
|
|
|
|
|
Gizmos.DrawWireCube(Vector3.zero, Vector3.one);
|
|
|
|
|
Gizmos.matrix = prevMatrix;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void DrawInvisibleBox(Vector3 center, Vector3 size, Quaternion rotation)
|
|
|
|
|
{
|
|
|
|
|
Color prevColor = Gizmos.color;
|
|
|
|
|
Gizmos.color = Transparent;
|
|
|
|
|
Matrix4x4 prevMatrix = Gizmos.matrix;
|
|
|
|
|
Gizmos.matrix *= Matrix4x4.TRS(center, rotation, size);
|
|
|
|
|
Gizmos.DrawCube(Vector3.zero, Vector3.one);
|
|
|
|
|
Gizmos.matrix = prevMatrix;
|
|
|
|
|
Gizmos.color = prevColor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void DrawWireSphere(Vector3 center, float radius, Vector3 scale, Quaternion rotation)
|
|
|
|
|
{
|
|
|
|
|
Matrix4x4 prevMatrix = Gizmos.matrix;
|
|
|
|
|
Gizmos.matrix *= Matrix4x4.TRS(center, rotation, scale);
|
|
|
|
|
Gizmos.DrawWireSphere(Vector3.zero, radius);
|
|
|
|
|
Gizmos.matrix = prevMatrix;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void DrawInvisibleSphere(Vector3 center, float radius, Vector3 scale, Quaternion rotation)
|
|
|
|
|
{
|
|
|
|
|
Color prevColor = Gizmos.color;
|
|
|
|
|
Gizmos.color = Transparent;
|
|
|
|
|
Matrix4x4 prevMatrix = Gizmos.matrix;
|
|
|
|
|
Gizmos.matrix *= Matrix4x4.TRS(center, rotation, scale);
|
|
|
|
|
Gizmos.DrawSphere(Vector3.zero, radius);
|
|
|
|
|
Gizmos.matrix = prevMatrix;
|
|
|
|
|
Gizmos.color = prevColor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void DrawWireCylinder(Vector3 center, float radius, float topRadiusOffset, float height, Quaternion rotation)
|
|
|
|
|
{
|
|
|
|
|
float topRadius = Mathf.Max(0.0f, radius + topRadiusOffset);
|
|
|
|
|
Vector3 hh = new Vector3(0.0f, 0.5f * height, 0.0f);
|
|
|
|
|
|
|
|
|
|
Matrix4x4 prevMatrix = Gizmos.matrix;
|
|
|
|
|
Gizmos.matrix *= Matrix4x4.TRS(center, rotation, Vector3.one);
|
|
|
|
|
DrawCircle(radius, -hh, Quaternion.identity);
|
|
|
|
|
DrawCircle(topRadius, hh, Quaternion.identity);
|
|
|
|
|
DrawLine(new Vector3(-radius, 0.0f, 0.0f) - hh, new Vector3(-topRadius, 0.0f, 0.0f) + hh);
|
|
|
|
|
DrawLine(new Vector3(radius, 0.0f, 0.0f) - hh, new Vector3(topRadius, 0.0f, 0.0f) + hh);
|
|
|
|
|
DrawLine(new Vector3(0.0f, 0.0f, -radius) - hh, new Vector3(0.0f, 0.0f, -topRadius) + hh);
|
|
|
|
|
DrawLine(new Vector3(0.0f, 0.0f, radius) - hh, new Vector3(0.0f, 0.0f, topRadius) + hh);
|
|
|
|
|
Gizmos.matrix = prevMatrix;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void DrawInvisibleCylinder(Vector3 center, float radius, float height, Quaternion rotation)
|
|
|
|
|
{
|
|
|
|
|
Color prevColor = Gizmos.color;
|
|
|
|
|
Gizmos.color = Transparent;
|
|
|
|
|
Matrix4x4 prevMatrix = Gizmos.matrix;
|
|
|
|
|
Gizmos.matrix *= Matrix4x4.TRS(center, rotation, new Vector3(radius, height, radius));
|
|
|
|
|
Gizmos.DrawMesh(CylinderMesh);
|
|
|
|
|
Gizmos.matrix = prevMatrix;
|
|
|
|
|
Gizmos.color = prevColor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void DrawWireCone(Vector3 baseCenter, float radius, float height, Quaternion rotation)
|
|
|
|
|
{
|
|
|
|
|
Vector3 h = new Vector3(0.0f, height, 0.0f);
|
|
|
|
|
|
|
|
|
|
Matrix4x4 prevMatrix = Gizmos.matrix;
|
|
|
|
|
Gizmos.matrix *= Matrix4x4.TRS(baseCenter, rotation, Vector3.one);
|
|
|
|
|
DrawCircle(radius, Vector3.zero, Quaternion.identity);
|
|
|
|
|
DrawLine(h, new Vector3(-radius, 0.0f, 0.0f));
|
|
|
|
|
DrawLine(h, new Vector3(radius, 0.0f, 0.0f));
|
|
|
|
|
DrawLine(h, new Vector3(0.0f, 0.0f, -radius));
|
|
|
|
|
DrawLine(h, new Vector3(0.0f, 0.0f, radius));
|
|
|
|
|
Gizmos.matrix = prevMatrix;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void DrawInvisibleCone(Vector3 baseCenter, float radius, float height, Quaternion rotation)
|
|
|
|
|
{
|
|
|
|
|
Color prevColor = Gizmos.color;
|
|
|
|
|
Gizmos.color = Transparent;
|
|
|
|
|
Matrix4x4 prevMatrix = Gizmos.matrix;
|
|
|
|
|
Gizmos.matrix *= Matrix4x4.TRS(baseCenter, rotation, new Vector3(radius, height, radius));
|
|
|
|
|
Gizmos.DrawMesh(ConeMesh);
|
|
|
|
|
Gizmos.matrix = prevMatrix;
|
|
|
|
|
Gizmos.color = prevColor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void DrawWireSolidAngle(Vector3 center, float radius, float angle, Quaternion rotation)
|
|
|
|
|
{
|
|
|
|
|
int numSegments = 32;
|
|
|
|
|
float t = 0.0f;
|
|
|
|
|
float dt = angle / numSegments;
|
|
|
|
|
float s = Mathf.Sin(angle);
|
|
|
|
|
float c = Mathf.Cos(angle);
|
|
|
|
|
Vector3 h = new Vector3(0.0f, radius * c, 0.0f);
|
|
|
|
|
|
|
|
|
|
Matrix4x4 prevMatrix = Gizmos.matrix;
|
|
|
|
|
Gizmos.matrix *= Matrix4x4.TRS(center, rotation, Vector3.one);
|
|
|
|
|
DrawCircle(radius * s, h, Quaternion.identity);
|
|
|
|
|
float prevS = 0.0f;
|
|
|
|
|
float prevC = 1.0f;
|
|
|
|
|
for (int i = 0; i < numSegments; ++i)
|
|
|
|
|
{
|
|
|
|
|
t += dt;
|
|
|
|
|
float currS = Mathf.Sin(t);
|
|
|
|
|
float currC = Mathf.Cos(t);
|
|
|
|
|
DrawLine(new Vector3(-radius * prevS, radius * prevC, 0.0f), new Vector3(-radius * currS, radius * currC, 0.0f));
|
|
|
|
|
DrawLine(new Vector3(radius * prevS, radius * prevC, 0.0f), new Vector3(radius * currS, radius * currC, 0.0f));
|
|
|
|
|
DrawLine(new Vector3(0.0f, radius * prevC, -radius * prevS), new Vector3(0.0f, radius * currC, -radius * currS));
|
|
|
|
|
DrawLine(new Vector3(0.0f, radius * prevC, radius * prevS), new Vector3(0.0f, radius * currC, radius * currS));
|
|
|
|
|
prevS = currS;
|
|
|
|
|
prevC = currC;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
if (angle < MathUtil.Pi - MathUtil.Epsilon)
|
|
|
|
|
{
|
|
|
|
|
DrawLine(Vector3.zero, new Vector3(-radius * prevS, radius * prevC, 0.0f));
|
|
|
|
|
DrawLine(Vector3.zero, new Vector3(radius * prevS, radius * prevC, 0.0f));
|
|
|
|
|
DrawLine(Vector3.zero, new Vector3(0.0f, radius * prevC, -radius * prevS));
|
|
|
|
|
DrawLine(Vector3.zero, new Vector3(0.0f, radius * prevC, radius * prevS));
|
|
|
|
|
}
|
|
|
|
|
if (angle > MathUtil.HalfPi)
|
|
|
|
|
{
|
|
|
|
|
DrawCircle(radius, Vector3.zero, Quaternion.identity);
|
|
|
|
|
}
|
|
|
|
|
Gizmos.matrix = prevMatrix;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void DrawBezierQuad(Vector3 a, Vector3 b, Vector3 controlPoint)
|
|
|
|
|
{
|
|
|
|
|
int numSegments = 32;
|
|
|
|
|
float t = 0;
|
|
|
|
|
float dt = 1.0f / numSegments;
|
|
|
|
|
Vector3 prev = a;
|
|
|
|
|
for (int i = 0; i < numSegments; ++i)
|
|
|
|
|
{
|
|
|
|
|
t += dt;
|
|
|
|
|
Vector3 curr = VectorUtil.BezierQuad(a, b, controlPoint, t);
|
|
|
|
|
DrawLine(prev, curr);
|
|
|
|
|
prev = curr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void DrawWireCatmullRom(Vector3 [] aPoint, float [] aRadius, Vector3 headControlPoint, Vector3 tailControlPoint)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < aPoint.Length; ++i)
|
|
|
|
|
{
|
|
|
|
|
DrawWireSphere(aPoint[i], aRadius[i], Vector3.one, Quaternion.identity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (VectorUtil.IsValid(headControlPoint))
|
|
|
|
|
{
|
|
|
|
|
DrawWireSphere(headControlPoint, aRadius[0], Vector3.one, Quaternion.identity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (VectorUtil.IsValid(tailControlPoint))
|
|
|
|
|
{
|
|
|
|
|
DrawWireSphere(tailControlPoint, aRadius[aPoint.Length - 1], Vector3.one, Quaternion.identity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (aPoint.Length == 1)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
var head = aPoint[0];
|
|
|
|
|
var postHead = aPoint[1];
|
|
|
|
|
Vector3 preHeadPos =
|
|
|
|
|
VectorUtil.IsValid(headControlPoint)
|
|
|
|
|
? headControlPoint
|
|
|
|
|
: 2.0f * head - postHead;
|
|
|
|
|
|
|
|
|
|
var tail = aPoint[aPoint.Length - 1];
|
|
|
|
|
var preTail = aPoint[aPoint.Length - 2];
|
|
|
|
|
Vector3 postTailPos =
|
|
|
|
|
VectorUtil.IsValid(tailControlPoint)
|
|
|
|
|
? tailControlPoint
|
|
|
|
|
: 2.0f * tail - preTail;
|
|
|
|
|
|
|
|
|
|
int numSegments = 16;
|
|
|
|
|
float t = 0.0f;
|
|
|
|
|
float dt = 1.0f / numSegments;
|
|
|
|
|
float prevT = 0.0f;
|
|
|
|
|
for (int i = 0; i < numSegments; ++i)
|
|
|
|
|
{
|
|
|
|
|
t += dt;
|
|
|
|
|
float currT = t;
|
|
|
|
|
DrawLine
|
|
|
|
|
(
|
|
|
|
|
VectorUtil.CatmullRom(preHeadPos, aPoint[0], aPoint[1], aPoint.Length > 2 ? aPoint[2] : postTailPos, prevT),
|
|
|
|
|
VectorUtil.CatmullRom(preHeadPos, aPoint[0], aPoint[1], aPoint.Length > 2 ? aPoint[2] : postTailPos, currT)
|
|
|
|
|
);
|
|
|
|
|
if (aPoint.Length > 2)
|
|
|
|
|
{
|
|
|
|
|
DrawLine
|
|
|
|
|
(
|
|
|
|
|
VectorUtil.CatmullRom(aPoint.Length > 2 ? aPoint[aPoint.Length - 3] : preHeadPos, aPoint[aPoint.Length - 2], aPoint[aPoint.Length - 1], postTailPos, prevT),
|
|
|
|
|
VectorUtil.CatmullRom(aPoint.Length > 2 ? aPoint[aPoint.Length - 3] : preHeadPos, aPoint[aPoint.Length - 2], aPoint[aPoint.Length - 1], postTailPos, currT)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
for (int j = 0; j < aPoint.Length - 3; ++j)
|
|
|
|
|
{
|
|
|
|
|
DrawLine
|
|
|
|
|
(
|
|
|
|
|
VectorUtil.CatmullRom(aPoint[j], aPoint[j + 1], aPoint[j + 2], aPoint[j + 3], prevT),
|
|
|
|
|
VectorUtil.CatmullRom(aPoint[j], aPoint[j + 1], aPoint[j + 2], aPoint[j + 3], currT)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
prevT = currT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void DrawInvisibleCatmullRom(Vector3 [] aPoint, float [] aRadius, Vector3 headControlPoint, Vector3 tailControlPoint)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < aPoint.Length; ++i)
|
|
|
|
|
{
|
|
|
|
|
DrawInvisibleSphere(aPoint[i], aRadius[i], Vector3.one, Quaternion.identity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (aPoint.Length == 1)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
var head = aPoint[0];
|
|
|
|
|
var postHead = aPoint[1];
|
|
|
|
|
Vector3 preHeadPos =
|
|
|
|
|
VectorUtil.IsValid(headControlPoint)
|
|
|
|
|
? headControlPoint
|
|
|
|
|
: 2.0f * head - postHead;
|
|
|
|
|
|
|
|
|
|
var tail = aPoint[aPoint.Length - 1];
|
|
|
|
|
var preTail = aPoint[aPoint.Length - 2];
|
|
|
|
|
Vector3 postTailPos =
|
|
|
|
|
VectorUtil.IsValid(tailControlPoint)
|
|
|
|
|
? tailControlPoint
|
|
|
|
|
: 2.0f * tail - preTail;
|
|
|
|
|
|
|
|
|
|
int numSegments = 4;
|
|
|
|
|
float t = 0.0f;
|
|
|
|
|
float dt = 1.0f / numSegments;
|
|
|
|
|
float prevT = 0.0f;
|
|
|
|
|
for (int i = 0; i < numSegments; ++i)
|
|
|
|
|
{
|
|
|
|
|
t += dt;
|
|
|
|
|
float currT = t;
|
|
|
|
|
DrawInvisibleSphere
|
|
|
|
|
(
|
|
|
|
|
VectorUtil.CatmullRom(preHeadPos, aPoint[0], aPoint[1], aPoint.Length > 2 ? aPoint[2] : postTailPos, prevT),
|
|
|
|
|
Mathf.Lerp(aRadius[0], aRadius[1], prevT),
|
|
|
|
|
Vector3.one,
|
|
|
|
|
Quaternion.identity
|
|
|
|
|
);
|
|
|
|
|
if (aPoint.Length > 2)
|
|
|
|
|
{
|
|
|
|
|
DrawInvisibleSphere
|
|
|
|
|
(
|
|
|
|
|
VectorUtil.CatmullRom(aPoint.Length > 2 ? aPoint[aPoint.Length - 3] : preHeadPos, aPoint[aPoint.Length - 2], aPoint[aPoint.Length - 1], postTailPos, prevT),
|
|
|
|
|
Mathf.Lerp(aRadius[aPoint.Length - 2], aRadius[aPoint.Length - 1], prevT),
|
|
|
|
|
Vector3.one,
|
|
|
|
|
Quaternion.identity
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
prevT = currT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void DrawWireTorus(Vector3 center, float radius, float width, float depth, Quaternion rotation)
|
|
|
|
|
{
|
|
|
|
|
width = Mathf.Abs(width);
|
|
|
|
|
depth = Mathf.Abs(depth);
|
|
|
|
|
|
|
|
|
|
DrawCircle(radius, center + 0.5f * (width - radius) * (rotation * Vector3.right), rotation * Quaternion.Euler(90.0f, 0.0f, 0.0f));
|
|
|
|
|
DrawCircle(radius, center - 0.5f * (width - radius) * (rotation * Vector3.right), rotation * Quaternion.Euler(90.0f, 0.0f, 0.0f));
|
|
|
|
|
DrawCircle(radius, center + 0.5f * (depth - radius) * (rotation * Vector3.forward), rotation * Quaternion.Euler(0.0f, 0.0f, 90.0f));
|
|
|
|
|
DrawCircle(radius, center - 0.5f * (depth - radius) * (rotation * Vector3.forward), rotation * Quaternion.Euler(0.0f, 0.0f, 90.0f));
|
|
|
|
|
|
|
|
|
|
int numSegments = 16;
|
|
|
|
|
float dt = MathUtil.Pi / numSegments;
|
|
|
|
|
float dimDiff = Mathf.Abs(width - depth);
|
|
|
|
|
float r = 0.5f * (Mathf.Min(width, depth) - radius);
|
|
|
|
|
Vector3 axisA =
|
|
|
|
|
width > depth
|
|
|
|
|
? rotation * Vector3.right
|
|
|
|
|
: rotation * Vector3.forward;
|
|
|
|
|
Vector3 axisB =
|
|
|
|
|
width > depth
|
|
|
|
|
? rotation * Vector3.forward
|
|
|
|
|
: rotation * Vector3.right;
|
|
|
|
|
float a = (width > depth ? width : depth) - 2.0f * r - 0.5f * radius;
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
float t = 0.0f;
|
|
|
|
|
Vector3 c = center + 0.5f * a * axisA;
|
|
|
|
|
Vector3 prev = c + r * axisB;
|
|
|
|
|
for (int i = 0; i < numSegments; ++i)
|
|
|
|
|
{
|
|
|
|
|
t += dt;
|
|
|
|
|
Vector3 curr = c + (r * (Mathf.Sin(t) * axisA + Mathf.Cos(t) * axisB));
|
|
|
|
|
DrawLine(prev, curr);
|
|
|
|
|
prev = curr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
float t = Mathf.PI;
|
|
|
|
|
Vector3 c = center - 0.5f * a * axisA;
|
|
|
|
|
Vector3 prev = c - r * axisB;
|
|
|
|
|
for (int i = 0; i < numSegments; ++i)
|
|
|
|
|
{
|
|
|
|
|
t += dt;
|
|
|
|
|
Vector3 curr = c + (r * (Mathf.Sin(t) * axisA + Mathf.Cos(t) * axisB));
|
|
|
|
|
DrawLine(prev, curr);
|
|
|
|
|
prev = curr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DrawLine(center + 0.5f * a * axisA + r * axisB, center - 0.5f * a * axisA + r * axisB);
|
|
|
|
|
DrawLine(center + 0.5f * a * axisA - r * axisB, center - 0.5f * a * axisA - r * axisB);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void DrawInvisibleTorus(Vector3 center, float radius, float width, float depth, Quaternion rotation)
|
|
|
|
|
{
|
|
|
|
|
width = Mathf.Abs(width);
|
|
|
|
|
depth = Mathf.Abs(depth);
|
|
|
|
|
|
|
|
|
|
Color prevColor = Gizmos.color;
|
|
|
|
|
Gizmos.color = Transparent;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
DrawInvisibleSphere(center + 0.5f * (width - radius) * (rotation * Vector3.right), radius, Vector3.one, Quaternion.identity);
|
|
|
|
|
DrawInvisibleSphere(center - 0.5f * (width - radius) * (rotation * Vector3.right), radius, Vector3.one, Quaternion.identity);
|
|
|
|
|
DrawInvisibleSphere(center + 0.5f * (depth - radius) * (rotation * Vector3.forward), radius, Vector3.one, Quaternion.identity);
|
|
|
|
|
DrawInvisibleSphere(center - 0.5f * (depth - radius) * (rotation * Vector3.forward), radius, Vector3.one, Quaternion.identity);
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
int numSegments = 6;
|
|
|
|
|
float dt = MathUtil.Pi / numSegments;
|
|
|
|
|
float dimDiff = Mathf.Abs(width - depth);
|
|
|
|
|
float r = 0.5f * (Mathf.Min(width, depth) - radius);
|
|
|
|
|
Vector3 axisA =
|
|
|
|
|
width > depth
|
|
|
|
|
? rotation * Vector3.right
|
|
|
|
|
: rotation * Vector3.forward;
|
|
|
|
|
Vector3 axisB =
|
|
|
|
|
width > depth
|
|
|
|
|
? rotation * Vector3.forward
|
|
|
|
|
: rotation * Vector3.right;
|
|
|
|
|
float a = (width > depth ? width : depth) - 2.0f * r - 0.5f * radius;
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
float t = 0.0f;
|
|
|
|
|
Vector3 c = center + 0.5f * a * axisA;
|
|
|
|
|
for (int i = 0; i < numSegments; ++i)
|
|
|
|
|
{
|
|
|
|
|
t += dt;
|
|
|
|
|
Vector3 curr = c + (r * (Mathf.Sin(t) * axisA + Mathf.Cos(t) * axisB));
|
|
|
|
|
DrawInvisibleSphere(curr, radius, Vector3.one, Quaternion.identity);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
float t = Mathf.PI;
|
|
|
|
|
Vector3 c = center - 0.5f * a * axisA;
|
|
|
|
|
for (int i = 0; i < numSegments; ++i)
|
|
|
|
|
{
|
|
|
|
|
t += dt;
|
|
|
|
|
Vector3 curr = c + (r * (Mathf.Sin(t) * axisA + Mathf.Cos(t) * axisB));
|
|
|
|
|
DrawInvisibleSphere(curr, radius, Vector3.one, Quaternion.identity);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
numSegments = 4;
|
|
|
|
|
float t = 0.0f;
|
|
|
|
|
dt = 1.0f / numSegments;
|
|
|
|
|
for (int i = 0; i <= numSegments; ++i)
|
|
|
|
|
{
|
|
|
|
|
DrawInvisibleSphere(Vector3.Lerp(center + 0.5f * a * axisA + (r * axisB), center - 0.5f * a * axisA + (r * axisB), t), radius, Vector3.one, Quaternion.identity);
|
|
|
|
|
DrawInvisibleSphere(Vector3.Lerp(center + 0.5f * a * axisA - (r * axisB), center - 0.5f * a * axisA - (r * axisB), t), radius, Vector3.one, Quaternion.identity);
|
|
|
|
|
t += dt;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Gizmos.color = prevColor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Mesh s_cylinderMesh;
|
|
|
|
|
private static Mesh CylinderMesh
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (s_cylinderMesh != null)
|
|
|
|
|
return s_cylinderMesh;
|
|
|
|
|
|
|
|
|
|
int numSegments = 16;
|
|
|
|
|
s_cylinderMesh = new Mesh();
|
|
|
|
|
|
|
|
|
|
Vector3[] aVert = new Vector3[numSegments * 6 + 2];
|
|
|
|
|
Vector3[] aNormal = new Vector3[aVert.Length];
|
|
|
|
|
int[] aIndex = new int[numSegments * 12];
|
|
|
|
|
|
|
|
|
|
Vector3 bottom = new Vector3(0.0f, -0.5f, 0.0f);
|
|
|
|
|
Vector3 top = new Vector3(0.0f, 0.5f, 0.0f);
|
|
|
|
|
|
|
|
|
|
int iBottomCapStart = 0;
|
|
|
|
|
int iTopCapStart = numSegments;
|
|
|
|
|
int iSideStart = numSegments * 2;
|
|
|
|
|
int iBottom = numSegments * 6;
|
|
|
|
|
int iTop = numSegments * 6 + 1;
|
|
|
|
|
|
|
|
|
|
aVert[iBottom] = bottom;
|
|
|
|
|
aVert[iTop] = top;
|
|
|
|
|
|
|
|
|
|
aNormal[iBottom] = new Vector3(0.0f, -1.0f, 0.0f);
|
|
|
|
|
aNormal[iTop] = new Vector3(0.0f, 1.0f, 0.0f);
|
|
|
|
|
|
|
|
|
|
int iIndex = 0;
|
|
|
|
|
float angleIncrement = 2.0f * Mathf.PI / numSegments;
|
|
|
|
|
float angle = 0.0f;
|
|
|
|
|
for (int i = 0; i < numSegments; ++i)
|
|
|
|
|
{
|
|
|
|
|
// caps
|
|
|
|
|
Vector3 offset = Mathf.Cos(angle) * Vector3.right + Mathf.Sin(angle) * Vector3.forward;
|
|
|
|
|
aVert[iBottomCapStart + i] = bottom + offset;
|
|
|
|
|
aVert[iTopCapStart + i] = top + offset;
|
|
|
|
|
|
|
|
|
|
aNormal[iBottomCapStart + i] = new Vector3(0.0f, -1.0f, 0.0f);
|
|
|
|
|
aNormal[iTopCapStart + i] = new Vector3(0.0f, 1.0f, 0.0f);
|
|
|
|
|
|
|
|
|
|
aIndex[iIndex++] = iBottom;
|
|
|
|
|
aIndex[iIndex++] = iBottomCapStart + i;
|
|
|
|
|
aIndex[iIndex++] = iBottomCapStart + ((i + 1) % numSegments);
|
|
|
|
|
|
|
|
|
|
aIndex[iIndex++] = iTop;
|
|
|
|
|
aIndex[iIndex++] = iTopCapStart + ((i + 1) % numSegments);
|
|
|
|
|
aIndex[iIndex++] = iTopCapStart + i;
|
|
|
|
|
|
|
|
|
|
angle += angleIncrement;
|
|
|
|
|
|
|
|
|
|
// sides
|
|
|
|
|
Vector3 offsetNext = Mathf.Cos(angle) * Vector3.right + Mathf.Sin(angle) * Vector3.forward;
|
|
|
|
|
aVert[iSideStart + i * 4] = bottom + offset;
|
|
|
|
|
aVert[iSideStart + i * 4 + 1] = top + offset;
|
|
|
|
|
aVert[iSideStart + i * 4 + 2] = bottom + offsetNext;
|
|
|
|
|
aVert[iSideStart + i * 4 + 3] = top + offsetNext;
|
|
|
|
|
|
|
|
|
|
Vector3 sideNormal = Vector3.Cross(top - bottom, offsetNext - offset).normalized;
|
|
|
|
|
aNormal[iSideStart + i * 4] = sideNormal;
|
|
|
|
|
aNormal[iSideStart + i * 4 + 1] = sideNormal;
|
|
|
|
|
aNormal[iSideStart + i * 4 + 2] = sideNormal;
|
|
|
|
|
aNormal[iSideStart + i * 4 + 3] = sideNormal;
|
|
|
|
|
|
|
|
|
|
aIndex[iIndex++] = iSideStart + i * 4;
|
|
|
|
|
aIndex[iIndex++] = iSideStart + i * 4 + 3;
|
|
|
|
|
aIndex[iIndex++] = iSideStart + i * 4 + 2;
|
|
|
|
|
|
|
|
|
|
aIndex[iIndex++] = iSideStart + i * 4;
|
|
|
|
|
aIndex[iIndex++] = iSideStart + i * 4 + 1;
|
|
|
|
|
aIndex[iIndex++] = iSideStart + i * 4 + 3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s_cylinderMesh.vertices = aVert;
|
|
|
|
|
s_cylinderMesh.normals = aNormal;
|
|
|
|
|
s_cylinderMesh.SetIndices(aIndex, MeshTopology.Triangles, 0);
|
|
|
|
|
|
|
|
|
|
return s_cylinderMesh;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Mesh s_coneMesh;
|
|
|
|
|
private static Mesh ConeMesh
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (s_coneMesh != null)
|
|
|
|
|
return s_coneMesh;
|
|
|
|
|
|
|
|
|
|
int numSegments = 16;
|
|
|
|
|
s_coneMesh = new Mesh();
|
|
|
|
|
|
|
|
|
|
Vector3[] aVert = new Vector3[numSegments * 3 + numSegments];
|
|
|
|
|
Vector3[] aNormal = new Vector3[aVert.Length];
|
|
|
|
|
int[] aIndex = new int[numSegments * 3 + (numSegments - 2) * 3];
|
|
|
|
|
|
|
|
|
|
Vector3 top = new Vector3(0.0f, 1.0f, 0.0f);
|
|
|
|
|
|
|
|
|
|
Vector3[] aBaseVert = new Vector3[numSegments];
|
|
|
|
|
float angleIncrement = 2.0f * Mathf.PI / numSegments;
|
|
|
|
|
float angle = 0.0f;
|
|
|
|
|
for (int i = 0; i < numSegments; ++i)
|
|
|
|
|
{
|
|
|
|
|
aBaseVert[i] = Mathf.Cos(angle) * Vector3.right + Mathf.Sin(angle) * Vector3.forward;
|
|
|
|
|
angle += angleIncrement;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int iVert = 0;
|
|
|
|
|
int iIndex = 0;
|
|
|
|
|
int iNormal = 0;
|
|
|
|
|
for (int i = 0; i < numSegments; ++i)
|
|
|
|
|
{
|
|
|
|
|
int iSideTriStart = iVert;
|
|
|
|
|
|
|
|
|
|
aVert[iVert++] = top;
|
|
|
|
|
aVert[iVert++] = aBaseVert[i];
|
|
|
|
|
aVert[iVert++] = aBaseVert[(i + 1) % numSegments];
|
|
|
|
|
|
|
|
|
|
Vector3 sideTriNormal = Vector3.Cross(aVert[iSideTriStart + 2] - aVert[iSideTriStart], aVert[iSideTriStart + 1] - aVert[iSideTriStart]).normalized;
|
|
|
|
|
aNormal[iNormal++] = sideTriNormal;
|
|
|
|
|
aNormal[iNormal++] = sideTriNormal;
|
|
|
|
|
aNormal[iNormal++] = sideTriNormal;
|
|
|
|
|
|
|
|
|
|
aIndex[iIndex++] = iSideTriStart;
|
|
|
|
|
aIndex[iIndex++] = iSideTriStart + 2;
|
|
|
|
|
aIndex[iIndex++] = iSideTriStart + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int iBaseStart = iVert;
|
|
|
|
|
for (int i = 0; i < numSegments; ++i)
|
|
|
|
|
{
|
|
|
|
|
aVert[iVert++] = aBaseVert[i];
|
|
|
|
|
|
|
|
|
|
aNormal[iNormal++] = new Vector3(0.0f, -1.0f, 0.0f);
|
|
|
|
|
|
|
|
|
|
if (i >= 2)
|
|
|
|
|
{
|
|
|
|
|
aIndex[iIndex++] = iBaseStart;
|
|
|
|
|
aIndex[iIndex++] = iBaseStart + i - 1;
|
|
|
|
|
aIndex[iIndex++] = iBaseStart + i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s_coneMesh.vertices = aVert;
|
|
|
|
|
s_coneMesh.normals = aNormal;
|
|
|
|
|
s_coneMesh.SetIndices(aIndex, MeshTopology.Triangles, 0);
|
|
|
|
|
|
|
|
|
|
return s_coneMesh;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|