Ejemplo n.º 1
0
        public void Apply(z_Mesh mesh)
        {
            foreach (z_AttributeLayout al in attributeLayout)
            {
                switch (al.channel)
                {
                case z_MeshChannel.UV0:
                case z_MeshChannel.UV2:
                case z_MeshChannel.UV3:
                case z_MeshChannel.UV4:
                {
                    List <Vector4> uv = new List <Vector4>(weights[channelMap[al.channel]]);
                    mesh.SetUVs(z_MeshChannelUtility.UVChannelToIndex(al.channel), uv);
                }
                break;

                case z_MeshChannel.Color:
                {
                    // @todo consider storing Color array separate from Vec4 since this cast costs ~5ms
                    mesh.colors = System.Array.ConvertAll(weights[channelMap[al.channel]], x => Vec4ToColor32(x));
                    break;
                }

                case z_MeshChannel.Tangent:
                {
                    mesh.tangents = weights[channelMap[z_MeshChannel.Tangent]];
                    break;
                }
                }
            }
        }
Ejemplo n.º 2
0
        public override void OnVerticesMoved(z_Mesh mesh)
        {
#if DO_RENDER_OVERLAY_MESH
            Vector3[] v = mesh.vertices;

            if (wireframeMesh != null)
            {
                wireframeMesh.vertices = v;
            }

            if (drawVertexBillboards)
            {
                int len = System.Math.Min(ushort.MaxValue / 4, common.Count);

                if (vertexMesh != null)
                {
                    Vector3[] v2 = new Vector3[len * 4];

                    for (int i = 0; i < len; i++)
                    {
                        int ind = common[i][0];

                        v2[i * 4 + 0] = v[ind];
                        v2[i * 4 + 1] = v[ind];
                        v2[i * 4 + 2] = v[ind];
                        v2[i * 4 + 3] = v[ind];
                    }

                    vertexMesh.vertices = v2;
                }
            }
#endif
        }
        /**
         *	Vertices that are common, form a seam, and should be smoothed.
         */
        public static List <List <int> > GetSmoothSeamLookup(z_Mesh m)
        {
            Vector3[] normals = m.normals;

            if (normals == null)
            {
                return(null);
            }

            List <List <int> > lookup = null;

            if (commonNormalsCache.TryGetValue(m, out lookup))
            {
                return(lookup);
            }

            List <List <int> > common = GetCommonVertices(m);

            var z = common
                    .SelectMany(x => x.GroupBy(i => (z_RndVec3)normals[i]))
                    .Where(n => n.Count() > 1)
                    .Select(t => t.ToList())
                    .ToList();

            commonNormalsCache.Add(m, z);

            return(z);
        }
        /**
         *	Builds a lookup with each vertex index and a list of all neighboring indices.
         */
        public static Dictionary <int, List <int> > GetAdjacentVertices(z_Mesh mesh)
        {
            List <List <int> >    common = GetCommonVertices(mesh);
            Dictionary <int, int> lookup = common.GetCommonLookup <int>();

            List <z_CommonEdge> edges = GetEdges(mesh, lookup).ToList();
            List <List <int> >  map   = new List <List <int> >();

            for (int i = 0; i < common.Count(); i++)
            {
                map.Add(new List <int>());
            }

            for (int i = 0; i < edges.Count; i++)
            {
                map[edges[i].cx].Add(edges[i].y);
                map[edges[i].cy].Add(edges[i].x);
            }

            Dictionary <int, List <int> > adjacent          = new Dictionary <int, List <int> >();
            IEnumerable <int>             distinctTriangles = mesh.GetTriangles().Distinct();

            foreach (int i in distinctTriangles)
            {
                adjacent.Add(i, map[lookup[i]]);
            }

            return(adjacent);
        }
        private static HashSet <z_CommonEdge> GetEdgesDistinct(z_Mesh m, Dictionary <int, int> lookup, out List <z_CommonEdge> duplicates)
        {
            int[] tris  = m.GetTriangles();
            int   count = tris.Length;

            HashSet <z_CommonEdge> edges = new HashSet <z_CommonEdge>();

            duplicates = new List <z_CommonEdge>();

            for (int i = 0; i < count; i += 3)
            {
                z_CommonEdge a = new z_CommonEdge(tris[i + 0], tris[i + 1], lookup[tris[i + 0]], lookup[tris[i + 1]]);
                z_CommonEdge b = new z_CommonEdge(tris[i + 1], tris[i + 2], lookup[tris[i + 1]], lookup[tris[i + 2]]);
                z_CommonEdge c = new z_CommonEdge(tris[i + 2], tris[i + 0], lookup[tris[i + 2]], lookup[tris[i + 0]]);

                if (!edges.Add(a))
                {
                    duplicates.Add(a);
                }

                if (!edges.Add(b))
                {
                    duplicates.Add(b);
                }

                if (!edges.Add(c))
                {
                    duplicates.Add(c);
                }
            }

            return(edges);
        }
        /**
         *	Return a mesh that is the combination of both additionalVertexStreams and the originalMesh.
         *		- Position
         *		- UV0
         *		- UV2
         *		- UV3
         *		- UV4
         *		- Color
         *		- Tangent
         *	If usingVertexStreams is false, null is returned.
         */
        private z_Mesh GetCompositeMesh()
        {
            if (_editMesh == null)
            {
                _editMesh = new z_Mesh();
            }

            _editMesh.Clear();
            _editMesh.name     = originalMesh.name;
            _editMesh.vertices = GetAttribute <Vector3[]>(x => { return(x.vertices); });
            _editMesh.normals  = GetAttribute <Vector3[]>(x => { return(x.normals); });
            _editMesh.colors   = GetAttribute <Color32[]>(x => { return(x.colors32); });
            _editMesh.tangents = GetAttribute <Vector4[]>(x => { return(x.tangents); });
            _editMesh.uv0      = GetAttribute <List <Vector4> >(x => { List <Vector4> l = new List <Vector4>(); x.GetUVs(0, l); return(l); });
            _editMesh.uv1      = GetAttribute <List <Vector4> >(x => { List <Vector4> l = new List <Vector4>(); x.GetUVs(1, l); return(l); });
            _editMesh.uv2      = GetAttribute <List <Vector4> >(x => { List <Vector4> l = new List <Vector4>(); x.GetUVs(2, l); return(l); });
            _editMesh.uv3      = GetAttribute <List <Vector4> >(x => { List <Vector4> l = new List <Vector4>(); x.GetUVs(3, l); return(l); });

            _editMesh.subMeshCount = originalMesh.subMeshCount;

            for (int i = 0; i < _editMesh.subMeshCount; i++)
            {
                _editMesh.SetTriangles(originalMesh.GetTriangles(i), i);
            }

            return(_editMesh);
        }
        /**
         *	Creates a new mesh using only the @src positions, normals, and a new color array.
         */
        public static Mesh CreateOverlayMesh(z_Mesh src)
        {
            Mesh m = new Mesh();

            m.name         = "Overlay Mesh: " + src.name;
            m.vertices     = src.vertices;
            m.normals      = src.normals;
            m.colors       = z_Util.Fill <Color>(new Color(0f, 0f, 0f, 0f), m.vertexCount);
            m.subMeshCount = src.subMeshCount;

            for (int i = 0; i < src.subMeshCount; i++)
            {
                if (src.GetTopology(i) == MeshTopology.Triangles)
                {
                    int[] tris  = src.GetIndices(i);
                    int[] lines = new int[tris.Length * 2];
                    int   index = 0;
                    for (int n = 0; n < tris.Length; n += 3)
                    {
                        lines[index++] = tris[n + 0];
                        lines[index++] = tris[n + 1];
                        lines[index++] = tris[n + 1];
                        lines[index++] = tris[n + 2];
                        lines[index++] = tris[n + 2];
                        lines[index++] = tris[n + 0];
                    }
                    m.SetIndices(lines, MeshTopology.Lines, i);
                }
                else
                {
                    m.SetIndices(src.GetIndices(i), src.GetTopology(i), i);
                }
            }
            return(m);
        }
