Moving spatial with appstate

Hi
i am New to Jmonkey and i have problems with appstate
well i want to move a caractere from appstate but when i do that i get a fixed postion version of the caractere and another when that work as i need 2
i have searched google and forums here and i didn’t find an answer
and what confuse me more the same code in the main class work perfectly

/*
  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package mygame;

import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.animation.LoopMode;
import com.jme3.app.Application;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.asset.AssetManager;
import com.jme3.bullet.BulletAppState;
import com.jme3.input.InputManager;
import com.jme3.input.controls.ActionListener;
import com.jme3.math.Quaternion;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;

public class Man extends AbstractAppState {

private SimpleApplication app;
private Node rootNode;
private AssetManager assetManager;
private AppStateManager stateManager;
private InputManager inputManager;
private ViewPort viewPort;
private BulletAppState physics;
public Spatial chair;
private long currentTime;
private long totalTime;
float cpt = 0;
private AnimControl control;
private AnimChannel channel;
private Spatial coiffeur;
private RenderManager renderManager;

@Override
public void initialize(AppStateManager stateManager, Application app) {
    super.initialize(stateManager, app);
    this.app = (SimpleApplication) app; // can cast Application to something more specific
    this.rootNode = this.app.getRootNode();
    this.assetManager = this.app.getAssetManager();
    this.stateManager = this.app.getStateManager();
    this.inputManager = this.app.getInputManager();
    this.viewPort = this.app.getViewPort();
    this.physics = this.stateManager.getState(BulletAppState.class);

    System.out.println("Here i am");
    initialized = true;
    simpleInitApp();



}

public void simpleInitApp() {

    System.out.println("Here i am");

    coiffeur = (Node) assetManager.loadModel("Models/Man/coiffeur.j3o");
    coiffeur.setMaterial(assetManager.loadMaterial("Materials/material.j3m"));
    rootNode.attachChild(coiffeur);
    coiffeur.rotate(0, 2, 0);
    coiffeur.updateGeometricState();

    totalTime = System.currentTimeMillis();
}
@Override
public void update(float tpf) {

    currentTime = System.currentTimeMillis();

    if (currentTime - totalTime >= 1000) {
        
          coiffeur.setLocalTranslation(cpt, coiffeur.getLocalTranslation().getY(), coiffeur.getLocalTranslation().getZ());
        cpt += .1;
        
        totalTime = currentTime;
    }

}

@Override
public void cleanup() {
    super.cleanup();

    //TODO: clean up what you initialized in the initialize method,
    //e.g. remove all spatials from rootNode
    //this is called on the OpenGL thread after the AppState has been detached
}

}

…does nothing in an app state.

You may also want to show how you attach the app state… so include your main class also.

And you should read the stick topic at the top of the forum that tells you how to post code blocks. It’s hard to miss.

1 Like
package mygame;

import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;

import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;

/**

  • test

  • @author normenhansen
    */
    public class Main extends SimpleApplication {

    Coiffeure_chaise chaise = new Coiffeure_chaise(1);

    public static void main(String[] args) {
    Main app = new Main();
    app.start();

    }
    public Spatial scene;
    public Spatial[] model2 = new Spatial[10];
    public int i = 0;
    public Quaternion R = new Quaternion();
    private Node coiffeur;
    private AnimControl control;
    private AnimChannel channel;
    private float cpt;
    private long currentTime;
    private long totalTime;

    @Override
    public void simpleInitApp() {
    Vector3f v1 = new Vector3f();
    //v1.add((float)4.6,(float)2.5 ,(float)-3.3 );
    v1.setX((float) -5.304646E-4);
    v1.setY((float) 2.621802);
    v1.setZ((float) -0.020643318);
    cam.setLocation(v1);
    R.set((float) 0.08475369, (float) 0.8765378, (float) -0.16763328, (float) 0.44316736);
    cam.setRotation®;

     scene = assetManager.loadModel("Scenes/roooom2.j3o");
    
     rootNode.attachChildAt(scene, 0);
    
     Spatial chair = assetManager.loadModel("Models/chair2/chaise_coif.j3o");;
     //coiffeur.setMaterial(assetManager.loadMaterial("Models/chair2/chaise_coif.material"));
     rootNode.attachChild(chair);
     Vector3f v2 = new Vector3f((float) 4.380863, (float) 0.061071157, (float) -1.6524669);
     chair.setLocalTranslation(v2);
     R.set(0, 0, 0, 0);
     chair.setLocalRotation(R);
     chair.setLocalScale((float) 0.25);
     Material mat = new Material(assetManager, "Common/MatDefs/Misc/ColoredTextured.j3md");       
     chair.setMaterial(mat);
    

// coiffeur = (Node) assetManager.loadModel(“Models/Man/coiffeur.j3o”);
// coiffeur.setMaterial(assetManager.loadMaterial(“Materials/material.j3m”));
// rootNode.attachChild(coiffeur);
// coiffeur.rotate(0, 2, 0);
// coiffeur.updateGeometricState();
//

    /*********** this the part where i do the attechement of appstate :/ ***/
    Man t = new Man();

    t.initialize(stateManager, this);

    stateManager.attach(t);

    t.setEnabled(true);
}

@Override
public void simpleUpdate(float tpf) {
    /******** this is the same code i use in appsatate and it works in main  *********/

// currentTime = System.currentTimeMillis();
//
// if (currentTime - totalTime >= 1000) {
// /* Spatial temp = this.app.getRootNode().getChild(“coiffeur”);
// temp*/ coiffeur.setLocalTranslation(cpt, coiffeur.getLocalTranslation().getY(), 0);
// cpt += .1;
// channel.setAnim(“my_animation”);
// channel.setLoopMode(LoopMode.Loop);
// coiffeur.updateGeometricState();
//
//
//
//
//
// Quaternion localRotation = new Quaternion();
// //localRotation = this.app.getRootNode().getChild(“chair”).getLocalRotation();
// //Vector3f localTranslation = chair.getLocalTranslation();
//
// if ((float) /*localRotation.getX() */ cpt < 180) {
//
// cpt++;
// } else {
// cpt = 0;
//
// }
// localRotation.set(0, 0, cpt, 0);
// //this.app.getRootNode().getChild(“chair”).setLocalRotation(localRotation);
// //this.app.getRootNode().getChild(“coiffeur”).setLocalRotation(localRotation);
// //Spatial chaire_temp = this.app.getRootNode().getChild(“chair”);
// //chaire_temp.rotate(localRotation);
// //chaire_temp.setLocalTranslation(cpt, temp.getLocalTranslation().getY() , 0);
// //cpt+=.1;
//
//
//
// System.out.println(/this.app.getRootNode().getChild(“chair”).getLocalRotation()/localRotation.toString());
//
// totalTime = currentTime;
// }

    //TODO: add update code
    /*
     if (i < 10) {
     model2[i] = assetManager.loadModel("Models/Man/coiffeur.j3o");
     model2[i].setLocalTranslation(i, 0, 0);
     rootNode.attachChild(model2[i]);
     i++;
     }*/
    //get camera position 
    //  Vector3f v = cam.getLocation();

// System.out.println("Location: " + cam.getLocation());
// System.out.println("Rotation: " + cam.getRotation());
}

@Override
public void simpleRender(RenderManager rm) {
    //TODO: add render code
}

}

sigh

1 Like

this is what i did :confused: what do i have to exactly the code isn’t it clear ? cause i can see like in ther posts

I just had a quik look and I would say your mistake is here:

 t.initialize(stateManager, this);

Do NOT call this in your code !!! It is called when you attach your app state to the AppStateManager what you are doing write afterwards with:

 stateManager.attach(t);

I would recommend you to have a look at the following wike entries:

https://jmonkeyengine.github.io/wiki/jme3/advanced/application_states.html#appstate
https://jmonkeyengine.github.io/wiki/jme3/advanced/application_states.html#toolbar

1 Like

first thank you for replaying
what i can say that i already looked to the link before but i can’t figure it out
i am starting to think that i am using the wrong tool ( appstate ) my goal is to control this spatial with its animation as a thread to make each caracter do his function

If only there were a bunch of tutorials or something…

1 Like

Oh yeah, this sarcasm :stuck_out_tongue_winking_eye:

For me it sounds like Controls are what your are searching for. And even here there are VERY GOOD wiki entries, you just have to read them. :wink:
https://jmonkeyengine.github.io/wiki/jme3/advanced/custom_controls.html#toolbar

1 Like

before i post anything here i make sure that this is my last option so thank for the motivation speach :stuck_out_tongue:

I have tried costum control its the same problem it dosent update correctly it keep a clone of the model and move another one like you can see in the picture i shared

Okay, lets go through this:

What you do right now is the following:

In the simpleInitApp() of the Main class you call the following code at the end:

Man t = new Man(); // you create a new instance, all fine so far ...

t.initialize(stateManager, this); // what the hell shall that be??? NO! REMOVE THIS LINE!

stateManager.attach(t); // this is the way to go! ONLY THIS !!!!!!!!!

t.setEnabled(true); // isn't really neccessary, but okay ...

Let’s have a look at your initialize method:

public void initialize(AppStateManager stateManager, Application app) {
  [ ... some code ... ]

    System.out.println("Here i am");
    initialized = true;
    simpleInitApp(); // in this method you create your model and attach it to the scene!
}

Your simpleInitApp() method does the following:

public void simpleInitApp() {

	System.out.println("Here i am");
            
            // the global field Coiffeur gets a value!!!
	coiffeur = (Node) assetManager.loadModel("Models/Man/coiffeur.j3o");
	coiffeur.setMaterial(assetManager.loadMaterial("Materials/material.j3m"));
	rootNode.attachChild(coiffeur); // is attached to scene
	coiffeur.rotate(0, 2, 0);
	coiffeur.updateGeometricState(); // not neccessary in newer jmes

	totalTime = System.currentTimeMillis();
}

Maybe you got it: Did you ask yourself why you see 2 models? Here is the answer, because you created 2 models (instances) and attached them both to the scene!

  1. time: t.initialize(stateManager, this); this calls simpleInitApp() of your AppState which in turn attaches a model to the Scene and gives a value to the global field Coiffeur.
  2. time: stateManager.attach(t) here the initialize method is called from the render thread of jme. The same happens like in 1. But now the global field Coiffeur is “overriden”. You only have access to the latest created model.

I hope it is clear now, what you are doing wrong here!

1 Like

Finally it worked thank very much u saved my day thank
he can walk normally now

I am glad it works :slight_smile:

But I really recommend you to read the wiki (about app states and controls and where they are used) and if you did already, do it again and make sure you really understand what you are reading.

Good luck and have fun developing your game!

1 Like