コード例 #1
0
 protected override void UpdateTempComponent(BrushTarget target, BrushSettings settings)
 {
     if (tempComponent != null)
     {
         ((OverlayRenderer)tempComponent).SetWeights(target.GetAllWeights(), settings.strength);
     }
 }
コード例 #2
0
        /// <summary>
        /// Update the temporary component with new weigths and strengh
        /// </summary>
        /// <param name="target">Target object containing the temporary component</param>
        /// <param name="settings">Current brush settings</param>
        protected virtual void UpdateTempComponent(BrushTarget target, BrushSettings settings)
        {
            if (!Util.IsValid(target))
            {
                return;
            }

            tempComponent.SetWeights(target.GetAllWeights(), settings.strength);
        }
コード例 #3
0
        protected override void UpdateTempComponent(BrushTarget target, BrushSettings settings)
        {
            if (!Util.IsValid(target))
            {
                return;
            }

            EditableObjectData data;

            if (m_EditableObjectsData.TryGetValue(target.editableObject, out data))
            {
                if (data.TempComponent != null)
                {
                    ((OverlayRenderer)data.TempComponent).SetWeights(target.GetAllWeights(), settings.strength);
                }
            }
        }
コード例 #4
0
        // Called whenever the brush is moved.  Note that @target may have a null editableObject.
        internal override void OnBrushMove(BrushTarget target, BrushSettings settings)
        {
            base.OnBrushMove(target, settings);

            if (!Util.IsValid(target) || !m_LikelySupportsTextureBlending || meshAttributes.Length == 0)
            {
                return;
            }

            bool invert = settings.isUserHoldingControl;

            float[] weights;

            if (paintMode == PaintMode.Brush)
            {
                weights = target.GetAllWeights();
            }
            else if (paintMode == PaintMode.Flood)
            {
                weights = new float[m_VertexCount];

                for (int i = 0; i < m_VertexCount; i++)
                {
                    weights[i] = 1f;
                }
            }
            else
            {
                weights = new float[m_VertexCount];
                int[] indices      = target.editableObject.editMesh.GetTriangles();
                int   index        = 0;
                float weightTarget = 1f;

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

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

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

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

                        for (int i = 0; i < 3; i++)
                        {
                            if (m_TriangleLookup.TryGetValue(m_FillModeEdges[i], out m_FillModeAdjacentTriangles))
                            {
                                for (int n = 0; n < m_FillModeAdjacentTriangles.Count; n++)
                                {
                                    index = m_FillModeAdjacentTriangles[n] * 3;

                                    weights[indices[index]]     = weightTarget;
                                    weights[indices[index + 1]] = weightTarget;
                                    weights[indices[index + 2]] = weightTarget;
                                }
                            }
                        }
                    }
                }
            }

            int mask = meshAttributes[selectedAttributeIndex].mask;

            splat_current.LerpWeights(splat_cache, invert ? splat_erase : splat_target, mask, weights);
            splat_current.Apply(target.editableObject.editMesh);
            target.editableObject.ApplyMeshAttributes();
        }
コード例 #5
0
        // Called whenever the brush is moved.  Note that @target may have a null editableObject.
        internal override void OnBrushMove(BrushTarget target, BrushSettings settings)
        {
            base.OnBrushMove(target, settings);

            if (!Util.IsValid(target) || !m_EditableObjectsData.ContainsKey(target.editableObject))
            {
                return;
            }

            bool invert = settings.isUserHoldingControl;

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

            float[] weights = target.GetAllWeights();

            var data            = m_EditableObjectsData[target.editableObject];
            var vertexColorInfo = data.MeshVertexColors;

            switch (paintMode)
            {
            case PaintMode.Flood:
                for (int i = 0; i < vertexCount; i++)
                {
                    vertexColorInfo.Colors[i] = invert? s_WhiteColor : vertexColorInfo.TargetColors[i];
                }
                break;

            case PaintMode.Fill:

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

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

                        vertexColorInfo.Colors[indices[index + 0]] = invert ? s_WhiteColor : vertexColorInfo.TargetColors[indices[index + 0]];
                        vertexColorInfo.Colors[indices[index + 1]] = invert ? s_WhiteColor : vertexColorInfo.TargetColors[indices[index + 1]];
                        vertexColorInfo.Colors[indices[index + 2]] = invert ? s_WhiteColor : vertexColorInfo.TargetColors[indices[index + 2]];

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

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

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

                        for (int i = 0; i < 3; i++)
                        {
                            if (data.TriangleLookup.TryGetValue(m_FillModeEdges[i], out m_FillModeAdjacentTriangles))
                            {
                                for (int n = 0; n < m_FillModeAdjacentTriangles.Count; n++)
                                {
                                    index = m_FillModeAdjacentTriangles[n] * 3;

                                    vertexColorInfo.Colors[indices[index + 0]] = invert ? s_WhiteColor : vertexColorInfo.TargetColors[indices[index + 0]];
                                    vertexColorInfo.Colors[indices[index + 1]] = invert ? s_WhiteColor : vertexColorInfo.TargetColors[indices[index + 1]];
                                    vertexColorInfo.Colors[indices[index + 2]] = invert ? s_WhiteColor : vertexColorInfo.TargetColors[indices[index + 2]];
                                }
                            }
                        }
                    }
                }

                break;

            default:
            {
                for (int i = 0; i < vertexCount; i++)
                {
                    vertexColorInfo.Colors[i] = Util.Lerp(vertexColorInfo.OriginalColors[i],
                                                          invert ? vertexColorInfo.EraseColors[i] : vertexColorInfo.TargetColors[i],
                                                          mask,
                                                          weights[i]);
                }

                break;
            }
            }

            target.editableObject.editMesh.colors = vertexColorInfo.Colors;
            target.editableObject.ApplyMeshAttributes(MeshChannel.Color);
        }