Ejemplo n.º 8
0
        /**
         *	Initialize a SplatSet with mesh and attribute layout.
         */
        public z_SplatSet(z_Mesh mesh, z_AttributeLayout[] attributes) : this(mesh.vertexCount, attributes, false)
        {
            foreach (var kvp in channelMap)
            {
                switch (kvp.Key)
                {
                case z_MeshChannel.UV0:
                case z_MeshChannel.UV2:
                case z_MeshChannel.UV3:
                case z_MeshChannel.UV4:
                {
                    List <Vector4> uv = mesh.GetUVs(z_MeshChannelUtility.UVChannelToIndex(kvp.Key));
                    weights[kvp.Value] = uv.Count == weightCount?uv.ToArray() : new Vector4[weightCount];
                }
                break;

                case z_MeshChannel.Color:
                {
                    Color32[] color = mesh.colors;
                    weights[kvp.Value] = color != null && color.Length == weightCount?System.Array.ConvertAll(color, x => Color32ToVec4(x)) : new Vector4[weightCount];
                }
                break;

                case z_MeshChannel.Tangent:
                {
                    Vector4[] tangent = mesh.tangents;
                    weights[kvp.Value] = tangent != null && tangent.Length == weightCount ? tangent : new Vector4[weightCount];
                }
                break;
                }
            }
        }
        /**
         *	Returns all vertex indices that are on an open edge.
         */
        public static HashSet <int> GetNonManifoldIndices(z_Mesh mesh)
        {
            List <z_CommonEdge>    duplicates;
            HashSet <z_CommonEdge> edges = GetEdgesDistinct(mesh, out duplicates);

            edges.ExceptWith(duplicates);
            HashSet <int> hash = z_CommonEdge.ToHashSet(edges);

            return(hash);
        }
        public static List <z_CommonEdge> GetEdges(z_Mesh m, Dictionary <int, int> lookup)
        {
            int[] tris  = m.GetTriangles();
            int   count = tris.Length;

            List <z_CommonEdge> edges = new List <z_CommonEdge>(count);

            for (int i = 0; i < count; i += 3)
            {
                edges.Add(new z_CommonEdge(tris[i + 0], tris[i + 1], lookup[tris[i + 0]], lookup[tris[i + 1]]));
                edges.Add(new z_CommonEdge(tris[i + 1], tris[i + 2], lookup[tris[i + 1]], lookup[tris[i + 2]]));
                edges.Add(new z_CommonEdge(tris[i + 2], tris[i + 0], lookup[tris[i + 2]], lookup[tris[i + 0]]));
            }

            return(edges);
        }
