//Cube Data
    // Makes a cube
    /// <summary>
    /// Makes a cube with data taken from X,Y,Z coords
    /// </summary>
    /// <returns></returns>
    private Mesh MakeCylinder(int num)
    {
        List <Color> colors = new List <Color>();



        //Set hue min and Max

        float hue = Mathf.Lerp(hueMin, hueMax, (num / (float)iterations));

        Mesh mesh = MeshTools.MakeCylinder(5);

        Vector3[] verts = mesh.vertices;

        for (int i = 0; i < mesh.vertexCount; i++)
        {
            float tempHue = hue + (1 / (float)iterations) * verts[i].y;

            Color color = Color.HSVToRGB(tempHue, 1, 1);

            colors.Add(color);
        }



        mesh.SetColors(colors);

        return(mesh);
    }
예제 #2
0
    /// <summary>
    /// creates a stem, growing from a position
    /// </summary>
    /// <param name="number">how long should the stem be</param>
    /// <param name="meshes">reference to list of meshes</param>
    /// <param name="pos">where to start the stem</param>
    /// <param name="rot">rotation of the stem</param>
    /// <param name="top">whether or not the stem is on top of the creature, used to calculate leaf direction</param>
    void GrowStem(int number, List <CombineInstance> meshes, Vector3 pos, Quaternion rot, bool top)
    {
        CombineInstance inst = new CombineInstance();

        inst.mesh      = MeshTools.MakeCylinder(5);
        inst.transform = Matrix4x4.TRS(pos, rot, new Vector3(.2f, number, .2f));

        meshes.Add(inst);

        rot *= Quaternion.Euler(0, 180, 90);

        if (!top)
        {
            rot *= Quaternion.Euler(180, 0, 0);
        }


        float x = .1f;

        while (x < 1)
        {
            if (x * 2 < 1)
            {
                x = Random.Range(2 * x, 1);
            }
            else
            {
                break;
            }
            pos = inst.transform.MultiplyPoint(Vector3.up * x);
            float scale = 1 + (1 - x) * 3;

            GrowLeaf(1, meshes, pos, rot, scale);
        }
    }
예제 #3
0
    /// <summary>
    /// Pieces together a mesh based on a set position, rotation, and iterations.
    /// </summary>
    /// <param name="num">The number of iterations that have passed already.</param>
    /// <param name="meshes">Stores all the meshes this function constructs.</param>
    /// <param name="pos">The position of the endPoint of the previous stem segment/spawner location.</param>
    /// <param name="rot">The rotation of the previous stem segment/spawner location</param>
    private void Grow(int num, List <CombineInstance> meshes, Vector3 pos, Quaternion rot)
    {
        if (num <= 0)
        {
            return;             //stop recursive function
        }
        //Adjust randomness for scale values:
        Vector3 tempStemScaling = (stemScaling * Random.Range(minRandomScaling, maxRandomScaling)) * objectScaling;
        Vector3 tempLeafScaling = (leafScaling * Random.Range(minRandomScaling, maxRandomScaling)) * objectScaling;

        //Adjust randomness for leaves:
        numberOfLeaves = Random.Range(minLeaves, maxLeaves);

        // Add Stem Mesh:
        CombineInstance stem = new CombineInstance();

        stem.mesh = MeshTools.MakeCylinder(5);
        AddColorToVertices(stem.mesh, num);
        stem.transform = Matrix4x4.TRS(pos, rot, tempStemScaling);
        meshes.Add(stem);

        // Add Leaves Mesh:
        for (int i = 1; i <= numberOfLeaves; i++)
        {
            CombineInstance leaves = new CombineInstance();
            leaves.mesh = MeshTools.MakeCube();
            AddColorToVertices(leaves.mesh, num);
            float      rotAmount = 360 / (numberOfLeaves * i);
            Quaternion leafRot   = rot * Quaternion.Euler(leafOffsetAngleX, leafOffsetAngleY * rotAmount, leafOffsetAngleZ);
            leaves.transform = Matrix4x4.TRS(pos, leafRot, tempLeafScaling);
            meshes.Add(leaves);
        }

        // Count down number of passes:
        num--;

        // Get the position of the end of this section:
        pos = stem.transform.MultiplyPoint(new Vector3(0, 1, 0));

        //Generate random angles based on set angle values:
        float randX = stemAngleX + Random.Range(minRandomAngle, maxRandomAngle);
        float randY = stemAngleY + Random.Range(minRandomAngle, maxRandomAngle);
        float randZ = stemAngleZ + Random.Range(minRandomAngle, maxRandomAngle);

        //Create a Quaternion to change the local transform to the world Vector3.up:
        Quaternion rot1 = Quaternion.FromToRotation(transform.up, Vector3.up);
        //Create a Quaternion using the random angles from earlier:
        Quaternion rot2 = Quaternion.Euler(randX, randY, randZ);

        //Use a slerp to create a Quaternion between rot1 and rot2, leaning more towards randomness in later segments:
        Quaternion finalRot = Quaternion.Slerp(rot1, rot2, (num / (float)iterations));

        //Grow another segment:
        Grow(num, meshes, pos, finalRot);
    }
