Example #1
0
            static void Bake(TE3ScatterArea target, GameObject root)
            {
                var bakedSources = new List <GameObject>();
                var bakedOutputs = new List <GameObject>();

                var mat2mesh = new Dictionary <Material, MeshCollector>();

                foreach (Transform child in root.transform)
                {
                    var childProxy = child.GetComponent <TE3ScatterProxy>();
                    if (!childProxy.bakeMesh)
                    {
                        continue;
                    }

                    var           childMR  = child.GetComponent <MeshRenderer>();
                    var           childMF  = child.GetComponent <MeshFilter>();
                    var           childMat = childMR.sharedMaterial;
                    MeshCollector childCol = null;
                    if (!mat2mesh.TryGetValue(childMat, out childCol))
                    {
                        childCol           = new MeshCollector();
                        mat2mesh[childMat] = childCol;
                    }

                    if (childProxy.wrapEnvironment == 0f)
                    {
                        childCol.PushMesh(childMF.sharedMesh, Matrix4x4.TRS(child.transform.localPosition, child.transform.localRotation, child.transform.localScale), -1);
                    }
                    else
                    {
                        Debug.Log("wrap: " + childProxy.wrapEnvironment);
                        var vtxColStart = childCol.VertexCount;
                        var vtxCount    = childMF.sharedMesh.vertexCount;
                        childCol.PushMesh(childMF.sharedMesh, Matrix4x4.TRS(child.transform.localPosition, child.transform.localRotation, child.transform.localScale), -1);

                        var indices = childMF.sharedMesh.triangles;
                        for (int i = 0, n = indices.Length; i < n; i += 3)
                        {
                            var p0 = childCol.GetPosition(vtxColStart + i + 0);
                            var p1 = childCol.GetPosition(vtxColStart + i + 1);
                            var p2 = childCol.GetPosition(vtxColStart + i + 2);
                            var n0 = childCol.GetNormal(vtxColStart + i + 0);
                            var n1 = childCol.GetNormal(vtxColStart + i + 1);
                            var n2 = childCol.GetNormal(vtxColStart + i + 2);

                            RaycastHit rhiPC0;
                            if (!Physics.Raycast(p0 - n0 * 0.01f, -n0, out rhiPC0, 1f))
                            {
                                rhiPC0.point = p0;
                            }
                            RaycastHit rhiPC1;
                            if (!Physics.Raycast(p1 - n1 * 0.01f, -n1, out rhiPC1, 1f))
                            {
                                rhiPC1.point = p1;
                            }
                            RaycastHit rhiPC2;
                            if (!Physics.Raycast(p2 - n2 * 0.01f, -n2, out rhiPC2, 1f))
                            {
                                rhiPC2.point = p2;
                            }

                            childCol.SetPosition(vtxColStart + i + 0, rhiPC0.point);
                            childCol.SetPosition(vtxColStart + i + 1, rhiPC1.point);
                            childCol.SetPosition(vtxColStart + i + 2, rhiPC2.point);
                        }
                    }

                    bakedSources.Add(child.gameObject);
                }

                foreach (var kvp in mat2mesh)
                {
                    var go = new GameObject("Baked_" + kvp.Key.name);
                    bakedOutputs.Add(go);

                    var mr = go.AddComponent <MeshRenderer>();
                    mr.sharedMaterial = kvp.Key;

                    var mf = go.AddComponent <MeshFilter>();
                    mf.sharedMesh = new Mesh();
                    kvp.Value.WriteMesh(mf.sharedMesh, 2);

                    mf.sharedMesh.RecalculateBounds();
                }

                target.SetBakedData(bakedSources, bakedOutputs);
            }