Ejemplo n.º 11
0
        public void SetMesh(z_Mesh m)
        {
#if DO_RENDER_OVERLAY_MESH
            wireframeMesh = z_MeshUtility.CreateOverlayMesh(m);

            wireframeMesh.hideFlags = HideFlags.HideAndDontSave;

            w_colors = new Color[wireframeMesh.vertexCount];

            if (drawVertexBillboards)
            {
                common               = z_MeshUtility.GetCommonVertices(m);
                vertexMesh           = z_MeshUtility.CreateVertexBillboardMesh(m, common);
                vertexMesh.hideFlags = HideFlags.HideAndDontSave;
                v_colors             = new Color[vertexMesh.vertexCount];
            }
#endif
        }
Ejemplo n.º 12
0
        protected void CacheBrushNormals(z_BrushTarget target)
        {
            brushNormalOnBeginApply.Clear();

            for (int i = 0; i < target.raycastHits.Count; i++)
            {
                brushNormalOnBeginApply.Add(target.raycastHits[i].normal);
            }

            z_Mesh mesh = target.editableObject.editMesh;

            cached_normals = new Vector3[mesh.vertexCount];

            if (mesh.normals != null && mesh.normals.Length == mesh.vertexCount)
            {
                System.Array.Copy(mesh.normals, 0, cached_normals, 0, mesh.vertexCount);
            }
        }
Ejemplo n.º 13
0
        private void RebuildCaches(z_EditableObject target, z_BrushSettings settings)
        {
            z_Mesh m           = target.editMesh;
            int    vertexCount = m.vertexCount;

            if (m.colors != null && m.colors.Length == vertexCount)
            {
                colors_cache = z_Util.Duplicate(m.colors);
            }
            else
            {
                colors_cache = z_Util.Fill <Color32>(x => { return(Color.white); }, vertexCount);
            }

            colors        = new Color32[vertexCount];
            target_colors = new Color32[vertexCount];
            erase_colors  = new Color32[vertexCount];

            RebuildColorTargets(brushColor, settings.strength);
        }
Ejemplo n.º 14
0
        private void RebuildCaches(z_Mesh m, float strength)
        {
            vertexCount    = m.vertexCount;
            triangleLookup = z_MeshUtility.GetAdjacentTriangles(m);

            if (meshAttributes == null)
            {
                // clear caches
                splat_cache   = null;
                splat_current = null;
                splat_target  = null;
                splat_erase   = null;
                return;
            }

            splat_cache   = new z_SplatSet(m, meshAttributes);
            splat_current = new z_SplatSet(splat_cache);
            splat_target  = new z_SplatSet(vertexCount, meshAttributes);
            splat_erase   = new z_SplatSet(vertexCount, meshAttributes);
        }
        /**
         *	Builds a lookup table for each vertex index and it's average normal with other vertices sharing a position.
         */
        public static Dictionary <int, Vector3> GetSmoothNormalLookup(z_Mesh mesh)
        {
            Vector3[] n = mesh.normals;
            Dictionary <int, Vector3> normals = new Dictionary <int, Vector3>();

            if (n == null || n.Length != mesh.vertexCount)
            {
                return(normals);
            }

            List <List <int> > groups = GetCommonVertices(mesh);

            Vector3 avg = Vector3.zero;
            Vector3 a   = Vector3.zero;

            foreach (var group in groups)
            {
                avg.x = 0f;
                avg.y = 0f;
                avg.z = 0f;

                foreach (int i in group)
                {
                    a = n[i];

                    avg.x += a.x;
                    avg.y += a.y;
                    avg.z += a.z;
                }

                avg /= (float)group.Count();

                foreach (int i in group)
                {
                    normals.Add(i, avg);
                }
            }

            return(normals);
        }
Ejemplo n.º 16
0
        /**
         *	Returns an array of weights where each index is the max of all raycast hits.
         */
        public float[] GetAllWeights(bool rebuildCache = false)
        {
            z_Mesh mesh        = editableObject.editMesh;
            int    vertexCount = mesh.vertexCount;

            if (mesh == null)
            {
                return(null);
            }

            if (!rebuildCache)
            {
                return(_weights);
            }

            for (int i = 0; i < vertexCount; i++)
            {
                _weights[i] = 0f;
            }

            for (int i = 0; i < raycastHits.Count; i++)
            {
                if (raycastHits[i].weights != null)
                {
                    float[] w = raycastHits[i].weights;

                    for (int n = 0; n < vertexCount; n++)
                    {
                        if (w[n] > _weights[n])
                        {
                            _weights[n] = w[n];
                        }
                    }
                }
            }

            return(_weights);
        }
        /**
         *	Recalculates a mesh's normals while retaining smoothed common vertices.
         */
        public static void RecalculateNormals(z_Mesh m)
        {
            List <List <int> > smooth = GetSmoothSeamLookup(m);

            m.RecalculateNormals();

            if (smooth != null)
            {
                Vector3[] normals = m.normals;

                foreach (List <int> l in smooth)
                {
                    Vector3 n = z_Math.Average(normals, l);

                    foreach (int i in l)
                    {
                        normals[i] = n;
                    }
                }

                m.normals = normals;
            }
        }