コード例 #6
0
        /// <summary>
        /// Draw scene gizmos. Base implementation draws the brush preview.
        /// </summary>
        /// <param name="target">Current target Object</param>
        /// <param name="settings">Current brush settings</param>
        internal virtual void DrawGizmos(BrushTarget target, BrushSettings settings)
        {
            UpdateBrushGizmosColor();
            foreach (PolyRaycastHit hit in target.raycastHits)
            {
                PolyHandles.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
            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 = 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
        }
コード例 #7
0
        // Called whenever the brush is moved.  Note that @target may have a null editableObject.
        internal override void OnBrushMove(BrushTarget target, BrushSettings settings)
        {
            base.OnBrushMove(target, settings);

            if (!Util.IsValid(target) || !m_LikelySupportsTextureBlending || meshAttributes.Length == 0)
            {
                return;
            }

            if (!m_EditableObjectsData.ContainsKey(target.editableObject))
            {
                return;
            }

            var data = m_EditableObjectsData[target.editableObject];

            if (!data.CacheMaterials.Contains(m_MainCacheMaterials[m_CurrentMeshACIndex]))
            {
                return;
            }

            bool invert = settings.isUserHoldingControl;

            float[] weights;

            if (m_PaintMode == PaintMode.Brush)
            {
                weights = target.GetAllWeights();
            }
            else if (m_PaintMode == PaintMode.Flood)
            {
                weights = new float[data.VertexCount];

                for (int i = 0; i < data.VertexCount; i++)
                {
                    weights[i] = 1f;
                }
            }
            else
            {
                weights = new float[data.VertexCount];
                int[] indices      = target.editableObject.editMesh.GetTriangles();
                int   index        = 0;
                float weightTarget = 1f;

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

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

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

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

                        for (int i = 0; i < 3; i++)
                        {
                            if (data.TriangleLookup.TryGetValue(m_FillModeEdges[i], out m_FillModeAdjacentTriangles))
                            {
                                for (int n = 0; n < m_FillModeAdjacentTriangles.Count; n++)
                                {
                                    index = m_FillModeAdjacentTriangles[n] * 3;

                                    weights[indices[index]]     = weightTarget;
                                    weights[indices[index + 1]] = weightTarget;
                                    weights[indices[index + 2]] = weightTarget;
                                }
                            }
                        }
                    }
                }
            }

            int mask = meshAttributes[selectedAttributeIndex].mask;

            if (data.SplatCurrent == null)
            {
                RebuildCaches(data);
            }

            data.SplatCurrent.LerpWeights(data.SplatCache, invert ? data.SplatErase : data.SplatTarget, mask, weights);
            data.SplatCurrent.Apply(target.editableObject.editMesh);
            target.editableObject.ApplyMeshAttributes();
        }
