UnsupportedOperationException on TangentBinormalGenerator.generate(spatial) ?

Hello guys, i have a problem. Ive made a sprite spammer witch generate and attach to root node a sprite at every x milisec and ive done it right but i dont know why sometimes(very frequently) i get this exception when I call TangentBinormalGenerator.generate(spatial) on the Sprite constructor...<br /> <br /> <br /> I dont 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…

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

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

[java]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+"&quot;+name+"&quot;+name+".mesh.xml");

scale(1.5f);

}

else

model=MyGame.assetManager.loadModel(MODELS_PATH+"&quot;+name+"&quot;+name+".obj");



TangentBinormalGenerator.generate(model);

}



}[/java]



public class Aerian extends DynamicEnemy…

public class NormalEnemy extends Enemy…

public class Enemy extends Sprite…



[java]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);

}

}[/java]



[java]

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;

}



}

[/java]

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?

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, ill give you an answer tomorrow.(sorry but now im very sleepy to work anymore, goodnight :slight_smile: and thank you again )

Hey, no, this are 3d sprites

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 ?

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.