//commented out code was ommited here

        /**
         *	Builds a list<group> with each vertex index and a list of all other vertices sharing a position.
         *  key: Index in vertices array
         *	value: List of other indices in positions array that share a point with this index.
         */
        public static List <List <int> > GetCommonVertices(z_Mesh mesh)
        {
            List <List <int> > indices;

            if (commonVerticesCache.TryGetValue(mesh, out indices))
            {
                // int min = mesh.vertexCount, max = 0;

                // for(int x = 0; x < indices.Count; x++)
                // {
                //  for(int y = 0; y < indices[x].Count; y++)
                //  {
                //      int index = indices[x][y];
                //      if(index < min) min = index;
                //      if(index > max) max = index;
                //  }
                // }

                // if(max - min + 1 == mesh.vertexCount)
                return(indices);
            }

            Vector3[] v = mesh.vertices;
            int[]     t = z_Util.Fill <int>((x) => { return(x); }, v.Length);
            indices = t.ToLookup(x => (z_RndVec3)v[x]).Select(y => y.ToList()).ToList();

            if (!commonVerticesCache.ContainsKey(mesh))
            {
                commonVerticesCache.Add(mesh, indices);
            }
            else
            {
                commonVerticesCache[mesh] = indices;
            }

            return(indices);
        }
Ejemplo n.º 19
0
        /**
         *	Calculates the per-vertex weight for each raycast hit and fills in brush target weights.
         */
        public static void CalculateWeightedVertices(z_BrushTarget target, z_BrushSettings settings)
        {
            if (target.editableObject == null)
            {
                return;
            }

            bool  uniformScale = z_Math.VectorIsUniform(target.transform.lossyScale);
            float scale        = uniformScale ? 1f / target.transform.lossyScale.x : 1f;

            z_Mesh mesh = target.editableObject.editMesh;

            List <List <int> > common = z_MeshUtility.GetCommonVertices(mesh);

            Transform transform   = target.transform;
            int       vertexCount = mesh.vertexCount;

            Vector3[] vertices = mesh.vertices;

            if (!uniformScale)
            {
                Vector3[] world = new Vector3[vertexCount];
                for (int i = 0; i < vertexCount; i++)
                {
                    world[i] = transform.TransformPoint(vertices[i]);
                }
                vertices = world;
            }

            AnimationCurve curve = settings.falloffCurve;
            float          radius = settings.radius * scale, falloff_mag = Mathf.Max((radius - radius * settings.falloff), 0.00001f);

            Vector3      hitPosition = Vector3.zero;
            z_RaycastHit hit;

            for (int n = 0; n < target.raycastHits.Count; n++)
            {
                hit = target.raycastHits[n];
                hit.SetVertexCount(vertexCount);

                hitPosition = uniformScale ? hit.position : transform.TransformPoint(hit.position);
                int c = common.Count;

                for (int i = 0; i < c; i++)
                {
                    int     commonArrayCount = common[i].Count;
                    Vector3 a = hitPosition, b = vertices[common[i][0]];
                    float   x = a.x - b.x, y = a.y - b.y, z = a.z - b.z;
                    float   dist = Mathf.Sqrt(x * x + y * y + z * z);

                    if (dist > radius)
                    {
                        for (int j = 0; j < commonArrayCount; j++)
                        {
                            hit.weights[common[i][j]] = 0f;
                        }
                    }
                    else
                    {
                        float weight = Mathf.Clamp(curve.Evaluate(1f - Mathf.Clamp((radius - dist) / falloff_mag, 0f, 1f)), 0f, 1f);

                        for (int j = 0; j < commonArrayCount; j++)
                        {
                            hit.weights[common[i][j]] = weight;
                        }
                    }
                }
            }

            target.GetAllWeights(true);
        }
