示例#1
0
        public VPaintVertexData GetOrCreate(VPaintObject vc)
        {
            if (vc == null)
            {
                return(null);
            }

            var data = Get(vc);

            if (data != null)
            {
                return(data);
            }

            data = new VPaintVertexData();
            data.vpaintObject = vc;

            var cols = vc.GetDefaultColors();

            data.colors       = new Color[cols.Length];
            data.transparency = new float[cols.Length];

            paintData.Add(data);
            return(data);
        }
示例#2
0
 public void Remove(IVPaintIdentifier vc)
 {
     for (int i = 0; i < paintData.Count; i++)
     {
         VPaintVertexData data = paintData[i];
         if (data.identifier.IsEqualTo(vc))
         {
             paintData.RemoveAt(i);
             i--;
         }
     }
 }
示例#3
0
        public VPaintVertexData Clone()
        {
            VPaintVertexData data = new VPaintVertexData();

            data.colorer      = colorer;
            data.colors       = new Color[colors.Length];
            data.transparency = new float[colors.Length];

            for (int i = 0; i < colors.Length; i++)
            {
                data.colors[i]       = colors[i];
                data.transparency[i] = transparency[i];
            }

            return(data);
        }
示例#4
0
 public VPaintVertexData Get(IVPaintIdentifier vc)
 {
     if (vc == null)
     {
         return(null);
     }
     for (int i = 0; i < paintData.Count; i++)
     {
         VPaintVertexData data = paintData[i];
         if (vc.IsEqualTo(data.identifier))
         {
             return(data);
         }
     }
     return(null);
 }
示例#5
0
        public void Merge(VPaintLayer layer, Color baseColor = new Color())
        {
            foreach (VPaintVertexData data in layer.paintData)
            {
                var rootData = Get(data.identifier);

                Color[] cols  = null;
                float[] trans = null;

                if (rootData != null)
                {
                    cols  = rootData.colors;
                    trans = rootData.transparency;
                }
                else
                {
                    cols = new Color[data.colors.Length];

                    for (int i = 0; i < cols.Length; i++)
                    {
                        cols[i] = baseColor;
                    }

                    trans = new float[data.transparency.Length];

                    rootData              = new VPaintVertexData();
                    rootData.colors       = cols;
                    rootData.transparency = trans;
                    rootData.colorer      = data.colorer;

                    paintData.Add(rootData);
                }

                VPaintUtility.MergeColors(
                    cols, trans,
                    data.colors, data.transparency,
                    layer.blendMode, layer.opacity,
                    layer.maskR, layer.maskG, layer.maskB, layer.maskA
                    );
            }
        }