예제 #4
0
    /// <summary>
    /// Grow is called to create all the mesh data to add to the spawner's mesh filter.
    /// </summary>
    /// <param name="meshes">A collection of meshes to push to the object.</param>
    /// <param name="pos">The x,y,z position of the object.</param>
    /// <param name="rot">The rotation of the object.</param>
    void Grow(List <CombineInstance> meshes, Vector3 pos, Quaternion rot)
    {
        //Set randomized values:
        numberOfArms = Random.Range(minArms, maxArms);
        float tempRandomScaling = Random.Range(minRandomScaling, maxRandomScaling);

        //Set random values to adjust arm width/height:
        float tempRandomArmScaleX = Random.Range(minRandomScaling, maxRandomScaling);
        float tempRandomArmScaleZ = Random.Range(minRandomScaling, maxRandomScaling);

        //Create temporary scaling for center and arms:
        Vector3 tempCenterScale = (centerScale * tempRandomScaling) * objectScaling;
        Vector3 tempArmScale    = (armScale * tempRandomScaling) * objectScaling;

        //Add arm length & width
        tempArmScale.x += Random.Range(minArmWidth, maxArmWidth);
        tempArmScale.z += Random.Range(minArmLength, maxArmLength);

        //Add randomness to arm width/height:
        tempArmScale.x *= tempRandomArmScaleX;
        tempArmScale.z *= tempRandomArmScaleZ;

        //Make center of the sea star:
        CombineInstance center = new CombineInstance();

        center.mesh = MeshTools.MakeCylinder(8);
        AddColorToVertices(center.mesh);

        //Adjust center values:
        Quaternion adjustRot = Quaternion.Euler(0, 15, 0) * rot;
        Vector3    adjustPos = pos;

        adjustPos.y += centerRiseAmount;

        //Set center transform:
        center.transform = Matrix4x4.TRS(adjustPos, adjustRot, tempCenterScale);
        meshes.Add(center);

        //Make arms of sea star:
        for (int i = 0; i < numberOfArms; i++)
        {
            CombineInstance arm = new CombineInstance();
            arm.mesh = MeshTools.MakeTaperCube(taperAmount);
            AddColorToVertices(arm.mesh);
            float rotDegrees = (360 / numberOfArms) * i;
            float rotRadians = rotDegrees * (Mathf.PI / 180.0f);

            //Build out arm in that direction:
            float armX = Mathf.Sin(rotRadians) * 1f;
            float armZ = Mathf.Cos(rotRadians) * 1f;

            Vector3    armPos = pos + new Vector3(armX, 0.5f, armZ);
            Quaternion armRot = Quaternion.Euler(0, rotDegrees, 0) * rot;

            // TODO: adjust arm position by scale


            arm.transform = Matrix4x4.TRS(armPos, armRot, tempArmScale);
            meshes.Add(arm);
        }
    }
예제 #5
0
    /// <summary>
    /// Primary recursive function used to grow segments of the body, and attached stems
    /// </summary>
    /// <param name="firstSegment">special modifier for the 'head' or first segment of the body</param>
    /// <param name="number">number of segments to grow, counts down to 0</param>
    /// <param name="meshes">reference to list of combine instances</param>
    /// <param name="pos">where to spawn the segment</param>
    /// <param name="rot">rotation of the segment</param>
    /// <param name="bodyScale">how much to scale each segment</param>
    /// <param name="switchDirection">used to change direction the segment grows in</param>
    /// <param name="stems">reference to list of combine instances for stems and leaves</param>
    void GrowBody(bool firstSegment, int number, List <CombineInstance> meshes, Vector3 pos, Quaternion rot, float bodyScale, bool switchDirection, List <CombineInstance> stems)
    {
        if (number <= 0)
        {
            return;
        }

        CombineInstance inst = new CombineInstance();

        inst.mesh      = MeshTools.MakeCylinder(5);
        inst.transform = Matrix4x4.TRS(pos, rot, new Vector3(bodyWidth, bodyScale, bodyWidth) * scale);

        meshes.Add(inst);


        //scale

        //rotation
        ;
        Vector3 stemRotation = new Vector3();

        //calculate which way to grow the next segment
        if (switchDirection)
        {//top side
            rot = Quaternion.Euler(-90, 0, 0);
            if (!firstSegment)
            {
                stemRotation.Set(-45, 0, 0);
            }
        }
        else
        {//bottom side
            rot = Quaternion.Euler(-180, 0, 0);
            if (!firstSegment)
            {
                stemRotation.Set(135, 0, 0);
            }
        }
        //don't spawn stems from the first segment
        if (!firstSegment)
        {
            //random chance for 2 stems
            if (Random.Range(0, 100) < chanceForMoreStems)
            {
                stemRotation = new Vector3(stemRotation.x, stemRotation.y, -45);
                GrowStem(stemSize, stems, pos, Quaternion.Euler(stemRotation), switchDirection);
                stemRotation = new Vector3(stemRotation.x, stemRotation.y, 45);
            }
            GrowStem(stemSize, stems, pos, Quaternion.Euler(stemRotation), switchDirection);
        }

        switchDirection = !switchDirection;

        pos = inst.transform.MultiplyPoint(new Vector3(0, 1, 0));

        //de increment iterations
        number--;

        //grow another segment
        GrowBody(false, number, meshes, pos, rot, bodyScale, switchDirection, stems);
    }