Ejemplo n.º 20
0
        public override void OnBrushApply(z_BrushTarget target, z_BrushSettings settings)
        {
            int rayCount = target.raycastHits.Count;

            Vector3[] normals = (direction == z_Direction.BrushNormal) ? target.editableObject.editMesh.normals : null;

            Vector3 v, t, avg, dirVec = direction.ToVector3();
            Plane   plane       = new Plane(Vector3.up, Vector3.zero);
            z_Mesh  mesh        = target.editableObject.editMesh;
            int     vertexCount = mesh.vertexCount;

            // don't use target.GetAllWeights because brush normal needs
            // to know which ray to use for normal
            for (int ri = 0; ri < rayCount; ri++)
            {
                z_RaycastHit hit = target.raycastHits[ri];

                if (hit.weights == null || hit.weights.Length < vertexCount)
                {
                    continue;
                }

                for (int i = 0; i < commonVertexCount; i++)
                {
                    int index = commonVertices[i][0];

                    if (hit.weights[index] < .0001f || (ignoreNonManifoldIndices && nonManifoldIndices.Contains(index)))
                    {
                        continue;
                    }

                    v = vertices[index];

                    if (direction == z_Direction.VertexNormal)
                    {
                        avg = z_Math.Average(vertices, neighborLookup[index]);
                    }
                    else
                    {
                        avg = z_Math.WeightedAverage(vertices, neighborLookup[index], hit.weights);

                        if (direction == z_Direction.BrushNormal)
                        {
                            if (brushNormalIsSticky)
                            {
                                dirVec = brushNormalOnBeginApply[ri];
                            }
                            else
                            {
                                dirVec = z_Math.WeightedAverage(normals, neighborLookup[index], hit.weights).normalized;
                            }
                        }

                        plane.SetNormalAndPosition(dirVec, avg);
                        avg = v - dirVec * plane.GetDistanceToPoint(v);
                    }

                    t = Vector3.Lerp(v, avg, hit.weights[index]);
                    List <int> indices = commonVertices[i];

                    Vector3 pos = v + (t - v) * settings.strength * SMOOTH_STRENGTH_MODIFIER;

                    for (int n = 0; n < indices.Count; n++)
                    {
                        vertices[indices[n]] = pos;
                    }
                }
            }

            mesh.vertices = vertices;

            if (tempComponent != null)
            {
                tempComponent.OnVerticesMoved(mesh);
            }

            base.OnBrushApply(target, settings);
        }
        /**
         *	Internal constructor.
         *	\sa Create
         */
        private z_EditableObject(GameObject go)
        {
            this.gameObject    = go;
            isProBuilderObject = z_ReflectionUtil.IsProBuilderObject(go);

            Mesh         advsMesh     = null;
            MeshRenderer meshRenderer = this.gameObject.GetComponent <MeshRenderer>();

            meshFilter = this.gameObject.GetComponent <MeshFilter>();
            SkinnedMeshRenderer skinFilter = this.gameObject.GetComponent <SkinnedMeshRenderer>();

            usingVertexStreams = false;

            this.originalMesh = meshFilter.sharedMesh;

            if (originalMesh == null && skinFilter != null)
            {
                this.originalMesh = skinFilter.sharedMesh;
            }

            if (z_Pref.GetBool(z_Pref.additionalVertexStreams, false) && !isProBuilderObject)
            {
                if (meshRenderer != null || skinFilter != null)
                {
                    additionalVertexStreams = gameObject.GetComponent <z_AdditionalVertexStreams>();

                    if (additionalVertexStreams == null)
                    {
                        additionalVertexStreams = gameObject.AddComponent <z_AdditionalVertexStreams>();
                    }

                    advsMesh = additionalVertexStreams.m_AdditionalVertexStreamMesh;

                    if (advsMesh == null)
                    {
                        advsMesh          = new Mesh();
                        advsMesh.vertices = originalMesh.vertices;
                        advsMesh.name     = string.Format("{0}({1})", originalMesh.name, additionalVertexStreams.GetInstanceID());
                        hadVertexStreams  = false;
                    }

                    usingVertexStreams = true;
                }
            }

            if (!usingVertexStreams)
            {
                // if editing a non-scene instance mesh, make it an instance
                // (unity primitives are a special case - they *are* scene instances but they also aren't)
                string guid = INSTANCE_MESH_GUID;
                this.source = z_EditorUtility.GetMeshGUID(originalMesh, ref guid);

                if (source != z_ModelSource.Scene || UnityPrimitiveMeshNames.Contains(originalMesh.name))
                {
                    this._graphicsMesh = z_MeshUtility.DeepCopy(meshFilter.sharedMesh);
                }
                else
                {
                    this._graphicsMesh = originalMesh;
                }
            }
            else
            {
                this._graphicsMesh = advsMesh;
                this.source        = z_ModelSource.AdditionalVertexStreams;
            }

            // if it's a probuilder object rebuild the mesh without optimization
            if (isProBuilderObject)
            {
                object pb = probuilderMesh = go.GetComponent("pb_Object");

                if (pb != null)
                {
                    z_ReflectionUtil.ProBuilder_ToMesh(pb);
                    z_ReflectionUtil.ProBuilder_Refresh(pb, (ushort)0xFF);
                }

                if (setVerticesMethod == null)
                {
                    setVerticesMethod = pb.GetType().GetMethod(
                        "SetVertices",
                        BindingFlags.Public | BindingFlags.Instance,
                        null,
                        SetVerticesArguments,
                        null);
                }

                if (setUvsMethod == null)
                {
                    setUvsMethod = pb.GetType().GetMethod(
                        "SetUVs",
                        BindingFlags.Public | BindingFlags.Instance,
                        null,
                        SetUVsArguments,
                        null);
                }

                if (setTangentsMethod == null)
                {
                    setTangentsMethod = pb.GetType().GetMethod(
                        "SetTangents",
                        BindingFlags.Public | BindingFlags.Instance,
                        null,
                        new Type[] { typeof(Vector4[]) },
                        null);
                }

                if (setColorsMethod == null)
                {
                    setColorsMethod = pb.GetType().GetMethod(
                        "SetColors",
                        BindingFlags.Public | BindingFlags.Instance,
                        null,
                        new Type[] { typeof(Color[]) },
                        null);
                }
            }

            _editMesh = GetCompositeMesh();

            if (!isProBuilderObject)
            {
                SetMesh(graphicsMesh);
            }
        }