示例#6
0
        /// <summary>
        /// Blends colors between objects using the radial method.
        /// </summary>
        /// <param name='layers'>
        /// The layers to affect. If acting on a VPaintLayerStack, use VPaintLayerStack.layers.ToArray()
        /// </param>
        /// <param name='blendObjects'>
        /// The objects to blend
        /// </param>
        /// <param name='blendTargets'>
        /// The objects to blend towards
        /// </param>
        /// <param name='direction'>
        /// The direction to apply the sample
        /// </param>
        /// <param name='distance'>
        /// The distance of the sample
        /// </param>
        /// <param name='intensity'>
        /// (Optional) The intensity of the blend operation
        /// </param>
        /// <param name='falloff'>
        /// (Optional) The falloff of the blend opreation
        /// </param>
        /// <param name='offset'>
        /// (Optional) the offset of the blend sample. Use this to avoid blend samples "missing" when the object intersects the target.
        /// </param>
        /// <param name='bounds'>
        /// (Optional) the bounds to constrain this blend operation to
        /// </param>
        public static IEnumerator <VPaintProgress> BlendDirectionalAsync(
            VPaintLayer[] layers,
            VPaintObject[] blendObjects,
            VPaintObject[] blendTargets,
            Vector3 direction,
            float distance,
            float intensity = 1,
            float falloff   = 1,
            Vector3?offset  = null,
            Bounds?bounds   = null
            )
        {
            if (!offset.HasValue)
            {
                offset = Vector3.zero;
            }

            var validTargets = new List <VPaintObject>();

            foreach (var vc in blendTargets)
            {
                if (Application.isPlaying && !vc.isDynamic)
                {
                    throw new VPaintObjectNotDynamicException();
                }
                if (bounds.HasValue)
                {
                    if (!bounds.Value.Intersects(vc.editorCollider.bounds))
                    {
                        continue;
                    }
                }
                validTargets.Add(vc);
            }

            for (int l = 0; l < layers.Length; l++)
            {
                var layer = layers[l];
                for (int i = 0; i < blendObjects.Length; i++)
                {
                    var    vc      = blendObjects[i];
                    string message = "Blending " + vc.name + " on layer " + layer.name;

                    float progressBase  = (float)i / blendObjects.Length;
                    float progressRange = ((float)(i + 1) / blendObjects.Length - progressBase) / 1;

                    Mesh      m        = vc.GetMeshInstance();
                    Vector3[] vertices = m.vertices;

                    var     paintData = layer.GetOrCreate(vc);
                    Color[] colors    = paintData.colors;
                    float[] trans     = paintData.transparency;

                    Transform t = vc.transform;

                    float offsetMagnitude = offset.Value.magnitude;

                    for (int v = 0; v < vertices.Length; v++)
                    {
                        yield return(new VPaintProgress()
                        {
                            message = message,
                            progress = progressBase + (progressRange * (float)v / vertices.Length)
                        });

                        var vert = t.TransformPoint(vertices[v]);

                        if (bounds.HasValue)
                        {
                            if (!bounds.Value.Contains(vert))
                            {
                                continue;
                            }
                        }

                        Vector4 avgCol  = Vector4.zero;
                        float   avgTran = 0;
                        float   fac     = 0;
                        float   count   = 0;

                        foreach (var target in validTargets)
                        {
                            var        mc = target.editorCollider;
                            Ray        r  = new Ray(vert + offset.Value, direction);
                            RaycastHit hit;
                            if (mc.Raycast(r, out hit, distance))
                            {
                                if (bounds.HasValue)
                                {
                                    if (!bounds.Value.Contains(hit.point))
                                    {
                                        continue;
                                    }
                                }
                                Mesh mi = target.GetMeshInstance();
                                if (!mi)
                                {
                                    continue;
                                }
                                int[]            triangles = mi.triangles;
                                VPaintVertexData pd        = layer.GetOrCreate(target);

                                int t1 = triangles[(hit.triangleIndex * 3) + 0];
                                int t2 = triangles[(hit.triangleIndex * 3) + 1];
                                int t3 = triangles[(hit.triangleIndex * 3) + 2];

                                //Colors
                                Color c1 = pd.colors[t1];
                                Color c2 = pd.colors[t2];
                                Color c3 = pd.colors[t3];

                                float tr1 = pd.transparency[t1];
                                float tr2 = pd.transparency[t2];
                                float tr3 = pd.transparency[t3];

                                Vector3 bc = hit.barycentricCoordinate;

                                Color sampleColor = c1 * bc.x + c2 * bc.y + c3 * bc.z;
                                float sampleTran  = tr1 * bc.x + tr2 * bc.y + tr3 * bc.z;

                                float factor = Mathf.Pow(1 - (hit.distance - offsetMagnitude) / distance, falloff);

                                fac     += factor;
                                avgTran += sampleTran * factor;
                                avgCol  += (Vector4)sampleColor * factor;
                                count++;
                            }
                        }

                        Color col  = (Color)(avgCol / fac);
                        float tran = avgTran / fac;
                        if (fac != 0)
                        {
                            float lerp = intensity * (fac / count);
                            colors[v] = Color.Lerp(colors[v], col, lerp);
                            trans[v]  = Mathf.Lerp(trans[v], tran, lerp);
                        }
                    }
                }
            }
        }