12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361 |
- using UnityEngine;
- using System.Collections.Generic;
- public class MegaTriangle
- {
- public int t;
- public Vector3 a, b, c;
- public Bounds bounds;
- public MegaTriangle(Vector3 a, Vector3 b, Vector3 c, Vector3 dir, int t)
- {
- this.t = t;
- this.a = a;
- this.b = b;
- this.c = c;
- //Vector3 cross = Vector3.Cross(b - a, c - a);
- Vector3 min = Vector3.Min(Vector3.Min(a, b), c);
- Vector3 max = Vector3.Max(Vector3.Max(a, b), c);
- bounds.SetMinMax(min, max);
- }
- public void Barycentric(Vector3 p, out float u, out float v, out float w)
- {
- Vector3 v0 = b - a, v1 = c - a, v2 = p - a;
- float d00 = Vector3.Dot(v0, v0);
- float d01 = Vector3.Dot(v0, v1);
- float d11 = Vector3.Dot(v1, v1);
- float d20 = Vector3.Dot(v2, v0);
- float d21 = Vector3.Dot(v2, v1);
- float denom = 1f / (d00 * d11 - d01 * d01);
- v = (d11 * d20 - d01 * d21) * denom;
- w = (d00 * d21 - d01 * d20) * denom;
- u = 1.0f - v - w;
- }
- }
- public class MegaVoxel
- {
- public class Voxel_t
- {
- public Vector3 position;
- public List<MegaTriangle> tris;
- public Voxel_t()
- {
- position = Vector3.zero;
- tris = new List<MegaTriangle>();
- }
- }
- public static void GetGridIndex(Vector3 p, out int x, out int y, out int z, float unit)
- {
- x = (int)((p.x - start.x) / unit);
- y = (int)((p.y - start.y) / unit);
- z = (int)((p.z - start.z) / unit);
- }
- public static Voxel_t[,,] volume;
- public static int width;
- public static int height;
- public static int depth;
- static Vector3 start;
- public static void Voxelize(Vector3[] vertices, int[] indices, Bounds bounds, int resolution, out float unit)
- {
- float maxLength = Mathf.Max(bounds.size.x, Mathf.Max(bounds.size.y, bounds.size.z));
- unit = maxLength / resolution;
- float hunit = unit * 0.5f;
- start = bounds.min - new Vector3(hunit, hunit, hunit);
- Vector3 end = bounds.max + new Vector3(hunit, hunit, hunit);
- Vector3 size = end - start;
- width = Mathf.CeilToInt(size.x / unit);
- height = Mathf.CeilToInt(size.y / unit);
- depth = Mathf.CeilToInt(size.z / unit);
- volume = new Voxel_t[width, height, depth];
- Bounds[,,] boxes = new Bounds[width, height, depth];
- Vector3 voxelSize = Vector3.one * unit;
- for (int x = 0; x < width; x++)
- {
- for (int y = 0; y < height; y++)
- {
- for (int z = 0; z < depth; z++)
- {
- Vector3 p = new Vector3(x, y, z) * unit + start;
- Bounds aabb = new Bounds(p, voxelSize);
- boxes[x, y, z] = aabb;
- volume[x, y, z] = new Voxel_t();
- }
- }
- }
- Vector3 direction = Vector3.forward;
- for (int i = 0, n = indices.Length; i < n; i += 3)
- {
- MegaTriangle tri = new MegaTriangle(vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]], direction, i);
- Vector3 min = tri.bounds.min - start;
- Vector3 max = tri.bounds.max - start;
- int iminX = (int)(min.x / unit), iminY = (int)(min.y / unit), iminZ = (int)(min.z / unit);
- int imaxX = (int)(max.x / unit), imaxY = (int)(max.y / unit), imaxZ = (int)(max.z / unit);
- iminX = Mathf.Clamp(iminX, 0, width - 1);
- iminY = Mathf.Clamp(iminY, 0, height - 1);
- iminZ = Mathf.Clamp(iminZ, 0, depth - 1);
- imaxX = Mathf.Clamp(imaxX, 0, width - 1);
- imaxY = Mathf.Clamp(imaxY, 0, height - 1);
- imaxZ = Mathf.Clamp(imaxZ, 0, depth - 1);
- for (int x = iminX; x <= imaxX; x++)
- {
- for (int y = iminY; y <= imaxY; y++)
- {
- for (int z = iminZ; z <= imaxZ; z++)
- {
- if (Intersects(tri, boxes[x, y, z]))
- {
- Voxel_t voxel = volume[x, y, z];
- voxel.position = boxes[x, y, z].center;
- voxel.tris.Add(tri);
- volume[x, y, z] = voxel;
- }
- }
- }
- }
- }
- }
- public static bool Intersects(MegaTriangle tri, Bounds aabb)
- {
- float p0, p1, p2, r;
- Vector3 center = aabb.center, extents = aabb.max - center;
- Vector3 v0 = tri.a - center,
- v1 = tri.b - center,
- v2 = tri.c - center;
- Vector3 f0 = v1 - v0,
- f1 = v2 - v1,
- f2 = v0 - v2;
- Vector3 a00 = new Vector3(0, -f0.z, f0.y),
- a01 = new Vector3(0, -f1.z, f1.y),
- a02 = new Vector3(0, -f2.z, f2.y),
- a10 = new Vector3(f0.z, 0, -f0.x),
- a11 = new Vector3(f1.z, 0, -f1.x),
- a12 = new Vector3(f2.z, 0, -f2.x),
- a20 = new Vector3(-f0.y, f0.x, 0),
- a21 = new Vector3(-f1.y, f1.x, 0),
- a22 = new Vector3(-f2.y, f2.x, 0);
- // Test axis a00
- p0 = Vector3.Dot(v0, a00);
- p1 = Vector3.Dot(v1, a00);
- p2 = Vector3.Dot(v2, a00);
- r = extents.y * Mathf.Abs(f0.z) + extents.z * Mathf.Abs(f0.y);
- if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
- return false;
- // Test axis a01
- p0 = Vector3.Dot(v0, a01);
- p1 = Vector3.Dot(v1, a01);
- p2 = Vector3.Dot(v2, a01);
- r = extents.y * Mathf.Abs(f1.z) + extents.z * Mathf.Abs(f1.y);
- if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
- return false;
- // Test axis a02
- p0 = Vector3.Dot(v0, a02);
- p1 = Vector3.Dot(v1, a02);
- p2 = Vector3.Dot(v2, a02);
- r = extents.y * Mathf.Abs(f2.z) + extents.z * Mathf.Abs(f2.y);
- if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
- return false;
- // Test axis a10
- p0 = Vector3.Dot(v0, a10);
- p1 = Vector3.Dot(v1, a10);
- p2 = Vector3.Dot(v2, a10);
- r = extents.x * Mathf.Abs(f0.z) + extents.z * Mathf.Abs(f0.x);
- if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
- return false;
- // Test axis a11
- p0 = Vector3.Dot(v0, a11);
- p1 = Vector3.Dot(v1, a11);
- p2 = Vector3.Dot(v2, a11);
- r = extents.x * Mathf.Abs(f1.z) + extents.z * Mathf.Abs(f1.x);
- if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
- return false;
- // Test axis a12
- p0 = Vector3.Dot(v0, a12);
- p1 = Vector3.Dot(v1, a12);
- p2 = Vector3.Dot(v2, a12);
- r = extents.x * Mathf.Abs(f2.z) + extents.z * Mathf.Abs(f2.x);
- if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
- return false;
- // Test axis a20
- p0 = Vector3.Dot(v0, a20);
- p1 = Vector3.Dot(v1, a20);
- p2 = Vector3.Dot(v2, a20);
- r = extents.x * Mathf.Abs(f0.y) + extents.y * Mathf.Abs(f0.x);
- if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
- return false;
- // Test axis a21
- p0 = Vector3.Dot(v0, a21);
- p1 = Vector3.Dot(v1, a21);
- p2 = Vector3.Dot(v2, a21);
- r = extents.x * Mathf.Abs(f1.y) + extents.y * Mathf.Abs(f1.x);
- if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
- return false;
- // Test axis a22
- p0 = Vector3.Dot(v0, a22);
- p1 = Vector3.Dot(v1, a22);
- p2 = Vector3.Dot(v2, a22);
- r = extents.x * Mathf.Abs(f2.y) + extents.y * Mathf.Abs(f2.x);
- if (Mathf.Max(-Mathf.Max(p0, p1, p2), Mathf.Min(p0, p1, p2)) > r)
- return false;
- if (Mathf.Max(v0.x, v1.x, v2.x) < -extents.x || Mathf.Min(v0.x, v1.x, v2.x) > extents.x)
- return false;
- if (Mathf.Max(v0.y, v1.y, v2.y) < -extents.y || Mathf.Min(v0.y, v1.y, v2.y) > extents.y)
- return false;
- if (Mathf.Max(v0.z, v1.z, v2.z) < -extents.z || Mathf.Min(v0.z, v1.z, v2.z) > extents.z)
- return false;
- Vector3 normal = Vector3.Cross(f1, f0).normalized;
- Plane pl = new Plane(normal, Vector3.Dot(normal, tri.a));
- return Intersects(pl, aabb);
- }
- public static bool Intersects(Plane pl, Bounds aabb)
- {
- Vector3 center = aabb.center;
- Vector3 extents = aabb.max - center;
- float r = extents.x * Mathf.Abs(pl.normal.x) + extents.y * Mathf.Abs(pl.normal.y) + extents.z * Mathf.Abs(pl.normal.z);
- float s = Vector3.Dot(pl.normal, center) - pl.distance;
- return Mathf.Abs(s) <= r;
- }
- }
- [System.Serializable]
- public class MegaBindInf
- {
- public float dist;
- public int face;
- public int i0;
- public int i1;
- public int i2;
- public Vector3 bary;
- public float weight;
- public float area;
- }
- [System.Serializable]
- public class MegaBindVert
- {
- public float weight;
- public List<MegaBindInf> verts = new List<MegaBindInf>();
- }
- public struct MegaCloseFace
- {
- public int face;
- public float dist;
- }
- [ExecuteInEditMode]
- public class MegaWrap : MonoBehaviour
- {
- public float gap = 0.0f;
- public float shrink = 1.0f;
- public List<int> neededVerts = new List<int>();
- public Vector3[] skinnedVerts;
- public Mesh mesh = null;
- public Vector3 offset = Vector3.zero;
- public bool targetIsSkin = false;
- public bool sourceIsSkin = false;
- public int nomapcount = 0;
- public Matrix4x4[] bindposes;
- public BoneWeight[] boneweights;
- public Transform[] bones;
- public float size = 0.01f;
- public int vertindex = 0;
- public Vector3[] freeverts; // position for any vert with no attachments
- public Vector3[] startverts;
- public Vector3[] verts;
- public MegaBindVert[] bindverts;
- public MegaModifyObject target;
- public float maxdist = 0.25f;
- public int maxpoints = 4;
- public bool WrapEnabled = true;
- public MegaNormalMethod NormalMethod = MegaNormalMethod.Unity;
- #if UNITY_5 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
- public bool UseBakedMesh = true;
- #endif
- [ContextMenu("Help")]
- public void Help()
- {
- Application.OpenURL("http://www.west-racing.com/mf/?page_id=3709");
- }
- Vector4 Plane(Vector3 v1, Vector3 v2, Vector3 v3)
- {
- Vector3 normal = Vector4.zero;
- normal.x = (v2.y - v1.y) * (v3.z - v1.z) - (v2.z - v1.z) * (v3.y - v1.y);
- normal.y = (v2.z - v1.z) * (v3.x - v1.x) - (v2.x - v1.x) * (v3.z - v1.z);
- normal.z = (v2.x - v1.x) * (v3.y - v1.y) - (v2.y - v1.y) * (v3.x - v1.x);
- normal = normal.normalized;
- return new Vector4(normal.x, normal.y, normal.z, -Vector3.Dot(v2, normal));
- }
- float PlaneDist(Vector3 p, Vector4 plane)
- {
- Vector3 n = plane;
- return Vector3.Dot(n, p) + plane.w;
- }
- public float GetDistance(Vector3 p, Vector3 p0, Vector3 p1, Vector3 p2)
- {
- return MegaNearestPointTest.DistPoint3Triangle3Dbl(p, p0, p1, p2);
- }
- public float GetPlaneDistance(Vector3 p, Vector3 p0, Vector3 p1, Vector3 p2)
- {
- Vector4 pl = Plane(p0, p1, p2);
- return PlaneDist(p, pl);
- }
- public Vector3 MyBary(Vector3 p, Vector3 p0, Vector3 p1, Vector3 p2)
- {
- Vector3 bary = Vector3.zero;
- Vector3 normal = FaceNormal(p0, p1, p2);
- float areaABC = Vector3.Dot(normal, Vector3.Cross((p1 - p0), (p2 - p0)));
- float areaPBC = Vector3.Dot(normal, Vector3.Cross((p1 - p), (p2 - p)));
- float areaPCA = Vector3.Dot(normal, Vector3.Cross((p2 - p), (p0 - p)));
- bary.x = areaPBC / areaABC; // alpha
- bary.y = areaPCA / areaABC; // beta
- bary.z = 1.0f - bary.x - bary.y; // gamma
- return bary;
- }
- public Vector3 MyBary1(Vector3 p, Vector3 a, Vector3 b, Vector3 c)
- {
- Vector3 v0 = b - a, v1 = c - a, v2 = p - a;
- float d00 = Vector3.Dot(v0, v0);
- float d01 = Vector3.Dot(v0, v1);
- float d11 = Vector3.Dot(v1, v1);
- float d20 = Vector3.Dot(v2, v0);
- float d21 = Vector3.Dot(v2, v1);
- float denom = d00 * d11 - d01 * d01;
- float w = (d11 * d20 - d01 * d21) / denom;
- float v = (d00 * d21 - d01 * d20) / denom;
- float u = 1.0f - v - w;
- return new Vector3(u, v, w);
- }
- public Vector3 CalcBary(Vector3 p, Vector3 p0, Vector3 p1, Vector3 p2)
- {
- return MyBary(p, p0, p1, p2);
- }
- public float CalcArea(Vector3 p0, Vector3 p1, Vector3 p2)
- {
- Vector3 e1 = p1 - p0;
- Vector3 e2 = p2 - p0;
- Vector3 e3 = Vector3.Cross(e1, e2);
- return 0.5f * e3.magnitude;
- }
- Vector3 e11 = Vector3.zero;
- Vector3 e22 = Vector3.zero;
- Vector3 cr = Vector3.zero;
- public Vector3 FaceNormal(Vector3 p0, Vector3 p1, Vector3 p2)
- {
- //Vector3 e1 = p1 - p0;
- //Vector3 e2 = p2 - p0;
- e11.x = p1.x - p0.x;
- e11.y = p1.y - p0.y;
- e11.z = p1.z - p0.z;
- e22.x = p2.x - p0.x;
- e22.y = p2.y - p0.y;
- e22.z = p2.z - p0.z;
- //Vector3 e2 = p2 - p0;
- cr.x = e11.y * e22.z - e22.y * e11.z;
- cr.y = -(e11.x * e22.z - e22.x * e11.z); // * -1;
- cr.z = e11.x * e22.y - e22.x * e11.y;
- return cr; //Vector3.Cross(e11, e22);
- }
- static void CopyBlendShapes(Mesh mesh1, Mesh clonemesh)
- {
- #if UNITY_5_3 || UNITY_5_4 || UNITY_5_5 || UNITY_5_6 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
- int bcount = mesh1.blendShapeCount; //GetBlendShapeFrameCount();
- Vector3[] deltaverts = new Vector3[mesh1.vertexCount];
- Vector3[] deltanorms = new Vector3[mesh1.vertexCount];
- Vector3[] deltatans = new Vector3[mesh1.vertexCount];
- for ( int j = 0; j < bcount; j++ )
- {
- int frames = mesh1.GetBlendShapeFrameCount(j);
- string bname = mesh1.GetBlendShapeName(j);
- for ( int f = 0; f < frames; f++ )
- {
- mesh1.GetBlendShapeFrameVertices(j, f, deltaverts, deltanorms, deltatans);
- float weight = mesh1.GetBlendShapeFrameWeight(j, f);
- clonemesh.AddBlendShapeFrame(bname, weight, deltaverts, deltanorms, deltatans);
- }
- }
- #endif
- }
- public Mesh CloneMesh(Mesh m)
- {
- Mesh clonemesh = new Mesh();
- clonemesh.vertices = m.vertices;
- #if UNITY_5_0 || UNITY_5_1 || UNITY_5 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
- clonemesh.uv2 = m.uv2;
- clonemesh.uv3 = m.uv3;
- clonemesh.uv4 = m.uv4;
- #else
- clonemesh.uv1 = m.uv1;
- clonemesh.uv2 = m.uv2;
- #endif
- clonemesh.uv = m.uv;
- clonemesh.normals = m.normals;
- clonemesh.tangents = m.tangents;
- clonemesh.colors = m.colors;
- clonemesh.subMeshCount = m.subMeshCount;
- for ( int s = 0; s < m.subMeshCount; s++ )
- clonemesh.SetTriangles(m.GetTriangles(s), s);
- CopyBlendShapes(m, clonemesh);
- clonemesh.boneWeights = m.boneWeights;
- clonemesh.bindposes = m.bindposes;
- clonemesh.name = m.name; // + "_copy";
- clonemesh.RecalculateBounds();
- return clonemesh;
- }
- [ContextMenu("Reset Mesh")]
- public void ResetMesh()
- {
- if ( mesh )
- {
- mesh.vertices = startverts;
- mesh.RecalculateBounds();
- RecalcNormals();
- //mesh.RecalculateNormals();
- }
- target = null;
- bindverts = null;
- }
- public void SetMesh()
- {
- MeshFilter mf = GetComponent<MeshFilter>();
- Mesh srcmesh = null;
- if ( mf != null )
- srcmesh = mf.sharedMesh;
- else
- {
- SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
- if ( smesh != null )
- srcmesh = smesh.sharedMesh;
- }
- if ( srcmesh != null )
- {
- mesh = CloneMesh(srcmesh);
- if ( mf )
- mf.sharedMesh = mesh;
- else
- {
- SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
- smesh.sharedMesh = mesh;
- }
- }
- }
- public void Attach()
- {
- var modobj = target;
- var mod = this;
- mod.targetIsSkin = false;
- mod.sourceIsSkin = false;
- if (mod.mesh && mod.startverts != null)
- mod.mesh.vertices = mod.startverts;
- if (modobj == null)
- {
- mod.bindverts = null;
- return;
- }
- mod.nomapcount = 0;
- if (mod.mesh)
- mod.mesh.vertices = mod.startverts;
- MeshFilter mf = mod.GetComponent<MeshFilter>();
- Mesh srcmesh = null;
- if (mf != null)
- {
- //skinned = false;
- srcmesh = mf.sharedMesh;
- }
- else
- {
- SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)mod.GetComponent(typeof(SkinnedMeshRenderer));
- if (smesh != null)
- {
- //skinned = true;
- srcmesh = smesh.sharedMesh;
- mod.sourceIsSkin = true;
- }
- }
- if (srcmesh == null)
- {
- Debug.LogWarning("No Mesh found on the target object, make sure target has a mesh and MegaFiers modifier attached!");
- return;
- }
- if (mod.mesh == null)
- mod.mesh = mod.CloneMesh(srcmesh); //mf.mesh);
- if (mf)
- mf.mesh = mod.mesh;
- else
- {
- SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)mod.GetComponent(typeof(SkinnedMeshRenderer));
- smesh.sharedMesh = mod.mesh;
- }
- if (mod.sourceIsSkin == false)
- {
- SkinnedMeshRenderer tmesh = (SkinnedMeshRenderer)modobj.GetComponent(typeof(SkinnedMeshRenderer));
- if (tmesh != null)
- {
- mod.targetIsSkin = true;
- if (!mod.sourceIsSkin)
- {
- Mesh sm = tmesh.sharedMesh;
- mod.bindposes = sm.bindposes;
- mod.boneweights = sm.boneWeights;
- mod.bones = tmesh.bones;
- mod.skinnedVerts = sm.vertices; //new Vector3[sm.vertexCount];
- }
- }
- }
- if (mod.targetIsSkin)
- {
- if (mod.boneweights == null || mod.boneweights.Length == 0)
- mod.targetIsSkin = false;
- }
- mod.neededVerts.Clear();
- mod.verts = mod.mesh.vertices;
- mod.startverts = mod.mesh.vertices;
- mod.freeverts = new Vector3[mod.startverts.Length];
- Vector3[] baseverts = modobj.verts; //basemesh.vertices;
- int[] basefaces = modobj.tris; //basemesh.triangles;
- mod.bindverts = new MegaBindVert[mod.verts.Length];
- // matrix to get vertex into local space of target
- Matrix4x4 tm = mod.transform.localToWorldMatrix * modobj.transform.worldToLocalMatrix;
- List<MegaCloseFace> closefaces = new List<MegaCloseFace>();
- Vector3 p0 = Vector3.zero;
- Vector3 p1 = Vector3.zero;
- Vector3 p2 = Vector3.zero;
- Vector3[] tverts = new Vector3[mod.target.sverts.Length];
- for (int i = 0; i < tverts.Length; i++)
- {
- if (mod.targetIsSkin && !mod.sourceIsSkin)
- tverts[i] = modobj.transform.InverseTransformPoint(mod.GetSkinPos(i));
- else
- tverts[i] = baseverts[i];
- }
- //EditorUtility.ClearProgressBar();
- float unit = 0.0f;
- mod.target.mesh.RecalculateBounds();
- MegaVoxel.Voxelize(tverts, basefaces, mod.target.mesh.bounds, 16, out unit);
- //Vector3 min = mod.target.mesh.bounds.min;
- for (int i = 0; i < mod.verts.Length; i++)
- {
- MegaBindVert bv = new MegaBindVert();
- mod.bindverts[i] = bv;
- Vector3 p = tm.MultiplyPoint(mod.verts[i]);
- p = mod.transform.TransformPoint(mod.verts[i]);
- p = modobj.transform.InverseTransformPoint(p);
- mod.freeverts[i] = p;
- closefaces.Clear();
- int gx = 0;
- int gy = 0;
- int gz = 0;
- MegaVoxel.GetGridIndex(p, out gx, out gy, out gz, unit);
- for (int x = gx - 1; x <= gx + 1; x++)
- {
- if (x >= 0 && x < MegaVoxel.width)
- {
- for (int y = gy - 1; y <= gy + 1; y++)
- {
- if (y >= 0 && y < MegaVoxel.height)
- {
- for (int z = gz - 1; z <= gz + 1; z++)
- {
- if (z >= 0 && z < MegaVoxel.depth)
- {
- List<MegaTriangle> tris = MegaVoxel.volume[x, y, z].tris;
- for (int t = 0; t < tris.Count; t++)
- {
- float dist = mod.GetDistance(p, tris[t].a, tris[t].b, tris[t].c);
- if (Mathf.Abs(dist) < mod.maxdist)
- {
- MegaCloseFace cf = new MegaCloseFace();
- cf.dist = Mathf.Abs(dist);
- cf.face = tris[t].t;
- bool inserted = false;
- for (int k = 0; k < closefaces.Count; k++)
- {
- if (cf.dist < closefaces[k].dist)
- {
- closefaces.Insert(k, cf);
- inserted = true;
- break;
- }
- }
- if (!inserted)
- closefaces.Add(cf);
- }
- }
- }
- }
- }
- }
- }
- }
- float tweight = 0.0f;
- int maxp = mod.maxpoints;
- if (maxp == 0)
- maxp = closefaces.Count;
- for (int j = 0; j < maxp; j++)
- {
- if (j < closefaces.Count)
- {
- int t = closefaces[j].face;
- p0 = tverts[basefaces[t]];
- p1 = tverts[basefaces[t + 1]];
- p2 = tverts[basefaces[t + 2]];
- Vector3 normal = mod.FaceNormal(p0, p1, p2);
- float dist = closefaces[j].dist; //GetDistance(p, p0, p1, p2);
- MegaBindInf bi = new MegaBindInf();
- bi.dist = mod.GetPlaneDistance(p, p0, p1, p2); //dist;
- bi.face = t;
- bi.i0 = basefaces[t];
- bi.i1 = basefaces[t + 1];
- bi.i2 = basefaces[t + 2];
- bi.bary = mod.CalcBary(p, p0, p1, p2);
- bi.weight = 1.0f / (1.0f + dist);
- bi.area = normal.magnitude * 0.5f; //CalcArea(baseverts[basefaces[t]], baseverts[basefaces[t + 1]], baseverts[basefaces[t + 2]]); // Could calc once at start
- tweight += bi.weight;
- bv.verts.Add(bi);
- }
- }
- if (mod.maxpoints > 0 && mod.maxpoints < bv.verts.Count)
- bv.verts.RemoveRange(mod.maxpoints, bv.verts.Count - mod.maxpoints);
- // Only want to calculate skin vertices we use
- if (!mod.sourceIsSkin && mod.targetIsSkin)
- {
- for (int fi = 0; fi < bv.verts.Count; fi++)
- {
- if (!mod.neededVerts.Contains(bv.verts[fi].i0))
- mod.neededVerts.Add(bv.verts[fi].i0);
- if (!mod.neededVerts.Contains(bv.verts[fi].i1))
- mod.neededVerts.Add(bv.verts[fi].i1);
- if (!mod.neededVerts.Contains(bv.verts[fi].i2))
- mod.neededVerts.Add(bv.verts[fi].i2);
- }
- }
- if (tweight == 0.0f)
- {
- mod.nomapcount++;
- break;
- }
- bv.weight = tweight;
- }
- }
- public void Attach(MegaModifyObject modobj)
- {
- targetIsSkin = false;
- sourceIsSkin = false;
- if ( mesh && startverts != null )
- mesh.vertices = startverts;
- if ( modobj == null )
- {
- bindverts = null;
- return;
- }
- nomapcount = 0;
- if ( mesh )
- mesh.vertices = startverts;
- MeshFilter mf = GetComponent<MeshFilter>();
- Mesh srcmesh = null;
- if ( mf != null )
- {
- //skinned = false;
- srcmesh = mf.mesh;
- }
- else
- {
- SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
- if ( smesh != null )
- {
- //skinned = true;
- srcmesh = smesh.sharedMesh;
- sourceIsSkin = true;
- }
- }
- if ( srcmesh == null )
- {
- Debug.LogWarning("No Mesh found on the target object, make sure target has a mesh and MegaFiers modifier attached!");
- return;
- }
- if ( mesh == null )
- mesh = CloneMesh(srcmesh); //mf.mesh);
- if ( mf )
- mf.mesh = mesh;
- else
- {
- SkinnedMeshRenderer smesh = (SkinnedMeshRenderer)GetComponent(typeof(SkinnedMeshRenderer));
- smesh.sharedMesh = mesh;
- }
- if ( sourceIsSkin == false )
- {
- SkinnedMeshRenderer tmesh = (SkinnedMeshRenderer)modobj.GetComponent(typeof(SkinnedMeshRenderer));
- if ( tmesh != null )
- {
- targetIsSkin = true;
- if ( !sourceIsSkin )
- {
- Mesh sm = tmesh.sharedMesh;
- bindposes = sm.bindposes;
- boneweights = sm.boneWeights;
- bones = tmesh.bones;
- skinnedVerts = sm.vertices; //new Vector3[sm.vertexCount];
- }
- }
- }
- if ( targetIsSkin )
- {
- if ( boneweights == null || boneweights.Length == 0 )
- targetIsSkin = false;
- }
- neededVerts.Clear();
- verts = mesh.vertices;
- startverts = mesh.vertices;
- freeverts = new Vector3[startverts.Length];
- Vector3[] baseverts = modobj.verts; //basemesh.vertices;
- int[] basefaces = modobj.tris; //basemesh.triangles;
- bindverts = new MegaBindVert[verts.Length];
- // matrix to get vertex into local space of target
- Matrix4x4 tm = transform.localToWorldMatrix * modobj.transform.worldToLocalMatrix;
- List<MegaCloseFace> closefaces = new List<MegaCloseFace>();
- Vector3 p0 = Vector3.zero;
- Vector3 p1 = Vector3.zero;
- Vector3 p2 = Vector3.zero;
- for ( int i = 0; i < verts.Length; i++ )
- {
- MegaBindVert bv = new MegaBindVert();
- bindverts[i] = bv;
- Vector3 p = tm.MultiplyPoint(verts[i]);
- p = transform.TransformPoint(verts[i]);
- p = modobj.transform.InverseTransformPoint(p);
- freeverts[i] = p;
- closefaces.Clear();
- for ( int t = 0; t < basefaces.Length; t += 3 )
- {
- if ( targetIsSkin && !sourceIsSkin )
- {
- p0 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t]));
- p1 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t + 1]));
- p2 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t + 2]));
- }
- else
- {
- p0 = baseverts[basefaces[t]];
- p1 = baseverts[basefaces[t + 1]];
- p2 = baseverts[basefaces[t + 2]];
- }
- float dist = GetDistance(p, p0, p1, p2);
- if ( Mathf.Abs(dist) < maxdist )
- {
- MegaCloseFace cf = new MegaCloseFace();
- cf.dist = Mathf.Abs(dist);
- cf.face = t;
- bool inserted = false;
- for ( int k = 0; k < closefaces.Count; k++ )
- {
- if ( cf.dist < closefaces[k].dist )
- {
- closefaces.Insert(k, cf);
- inserted = true;
- break;
- }
- }
- if ( !inserted )
- closefaces.Add(cf);
- }
- }
- float tweight = 0.0f;
- int maxp = maxpoints;
- if ( maxp == 0 )
- maxp = closefaces.Count;
- for ( int j = 0; j < maxp; j++ )
- {
- if ( j < closefaces.Count )
- {
- int t = closefaces[j].face;
- if ( targetIsSkin && !sourceIsSkin )
- {
- p0 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t]));
- p1 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t + 1]));
- p2 = modobj.transform.InverseTransformPoint(GetSkinPos(basefaces[t + 2]));
- }
- else
- {
- p0 = baseverts[basefaces[t]];
- p1 = baseverts[basefaces[t + 1]];
- p2 = baseverts[basefaces[t + 2]];
- }
- Vector3 normal = FaceNormal(p0, p1, p2);
- float dist = closefaces[j].dist; //GetDistance(p, p0, p1, p2);
- MegaBindInf bi = new MegaBindInf();
- bi.dist = GetPlaneDistance(p, p0, p1, p2); //dist;
- bi.face = t;
- bi.i0 = basefaces[t];
- bi.i1 = basefaces[t + 1];
- bi.i2 = basefaces[t + 2];
- bi.bary = CalcBary(p, p0, p1, p2);
- bi.weight = 1.0f / (1.0f + dist);
- bi.area = normal.magnitude * 0.5f; //CalcArea(baseverts[basefaces[t]], baseverts[basefaces[t + 1]], baseverts[basefaces[t + 2]]); // Could calc once at start
- tweight += bi.weight;
- bv.verts.Add(bi);
- }
- }
- if ( maxpoints > 0 && maxpoints < bv.verts.Count )
- bv.verts.RemoveRange(maxpoints, bv.verts.Count - maxpoints);
- // Only want to calculate skin vertices we use
- if ( !sourceIsSkin && targetIsSkin )
- {
- for ( int fi = 0; fi < bv.verts.Count; fi++ )
- {
- if ( !neededVerts.Contains(bv.verts[fi].i0) )
- neededVerts.Add(bv.verts[fi].i0);
- if ( !neededVerts.Contains(bv.verts[fi].i1) )
- neededVerts.Add(bv.verts[fi].i1);
- if ( !neededVerts.Contains(bv.verts[fi].i2) )
- neededVerts.Add(bv.verts[fi].i2);
- }
- }
- if ( tweight == 0.0f )
- nomapcount++;
- bv.weight = tweight;
- }
- }
- void LateUpdate()
- {
- DoUpdate();
- }
- public Vector3 GetSkinPos(int i)
- {
- Vector3 pos = target.sverts[i];
- Vector3 bpos = bindposes[boneweights[i].boneIndex0].MultiplyPoint(pos);
- Vector3 p = bones[boneweights[i].boneIndex0].TransformPoint(bpos) * boneweights[i].weight0;
- bpos = bindposes[boneweights[i].boneIndex1].MultiplyPoint(pos);
- p += bones[boneweights[i].boneIndex1].TransformPoint(bpos) * boneweights[i].weight1;
- bpos = bindposes[boneweights[i].boneIndex2].MultiplyPoint(pos);
- p += bones[boneweights[i].boneIndex2].TransformPoint(bpos) * boneweights[i].weight2;
- bpos = bindposes[boneweights[i].boneIndex3].MultiplyPoint(pos);
- p += bones[boneweights[i].boneIndex3].TransformPoint(bpos) * boneweights[i].weight3;
- return p;
- }
- Vector3 gcp = Vector3.zero;
- public Vector3 GetCoordMine(Vector3 A, Vector3 B, Vector3 C, Vector3 bary)
- {
- //Vector3 p = Vector3.zero;
- gcp.x = (bary.x * A.x) + (bary.y * B.x) + (bary.z * C.x);
- gcp.y = (bary.x * A.y) + (bary.y * B.y) + (bary.z * C.y);
- gcp.z = (bary.x * A.z) + (bary.y * B.z) + (bary.z * C.z);
- return gcp;
- }
- SkinnedMeshRenderer tmesh;
- #if UNITY_5 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
- Mesh bakedmesh = null;
- #endif
- void DoUpdate()
- {
- if ( WrapEnabled == false || target == null || bindverts == null ) //|| bindposes == null )
- return;
- if ( mesh == null )
- SetMesh();
- if ( mesh == null )
- return;
- if ( targetIsSkin && neededVerts != null && neededVerts.Count > 0 ) //|| (targetIsSkin && boneweights == null) )
- {
- if ( boneweights == null || tmesh == null )
- {
- tmesh = (SkinnedMeshRenderer)target.GetComponent(typeof(SkinnedMeshRenderer));
- if ( tmesh != null )
- {
- if ( !sourceIsSkin )
- {
- Mesh sm = tmesh.sharedMesh;
- bindposes = sm.bindposes;
- bones = tmesh.bones;
- boneweights = sm.boneWeights;
- }
- }
- }
- #if UNITY_5 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
- if ( tmesh == null )
- tmesh = (SkinnedMeshRenderer)target.GetComponent(typeof(SkinnedMeshRenderer));
- if ( UseBakedMesh )
- {
- if ( bakedmesh == null )
- bakedmesh = new Mesh();
- tmesh.BakeMesh(bakedmesh);
- skinnedVerts = bakedmesh.vertices;
- }
- else
- {
- for ( int i = 0; i < neededVerts.Count; i++ )
- skinnedVerts[neededVerts[i]] = GetSkinPos(neededVerts[i]);
- }
- #else
- for ( int i = 0; i < neededVerts.Count; i++ )
- skinnedVerts[neededVerts[i]] = GetSkinPos(neededVerts[i]);
- #endif
- }
- Matrix4x4 stm = Matrix4x4.identity;
- Vector3 p = Vector3.zero;
- if ( targetIsSkin && !sourceIsSkin )
- {
- #if UNITY_5 || UNITY_2017 || UNITY_2018 || UNITY_2019 || UNITY_2020
- if ( UseBakedMesh )
- stm = transform.worldToLocalMatrix * target.transform.localToWorldMatrix; // * transform.worldToLocalMatrix;
- else
- stm = transform.worldToLocalMatrix; // * target.transform.localToWorldMatrix; // * transform.worldToLocalMatrix;
- #else
- stm = transform.worldToLocalMatrix; // * target.transform.localToWorldMatrix; // * transform.worldToLocalMatrix;
- #endif
- for ( int i = 0; i < bindverts.Length; i++ )
- {
- if ( bindverts[i].verts.Count > 0 )
- {
- p = Vector3.zero;
- float oow = 1.0f / bindverts[i].weight;
- int cnt = bindverts[i].verts.Count;
- for ( int j = 0; j < cnt; j++ )
- {
- MegaBindInf bi = bindverts[i].verts[j];
- Vector3 p0 = skinnedVerts[bi.i0];
- Vector3 p1 = skinnedVerts[bi.i1];
- Vector3 p2 = skinnedVerts[bi.i2];
- Vector3 cp = GetCoordMine(p0, p1, p2, bi.bary);
- Vector3 norm = FaceNormal(p0, p1, p2);
- float sq = 1.0f / Mathf.Sqrt(norm.x * norm.x + norm.y * norm.y + norm.z * norm.z);
- float d = (bi.dist * shrink) + gap;
- //cp += d * norm.x;
- cp.x += d * norm.x * sq;
- cp.y += d * norm.y * sq;
- cp.z += d * norm.z * sq;
- float bw = bi.weight * oow;
- if ( j == 0 )
- {
- p.x = cp.x * bw;
- p.y = cp.y * bw;
- p.z = cp.z * bw;
- }
- else
- {
- p.x += cp.x * bw;
- p.y += cp.y * bw;
- p.z += cp.z * bw;
- }
- //cp += ((bi.dist * shrink) + gap) * norm.normalized;
- //p += cp * (bi.weight / bindverts[i].weight);
- }
- Vector3 pp = stm.MultiplyPoint3x4(p);
- verts[i].x = pp.x + offset.x;
- verts[i].y = pp.y + offset.y;
- verts[i].z = pp.z + offset.z;
- //verts[i] = transform.InverseTransformPoint(p) + offset;
- }
- }
- }
- else
- {
- stm = transform.worldToLocalMatrix * target.transform.localToWorldMatrix; // * transform.worldToLocalMatrix;
- //Matrix4x4 tm = target.transform.localToWorldMatrix;
- for ( int i = 0; i < bindverts.Length; i++ )
- {
- if ( bindverts[i].verts.Count > 0 )
- {
- p = Vector3.zero;
- float oow = 1.0f / bindverts[i].weight;
- for ( int j = 0; j < bindverts[i].verts.Count; j++ )
- {
- MegaBindInf bi = bindverts[i].verts[j];
- Vector3 p0 = target.sverts[bi.i0];
- Vector3 p1 = target.sverts[bi.i1];
- Vector3 p2 = target.sverts[bi.i2];
- Vector3 cp = GetCoordMine(p0, p1, p2, bi.bary);
- Vector3 norm = FaceNormal(p0, p1, p2);
- float sq = 1.0f / Mathf.Sqrt(norm.x * norm.x + norm.y * norm.y + norm.z * norm.z);
- float d = (bi.dist * shrink) + gap;
- //cp += d * norm.x;
- cp.x += d * norm.x * sq;
- cp.y += d * norm.y * sq;
- cp.z += d * norm.z * sq;
- float bw = bi.weight * oow;
- if ( j == 0 )
- {
- p.x = cp.x * bw;
- p.y = cp.y * bw;
- p.z = cp.z * bw;
- }
- else
- {
- p.x += cp.x * bw;
- p.y += cp.y * bw;
- p.z += cp.z * bw;
- }
- //cp += ((bi.dist * shrink) + gap) * norm.normalized;
- //p += cp * (bi.weight / bindverts[i].weight);
- }
- }
- else
- p = freeverts[i]; //startverts[i];
- Vector3 pp = stm.MultiplyPoint3x4(p);
- verts[i].x = pp.x + offset.x;
- verts[i].y = pp.y + offset.y;
- verts[i].z = pp.z + offset.z;
- //p = target.transform.TransformPoint(p);
- //verts[i] = transform.InverseTransformPoint(p) + offset;
- }
- }
- mesh.vertices = verts;
- RecalcNormals();
- mesh.RecalculateBounds();
- }
- public MegaNormMap[] mapping;
- public int[] tris;
- public Vector3[] facenorms;
- public Vector3[] norms;
- int[] FindFacesUsing(Vector3 p, Vector3 n)
- {
- List<int> faces = new List<int>();
- Vector3 v = Vector3.zero;
- for ( int i = 0; i < tris.Length; i += 3 )
- {
- v = verts[tris[i]];
- if ( v.x == p.x && v.y == p.y && v.z == p.z )
- {
- if ( n.Equals(norms[tris[i]]) )
- faces.Add(i / 3);
- }
- else
- {
- v = verts[tris[i + 1]];
- if ( v.x == p.x && v.y == p.y && v.z == p.z )
- {
- if ( n.Equals(norms[tris[i + 1]]) )
- faces.Add(i / 3);
- }
- else
- {
- v = verts[tris[i + 2]];
- if ( v.x == p.x && v.y == p.y && v.z == p.z )
- {
- if ( n.Equals(norms[tris[i + 2]]) )
- faces.Add(i / 3);
- }
- }
- }
- }
- return faces.ToArray();
- }
- // Should call this from inspector when we change to mega
- public void BuildNormalMapping(Mesh mesh, bool force)
- {
- if ( mapping == null || mapping.Length == 0 || force )
- {
- // so for each normal we have a vertex, so find all faces that share that vertex
- tris = mesh.triangles;
- norms = mesh.normals;
- facenorms = new Vector3[tris.Length / 3];
- mapping = new MegaNormMap[verts.Length];
- for ( int i = 0; i < verts.Length; i++ )
- {
- mapping[i] = new MegaNormMap();
- mapping[i].faces = FindFacesUsing(verts[i], norms[i]);
- }
- }
- }
- public void RecalcNormals()
- {
- if ( NormalMethod == MegaNormalMethod.Unity ) //|| mapping == null )
- mesh.RecalculateNormals();
- else
- {
- if ( mapping == null )
- BuildNormalMapping(mesh, false);
- RecalcNormals(mesh, verts);
- }
- }
- public void RecalcNormals(Mesh ms, Vector3[] _verts)
- {
- int index = 0;
- Vector3 v30 = Vector3.zero;
- Vector3 v31 = Vector3.zero;
- Vector3 v32 = Vector3.zero;
- Vector3 va = Vector3.zero;
- Vector3 vb = Vector3.zero;
- for ( int f = 0; f < tris.Length; f += 3 )
- {
- v30 = _verts[tris[f]];
- v31 = _verts[tris[f + 1]];
- v32 = _verts[tris[f + 2]];
- va.x = v31.x - v30.x;
- va.y = v31.y - v30.y;
- va.z = v31.z - v30.z;
- vb.x = v32.x - v31.x;
- vb.y = v32.y - v31.y;
- vb.z = v32.z - v31.z;
- v30.x = va.y * vb.z - va.z * vb.y;
- v30.y = va.z * vb.x - va.x * vb.z;
- v30.z = va.x * vb.y - va.y * vb.x;
- // Uncomment this if you dont want normals weighted by poly size
- //float l = v30.x * v30.x + v30.y * v30.y + v30.z * v30.z;
- //l = 1.0f / Mathf.Sqrt(l);
- //v30.x *= l;
- //v30.y *= l;
- //v30.z *= l;
- facenorms[index++] = v30;
- }
- for ( int n = 0; n < norms.Length; n++ )
- {
- if ( mapping[n].faces.Length > 0 )
- {
- Vector3 norm = facenorms[mapping[n].faces[0]];
- for ( int i = 1; i < mapping[n].faces.Length; i++ )
- {
- v30 = facenorms[mapping[n].faces[i]];
- norm.x += v30.x;
- norm.y += v30.y;
- norm.z += v30.z;
- }
- float l = norm.x * norm.x + norm.y * norm.y + norm.z * norm.z;
- l = 1.0f / Mathf.Sqrt(l);
- norm.x *= l;
- norm.y *= l;
- norm.z *= l;
- norms[n] = norm;
- }
- else
- norms[n] = Vector3.up;
- }
- ms.normals = norms;
- }
- }
|