Ejemplo n.º 22
0
        // Draw scene gizmos.  Base implementation draws the brush preview.
        public virtual void DrawGizmos(z_BrushTarget target, z_BrushSettings settings)
        {
            foreach (z_RaycastHit hit in target.raycastHits)
            {
                z_Handles.DrawBrush(hit.position, hit.normal, settings, target.localToWorldMatrix, innerColor, outerColor);
            }

#if Z_DEBUG
#if Z_DRAW_WEIGHTS || DRAW_PER_VERTEX_ATTRIBUTES
            float[] w = target.GetAllWeights();
#endif

#if Z_DRAW_WEIGHTS
            Mesh       m       = target.mesh;
            Vector3[]  v       = m.vertices;
            GUIContent content = new GUIContent("", "");

            Handles.BeginGUI();
            for (int i = 0; i < v.Length; i++)
            {
                if (w[i] < .0001f)
                {
                    continue;
                }

                content.text = w[i].ToString("F2");
                GUI.Label(HandleUtility.WorldPointToSizedRect(target.transform.TransformPoint(v[i]), content, EditorStyles.label), content);
            }
            Handles.EndGUI();
#endif

#if DRAW_PER_VERTEX_ATTRIBUTES
            z_Mesh         m        = target.editableObject.editMesh;
            Color32[]      colors   = m.colors;
            Vector4[]      tangents = m.tangents;
            List <Vector4> uv0      = m.uv0;
            List <Vector4> uv1      = m.uv1;
            List <Vector4> uv2      = m.uv2;
            List <Vector4> uv3      = m.uv3;

            int vertexCount = m.vertexCount;

            Vector3[]  verts = m.vertices;
            GUIContent gc    = new GUIContent("");

            List <List <int> >        common = z_MeshUtility.GetCommonVertices(m);
            System.Text.StringBuilder sb     = new System.Text.StringBuilder();

            Handles.BeginGUI();
            foreach (List <int> l in common)
            {
                if (w[l[0]] < .001)
                {
                    continue;
                }

                Vector3 v = target.transform.TransformPoint(verts[l[0]]);

                if (colors != null)
                {
                    sb.AppendLine("color: " + colors[l[0]].ToString("F2"));
                }
                if (tangents != null)
                {
                    sb.AppendLine("tangent: " + tangents[l[0]].ToString("F2"));
                }
                if (uv0 != null && uv0.Count == vertexCount)
                {
                    sb.AppendLine("uv0: " + uv0[l[0]].ToString("F2"));
                }
                if (uv1 != null && uv1.Count == vertexCount)
                {
                    sb.AppendLine("uv1: " + uv1[l[0]].ToString("F2"));
                }
                if (uv2 != null && uv2.Count == vertexCount)
                {
                    sb.AppendLine("uv2: " + uv2[l[0]].ToString("F2"));
                }
                if (uv3 != null && uv3.Count == vertexCount)
                {
                    sb.AppendLine("uv3: " + uv3[l[0]].ToString("F2"));
                }

                gc.text = sb.ToString();
                sb.Remove(0, sb.Length);                        // @todo .NET 4.0
                GUI.Label(HandleUtility.WorldPointToSizedRect(v, gc, EditorStyles.label), gc);
            }
            Handles.EndGUI();
#endif
#endif
        }
Ejemplo n.º 23
0
        public override void OnBrushApply(z_BrushTarget target, z_BrushSettings settings)
        {
            int rayCount = target.raycastHits.Count;

            if (rayCount < 1)
            {
                return;
            }

            Vector3 n = direction.ToVector3();

            float scale = 1f / (Vector3.Scale(target.transform.lossyScale, n).magnitude);
            float sign  = Event.current.shift ? -1f : 1f;

            float maxMoveDistance = settings.strength * STRENGTH_MODIFIER * sign * brushStrength;
            int   vertexCount     = target.editableObject.vertexCount;

            z_Mesh mesh = target.editableObject.editMesh;

            for (int ri = 0; ri < rayCount; ri++)
            {
                z_RaycastHit hit = target.raycastHits[ri];

                if (hit.weights == null || hit.weights.Length < vertexCount)
                {
                    continue;
                }

                if (direction == z_Direction.BrushNormal)
                {
                    if (brushNormalIsSticky)
                    {
                        n = brushNormalOnBeginApply[ri];
                    }
                    else
                    {
                        n = target.raycastHits[ri].normal;
                    }

                    scale = 1f / (Vector3.Scale(target.transform.lossyScale, n).magnitude);
                }

                for (int i = 0; i < commonVertexCount; i++)
                {
                    int index = commonVertices[i][0];

                    if (hit.weights[index] < .0001f || (ignoreNonManifoldIndices && nonManifoldIndices.Contains(index)))
                    {
                        continue;
                    }

                    if (direction == z_Direction.VertexNormal)
                    {
                        n     = normalLookup[index];
                        scale = 1f / (Vector3.Scale(target.transform.lossyScale, n).magnitude);
                    }

                    Vector3 pos = vertices[index] + n * (hit.weights[index] * maxMoveDistance * scale);

                    List <int> indices = commonVertices[i];

                    for (int it = 0; it < indices.Count; it++)
                    {
                        vertices[indices[it]] = pos;
                    }
                }
            }

            mesh.vertices = vertices;

            // different than setting weights on temp component,
            // which is what z_BrushModeMesh.OnBrushApply does.
            if (tempComponent != null)
            {
                tempComponent.OnVerticesMoved(mesh);
            }

            base.OnBrushApply(target, settings);
        }
