Example #1
0
        public void StartGrow()
        {
            if (IvyRoot.transform.parent == null)
            {
                return;
            }

            m_DoNotDrawGizmos = false;

            Mesh _mesh = IvyRoot.transform.parent.GetComponent <MeshFilter>().sharedMesh;

            Vector3[] _vertices  = _mesh.vertices;
            Vector2[] _UVs       = _mesh.uv;
            Vector3[] _normals   = _mesh.normals;
            int[]     _triangles = _mesh.triangles;

            //Debug.Log(_vertices.Length + "   " + _UVs.Length + "    " + _normals.Length + "    " + _triangles.Length);

            for (int i = 0; i < _mesh.vertexCount; i++)
            {
                SceneObjMesh.vertices.Add(new BasicVertex(_vertices[i]));
            }
            if (_mesh.normals.Length > 0)
            {
                for (int j = 0; j < _mesh.normals.Length; j++)
                {
                    SceneObjMesh.normals.Add(new BasicNormal(_normals[j]));
                }
            }
            else
            {
                for (int j = 0; j < _mesh.vertexCount; j++)
                {
                    SceneObjMesh.normals.Add(new BasicNormal());
                }
            }
            if (_mesh.uv.Length > 0)
            {
                for (int k = 0; k < _mesh.uv.Length; k++)
                {
                    SceneObjMesh.texCoords.Add(new BasicTexCoord(_UVs[k]));
                }
            }
            else
            {
                for (int k = 0; k < _mesh.vertexCount; k++)
                {
                    SceneObjMesh.texCoords.Add(new BasicTexCoord());
                }
            }
            for (int t = 0; t < _triangles.Length / 3; t++)
            {
                BasicTriangle temptri = new BasicTriangle();
                temptri.v0id = (uint)_triangles[t * 3] + 1;
                temptri.v1id = (uint)_triangles[t * 3 + 1] + 1;
                temptri.v2id = (uint)_triangles[t * 3 + 2] + 1;
                temptri.n0id = (uint)_triangles[t * 3] + 1;
                temptri.n1id = (uint)_triangles[t * 3 + 1] + 1;
                temptri.n2id = (uint)_triangles[t * 3 + 2] + 1;
                temptri.t0id = (uint)_triangles[t * 3] + 1;
                temptri.t1id = (uint)_triangles[t * 3 + 1] + 1;
                temptri.t2id = (uint)_triangles[t * 3 + 2] + 1;

                SceneObjMesh.triangles.Add(temptri);
            }

            SceneObjMesh.prepareData();
            SceneObjMesh.calculateVertexNormals();
            SceneObjMesh.prepareData();
        }
Example #2
0
        /** creates the ivy triangle mesh */
        public void birth()
        {
            //evolve a gaussian filter over the adhesian vectors

            float [] gaussian = { 1.0f, 2.0f, 4.0f, 7.0f, 9.0f, 10.0f, 9.0f, 7.0f, 4.0f, 2.0f, 1.0f };

            foreach (var root in roots)
            {
                for (int g = 0; g < 5; ++g)
                {
                    for (int node = 0; node < root.nodes.Count; node++)
                    {
                        Vector3 e = Vector3.zero;

                        for (int i = -5; i <= 5; ++i)
                        {
                            Vector3 tmpAdhesion = Vector3.zero;

                            if ((node + i) < 0)
                            {
                                tmpAdhesion = root.nodes[0].adhesionVector;
                            }
                            if ((node + i) >= root.nodes.Count)
                            {
                                tmpAdhesion = root.nodes[root.nodes.Count - 1].adhesionVector;
                            }
                            if (((node + i) >= 0) && ((node + i) < root.nodes.Count))
                            {
                                tmpAdhesion = root.nodes[node + i].adhesionVector;
                            }

                            e += tmpAdhesion * gaussian[i + 5];
                        }

                        root.nodes[node].smoothAdhesionVector = e / 56.0f;
                    }

                    foreach (var _node in root.nodes)
                    {
                        _node.adhesionVector = _node.smoothAdhesionVector;
                    }
                }
            }


            //parameters that depend on the scene object bounding sphere
            float local_ivyLeafSize = IvyManager.SceneObjMesh.boundingSphereRadius * ivySize * ivyLeafSize;

            float local_ivyBranchSize = IvyManager.SceneObjMesh.boundingSphereRadius * ivySize * ivyBranchSize;


            //reset existing geometry
            reset();


            //set data path
            path = "../textures/";


            //create material for leafs
            BasicMaterial tmpMaterial = new BasicMaterial();

            tmpMaterial.id      = 1;
            tmpMaterial.name    = "leaf_adult";
            tmpMaterial.texFile = IvyManager.LeafAdultTexPathName;

            materials.Add(tmpMaterial);


            //create second material for leafs
            tmpMaterial         = new BasicMaterial();
            tmpMaterial.id      = 2;
            tmpMaterial.name    = "leaf_young";
            tmpMaterial.texFile = IvyManager.LeafYoungTexPathName;

            materials.Add(tmpMaterial);


            //create material for branches
            tmpMaterial         = new BasicMaterial();
            tmpMaterial.id      = 3;
            tmpMaterial.name    = "branch";
            tmpMaterial.texFile = IvyManager.branchTexPathName;

            materials.Add(tmpMaterial);


            //create leafs
            foreach (var root in roots)
            {
                //simple multiplier, just to make it a more dense
                for (int i = 0; i < 10; ++i)
                {
                    //srand(i + (root - roots.begin()) * 10);

                    foreach (var node in root.nodes)
                    {
                        IvyNode back_node = root.nodes[root.nodes.Count - 1];
                        //weight depending on ratio of node length to total length
                        float weight = Mathf.Pow(node.length / back_node.length, 0.7f);

                        //test: the probability of leaves on the ground is increased
                        float groundIvy = Mathf.Max(0.0f, -Vector3.Dot(new Vector3(0.0f, 1.0f, 0.0f), node.adhesionVector.normalized));
                        weight += groundIvy * Mathf.Pow(1.0f - node.length / back_node.length, 2.0f);

                        //random influence
                        float probability = Random.value;

                        if (probability * weight > leafProbability)
                        {
                            //alignment weight depends on the adhesion "strength"
                            float alignmentWeight = node.adhesionVector.magnitude;



                            //horizontal angle (+ an epsilon vector, otherwise there's a problem at 0?and 90?.. mmmh)
                            float phi = vector2ToPolar(new Vector2(node.adhesionVector.z, node.adhesionVector.x).normalized + new Vector2(Vector2.kEpsilon, Vector2.kEpsilon)) - Mathf.PI * 0.5f;

                            //vertical angle, trimmed by 0.5
                            float theta = Vector3.Angle(node.adhesionVector, new Vector3(0.0f, -1.0f, 0.0f)) * 0.5f;

                            //center of leaf quad
                            Vector3 center = node.pos + new Vector3(Random.Range(-0.5f, 0.5f), Random.Range(-0.5f, 0.5f), Random.Range(-0.5f, 0.5f)).normalized *local_ivyLeafSize;

                            //size of leaf
                            float sizeWeight = 1.5f - (Mathf.Cos(weight * 2.0f * Mathf.PI) * 0.5f + 0.5f);


                            //random influence
                            phi += Random.Range(-0.5f, 0.5f) * (1.3f - alignmentWeight);

                            theta += Random.Range(-0.5f, 0.5f) * (1.1f - alignmentWeight);



                            //create vertices
                            BasicVertex tmpVertex = new BasicVertex();


                            tmpVertex.pos  = center + new Vector3(-local_ivyLeafSize * sizeWeight, 0.0f, local_ivyLeafSize * sizeWeight);
                            tmpVertex.pos  = rotateAroundAxis(tmpVertex.pos, center, new Vector3(0.0f, 0.0f, 1.0f), theta);
                            tmpVertex.pos  = rotateAroundAxis(tmpVertex.pos, center, new Vector3(0.0f, 1.0f, 0.0f), phi);
                            tmpVertex.pos += new Vector3(Random.Range(-0.5f, 0.5f), Random.Range(-0.5f, 0.5f), Random.Range(-0.5f, 0.5f)).normalized *local_ivyLeafSize *sizeWeight * 0.5f;
                            vertices.Add(tmpVertex);

                            tmpVertex      = new BasicVertex();
                            tmpVertex.pos  = center + new Vector3(local_ivyLeafSize * sizeWeight, 0.0f, local_ivyLeafSize * sizeWeight);
                            tmpVertex.pos  = rotateAroundAxis(tmpVertex.pos, center, new Vector3(0.0f, 0.0f, 1.0f), theta);
                            tmpVertex.pos  = rotateAroundAxis(tmpVertex.pos, center, new Vector3(0.0f, 1.0f, 0.0f), phi);
                            tmpVertex.pos += new Vector3(Random.Range(-0.5f, 0.5f), Random.Range(-0.5f, 0.5f), Random.Range(-0.5f, 0.5f)).normalized *local_ivyLeafSize *sizeWeight * 0.5f;
                            vertices.Add(tmpVertex);

                            tmpVertex      = new BasicVertex();
                            tmpVertex.pos  = center + new Vector3(-local_ivyLeafSize * sizeWeight, 0.0f, -local_ivyLeafSize * sizeWeight);
                            tmpVertex.pos  = rotateAroundAxis(tmpVertex.pos, center, new Vector3(0.0f, 0.0f, 1.0f), theta);
                            tmpVertex.pos  = rotateAroundAxis(tmpVertex.pos, center, new Vector3(0.0f, 1.0f, 0.0f), phi);
                            tmpVertex.pos += new Vector3(Random.Range(-0.5f, 0.5f), Random.Range(-0.5f, 0.5f), Random.Range(-0.5f, 0.5f)).normalized *local_ivyLeafSize *sizeWeight * 0.5f;
                            vertices.Add(tmpVertex);

                            tmpVertex      = new BasicVertex();
                            tmpVertex.pos  = center + new Vector3(local_ivyLeafSize * sizeWeight, 0.0f, -local_ivyLeafSize * sizeWeight);
                            tmpVertex.pos  = rotateAroundAxis(tmpVertex.pos, center, new Vector3(0.0f, 0.0f, 1.0f), theta);
                            tmpVertex.pos  = rotateAroundAxis(tmpVertex.pos, center, new Vector3(0.0f, 1.0f, 0.0f), phi);
                            tmpVertex.pos += new Vector3(Random.Range(-0.5f, 0.5f), Random.Range(-0.5f, 0.5f), Random.Range(-0.5f, 0.5f)).normalized *local_ivyLeafSize *sizeWeight * 0.5f;
                            vertices.Add(tmpVertex);


                            //create texCoords
                            BasicTexCoord tmpTexCoord = new BasicTexCoord();
                            tmpTexCoord.uv = new Vector2(0.0f, 1.0f);
                            texCoords.Add(tmpTexCoord);

                            tmpTexCoord    = new BasicTexCoord();
                            tmpTexCoord.uv = new Vector2(1.0f, 1.0f);
                            texCoords.Add(tmpTexCoord);

                            tmpTexCoord    = new BasicTexCoord();
                            tmpTexCoord.uv = new Vector2(0.0f, 0.0f);
                            texCoords.Add(tmpTexCoord);

                            tmpTexCoord    = new BasicTexCoord();
                            tmpTexCoord.uv = new Vector2(1.0f, 0.0f);
                            texCoords.Add(tmpTexCoord);


                            //create triangle
                            BasicTriangle tmpTriangle = new BasicTriangle();
                            tmpTriangle.matid = 1;

                            float _probability = Random.value;
                            if (_probability * weight > leafProbability)
                            {
                                tmpTriangle.matid = 2;
                            }

                            tmpTriangle.v0id = (uint)vertices.Count - 1;
                            tmpTriangle.v1id = (uint)vertices.Count - 3;
                            tmpTriangle.v2id = (uint)vertices.Count - 2;

                            tmpTriangle.t0id = (uint)vertices.Count - 1;
                            tmpTriangle.t1id = (uint)vertices.Count - 3;
                            tmpTriangle.t2id = (uint)vertices.Count - 2;

                            triangles.Add(tmpTriangle);

                            BasicTriangle tmpTriangle2 = new BasicTriangle();
                            tmpTriangle2.matid = tmpTriangle.matid;

                            tmpTriangle2.v0id = (uint)vertices.Count - 2;
                            tmpTriangle2.v1id = (uint)vertices.Count - 0;
                            tmpTriangle2.v2id = (uint)vertices.Count - 1;

                            tmpTriangle2.t0id = (uint)vertices.Count - 2;
                            tmpTriangle2.t1id = (uint)vertices.Count - 0;
                            tmpTriangle2.t2id = (uint)vertices.Count - 1;

                            triangles.Add(tmpTriangle2);
                        }
                    }
                }
            }



            //branches
            foreach (var root in roots)
            {
                //process only roots with more than one node
                if (root.nodes.Count == 1)
                {
                    continue;
                }


                //branch diameter depends on number of parents
                float local_ivyBranchDiameter = 1.0f / (float)(root.parents + 1) + 1.0f;


                for (int node = 0; node < root.nodes.Count - 1; node++)
                {
                    //weight depending on ratio of node length to total length
                    float weight = root.nodes[node].length / root.nodes[root.nodes.Count - 1].length;


                    //create trihedral vertices
                    Vector3 up = new Vector3(0.0f, -1.0f, 0.0f);

                    Vector3 basis = (root.nodes[node + 1].pos - root.nodes[node].pos).normalized;

                    Vector3 b0 = Vector3.Cross(up, basis).normalized *local_ivyBranchDiameter *local_ivyBranchSize *(1.3f - weight) + root.nodes[node].pos;

                    Vector3 b1 = rotateAroundAxis(b0, root.nodes[node].pos, basis, 2.09f);

                    Vector3 b2 = rotateAroundAxis(b0, root.nodes[node].pos, basis, 4.18f);

                    //create vertices
                    BasicVertex tmpVertex = new BasicVertex();
                    tmpVertex.pos = b0;
                    vertices.Add(tmpVertex);

                    tmpVertex     = new BasicVertex();
                    tmpVertex.pos = b1;
                    vertices.Add(tmpVertex);

                    tmpVertex     = new BasicVertex();
                    tmpVertex.pos = b2;
                    vertices.Add(tmpVertex);


                    //create texCoords
                    BasicTexCoord tmpTexCoord = new BasicTexCoord();

                    float texV = (node % 2 == 0 ? 1.0f : 0.0f);

                    tmpTexCoord.uv = new Vector2(0.0f, texV);
                    texCoords.Add(tmpTexCoord);

                    tmpTexCoord    = new BasicTexCoord();
                    tmpTexCoord.uv = new Vector2(0.3f, texV);
                    texCoords.Add(tmpTexCoord);

                    tmpTexCoord    = new BasicTexCoord();
                    tmpTexCoord.uv = new Vector2(0.6f, texV);
                    texCoords.Add(tmpTexCoord);


                    if (node == 0)
                    {
                        continue;
                    }


                    //create triangle
                    BasicTriangle tmpTriangle = new BasicTriangle();
                    tmpTriangle.matid = 3;

                    tmpTriangle.v0id = (uint)vertices.Count - 3;
                    tmpTriangle.v1id = (uint)vertices.Count - 0;
                    tmpTriangle.v2id = (uint)vertices.Count - 4;

                    tmpTriangle.t0id = (uint)vertices.Count - 3;
                    tmpTriangle.t1id = (uint)vertices.Count - 0;
                    tmpTriangle.t2id = (uint)vertices.Count - 4;

                    triangles.Add(tmpTriangle);

                    tmpTriangle       = new BasicTriangle();
                    tmpTriangle.matid = 3;
                    tmpTriangle.v0id  = (uint)vertices.Count - 4;
                    tmpTriangle.v1id  = (uint)vertices.Count - 0;
                    tmpTriangle.v2id  = (uint)vertices.Count - 1;

                    tmpTriangle.t0id = (uint)vertices.Count - 4;
                    tmpTriangle.t1id = (uint)vertices.Count - 0;
                    tmpTriangle.t2id = (uint)vertices.Count - 1;

                    triangles.Add(tmpTriangle);

                    tmpTriangle       = new BasicTriangle();
                    tmpTriangle.matid = 3;
                    tmpTriangle.v0id  = (uint)vertices.Count - 4;
                    tmpTriangle.v1id  = (uint)vertices.Count - 1;
                    tmpTriangle.v2id  = (uint)vertices.Count - 5;

                    tmpTriangle.t0id = (uint)vertices.Count - 4;
                    tmpTriangle.t1id = (uint)vertices.Count - 1;
                    tmpTriangle.t2id = (uint)vertices.Count - 5;

                    triangles.Add(tmpTriangle);

                    tmpTriangle       = new BasicTriangle();
                    tmpTriangle.matid = 3;
                    tmpTriangle.v0id  = (uint)vertices.Count - 5;
                    tmpTriangle.v1id  = (uint)vertices.Count - 1;
                    tmpTriangle.v2id  = (uint)vertices.Count - 2;

                    tmpTriangle.t0id = (uint)vertices.Count - 5;
                    tmpTriangle.t1id = (uint)vertices.Count - 1;
                    tmpTriangle.t2id = (uint)vertices.Count - 2;

                    triangles.Add(tmpTriangle);

                    tmpTriangle       = new BasicTriangle();
                    tmpTriangle.matid = 3;
                    tmpTriangle.v0id  = (uint)vertices.Count - 5;
                    tmpTriangle.v1id  = (uint)vertices.Count - 2;
                    tmpTriangle.v2id  = (uint)vertices.Count - 0;

                    tmpTriangle.t0id = (uint)vertices.Count - 5;
                    tmpTriangle.t1id = (uint)vertices.Count - 2;
                    tmpTriangle.t2id = (uint)vertices.Count - 0;

                    triangles.Add(tmpTriangle);

                    tmpTriangle       = new BasicTriangle();
                    tmpTriangle.matid = 3;
                    tmpTriangle.v0id  = (uint)vertices.Count - 5;
                    tmpTriangle.v1id  = (uint)vertices.Count - 0;
                    tmpTriangle.v2id  = (uint)vertices.Count - 3;

                    tmpTriangle.t0id = (uint)vertices.Count - 5;
                    tmpTriangle.t1id = (uint)vertices.Count - 0;
                    tmpTriangle.t2id = (uint)vertices.Count - 3;

                    triangles.Add(tmpTriangle);
                }
            }


            //initialize ivy mesh
            //loadTextures();

            prepareData();

            calculateVertexNormals();

            prepareData();

            //createDisplayList(true);
        }