|
55 | 55 | import com.jme3.util.clone.IdentityCloneFunction; |
56 | 56 | import com.jme3.util.clone.JmeCloneable; |
57 | 57 | import com.jme3.vulkan.material.NewMaterial; |
| 58 | +import com.jme3.vulkan.scene.NotSpatial; |
58 | 59 |
|
59 | 60 | import java.io.IOException; |
60 | 61 | import java.util.*; |
|
70 | 71 | * @author Joshua Slack |
71 | 72 | * @version $Revision: 4075 $, $Data$ |
72 | 73 | */ |
73 | | -public abstract class Spatial implements Savable, Cloneable, Collidable, |
| 74 | +public abstract class Spatial implements Iterable<Spatial>, Savable, Cloneable, Collidable, |
74 | 75 | CloneableSmartAsset, JmeCloneable, HasLocalTransform { |
75 | 76 | private static final Logger logger = Logger.getLogger(Spatial.class.getName()); |
76 | 77 |
|
@@ -1876,4 +1877,88 @@ public void breadthFirstTraversal(SceneGraphVisitor visitor) { |
1876 | 1877 | } |
1877 | 1878 |
|
1878 | 1879 | protected abstract void breadthFirstTraversal(SceneGraphVisitor visitor, Queue<Spatial> queue); |
| 1880 | + |
| 1881 | + protected abstract void findNextIteration(GraphIterator iterator); |
| 1882 | + |
| 1883 | + @Override |
| 1884 | + public Iterator<Spatial> iterator() { |
| 1885 | + return new GraphIterator(this); |
| 1886 | + } |
| 1887 | + |
| 1888 | + public static class GraphIterator implements Iterator<Spatial> { |
| 1889 | + |
| 1890 | + private final Stack<Integer> childIndices = new Stack<>(); |
| 1891 | + private Spatial current; |
| 1892 | + private int currentIndex = 0; |
| 1893 | + private int iteration = -1; |
| 1894 | + |
| 1895 | + public GraphIterator(Spatial start) { |
| 1896 | + current = Objects.requireNonNull(start); |
| 1897 | + } |
| 1898 | + |
| 1899 | + @Override |
| 1900 | + public boolean hasNext() { |
| 1901 | + return current != null; |
| 1902 | + } |
| 1903 | + |
| 1904 | + @Override |
| 1905 | + public Spatial next() { |
| 1906 | + if (++iteration > 0) { |
| 1907 | + current.findNextIteration(this); |
| 1908 | + } |
| 1909 | + return current; |
| 1910 | + } |
| 1911 | + |
| 1912 | + @Override |
| 1913 | + public void remove() { |
| 1914 | + if (current.getParent() != null) { |
| 1915 | + current.removeFromParent(); |
| 1916 | + moveUp(); |
| 1917 | + currentIndex--; |
| 1918 | + } |
| 1919 | + } |
| 1920 | + |
| 1921 | + protected void moveUp() { |
| 1922 | + if (!childIndices.isEmpty()) { |
| 1923 | + current = current.getParent(); |
| 1924 | + currentIndex = childIndices.pop(); |
| 1925 | + if (current != null) { |
| 1926 | + current.findNextIteration(this); |
| 1927 | + } |
| 1928 | + } else { |
| 1929 | + current = null; |
| 1930 | + } |
| 1931 | + } |
| 1932 | + |
| 1933 | + protected void moveDown(Spatial node) { |
| 1934 | + if (node.getParent() != current) { |
| 1935 | + throw new IllegalArgumentException("Next node must be a child of the current node."); |
| 1936 | + } |
| 1937 | + current = node; |
| 1938 | + childIndices.push(currentIndex); |
| 1939 | + currentIndex = 0; |
| 1940 | + } |
| 1941 | + |
| 1942 | + protected int advanceIndex() { |
| 1943 | + return currentIndex++; |
| 1944 | + } |
| 1945 | + |
| 1946 | + protected int getCurrentIndex() { |
| 1947 | + return currentIndex; |
| 1948 | + } |
| 1949 | + |
| 1950 | + public void skipChildren() { |
| 1951 | + moveUp(); |
| 1952 | + } |
| 1953 | + |
| 1954 | + public int getDepth() { |
| 1955 | + return childIndices.size(); |
| 1956 | + } |
| 1957 | + |
| 1958 | + public int getIteration() { |
| 1959 | + return iteration; |
| 1960 | + } |
| 1961 | + |
| 1962 | + } |
| 1963 | + |
1879 | 1964 | } |
0 commit comments