Ejemplo n.º 24
0
        public override void DrawGizmos(z_BrushTarget target, z_BrushSettings settings)
        {
            z_Mesh mesh = target.editableObject.editMesh;

            if (z_Util.IsValid(target) && paintMode == z_PaintMode.Fill)
            {
                Vector3[] vertices = mesh.vertices;
                int[]     indices  = mesh.GetTriangles();

                z_Handles.PushMatrix();
                z_Handles.PushHandleColor();

                Handles.matrix = target.transform.localToWorldMatrix;

                int index = 0;

                foreach (z_RaycastHit hit in target.raycastHits)
                {
                    if (hit.triangle > -1)
                    {
                        Handles.color = Color.green;

                        index = hit.triangle * 3;

                        Handles.DrawLine(vertices[indices[index + 0]] + hit.normal * .1f, vertices[indices[index + 1]] + hit.normal * .1f);
                        Handles.DrawLine(vertices[indices[index + 1]] + hit.normal * .1f, vertices[indices[index + 2]] + hit.normal * .1f);
                        Handles.DrawLine(vertices[indices[index + 2]] + hit.normal * .1f, vertices[indices[index + 0]] + hit.normal * .1f);

                        _fillModeEdges[0].x = indices[index + 0];
                        _fillModeEdges[0].y = indices[index + 1];

                        _fillModeEdges[1].x = indices[index + 1];
                        _fillModeEdges[1].y = indices[index + 2];

                        _fillModeEdges[2].x = indices[index + 2];
                        _fillModeEdges[2].y = indices[index + 0];

                        for (int i = 0; i < 3; i++)
                        {
                            if (triangleLookup.TryGetValue(_fillModeEdges[i], out _fillModeAdjacentTris))
                            {
                                for (int n = 0; n < _fillModeAdjacentTris.Count; n++)
                                {
                                    index = _fillModeAdjacentTris[n] * 3;

                                    Handles.DrawLine(vertices[indices[index + 0]] + hit.normal * .1f, vertices[indices[index + 1]] + hit.normal * .1f);
                                    Handles.DrawLine(vertices[indices[index + 1]] + hit.normal * .1f, vertices[indices[index + 2]] + hit.normal * .1f);
                                    Handles.DrawLine(vertices[indices[index + 2]] + hit.normal * .1f, vertices[indices[index + 0]] + hit.normal * .1f);
                                }
                            }
                        }
                    }
                }

                z_Handles.PopHandleColor();
                z_Handles.PopMatrix();
            }
            else
            {
                base.DrawGizmos(target, settings);
            }
        }
        public static List <z_CommonEdge> GetEdges(z_Mesh m)
        {
            Dictionary <int, int> lookup = GetCommonVertices(m).GetCommonLookup <int>();

            return(GetEdges(m, lookup));
        }
        public static HashSet <z_CommonEdge> GetEdgesDistinct(z_Mesh mesh, out List <z_CommonEdge> duplicates)
        {
            Dictionary <int, int> lookup = GetCommonVertices(mesh).GetCommonLookup <int>();

            return(GetEdgesDistinct(mesh, lookup, out duplicates));
        }
