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); }