コード例 #8
0
        /// <summary>
        /// Calculates the per-vertex weight for each raycast hit and fills in brush target weights.
        /// </summary>
        /// <param name="target"></param>
        /// <param name="settings"></param>
        /// <param name="tool"></param>
        /// <param name="bMode"></param>
        internal static void CalculateWeightedVertices(BrushTarget target, BrushSettings settings, BrushTool tool = BrushTool.None, BrushMode bMode = null)
        {
            if (target == null || settings == null)
            {
                return;
            }

            if (target.editableObject == null)
            {
                return;
            }

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

            PolyMesh mesh = target.editableObject.visualMesh;

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

            Vector3[] vertices = mesh.vertices;

            if (!uniformScale)
            {
                // As we only increase size only when it's needed, always make sure to
                // use the vertexCount variable in loop statements and not the buffer length.
                if (s_WorldBuffer.Length < vertexCount)
                {
                    System.Array.Resize <Vector3>(ref s_WorldBuffer, vertexCount);
                }

                for (int i = 0; i < vertexCount; i++)
                {
                    s_WorldBuffer[i] = transform.TransformPoint(vertices[i]);
                }
                vertices = s_WorldBuffer;
            }

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

            Vector3        hitPosition = Vector3.zero;
            PolyRaycastHit hit;

            if (tool == BrushTool.Texture && mesh.subMeshCount > 1)
            {
                var   mode           = bMode as BrushModeTexture;
                int[] submeshIndices = mesh.subMeshes[mode.m_CurrentMeshACIndex].indexes;

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

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

                    hitPosition = uniformScale ? hit.position : transform.TransformPoint(hit.position);

                    for (int i = 0; i < submeshIndices.Length; i++)
                    {
                        int   currentIndex = submeshIndices[i];
                        float dist         = (hitPosition - vertices[currentIndex]).magnitude;
                        float delta        = radius - dist;

                        if (delta >= 0)
                        {
                            float weight = Mathf.Clamp(curve.Evaluate(1f - Mathf.Clamp(delta / falloff_mag, 0f, 1f)), 0f, 1f);

                            hit.weights[currentIndex] = weight;
                        }
                    }
                }
            }
            else
            {
                int[][] common = PolyMeshUtility.GetCommonVertices(mesh);

                Vector3 buf = Vector3.zero;

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

                    hitPosition = uniformScale ? hit.position : transform.TransformPoint(hit.position);

                    for (int i = 0; i < common.Length; i++)
                    {
                        int[] commonItem       = common[i];
                        int   commonArrayCount = commonItem.Length;

                        Math.Subtract(vertices[commonItem[0]], hitPosition, ref buf);

                        float sqrDist = buf.sqrMagnitude;

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

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

            target.GetAllWeights(true);
        }
コード例 #9
0
        /// <summary>
        /// Calculates the per-vertex weight for each raycast hit and fills in brush target weights.
        /// </summary>
        /// <param name="target"></param>
        /// <param name="settings"></param>
        /// <param name="tool"></param>
        /// <param name="bMode"></param>
        internal static void CalculateWeightedVertices(BrushTarget target, BrushSettings settings, BrushTool tool = BrushTool.None, BrushMode bMode = null)
        {
            //null checks
            if (target == null || settings == null)
            {
                return;
            }

            if (target.editableObject == null)
            {
                return;
            }

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

            PolyMesh mesh = target.editableObject.visualMesh;

            if (tool == BrushTool.Texture && mesh.subMeshCount > 1)
            {
                var   mode           = bMode as BrushModeTexture;
                int[] submeshIndices = mesh.subMeshes[mode.currentMeshACIndex].indexes;

                //List<List<int>> common = PolyMeshUtility.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;
                PolyRaycastHit hit;

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

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

                    hitPosition = uniformScale ? hit.position : transform.TransformPoint(hit.position);

                    for (int i = 0; i < submeshIndices.Length; i++)
                    {
                        int   currentIndex = submeshIndices[i];
                        float dist         = (hitPosition - vertices[currentIndex]).magnitude;
                        float delta        = radius - dist;

                        if (delta >= 0)
                        {
                            float weight = Mathf.Clamp(curve.Evaluate(1f - Mathf.Clamp(delta / falloff_mag, 0f, 1f)), 0f, 1f);

                            hit.weights[currentIndex] = weight;
                        }
                    }
                }
            }
            else
            {
                List <List <int> > common = PolyMeshUtility.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;
                PolyRaycastHit 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);

                    for (int i = 0; i < common.Count; i++)
                    {
                        int   commonArrayCount = common[i].Count;
                        float sqrDist          = (hitPosition - vertices[common[i][0]]).sqrMagnitude;

                        if (sqrDist > radius * 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 - Mathf.Sqrt(sqrDist)) / falloff_mag, 0f, 1f)), 0f, 1f);

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