Ejemplo n.º 27
0
        // Called whenever the brush is moved.  Note that @target may have a null editableObject.
        public override void OnBrushMove(z_BrushTarget target, z_BrushSettings settings)
        {
            base.OnBrushMove(target, settings);

            if (!z_Util.IsValid(target))
            {
                return;
            }

            bool shift = Event.current.shift && Event.current.type != EventType.ScrollWheel;

            z_Mesh mesh        = target.editableObject.editMesh;
            int    vertexCount = mesh.vertexCount;

            float[] weights = target.GetAllWeights();

            switch (paintMode)
            {
            case z_PaintMode.Flood:
                for (int i = 0; i < vertexCount; i++)
                {
                    colors[i] = target_colors[i];
                }
                break;

            case z_PaintMode.Fill:

                System.Array.Copy(colors_cache, colors, vertexCount);
                int[] indices = target.editableObject.editMesh.GetTriangles();
                int   index   = 0;

                foreach (z_RaycastHit hit in target.raycastHits)
                {
                    if (hit.triangle > -1)
                    {
                        index = hit.triangle * 3;

                        colors[indices[index + 0]] = shift ? WHITE : target_colors[indices[index + 0]];
                        colors[indices[index + 1]] = shift ? WHITE : target_colors[indices[index + 1]];
                        colors[indices[index + 2]] = shift ? WHITE : target_colors[indices[index + 2]];

                        _fillModeEdges[0].x = indices[index + 0];
                        _fillModeEdges[0].y = indices[index + 1];

                        _fillModeEdges[1].x = indices[index + 1];
                        _fillModeEdges[1].y = indices[index + 2];

                        _fillModeEdges[2].x = indices[index + 2];
                        _fillModeEdges[2].y = indices[index + 0];

                        for (int i = 0; i < 3; i++)
                        {
                            if (triangleLookup.TryGetValue(_fillModeEdges[i], out _fillModeAdjacentTris))
                            {
                                for (int n = 0; n < _fillModeAdjacentTris.Count; n++)
                                {
                                    index = _fillModeAdjacentTris[n] * 3;

                                    colors[indices[index + 0]] = shift ? WHITE : target_colors[indices[index + 0]];
                                    colors[indices[index + 1]] = shift ? WHITE : target_colors[indices[index + 1]];
                                    colors[indices[index + 2]] = shift ? WHITE : target_colors[indices[index + 2]];
                                }
                            }
                        }
                    }
                }

                break;

            default:
            {
                for (int i = 0; i < vertexCount; i++)
                {
                    colors[i] = z_Util.Lerp(colors_cache[i],
                                            shift ? erase_colors[i] : target_colors[i],
                                            mask,
                                            weights[i]);
                }
                break;
            }
            }

            target.editableObject.editMesh.colors = colors;
            target.editableObject.ApplyMeshAttributes(z_MeshChannel.Color);
        }
        /**
         *	Returns a dictionary where each z_Edge is mapped to a list of triangle indices that share that edge.
         *	To translate triangle list to vertex indices, multiply by 3 and take those indices (ex, triangles[index+{0,1,2}])
         */
        public static Dictionary <z_Edge, List <int> > GetAdjacentTriangles(z_Mesh m)
        {
            int len = m.GetTriangles().Length;

            if (len % 3 != 0 || len / 3 == m.vertexCount)
            {
                return(new Dictionary <z_Edge, List <int> >());
            }

            Dictionary <z_Edge, List <int> > lookup = null;

            // @todo - should add some checks to make sure triangle structure hasn't changed
            if (adjacentTrianglesCache.TryGetValue(m, out lookup))
            {
                return(lookup);
            }

            int smc = m.subMeshCount;

            lookup = new Dictionary <z_Edge, List <int> >();
            List <int> connections;

            for (int n = 0; n < smc; n++)
            {
                int[] tris = m.GetIndices(n);

                for (int i = 0; i < tris.Length; i += 3)
                {
                    int index = i / 3;

                    z_Edge a = new z_Edge(tris[i], tris[i + 1]);
                    z_Edge b = new z_Edge(tris[i + 1], tris[i + 2]);
                    z_Edge c = new z_Edge(tris[i + 2], tris[i]);

                    if (lookup.TryGetValue(a, out connections))
                    {
                        connections.Add(index);
                    }
                    else
                    {
                        lookup.Add(a, new List <int>()
                        {
                            index
                        });
                    }

                    if (lookup.TryGetValue(b, out connections))
                    {
                        connections.Add(index);
                    }
                    else
                    {
                        lookup.Add(b, new List <int>()
                        {
                            index
                        });
                    }

                    if (lookup.TryGetValue(c, out connections))
                    {
                        connections.Add(index);
                    }
                    else
                    {
                        lookup.Add(c, new List <int>()
                        {
                            index
                        });
                    }
                }
            }

            adjacentTrianglesCache.Add(m, lookup);

            return(lookup);
        }
Ejemplo n.º 29
0
 /**
  *	Let the temp mesh know that vertex positions have changed.
  */
 public virtual void OnVerticesMoved(z_Mesh mesh)
 {
 }
        public static Mesh CreateVertexBillboardMesh(z_Mesh src, List <List <int> > common)
        {
            int vertexCount = System.Math.Min(ushort.MaxValue / 4, common.Count());

            Vector3[] positions = new Vector3[vertexCount * 4];
            Vector2[] uv0       = new Vector2[vertexCount * 4];
            Vector2[] uv2       = new Vector2[vertexCount * 4];
            Color[]   colors    = new Color[vertexCount * 4];
            int[]     tris      = new int[vertexCount * 6];

            int n = 0;
            int t = 0;

            Vector3 up    = Vector3.up;         // * .1f;
            Vector3 right = Vector3.right;      // * .1f;

            Vector3[] v = src.vertices;

            for (int i = 0; i < vertexCount; i++)
            {
                int tri = common[i][0];

                positions[t + 0] = v[tri];
                positions[t + 1] = v[tri];
                positions[t + 2] = v[tri];
                positions[t + 3] = v[tri];

                uv0[t + 0] = Vector3.zero;
                uv0[t + 1] = Vector3.right;
                uv0[t + 2] = Vector3.up;
                uv0[t + 3] = Vector3.one;

                uv2[t + 0] = -up - right;
                uv2[t + 1] = -up + right;
                uv2[t + 2] = up - right;
                uv2[t + 3] = up + right;

                tris[n + 0] = t + 0;
                tris[n + 1] = t + 1;
                tris[n + 2] = t + 2;
                tris[n + 3] = t + 1;
                tris[n + 4] = t + 3;
                tris[n + 5] = t + 2;

                colors[t + 0] = clear;
                colors[t + 1] = clear;
                colors[t + 2] = clear;
                colors[t + 3] = clear;

                t += 4;
                n += 6;
            }

            Mesh m = new Mesh();

            m.vertices  = positions;
            m.uv        = uv0;
            m.uv2       = uv2;
            m.colors    = colors;
            m.triangles = tris;

            return(m);
        }