In my game, I want to display a spatial in GUI node and remove from rootNode when a user clicks on it and place it back when the user clicks on empty surface.
For that I’m using the code
private void pickSpatial(Spatial s) {
shootables.detachChild(s);
// Display spatial on GUI node
//scale = s.getWorldScale();
s2 = s.clone();
s2.setLocalTranslation(25,25,0);
s2.scale(20);
s2.rotate(r, 0, -r);
app.getGuiNode().attachChild(s2);
//app.getGuiNode().setLocalTranslation(0, 0, 0);
}
private void placeSpatial (Spatial s) {
/*
* Process the position to adjust it accordingle if a magnet or some other
* component wants to change it.
*/
// Remove from GUI node
app.getGuiNode().detachChild(s2);
s2 = null;
To display it on GUI node I need to scale up he spatial as one WU is only 1 pixel in guiNode. So if I want to use the same spatial, I need to store its scale info in a variable so that I can restore the same scale back when placing. I tried storing this info using various methods but when I tried restoring it back to old scale, I did not get the same size spatial. How can I store scale info and later set it back so that I get the same size spatial as earlier?
I tried another way by first creating a clone and attaching it to gui node and later turning it to null after deattaching it. Does this successfully garbage collect the spatial (by turning it to null)???
Spatials get garbage collected just like any other object.
You could attach your own parent node to the guiNode and then apply scale to it instead of the objects. Attach the objects to that parent instead of directly to the guiNode.
…then you wouldn’t have to keep track of the scale.
Also, scale() is relative to the current scale. You probably wanted setLocalScale() anyway.
@pspeed said:
Spatials get garbage collected just like any other object.
You could attach your own parent node to the guiNode and then apply scale to it instead of the objects. Attach the objects to that parent instead of directly to the guiNode.
…then you wouldn’t have to keep track of the scale.
Also, scale() is relative to the current scale. You probably wanted setLocalScale() anyway.
I think there’s very few z depth in the gui and that is why spatials can look bad there.
The way I resolved it is by outputting a frameBuffer to the texture of an element in the gui.
Here is the code (nb: done with toneGodGUI, but same principles for other 2D libs):
private void setupModelViewer(Node node) {
offCamera = new Camera(WIDTH, HEIGHT);
modelView = game.getRenderManager().createPreView("model3DView", offCamera);
modelView.setClearFlags(true, true, true);
modelView.setBackgroundColor(ColorRGBA.DarkGray);
//setup framebuffer's cam
offCamera.setFrustumPerspective(30, 3f, 1f, 500f);
offCamera.setLocation(new Vector3f(0, 0, -6));
offCamera.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
// create offscreen framebuffer
offBuffer = new FrameBuffer(WIDTH, HEIGHT, 1);
//setup framebuffer's texture
offTex = new Texture2D(WIDTH, HEIGHT, Image.Format.RGBA8);
// offTex.setMinFilter(Texture.MinFilter.Trilinear);
// offTex.setMagFilter(Texture.MagFilter.Bilinear);
//setup framebuffer to use texture
offBuffer.setDepthBuffer(Image.Format.Depth);
offBuffer.setColorTexture(offTex);
//set viewport to render to offscreen framebuffer
modelView.setOutputFrameBuffer(offBuffer);
node.updateGeometricState();
modelView.attachScene(node);
}
private void displayModelView() {
Element displayModel = new Element(screen, "displayModelElement",
new Vector2f(5, 50),
new Vector2f(WIDTH, HEIGHT),
Vector4f.ZERO, "Interface/Launcher/corsicansInSpace.png");//replace img by small blank one
displayModel.getMaterial().setTexture("ColorMap", offTex);
displayModel.getMaterial().getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Back);
mainTabControl.addTabChild(TAB_CHILD, displayModel);
}
Works fine for my needs, but not knowledgeable enough to know how good/efficient a solution that is.
For 2D lib, you have a choice between nifty (officially supported) and toneGodGUI and Lemur.
In my snippet, setupModelViewer() is “generic”; only displayModelView() is linked to the 2D lib. So you can use any lib or do it yourself and use this… just set the texture of the element in 2D (displayModel.getMaterial().setTexture(“ColorMap”, offTex);).
I’ve found it easier to follow easy paths to get the architecture going and only focus on pretty/specific difficulties later on. So maybe you shouldn’t be focusing on this kind of stuff from the get-go.
Sorry for reanimating this thread from the book of dead topics:
I’m currently in need to render a 3D compass or a Jaime monkey “to the guiNode”.
(well, not exactly that - I could make another gui3dNode or other idea)
I’m not using anything that’s not part of the jME 3 (3.0) SDK (so no ToneGod UI).
I want the background to be transparent (show the things in the rootNode behind the compass).
I did something like that for a jME 2.0 project but can’t find the old code and it might not work with jME 3 anyways.
So, if anybody has a good solution to this problem - don’t hesitate to post it or to contact me.
Could be something simple, like another render pass after everything was rendered (how would I do that?).
I will try the description from loopies without ToneGod.
If there is no solution, I will use a simple 2D fallback.
If it’s a single mesh (or simple meshes) then just put it in the gui node and scale it up. Done.
Else you will want to create a separate main viewport with its own camera. Create an app state to manage the updateLogicalState()/updateGeometricState() of that viewport’s root node (that you create and have to manage yourself).
No, the monkey does not render correctly when attached to gui node.
See the link of @NoUserName from Jan’15 - that’s what happens.
It also happens to my 3D compass since it’s 7 geometries, not 1.
Does the viewport allow for transparent background?
Maybe I could do RTT (render-to-texture) to get a transparent background?
I use TGG because it comes with lots of controls such as lists, tables etc that are very useful for my project.
In your case, if you don’t need all of that, you might be better short-cutting TGG and only creating a quad, attaching it to the gui and setting it’s texture about the same way. Anyway, if you have a question, you know where to find me… I’ll be in my cave trying to master… fire :D.