Quaternion lookat was it changed Jme 3.3

No no, I am not using the test models it’s an old animated ghoul and M16

If you are using your own custom models and don’t want to use the new animation system then you would need to use j3os created on 3.2.

Models loaded from various formats on 3.3 will be using the new animation system. A j3o file already has those controls ‘locked in’, so to speak, and so will use whatever it was exported with.

Edit: and if you were not using j3o files at all… well “there’s your problem” as you shouldn’t be loading things like ogre in your game.

It not that I don’t want to use the new system I just wanted to concentrate my ideas first and fix all those other issues after.

anyway is there an example of manual conversion anywhere or tool

99.9% sure that JmeConvert jars were built with 3.2 (the build.gradle file says so):

So if you use that to convert a model to j3o then it will use the old animation system. (Except for gltf which always used the new animation system.)

Else you can download an SDK that uses 3.2 and use it to convert your model.

@pspeed thanks for the help appreciated

I can confirm that my game sample now starts in 3.3 however I encountered yet another issue that I am trying track down my ghoul model only loads in T pose and won’t call it’s animations, while my m16 loads and will play all animation as expected, both models have and should spawn with their idle animation set, the difference between the two models is the M16 is loaded at runtime and the ghoul instances, for now, loaded by input action.

Is there an additional step that is required to trigger the animation control for “old” models not loaded at run time.

I used the SDK to convert the models and can confirm that animations appear to have been converted also, i.e. they playback in the SDK

Note: in 3.2 ghoul instances would sometimes load in T pose but only when jme3 was under “stress”, 150+ attacking and friendly ghouls just for kicks…quite a sample I wasn’t fortunate enough to discover and build upon, that

We’d probably have to see the code you use to set the idle animation to help debug it for you.

the model setup

private void setupModel(String mat,String modelNode)
{
	   /* Material skin = new Material(main_HKR.getAssetManager(), mat);
        skin.setTexture("DiffuseMap", main_HKR.getAssetManager().loadTexture(dif));
        skin.setTexture("NormalMap", main_HKR.getAssetManager().loadTexture(norm));
        skin.setTexture("SpecularMap", main_HKR.getAssetManager().loadTexture(spec));*/
                Material skin = new hks.matDefs.MaterialSP2(main_HKR.getAssetManager().loadMaterial(mat));
                model = (Node)main_HKR.getAssetManager().loadModel(modelNode);
        TangentBinormalGenerator.generate(model);
        model.setMaterial(skin);
		model.getChild(0).setName(Integer.toString(id));
		animControl = model.getControl(AnimControl.class);
		animChannel = animControl.createChannel();
		animControl.addListener(this);
		animChannel.setAnim("idle");
		
		soldier = new Node();
		soldier.attachChild(model);
		model.setLocalTranslation(modelOffset);
		model.setLocalScale(1.0625f);
		main_HKR.getRootNode().attachChild(soldier);
		capsule = new CapsuleCollisionShape(.506f, .956f, 1);//12.5% increase
		control = new RigidBodyControl(capsule, 50);
		control.setAngularFactor(0);
		control.setLinearDamping(linearDamping);
		main_HKR.getBulletAppState().getPhysicsSpace().add(control);
	}

the input action

if (name.equals("spawnEnemy") && !keyPressed)
				m.getEnemies(id).add(new NPC_HKR(m,ghoul.mat, ghoul.model));

“The def” holds asset path

package hkr.start.actor.defs;

public class Ghoul {
    public String model="hkr/start/assets/ghoul/ghoul.mesh.j3o";
    public String mat="hkr/start/assets/ghoul/ghoul.j3m";
}

In the old animation system, animations were stored in an AnimControl. In the new system, they’re stored in an AnimComposer.

The old system always loaded models in bind pose. The new system doesn’t necessarily load models in bind pose. To get the model to bind pose, you may need to invoke applyBindPose() on the Armature object. (Armature is roughly equivalent to the old Skeleton class.)

No you misunderstand I want the model to start it’s animation on loading which it does in 3.2, only under “stress” …“as in me very quickly loading ghouls” it would load model in bind pose or a model would enter bind pose sometimes, in 3.3 it loads in bind pose and doesn’t leave bind pose at all…at this stage I am using the old animation for a while still since the models are placeholders for now

And so NPC_HKR somehow calls setupModel() I guess?

my bad sorry

public NPC_HKR(Main_HKR m,String mat, String modelNode)
	{
		main_HKR = m;
		id = main_HKR.getId();
		
		setupModel(mat,modelNode);
		
		targetTime = main_HKR.getTime() - reTargetTime;
		attackTime = main_HKR.getTime();
		sprintStartTime = main_HKR.getTime();
	}

any word on what might be the issue, by best guess is 3.3 has issues with how I load the ghoul or the export is some how messing up the animations

My guess is that 3.3 fixed the randomness you were seeing in 3.2, ie: the problem happens every time now instead of randomly.

Personally, I’ve never had this particular issue… and if I did, I’d be looking at the rest of my code to make sure I’m not resetting the animation somewhere where there could be a race condition.

Also, if you can manage to put together a simple single class test case that illustrates the problem then it will be easier to track down. And if that test case happens to work for you then you have something to poke at to find the gap.

yeah I’ll do that seems the best course at this point

I dont know if this will help but have you tried moving your animation stuff to a control and using setSpatial to set animation on adding the control?

The control should have the AnimEventListener listener for animations in it. I use a spatials position to determine what animation to play, which is determined when the animation ends by a check of spatials position. I have not used this with the new animation system but I am thinking it should work similar with some modifications.

Then other controls, like a physics control (a control for physics actions like navigation) for example can determine positions like set running, idle, walking, whatever, and when you want a position to be checked, just stop the animation. The control will then check for a position and start the new animation.

You then use default T pose to signal visually when something goes wrong. You see a T pose and you know something isn’t working.

If I remember correctly, I ran into situations where animations wouldn’t work, depending on when and where in the code you set them, as well as having delays in animations starting when I wanted on occasion. By setting the animation when the control was added, and using the control to set animations, it fixed that for me.

The unmodified version of the sample I am building around doesn’t seem to suffer this, so I am guessing a change I made to extend my version doesn’t play well with 3.3. I am trying the track it down now

yeah I can confirm that my change to the way the models and animation control are loaded is messing with jme3.3, the original code loaded the model in a “hard coded” which worked and continues to work, I changed the code to allow for any model and material to be loaded by defining path strings in the constructor most of the code remained more or less the same, I checked very carefully to make certain as a test wrote both methods and constructors into the my app the original and my version worked in 3.2 and 3.3 only the hard coded loading works as expected the fed path loading fails to trigger the animations

I am quite puzzled at how or why that change managed to create such an adverse effect between both versions

the original constructor and load method

	public NPC(Stage s)
	{
		stage = s;
		id = stage.getId();
		
		setupModel();
				
		targetTime = stage.getTime() - reTargetTime;
		attackTime = stage.getTime();
		sprintStartTime = stage.getTime();
	}


private void setupModel()
	{
		Material skin = new Material(stage.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
		skin.setTexture("DiffuseMap", stage.getAssetManager().loadTexture(new String("assets/ghoul/diffuse.png")));
		skin.setTexture("NormalMap", stage.getAssetManager().loadTexture("assets/ghoul/normal.png"));
		skin.setTexture("SpecularMap", stage.getAssetManager().loadTexture("assets/ghoul/specular.png"));
		
		model = (Node)stage.getAssetManager().loadModel("hkr/start/assets/ghoul/ghoul.mesh.j3o");
		model.setMaterial(skin);
		model.getChild(0).setName(Integer.toString(id));
		TangentBinormalGenerator.generate(model);
		
		animControl = model.getControl(AnimControl.class);
		animChannel = animControl.createChannel();
		animControl.addListener(this);
		animChannel.setAnim("idle");
		
		ghoul = new Node();
		ghoul.attachChild(model);
		model.setLocalTranslation(modelOffset);
		//model.setLocalScale(.875f);
		model.setLocalScale(1.0625f);
		stage.getRootNode().attachChild(ghoul);
		
		//capsule = new CapsuleCollisionShape(.45f, .85f, 1);
		capsule = new CapsuleCollisionShape(.506f, .956f, 1);//12.5% increase
		control = new RigidBodyControl(capsule, 50);
		control.setAngularFactor(0);
		control.setLinearDamping(linearDamping);
		stage.getBulletAppState().getPhysicsSpace().add(control);
	}

My version constructor and load method

public NPC(Stage s,String mat, String modelNode)
    {
	    stage = s;
        id = s.getId();
        
        setupModel(mat,modelNode);
        
        targetTime = stage.getTime() - reTargetTime;
        attackTime = stage.getTime();
        sprintStartTime = stage.getTime();
    }

private void setupModel(String mat,String modelNode)
    {
       /* Material skin = new Material(main_HKR.getAssetManager(), mat);
        skin.setTexture("DiffuseMap", main_HKR.getAssetManager().loadTexture(dif));
        skin.setTexture("NormalMap", main_HKR.getAssetManager().loadTexture(norm));
        skin.setTexture("SpecularMap", main_HKR.getAssetManager().loadTexture(spec));*/
        
        Material skin = new hks.matDefs.MaterialSP2(stage.getAssetManager().loadMaterial(mat));
        
        model = (Node)stage.getAssetManager().loadModel(modelNode);
        model.setMaterial(skin);
        model.getChild(0).setName(Integer.toString(id));
        TangentBinormalGenerator.generate(model);
        
       /* animControl = model.getControl(AnimControl.class);
        animChannel = animControl.createChannel();
        animControl.addListener(this);
        animChannel.setAnim("idle");*/
        
        ghoul = new Node();
        ghoul.attachChild(model);
        model.setLocalTranslation(modelOffset);
        model.setLocalScale(1.0625f);
        stage.getRootNode().attachChild(ghoul);
        
        animControl = model.getControl(AnimControl.class);
        animChannel = animControl.createChannel();
        animControl.addListener(this);
        animChannel.setAnim("idle");
        
        capsule = new CapsuleCollisionShape(.506f, .956f, 1);//12.5% increase
        control = new RigidBodyControl(capsule, 50);
        control.setAngularFactor(0);
        control.setLinearDamping(linearDamping);
        stage.getBulletAppState().getPhysicsSpace().add(control);
    }
	

What is your custom material class do? (Why do you have a custom material class?)

Are you extending JME classes just to avoid some factory methods or are they actually doing stuff?

That’s it thanks, that material class is broken, I adopted it so long ago that I can’t even remember why other than it may have had a feature I considered useful at that time, I imagine I’ll probably stumble back upon that reason at some point but I am glad you mentioned that, would have never looked in that direction, weirdly the breakage wasn’t highlighted had to open the file to see it, I didn’t even notice any visual issues with the textures :confused: