/// <summary> /// Returns a list of transforms including this transform and ALL of its children, /// including the children of its children, and the children of their children, and /// so on. /// /// THIS ALLOCATES GARBAGE. Use it for editor code only. /// </summary> public static List <Transform> GetSelfAndAllChildren(this Transform t, bool includeInactiveObjects = false) { var allChildren = new List <Transform>(); Stack <Transform> toVisit = Pool <Stack <Transform> > .Spawn(); try { // Traverse the hierarchy of this object's transform to find all of its Colliders. toVisit.Push(t.transform); Transform curTransform; while (toVisit.Count > 0) { curTransform = toVisit.Pop(); // Recursively search children and children's children foreach (var child in curTransform.GetChildren()) { // Ignore children with Rigidbodies of their own; its own Rigidbody // owns its own colliders and the colliders of its children if (includeInactiveObjects || child.gameObject.activeSelf) { toVisit.Push(child); } } // Since we'll visit every valid child, all we need to do is add the colliders // of every transform we visit. allChildren.Add(curTransform); } } finally { toVisit.Clear(); Pool <Stack <Transform> > .Recycle(toVisit); } return(allChildren); }
private void refreshMesh() { if (outputToFilter == null) { return; } if (outputToFilter.sharedMesh == null) { outputToFilter.sharedMesh = new Mesh(); outputToFilter.sharedMesh.name = "PoseRibbonMesh Test"; } var mesh = outputToFilter.sharedMesh; mesh.Clear(); var pose0 = poseSource0.ToLocalPose(); var pose1 = poseSource1.ToLocalPose(); var pose2 = poseSource2.ToLocalPose(); var poses = Pool <List <Pose> > .Spawn(); poses.Clear(); try { poses.Add(pose0); poses.Add(pose1); poses.Add(pose2); if (!usePolyMeshMethod) { #region Non-PolyMesh Method var verts = Pool <List <Vector3> > .Spawn(); verts.Clear(); var indices = Pool <List <int> > .Spawn(); indices.Clear(); try { for (int i = 0; i < poses.Count; i++) { var p = poses[i]; verts.Add(left(p)); verts.Add(right(p)); } int vertsPerPose = 2; bool closeLoop = vertsPerPose != 2; for (int p = 0; p + 1 < poses.Count; p++) { for (int csi = 0; csi < vertsPerPose - (closeLoop ? 0 : 1); csi++) { var csRootIndex = p * vertsPerPose; var nextCSRootIndex = (p + 1) * vertsPerPose; var i0 = csRootIndex + csi; var i1 = nextCSRootIndex + csi; var i2 = nextCSRootIndex + ((csi + 1) % vertsPerPose); var i3 = csRootIndex + ((csi + 1) % vertsPerPose); indices.Add(i0); indices.Add(i1); indices.Add(i2); indices.Add(i0); indices.Add(i2); indices.Add(i3); } } mesh.SetVertices(verts); mesh.SetTriangles(indices, 0, true); mesh.RecalculateNormals(); } finally { verts.Clear(); Pool <List <Vector3> > .Recycle(verts); indices.Clear(); Pool <List <int> > .Recycle(indices); } #endregion } else { polyMesh.Clear(); // quad 0 polyMesh.AddPosition(left(pose0)); polyMesh.AddPosition(right(pose0)); polyMesh.AddPosition(left(pose1)); polyMesh.AddPosition(right(pose1)); var newPoly = Polygon.SpawnQuad(1, 0, 2, 3); polyMesh.AddPolygon(newPoly); // quad 1 polyMesh.AddPosition(left(pose2)); polyMesh.AddPosition(right(pose2)); var nextPoly = Polygon.SpawnQuad(3, 2, 4, 5); polyMesh.AddPolygon(nextPoly); // mark the edge between the two quads as smooth. polyMesh.MarkEdgeSmooth(new Edge(2, 3)); polyMesh.FillUnityMesh(mesh, doubleSided: true); } } finally { poses.Clear(); Pool <List <Pose> > .Recycle(poses); } }