//Creates a vertex strip bridging two other strips, interpolated between by a certain amount based on progress
 public VertexStrip(VertexStrip bottomStrip, VertexStrip topStrip, float progress, float smoothness)
 {
     if (bottomStrip.verts.Count == topStrip.verts.Count)
     {
         for (int i = 0; i < bottomStrip.verts.Count; i++)
         {
             float smoothPower = Mathf.Pow(progress, 2.0f - progress * 2.0f);
             verts.Add(
                 Vector3.Lerp(Vector3.Lerp(bottomStrip.verts[i], topStrip.verts[i], progress),
                              new Vector3(Mathf.Lerp(bottomStrip.verts[i].x, topStrip.verts[i].x, smoothPower),
                                          Mathf.Lerp(bottomStrip.verts[i].y, topStrip.verts[i].y, progress),
                                          Mathf.Lerp(bottomStrip.verts[i].z, topStrip.verts[i].z, smoothPower)),
                              smoothness));
         }
     }
     else
     {
         Debug.LogWarning("Cannot create average vertex strip because reference strips have different vertex counts.");
     }
 }
Exemplo n.º 2
0
        //Actual mesh generation with the indicated properties and generation container; do not call this directly
        static void GenerateMesh(ref GeneratorInstance gi, GeneratorProps genProps)
        {
            //Important vertex strips at ends of sections
            VertexStrip firstBottomStrip = new VertexStrip();
            VertexStrip lastBottomStrip  = new VertexStrip();
            VertexStrip firstTopStrip    = new VertexStrip();
            VertexStrip lastTopStrip     = new VertexStrip();

            int bottomSegments = Mathf.Max(1, genProps.bottomSegments);
            int topSegments    = Mathf.Max(1, genProps.topSegments);

            //Bottom section verts
            for (int i = 0; i < bottomSegments + 1; i++)
            {
                float stripProgress = (i * 1.0f) / (bottomSegments * 1.0f);

                //Properties for current vertex strip
                VertexStripProps stripProps = new VertexStripProps
                {
                    isTop            = false,
                    flat             = genProps.bottomSegments == 0,
                    cornerDetails    = genProps.cornerDetails,
                    XYDetail         = genProps.XYDetail,
                    YZDetail         = genProps.YZDetail,
                    cornerProgress   = Mathf.Pow(1.0f - Mathf.Pow(stripProgress, genProps.stripDistribution1), genProps.stripDistribution2),
                    corners          = genProps.corners,
                    detailSmoothness = genProps.detailSmoothness
                };

                lastBottomStrip = new VertexStrip(stripProps);
                gi.strips.Add(lastBottomStrip);

                if (i == 0)
                {
                    firstBottomStrip = new VertexStrip(stripProps);
                }
            }

            //Top section verts
            for (int i = 0; i < topSegments + 1; i++)
            {
                float stripProgress = 1.0f - (i * 1.0f) / (topSegments * 1.0f);

                //Properties for current vertex strip
                VertexStripProps stripProps = new VertexStripProps
                {
                    isTop            = true,
                    flat             = genProps.topSegments == 0,
                    cornerDetails    = genProps.cornerDetails,
                    XYDetail         = genProps.XYDetail,
                    YZDetail         = genProps.YZDetail,
                    cornerProgress   = Mathf.Pow(1.0f - Mathf.Pow(stripProgress, genProps.stripDistribution1), genProps.stripDistribution2),
                    corners          = genProps.corners,
                    detailSmoothness = genProps.detailSmoothness
                };

                firstTopStrip = new VertexStrip(stripProps);

                //Add lateral strips between top and bottom sections
                if (genProps.XZDetail > 0 && i == 0)
                {
                    int curStrip = 1;
                    while (curStrip < genProps.XZDetail + 1)
                    {
                        gi.strips.Add(new VertexStrip(lastBottomStrip, firstTopStrip, ((curStrip * 1.0f) / ((genProps.XZDetail + 1) * 1.0f)), genProps.detailSmoothness));
                        curStrip++;
                    }
                }
                else if (i == topSegments)
                {
                    lastTopStrip = new VertexStrip(stripProps);
                }

                gi.strips.Add(firstTopStrip);
            }

            //Top cap
            lastTopStrip.ArrangeSides();
            lastTopStrip.GenerateCap();

            //Bottom cap
            firstBottomStrip.ArrangeSides();
            firstBottomStrip.GenerateCap();

            //Final vert array concatenation
            List <Vector3> tempVerts = new List <Vector3>();

            for (int i = 0; i < gi.strips.Count; i++)
            {
                tempVerts.AddRange(gi.strips[i].verts);
            }

            //Adding vertices of the caps
            int capStartIndex = tempVerts.Count;

            tempVerts.AddRange(lastTopStrip.capVerts);
            tempVerts.AddRange(firstBottomStrip.capVerts);
            gi.finalVerts = tempVerts.ToArray();

            //Triangle assignment
            int stripLength = gi.strips[0].verts.Count;
            int baseVert    = 0;
            int stripLoop   = 0;

            while (stripLoop < gi.strips.Count - 1)
            {
                for (int i = 0; i < stripLength - 1; i++)
                {
                    gi.tris.Add(baseVert + i);
                    gi.tris.Add(baseVert + stripLength + 1 + i);
                    gi.tris.Add(baseVert + i + 1);

                    gi.tris.Add(baseVert + stripLength + i);
                    gi.tris.Add(baseVert + stripLength + 1 + i);
                    gi.tris.Add(baseVert + i);
                }
                baseVert += stripLength;
                stripLoop++;
            }

            //Top cap triangles
            stripLength = lastTopStrip.side1.Count;
            for (int i = 0; i < lastTopStrip.capVerts.Count - stripLength - 1; i++)
            {
                if ((i + 1) % stripLength != 0)
                {
                    gi.tris.Add(capStartIndex + i);
                    gi.tris.Add(capStartIndex + i + 1);
                    gi.tris.Add(capStartIndex + stripLength + i);

                    gi.tris.Add(capStartIndex + stripLength + i);
                    gi.tris.Add(capStartIndex + i + 1);
                    gi.tris.Add(capStartIndex + stripLength + 1 + i);
                }
            }

            //Bottom cap triangles
            capStartIndex += lastTopStrip.capVerts.Count;
            stripLength    = firstBottomStrip.side1.Count;
            for (int i = 0; i < firstBottomStrip.capVerts.Count - stripLength - 1; i++)
            {
                if ((i + 1) % stripLength != 0)
                {
                    gi.tris.Add(capStartIndex + i + 1);
                    gi.tris.Add(capStartIndex + i);
                    gi.tris.Add(capStartIndex + stripLength + i);

                    gi.tris.Add(capStartIndex + i + 1);
                    gi.tris.Add(capStartIndex + stripLength + i);
                    gi.tris.Add(capStartIndex + stripLength + 1 + i);
                }
            }

            //Hook Deformation
            if (genProps.hooks.Length > 0)
            {
                for (int i = 0; i < genProps.hooks.Length; i++)
                {
                    DeformHook curHook = genProps.hooks[i];
                    if (curHook.enabled)
                    {
                        for (int j = 0; j < gi.finalVerts.Length; j++)
                        {
                            Vector3 curVert      = gi.finalVerts[j];
                            float   deformAmount = Mathf.Pow(Mathf.Max(0.0f, curHook.radius - Vector3.Distance(curVert, curHook.localPos)), curHook.falloff);
                            switch (curHook.hookType)
                            {
                            case DeformHook.HookType.Pull:
                                gi.finalVerts[j] += curHook.localRot * Vector3.forward * deformAmount * curHook.strength;
                                break;

                            case DeformHook.HookType.Twist:
                                Vector3 newVert = curHook.localPos + curHook.localRot * (curVert - curHook.localPos);
                                gi.finalVerts[j] += (newVert - curVert) * deformAmount * curHook.strength;
                                break;

                            case DeformHook.HookType.Expand:
                                gi.finalVerts[j] += curHook.localPos + (curVert - curHook.localPos) * (1.0f + (curHook.strength - 1.0f) * deformAmount) - curVert;
                                break;
                            }
                        }
                    }
                }
            }

            //Set final mesh data
            gi.colMesh           = new Mesh();
            gi.colMesh.vertices  = gi.finalVerts;
            gi.colMesh.triangles = gi.tris.ToArray();
        }