using System.Collections.Generic; using UMA; using Unity.Collections; using UnityEngine; public class DecalDefinition { public string Name; public int InitialIndex; public GameObject DecalMeshObject; public Mesh bakedMesh; public Plane[] planesInWorldSpace; public int VertexNumber; public Vector3 WorldImpactPoint; public Vector3 LocalImpactPoint; public Material material; public float offset; // zbias or offset for rendering. vertex = vertex + normal * offset. List Instances = new List(); public GameObject InstantiateSimpleDecal(GameObject umaParent, SkinnedMeshRenderer baseRenderer) { // instantiate a new one here??? GameObject newDecal = GameObject.Instantiate(DecalMeshObject,umaParent.transform); SkinnedMeshRenderer smr = newDecal.GetComponent(); if (smr == null) { Debug.LogWarning("Unable to instantiate decal - no SMR"); return null; } // Copy bindposes from main. // copy bones from main. smr.sharedMesh.bindposes = baseRenderer.sharedMesh.bindposes; smr.bones = baseRenderer.bones; return newDecal; } public void AddInstance(UMAData umaData, List Vertexes) { } public void AddSubmesh(SkinnedMeshRenderer smr) { // we can't reuse the vertexes because the UV coordinates are different... if (Instances == null) { return; } if (Instances.Count == 0) { return; } List mats = new List(); smr.GetMaterials(mats); mats.Add(material); // read old data List Vertexes = new List(); List Normals = new List(); List Tangents = new List(); List Colors = new List(); List UV = new List(); List UV2 = new List(); List UV3 = new List(); List UV4 = new List(); List Tris = new List(); // TODO: these should be NativeArray. Size to mesh size + all DI sizes. List bonesPerVertex = new List(); List boneWeights = new List(); Mesh mesh = smr.sharedMesh; mesh.GetVertices(Vertexes); mesh.GetNormals(Normals); mesh.GetTangents(Tangents); mesh.GetColors(Colors); mesh.GetUVs(0, UV); mesh.GetUVs(1, UV2); mesh.GetUVs(2, UV3); mesh.GetUVs(3, UV4); bonesPerVertex.AddRange(mesh.GetBonesPerVertex()); boneWeights.AddRange(mesh.GetAllBoneWeights()); // boneweights // bonespervertex // blendshapes <-- later? int baseVertex = Vertexes.Count; foreach(DecalInstance di in Instances) { Vertexes.AddRange(di.vertexes); // add the triangles for(int i=0;i(bonesPerVertex.ToArray(), Allocator.Persistent); var unityBoneWeights = new NativeArray(boneWeights.ToArray(), Allocator.Persistent); mesh.SetBoneWeights(unityBonesPerVertex, unityBoneWeights); unityBonesPerVertex.Dispose(); unityBoneWeights.Dispose(); } } public struct faceData { int oldFaceNumber; Vector3 Normal; } public class DecalInstance { float offset; // z bias, or add to vertexes? public Vector3[] vertexes; // copied from slot(s) public Vector3[] normals; // copied from slot(s) public Vector4[] tangents; // copied from slot(s) public Color32[] colors32; // copied from slot(s) public Vector2[] uv; // calculated at capture time by projecting to plane public int[] TriangleList; // calculated at capture time (each triangle found is translated to local triangles and added to list). public byte[] bonesPerVertex; public BoneWeight1[] boneWeights; /// /// Creates a skinned decal /// /// t is the transform of the meshes game object in the scene. /// m is the mesh as it is *right now* in the scene, captured at the current frame. /// It's used in place of the meshdata, and is used for everything *except* as the vertex position /// when creating the skinned mesh!!! /// RayOrigin is the origin of the ray. Used to determine if a face is "facing" the origin of the decal. /// This is the UMAMeshData that holds all the data. This is the information /// that is pre-bound to the rig. It's used for constructing the submesh /// planes is the list of planes in world space that define the bounds /// public bool Create(Transform t, Mesh m, Vector3 RayOrigin, UMAMeshData meshData, Plane[] planes) { List newVerts = new List(); List newNormals = new List(); List newTangents = new List(); List newColors32 = new List(); List newUv = new List(); List newTriangleList = new List(); List newBonesPerVertex = new List(); List newBoneWeights = new List(); List oldVertexNumbers = new List(); HashSet vertHash = new HashSet(); // calculate the face normals for each vertex. // int = the source vertex number from the mesh. // List = the list of normals for this vertex (one from each face it's connected to). //Dictionary> oldVertexnumberFaceNormals = CalculateFaceNormals(m, meshData); List meshVerts = new List(); m.GetVertices(meshVerts); for (int i=0;i= 0.0f) { if (vertHash.Contains(i1) || vertHash.Contains(i2) || vertHash.Contains(i3)) { // Add this triangle. // add meshVerts[i1], meshVerts[i2], meshVerts[i3] to new triangle list. // add translation for i1,i2,i3 to lookup (new, old) // Calculate UV for each one based on distance to UV planes } } } } } return false; } // Return true if vertex is inside plane group. private bool OnRight(Vector3 vert, Plane[] planes) { foreach (Plane p in planes) { if (p.GetDistanceToPoint(vert) <= 0.0f) { return false; } } return true; } private Dictionary> CalculateFaceNormals(Mesh m, UMAMeshData meshData) { Dictionary> retval = new Dictionary>(); return retval; } // index of vertexes in the slot. // These need to be translate d to the mesh index after the build is complete. // To do this, we will need to track for each slot in the UMAData (during the build process) // What SMR the slot is actually in, in case there are multiples // what vertex position the slot starts at in the SMR }