Пример #1
0
    // Use this for initialization
    void Start()
    {
        distributionObject = this.gameObject;

        vectors = new List <Vector3>();
        normals = new List <Vector3>();

        //normals = new List<Vector3>();
        gears = new List <GFGearGen>();
        if (distributionObject != null && gearEntity != null)
        {
            MeshFilter m = (MeshFilter)distributionObject.GetComponent(typeof(MeshFilter));
            if (m != null)
            {
                followNormals = followNormals && m.mesh.normals.Length == m.mesh.vertices.Length && m.mesh.normals.Length > 0;

                // Walk through faces
                for (int i = 0; i < m.mesh.triangles.Length; i += 3)
                {
                    int[] triangle = new int[] { m.mesh.triangles[i], m.mesh.triangles[i + 1], m.mesh.triangles[i + 2] };

                    // For every face, get the three vertices
                    // Get the longest distance between two vertices

                    float d01     = Vector3.Distance(m.mesh.vertices[triangle[0]], m.mesh.vertices[triangle[1]]);
                    float d12     = Vector3.Distance(m.mesh.vertices[triangle[1]], m.mesh.vertices[triangle[2]]);
                    float d20     = Vector3.Distance(m.mesh.vertices[triangle[2]], m.mesh.vertices[triangle[0]]);
                    int   idxFrom = 2;
                    int   idxTo   = 0;
//					float dist;// = d20;

                    if (d01 > d12 && d01 > d20)
                    {
                        idxFrom = 0;
                        idxTo   = 1;
//						dist = d01;
                    }
                    else
                    {
                        if (d12 > d01 && d12 > d20)
                        {
                            idxFrom = 1;
                            idxTo   = 2;
//							dist = d12;
                        }
                    }

                    // Face normal
                    Vector3 n = Vector3.zero;
                    if (followNormals)
                    {
                        Vector3 n1 = m.mesh.normals[triangle[1]];
                        Vector3 n2 = m.mesh.normals[triangle[2]];
                        Vector3 n3 = m.mesh.normals[triangle[0]];
                        n = (n1 + n2 + n3) / 3.0f;
                        n.Normalize();
                    }


                    // Get center of line segment
                    Vector3 center = Vector3.Lerp(m.mesh.vertices[triangle[idxFrom]], m.mesh.vertices[triangle[idxTo]], 0.5f);

                    // If center isn't already occupied: add vector
                    if (!vectors.Contains(center))
                    {
                        vectors.Add(center);
                        if (followNormals)
                        {
                            normals.Add(n);
                        }
                        //	normals.Add(center.normalized);
                    }
                }

                // Walk through vectors and instantiate a gear

                GFGearGen gg;
                for (int i = 0; i < vectors.Count; i++)
                {
                    Vector3    v  = /*distributionObject.transform.localToWorldMatrix * */ vectors[i];                // + m.transform.position;// m.mesh.vertices[i];
                    Quaternion lr = Quaternion.LookRotation(followNormals ? normals[i] : v.normalized);

                    if (i == 0)
                    {
                        //gearEntity.gameObject.active = false;
                        gearEntity.transform.position = v;                        //distributionObject.transform.TransformPoint(v);
                        gearEntity.transform.rotation = lr;
                        gearEntity.transform.localRotation.eulerAngles.Set(0.0f, 0.0f, 0.0f);
                        gg = gearEntity;
                    }
                    else
                    {
                        gg = (GFGearGen)Instantiate(gearEntity);                        //, /*distributionObject.transform.TransformPoint(v)*/v, Quaternion.LookRotation(v.normalized));

                        gg.transform.parent   = gearEntity.transform.parent;
                        gg.transform.position = v;
                        gg.transform.rotation = lr;

                        if (gg.gear != null)
                        {
                            GFGear prevgear = gears[i - 1].gear;
                            if (prevgear != null)
                            {
                                gg.gear.DrivenBy = prevgear;
                            }
                        }
                    }
                    gears.Add(gg);
                }

                GFGear gear = gearEntity.gear;                // (GFGear)gearEntity.gameObject.GetComponent(typeof(GFGear));
                if (gear != null)
                {
                    if (gear.machine != null)
                    {
                        gear.machine.RecalculateGears();
                    }
                }


                #region Combine meshes to reduce draw calls
                if (combineMeshes)
                {
                    //transform.position = distributionObject.transform.position;
                    //transform.rotation = distributionObject.transform.rotation;

                    List <CombineInstance> cmb = new List <CombineInstance>();
                    for (int i = 0; i < gears.Count; i++)
                    {
                        MeshFilter mf = gears[i].gameObject.GetComponent <MeshFilter>();
                        if (mf != null)
                        {
                            CombineInstance ci = new CombineInstance();
                            ci.mesh      = mf.sharedMesh;
                            ci.transform = mf.transform.localToWorldMatrix;

                            mf.gameObject.SetActive(false);
                            cmb.Add(ci);
                        }
                    }
                    MeshFilter currentMf = transform.GetComponent <MeshFilter>();
                    currentMf.SetMesh(new Mesh());
                    currentMf.sharedMesh.CombineMeshes(cmb.ToArray());

                    MeshRenderer currentMr = transform.GetComponent <MeshRenderer>();
                    if (currentMr == null)
                    {
                        currentMr = (MeshRenderer)transform.gameObject.AddComponent(typeof(MeshRenderer));
                    }
                    transform.gameObject.SetActive(true);
                }
                #endregion

                m.GetComponent <Renderer>().enabled = !hideEmitter;
            }
        }
    }