Attach 3d model to lemur container

i have gui contaner

public Container prev = new Container();

init spatial with gui control

    public Building(String name,String model,String id,LevelAppState appState , Vector3f position){
        this.name = name;
        this.model = model;
        this.appState = appState;
        this.id = id;
        this.position = position;
        
        spatial = this.appState.assetManager.loadModel("Models/"+this.model+".glb");
       
        prev = this.appState.assetManager.loadModel("Models/"+this.model+".glb");
        GuiControl gc = new GuiControl("");
        prev.addControl(gc);
        this.appState.rootNode.attachChild(prev);

and attach spatial to container

                            prev.attachChild(build.prev);

but the spatial is not showing

Your code makes no sense.

What is ā€˜prevā€™ supposed to do? You create a container then throw that away and reset it to the model then add it to the root node. Is it supposed to be a gui in 3D space?

1 Like

no
it happens in different classes

public class Building {
    public String name;
    public LevelAppState appState;
    public String model;
    public Spatial spatial;
    public Spatial prevSpatial;

    public int hp = 100;
    public String id;
    public Vector3f position;
    public RigidBodyControl build;
    public GhostControl ghost;

    public Building(String name,String model,String id,LevelAppState appState , Vector3f position){
        this.name = name;
        this.model = model;
        this.appState = appState;
        this.id = id;
        this.position = position;
        
        spatial = this.appState.assetManager.loadModel("Models/"+this.model+".glb");
       
        prevSpatial = this.appState.assetManager.loadModel("Models/"+this.model+".glb");
        GuiControl gc = new GuiControl("");
        prev.addControl(gc);
        this.appState.rootNode.attachChild(prev);

        spatial.setName(id);
        this.appState.buildingNode.attachChild(spatial);
        
        CollisionShape sceneShape = CollisionShapeFactory.createMeshShape(spatial);
        build = new RigidBodyControl(sceneShape, 0);
        spatial.addControl(build);
                
        ghost = new GhostControl(CollisionShapeFactory.createDynamicMeshShape(spatial)); 
        spatial.addControl(ghost); 
        
        this.appState.bulletAppState.getPhysicsSpace().add(ghost);
    
        this.appState.bulletAppState.getPhysicsSpace().add(build);
        
        build.setKinematicSpatial(true);
        spatial.setLocalTranslation(position.x, position.y, position.z);
}
    
    public Container actionsGui(){
        return new Container();
    }
    
    public static String generateString() {
        String uuid = UUID.randomUUID().toString();
        return  uuid;
    }
    
}

in another class

    public Container prev = new Container();

 Building build = buildingA.get(buildName);
                            
                            Label prevLabel = new Label(build.name);
                            prev.addChild(prevLabel);
                            build.prevSpatial.scale(0.6f);
                            prev.attachChild(build.prevSpatial);

prev is not even visible in that method. I suspect you arenā€™t even showing the real code.

I apologize. It was my mistake even reading this thread.

Before I go back to ignoring these posts, something to remember is that the GUI is in pixels and the models are usually in meters. Also, a GuiControl on its own wonā€™t know what size it isā€¦ so is effectively 0,0,0 in size.

2 Likes

how to setup size for gui control?
i give full code

And because you believe that is why Iā€™m not helping in these threads anymore. I highlighted was is missing based just on what is posted. ā€œprevā€ not found.

Hopefully someone else is ready to ā€œpeer programā€ with you and figure out what you need.

In another month or two when I decide to try reading your posts again, if you have started including fully runnable single-file test classes exhibiting the problem/question then I might look into your issues. Otherwise, I defer to the more patient members of the community.

Good luck.

1 Like

Please, create a simple runnable test case to demonstrate what you want to do, you shouldnā€™t post the full code, your code is trivial.

1 Like
package test;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.GuiGlobals;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.core.GuiControl;
import com.simsilica.lemur.style.BaseStyles;

/**
 * This is the Main Class of your Game. It should boot up your game and do initial initialisation
 * Move your Logic into AppStates or Controls or other java classes
 */
public class Test extends SimpleApplication {

    public static void main(String[] args) {
        Test app = new Test();
        app.setShowSettings(false); //Settings dialog not supported on mac
        app.start();
    }

    @Override
    public void simpleInitApp() {
        GuiGlobals.initialize(this);
        GuiGlobals.getInstance().getStyles().setDefaultStyle("glass");
        BaseStyles.loadGlassStyle();
        
        Spatial        prevSpatial = assetManager.loadModel("Models/main.glb");
        GuiControl gc = new GuiControl("");
        gc.setSize(new Vector3f(100,100,100));
        prevSpatial.addControl(gc);
        
        Container container = new Container();
        container.setLocalTranslation(200, 200, 20);
        container.addChild(new Label("test"));
        container.attachChild(prevSpatial);
        guiNode.attachChild(container);
    }

    @Override
    public void simpleUpdate(float tpf) {
        //this method will be called every game tick and can be used to make updates
    }

    @Override
    public void simpleRender(RenderManager rm) {
        //add render code here (if any)
    }
}

The problem here is that you cannot add a 3d object to a 2d GUI node, the translations and the scales are different.

What are you trying to do?

1 Like

i try add 3object to gui node
like this example

1 Like

Try using the settings.getWidth() and settings.getHeight() instead of using scene units.

Have a look at this simple HUD tutorial, this is how guiNode works, it utilizes your screen units not the scene units:

right?

package test;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.GuiGlobals;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.core.GuiControl;
import com.simsilica.lemur.style.BaseStyles;

/**
 * This is the Main Class of your Game. It should boot up your game and do initial initialisation
 * Move your Logic into AppStates or Controls or other java classes
 */
public class Test extends SimpleApplication {

    public static void main(String[] args) {
        Test app = new Test();
        app.setShowSettings(false); //Settings dialog not supported on mac
        app.start();
    }

    @Override
    public void simpleInitApp() {
        GuiGlobals.initialize(this);
        GuiGlobals.getInstance().getStyles().setDefaultStyle("glass");
        BaseStyles.loadGlassStyle();
        
        Spatial        prevSpatial = assetManager.loadModel("Models/main.glb");
        GuiControl gc = new GuiControl("");
        gc.setSize(new Vector3f(settings.getWidth()/4,settings.getHeight()/4,100));
        prevSpatial.addControl(gc);
        
        Container container = new Container();
        container.setLocalTranslation(100, 100, 20);
        container.addChild(new Label("test"));
        container.attachChild(prevSpatial);
        guiNode.attachChild(container);
    }

    @Override
    public void simpleUpdate(float tpf) {
        //this method will be called every game tick and can be used to make updates
    }

    @Override
    public void simpleRender(RenderManager rm) {
        //add render code here (if any)
    }
}

not work

You are still using scene units here, start with the (0f, 0f, 0f).

1 Like

try

        gc.setSize(new Vector3f(0.8f,0.8f,0.8f));
        gc.setSize(new Vector3f(0f,0f,0f));
        gc.setSize(new Vector3f(1f,1f,1f));
        gc.setSize(new Vector3f(2f,2f,2f));

Please, take your time and read this tutorial, very useful indeed, donā€™t ignore it.

Have you tried setting a size on this container? As mentioned already:

I havenā€™t done anything like this in a while to remember exactly, but Iā€™m fairly certain that a Lemur container will not auto-size itself to fit anything that is added with the Spatialā€™s .attachChild() method; container swill only be auto sized for things that are added with the lemur-layout-compatible addChild() method when using the springGridLayout with the default settings.

I also canā€™t help but mention that you could have very easily looked up ā€œhow to set size on a lemur componentā€ and find the 2 methods: setPreferredSize() and setSize(), typically you always want to use setPreferredSize() but I think in some case the setSize() method is also useful.

But this is very easy information to find out. I typically donā€™t mind sharing obvious answers like this, because I too have been in situations where Iā€™m having a tough coding-day and end up struggling to find a simple answer for myself because Iā€™m frustrated and am not looking at an issue from the proper angle, and it is nice when someone just gives you the exact line of code youā€™re missing to solve it for you right away.
But I think you are starting to develop a bad habit of asking simple questions that have already been answered in other threads that can easily be found on your own, and doing so is depriving yourself of learning how to navigate jmeā€™s documentation and long history of past-threads to find answers on your own (and may also cause some other busy devs to not want to answer your questions because they think you will ask 10 super-easy follow up questions to them afterwards). These are skills which are not only useful for answering simple questions yourself, but also are skills that will be imperative to your success in the future when your games progresses far enough that you run into complex questions that are so unique to your game that no one else will be able to give you a direct answer to and you will have no other choice but to figure out for yourself.

1 Like

thanks i search 2 themes and not search ansver
i try set preferent size for contaner
spatial and gui control not have this method

package test;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.GuiGlobals;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.core.GuiControl;
import com.simsilica.lemur.style.BaseStyles;

/**
 * This is the Main Class of your Game. It should boot up your game and do initial initialisation
 * Move your Logic into AppStates or Controls or other java classes
 */
public class Test extends SimpleApplication {

    public static void main(String[] args) {
        Test app = new Test();
        app.setShowSettings(false); //Settings dialog not supported on mac
        app.start();
    }

    @Override
    public void simpleInitApp() {
        GuiGlobals.initialize(this);
        GuiGlobals.getInstance().getStyles().setDefaultStyle("glass");
        BaseStyles.loadGlassStyle();
        
        Spatial        prevSpatial = assetManager.loadModel("Models/cube.glb");
        GuiControl gc = new GuiControl("");
        gc.setSize(new Vector3f(1f,1f,1f));
        prevSpatial.addControl(gc);
        
        Container container = new Container();
        container.setPreferredSize(new Vector3f(200,200,10));
        container.setLocalTranslation(200, 200, 20);
        container.addChild(new Label("test"));
        container.attachChild(prevSpatial);
        guiNode.attachChild(container);
    }

    @Override
    public void simpleUpdate(float tpf) {
        //this method will be called every game tick and can be used to make updates
    }

    @Override
    public void simpleRender(RenderManager rm) {
        //add render code here (if any)
    }
}

but spatial not showing

Iā€™ve never used a GUIControl to attach a spatial to a Lemur interface, so I have no clue if that is doing anything useful or if it is potentially changing/breaking things and making it more complicated.

But based on my own code from my talent interface, you should be able to do something like this to make a spatial attached to a Lemur container in the center of your screen.

Container container = new Container();
Spatial spatial = assetManager.loadModel("model.j3o");
container.attachChild(spatial);

Vector3f screenCenterPos = new Vecto3f(screenX * 0.5f, screenY * 0.5fl, 1);
container.setLocalTranslation(screenCenterPos);

Vector3f size = screenCenterPos.mult(0.5f);
container.setSize(size);

Typically you need to call setPreferredSize() on lemur Containers, but from my experience, you need to instead call setSize() when you attach a container with the attachChild() method since this bypasses lemurā€™s internal auto-sizing that you get if you were to use addChild() with the proper layout. If you ever forget which to use, you can always try both and see which works.

Also you probably donā€™t even need to attach the spatial to a lemur container in the first place. Why not just attach it directly to the guiNode? Then you wouldnā€™t need to worry about attaching it to a lemur component and could cut out all the sizing code.

try this

package test;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.GuiGlobals;
import com.simsilica.lemur.Label;
import com.simsilica.lemur.core.GuiControl;
import com.simsilica.lemur.style.BaseStyles;

/**
 * This is the Main Class of your Game. It should boot up your game and do initial initialisation
 * Move your Logic into AppStates or Controls or other java classes
 */
public class Test extends SimpleApplication {

    public static void main(String[] args) {
        Test app = new Test();
        app.setShowSettings(false); //Settings dialog not supported on mac
        app.start();
    }

    @Override
    public void simpleInitApp() {
        GuiGlobals.initialize(this);
        GuiGlobals.getInstance().getStyles().setDefaultStyle("glass");
        BaseStyles.loadGlassStyle();
        
        Spatial        prevSpatial = assetManager.loadModel("Models/main.glb");
        GuiControl gc = new GuiControl("");
       // gc.setSize(new Vector3f(200f,200f,29f));
        prevSpatial.addControl(gc);
        
        Container container = new Container();
        float screenX = settings.getWidth();
        float screenY = settings.getHeight();

        Vector3f screenCenterPos = new Vector3f(screenX * 0.5f, screenY * 0.5f, 1);
        Vector3f size = screenCenterPos.mult(0.5f);

        container.setPreferredSize(size);
        
        container.setLocalTranslation(screenCenterPos);
        container.setSize(size);

        container.addChild(new Label("test"));
        container.attachChild(prevSpatial);
        guiNode.attachChild(container);
    }

    @Override
    public void simpleUpdate(float tpf) {
        //this method will be called every game tick and can be used to make updates
    }

    @Override
    public void simpleRender(RenderManager rm) {
        //add render code here (if any)
    }
}


i need mini preview for my characters like warcraf3

You can render the character on a 3d scene as a preview without the need of gui and you can still use lemur to interact with it.

2 Likes