UnsupportedOperationException on TangentBinormalGenerator.generate(spatial) ? (8 posts)

  • Profile picture of pengu pengu6p said 3 months, 2 weeks ago:

    Hello guys, i have a problem. I`ve made a sprite spammer witch generate and attach to root node a sprite at every x milisec and i`ve done it right but i don`t know why sometimes(very frequently) i get this exception when I call TangentBinormalGenerator.generate(spatial) on the Sprite constructor…

    I don`t know why i get this exception when I call TangentBinormalGenerator.generate(spatial).
    SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
    java.lang.UnsupportedOperationException: Data has already been sent. Cannot setupData again.
    at com.jme3.scene.VertexBuffer.setupData(VertexBuffer.java:476)
    at com.jme3.scene.Mesh.setBuffer(Mesh.java:885)
    at com.jme3.util.TangentBinormalGenerator.processTriangleData(TangentBinormalGenerator.java:601)
    at com.jme3.util.TangentBinormalGenerator.generate(TangentBinormalGenerator.java:158)
    at com.jme3.util.TangentBinormalGenerator.generate(TangentBinormalGenerator.java:114)
    at com.jme3.util.TangentBinormalGenerator.generate(TangentBinormalGenerator.java:125)
    at game.sprite.enemies.dyna.aer.Wraith.(Wraith.java:22)
    at game.levels.spammer.AerianEnemiesSpammer.spam(AerianEnemiesSpammer.java:59)
    at game.levels.spammer.Spammer.onUpdate(Spammer.java:122)
    at game.SpammersManager.update(SpammersManager.java:12)
    at game.MyGame.simpleUpdate(MyGame.java:230)
    at com.jme3.app.SimpleApplication.update(SimpleApplication.java:258)
    at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:149)
    at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:185)

    at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:223)
    at java.lang.Thread.run(Unknown Source)

    Can you help me please…

  • Profile picture of pspeed pspeed815p said 3 months, 2 weeks ago:

    Because you are calling it after you’ve added the sprite’s mesh to the scene.

  • Profile picture of pengu pengu6p said 3 months, 2 weeks ago:

    No,I call it before I attach the sprite mesh to the scane.

    public abstract class DynamicEnemy extends NormalEnemy
    {
    	............................................................
    	protected void loadModel(String name, boolean XML)
    	{
    		this.name=name;
    		xmlModel=XML;
    		if(XML)
    		{
    			model=MyGame.assetManager.loadModel(MODELS_PATH+""+name+""+name+".mesh.xml");
    			scale(1.5f);
    		}
    		else
    			model=MyGame.assetManager.loadModel(MODELS_PATH+""+name+""+name+".obj");
    
    		TangentBinormalGenerator.generate(model);
    	}
    	......................................................
    }

    public class Aerian extends DynamicEnemy……….
    public class NormalEnemy extends Enemy……….
    public class Enemy extends Sprite……..

    public class Wraith extends Aerian
    {
    	public Wraith()
    	{
    		init();
    		attachChild(model);
    		Reactie reactor=new Reactie(this, new Vector3f(0, 0.45f, -0.8f));
    		attachChild(reactor);
    		initGuns();
    	}
    	@Override
    	protected void init()
    	{
    		loadModel("Wraith",false);
    		Material mat=MaterialsBank.LIGHTING.clone();
    		addDiffuseTexture(mat, "wraith_diffuse.png");
    		addNormalTexture(mat, "wraith_normal.png");
    		model.setMaterial(mat);
    	}
    }
    public class Spammer
    {
    .......................................
    //this methid is called once at x milisec when i need to spam a sprite
    @Override
    	protected Sprite spam()
    	{
    		Class clasaAleasa=chooseRandom(false);
    		Sprite obj=null;
    		if(clasaAleasa.getName().equals(Banshee.class.getName()))
    			obj=new Banshee();
    		if(clasaAleasa.getName().equals(Mutalisk.class.getName()))
    			obj=new Mutalisk();
    		if(clasaAleasa.getName().equals(Phoenix.class.getName()))
    			obj=new Phoenix();
    		if(clasaAleasa.getName().equals(Reaper.class.getName()))
    			obj=new Reaper();
    		if(clasaAleasa.getName().equals(Scourge.class.getName()))
    			obj=new Scourge();
    		if(clasaAleasa.getName().equals(Scout.class.getName()))
    			obj=new Scout();
    		if(clasaAleasa.getName().equals(SuperCow.class.getName()))
    			obj=new SuperCow();
    		if(clasaAleasa.getName().equals(UFO.class.getName()))
    			obj=new UFO();
    		if(clasaAleasa.getName().equals(Wraith.class.getName()))
    			obj=new Wraith();
    
    		MyGame.rootNode.attachChild(obj);
    //		level.attachChild(obj);
    		return obj;
    	}
    .......................................
    }
    
  • Profile picture of pspeed pspeed815p said 3 months, 2 weeks ago:

    Well, you do call it after you’ve attached the _mesh_ to the scene… you just don’t realize that you do. I’m just telling you what the error message means and it is unmistakeable.

    So then we try to find reasons that what you think you are doing is not what you are actually doing.

    In your loadModel() call if the same model has been loaded previously then it is cached and does not need tangent generation. Also, that means it’s mesh was shared and added to the scene the last time you used it.

    Are these just 2D sprites?

  • Profile picture of pengu pengu6p said 3 months, 2 weeks ago:

    oohh, i think i got it. So I must call it only first time when I attach a mesh to the scene node, not every time ahh thank you, i`ll give you an answer tomorrow.(sorry but now i`m very sleepy to work anymore, goodnight :) and thank you again )

  • Profile picture of pengu pengu6p said 3 months, 2 weeks ago:

    Hey, no, this are 3d sprites

  • Profile picture of pengu pengu6p said 3 months, 2 weeks ago:

    What about if i detach the spatial from the scene graph, do I need to generate the tangent when second time too?Is there any possible way to find if a mesh tangent was generated ?

  • Profile picture of pspeed pspeed815p said 3 months, 2 weeks ago:

    You only ever need to generate it once for a mesh.

    If a mesh starts with no tangent buffer.

    You generate tangents… now it has a tangent buffer.

    It will always have the tangent buffer from that point on until you remove it.

    You can see if it has a tangent buffer by trying to get that VertexBuffer from the Mesh.