Skip to content

feat: BillboardControl optimization + javadoc + bugfix + new Constructor #2495

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

capdevon
Copy link
Contributor

@capdevon capdevon commented Jun 13, 2025

This PR introduces significant performance optimizations, a new constructor for easier initialization, and comprehensive documentation for the BillboardControl class.

Key Changes & Improvements:

  • New Constructor:
    • Added a constructor BillboardControl(Alignment alignment) that allows specifying the initial billboard alignment directly upon instantiation. This simplifies common usage patterns.
  • Performance Optimization:
    • Replaced new Quaternion() with a reusable tempQuat instance in rotateScreenAligned() to reduce per-frame object allocations, thereby minimizing garbage collection pauses and improving overall frame rate stability.
  • Code Quality & Maintainability:
    • Added comprehensive Javadoc comments to the class, its methods, and member variables. This improves code readability, makes the control easier to understand, and facilitates future maintenance and development.
  • Demo:
    • Updated the TestBillboard class to demonstrate the functionality of the optimized BillboardControl and its various alignment options at runtime.

These changes ensure the BillboardControl remains functionally identical while significantly improving its runtime efficiency and developer experience.

Edit:
To ensure maximum performance efficiency for the game loop, I removed the fixRefreshFlags() method and its call from controlRender()

Reasoning:
When spatial.setLocalRotation(orient) is called in rotateCameraAligned, rotateScreenAligned, or rotateAxial, JME3 automatically marks the spatial as "dirty" (sets an internal TRANSFORM_DIRTY flag). The engine's core update loop, which runs after all controls' controlUpdate and before controlRender (though the billboard logic is in controlRender here), will then efficiently propagate these transform changes and update world bounds as needed.

Impact: Calling spatial.updateGeometricState() and especially rootNode.getWorldBound() manually every frame is redundant and computationally expensive. rootNode.getWorldBound() can involve traversing a significant portion of the scene graph. By forcing these updates, you're essentially making JME do work it would already do, or doing it at a less optimal time, which can lead to performance bottlenecks (e.g., CPU spikes), even if it doesn't create new objects that need garbage collection.

image

@capdevon capdevon changed the title feat: illboardControl optimization + javadoc + bugfix + new Constructor feat: BillboardControl optimization + javadoc + bugfix + new Constructor Jun 13, 2025
@yaRnMcDonuts yaRnMcDonuts added this to the v3.9.0 milestone Jun 14, 2025
private Vector3f look;
private Vector3f left;
private Alignment alignment;
// Member variables for calculations, reused to avoid constant object allocation.
Copy link
Member

@richardTingle richardTingle Jun 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

orient, look & left looked to already be reused temp variables. They were effectively final other than when they were set by the read method. Why not keep the understandable names?

(You're right about the new Quaternion() though, might as well introduce a new temp variable for that)

@richardTingle
Copy link
Member

In the example, how is the yellow quad supposed to behave. Even in JME today it behaves weirdly (so not your change) but I want to understand what it is supposed to do (it doesn't seem to billboard, just flip between two different orientations)

@capdevon
Copy link
Contributor Author

capdevon commented Jun 17, 2025

In the example, how is the yellow quad supposed to behave. Even in JME today it behaves weirdly (so not your change) but I want to understand what it is supposed to do (it doesn't seem to billboard, just flip between two different orientations)

That's a good question about the yellow quad's intended behavior. Honestly, I'm not entirely sure what its original purpose was or how it's supposed to behave. I've encountered a fair amount of code in the jME core module that seems redundant, incomplete, or a bit strange, and this might be another instance of that.

From my perspective, the most useful and commonly utilized behaviors are Alignment.Screen (for true billboarding) and Alignment.AxialY (for rotation around the Y-axis).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants