Add scene-graph versioning via Spatial.getLastGeomChangeId()#1
Add scene-graph versioning via Spatial.getLastGeomChangeId()#1
Spatial.getLastGeomChangeId()#1Conversation
- Add `lastGeomChangeId` (transient long) to Spatial, initialised from a global AtomicLong counter on construction so each new Spatial carries a unique positive change ID immediately. - Add private `incrementGeomChangeId()` which obtains a new ID from the global counter, writes it on `this`, and propagates it upward to all ancestors, so comparing the root's ID is enough to know whether *anything* anywhere in the tree has changed. - Call `incrementGeomChangeId()` from `setBoundRefresh()`, `setLightListRefresh()`, and `setMatParamOverrideRefresh()`. `setTransformRefresh()` already delegates to `setBoundRefresh()`, so transform changes are covered automatically without double-incrementing. - Expose `public long getLastGeomChangeId()` with full Javadoc including a frame-skipping usage example. - Add `SceneGraphVersioningTest` with 10 unit tests covering creation, propagation, sibling isolation, no-op reads, attach/detach, deep trees, monotonicity, and the frame-skipping pattern. Agent-Logs-Url: https://github.com/zzuegg/jmonkeyengine/sessions/facaf9bb-f6a0-4825-a14a-4f5bd3f12424 Co-authored-by: zzuegg <2301442+zzuegg@users.noreply.github.com>
Spatial.getLastGeomChangeId()
|
@copilot can i then also skip subbranches with < lastChangeId? |
Yes — the propagation is strictly upward (ancestors only, never siblings), so every branch retains the ID of the most recent change in its own sub-tree. That makes the comparison work directly: // After completing a culling pass, snapshot the current frontier:
long lastCullId = rootNode.getLastGeomChangeId();
// Next frame, when recursing into sub-branches:
private void renderSubScene(Spatial scene, ViewPort vp, long lastCullId) {
if (scene.getLastGeomChangeId() <= lastCullId) {
// Nothing in this sub-tree changed since the last cull.
// Re-queue previous results and skip the traversal entirely.
return;
}
// ... normal cull / recurse
}
|
|
@copilot how many hours would a game run if i have 2000 moving objects at 240fps? |
At 2000 moving objects × 240 fps = 480,000 increments/second, and |
Callers currently have no cheap way to determine whether a scene-graph branch has changed between frames, forcing culling traversals even when nothing has moved. This adds a monotonically-increasing change ID to every
Spatialthat propagates upward on any geometric mutation, enabling branch-level change detection in O(1).Changes
Spatialprivate static final AtomicLong nextGeomChangeId— JVM-wide counter; each increment produces a globally unique ID.protected transient long lastGeomChangeId— set to a fresh ID at construction (creation is itself a change), updated on every geometric mutation.private void incrementGeomChangeId()— obtains next ID, writes it onthis, then walks the parent chain writing the same ID to every ancestor. Ensuresroot.getLastGeomChangeId()always reflects the most recent change anywhere in the subtree.setBoundRefresh()(covers transform changes too, sincesetTransformRefresh()→setBoundRefresh()),setLightListRefresh(),setMatParamOverrideRefresh().public long getLastGeomChangeId()— public API with usage Javadoc.Usage pattern
Key properties:
incrementGeomChangeId()call (viasetBoundRefresh), no double-increment.transient— excluded from serialization; ID is runtime state only.Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
dl.google.com/usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:+HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en(dns block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt