How to remove an object from the scene?

Hello,



I got a new problem : i’m trying to remove an object from a scenegraph.

it causes the program to crash !!! How can i avoid this ?

in my case the object has exploded anf i want to remove it from the scene.

Thanks in advance for your help.

In what way did you try to remove it? Detatching from the root node or force culling?



Could you elaborate this crash of yours?

considering i want to detach node object from the scene,

I do the following :


node.getParent().detachChild(node);



What 's wrong in that ?

Thanks

I don’t know… :slight_smile:



Could you show a stack trace or anything that describes what happened?

Here is the trace i got :



java.lang.IndexOutOfBoundsException: Index: 68, Size: 68

at java.util.ArrayList.RangeCheck(Unknown Source)

at java.util.ArrayList.get(Unknown Source)

at com.jme.scene.Node.draw(Node.java:300)

at com.jme.scene.Spatial.onDraw(Spatial.java:278)

at com.jme.scene.Node.draw(Node.java:301)

at com.jme.scene.Spatial.onDraw(Spatial.java:278)

at com.jme.renderer.lwjgl.LWJGLRenderer.draw(LWJGLRenderer.java:1108)

at com.jme.app.SimpleGame.render(SimpleGame.java:178)

at com.jme.app.BaseGame.start(BaseGame.java:71)

at bombastic.jme.BombasticUI.main(BombasticUI.java:47)



I don’t know what happen. It seems that the object has been removed while the renderer still try to draw it !!!

make sure you call updateGeometricState after changing the scenegraph in anyway. This (I hope) is your problem.

i do not have enough time to call updateGeometricState. it crashes while i’m not out of detachChild(node) method.



I may have to do it in my update method of the scenegraph. It is done actually from another thread.



i’ll test it and report the result to you.

according to your stack trace it is crashing during the render call…



at com.jme.app.SimpleGame.render(SimpleGame.java:178)



This is the danger of multithreading. Do all your graphics in a single thread. You are probably yanking out the node in one thread while it’s trying to draw it in the other.

I’ve been thinking about this a bit, it’s somewhat an interesting exercise in design. Depending on how it could be implemented it would be interesting to be able to ‘lock’ the node tree during rendering, but allow for updates to it via a threadsafe queue while it was rendering. Then right before the next ‘lock’ or part of the process would be to update the node tree with those queued updates. That way a different (or multiple) thread(s) would be able to update the rendered node tree, or even attach threaded nodes to the tree itself.

I confirm, the detach must be call in the update thread followed by the updateGeometric.



But I agree with you guurk, there should be a lock mechanism to avoid these kind of problem.

//ok here i need some code to delete the bullet which is thrown to space after collision

//at the end of the class there is space to write the code

//i simply want object to be deleted after it had impact with target object thats all



package mygame;



import com.jme3.app.SimpleBulletApplication;

import com.jme3.bullet.collision.PhysicsCollisionEvent;

import com.jme3.bullet.collision.PhysicsCollisionListener;

import com.jme3.bullet.collision.PhysicsCollisionObject;

import com.jme3.bullet.collision.shapes.MeshCollisionShape;

import com.jme3.bullet.collision.shapes.SphereCollisionShape;

import com.jme3.bullet.nodes.PhysicsNode;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.MouseButtonTrigger;

import com.jme3.renderer.RenderManager;

import com.jme3.scene.Geometry;

import com.jme3.scene.shape.Box;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Quaternion;

import com.jme3.math.Vector3f;





public class testClass extends SimpleBulletApplication implements ActionListener, PhysicsCollisionListener {





private Material myTmat;

private Material mymat;



private static final Box ball;

private static final SphereCollisionShape bulletCollisionShape;



static {

ball = new Box(Vector3f.ZERO,1,1,1f);



bulletCollisionShape = new SphereCollisionShape(1f);

}



public static void main(String[] args) {

testClass app = new testClass();

app.start();

}



private void setupKeys() {

inputManager.addMapping(“shoot”, new MouseButtonTrigger(0));

inputManager.addListener(this, “shoot”);



inputManager.addMapping(“remove”, new MouseButtonTrigger(1));

inputManager.addListener(this, “remove”);

}





@Override

public void simpleInitApp() {

setupKeys();

myTmat = new Material(getAssetManager(), “Common/MatDefs/Misc/WireColor.j3md”);

myTmat.setColor(“m_Color”, ColorRGBA.Red);

mymat = new Material(getAssetManager(), “Common/MatDefs/Misc/WireColor.j3md”);

mymat.setColor(“m_Color”, ColorRGBA.Blue);

PhysicsNode node2 = new PhysicsNode(new MeshCollisionShape(new Box(Vector3f.ZERO,1,1,1f)), 0);

node2.setName(“theTarget”);

node2.setLocalTranslation(new Vector3f(0f, 0f, -10f));

node2.attachDebugShape(assetManager);

node2.setMaterial(myTmat);

rootNode.attachChild(node2);

getPhysicsSpace().add(node2);

// add ourselves as collision listener

getPhysicsSpace().addCollisionListener(this);



cam.setLocation(new Vector3f(0, 3f, 10));

cam.setRotation(new Quaternion(1.5714673E-4f, 1f, -0.16091813f, 9.6381607E-4f));

}



@Override

public void simpleUpdate(float tpf) {



}



@Override

public void simplePhysicsUpdate(float tpf) {

//TODO: add update code

}



@Override

public void simpleRender(RenderManager rm) {

//TODO: add render code

}



public void collision(PhysicsCollisionEvent event) {



if (“theTarget”.equals(event.getNodeA().getName()) || “theTarget”.equals(event.getNodeB().getName())) {

if (“ball”.equals(event.getNodeA().getName()) || “ball”.equals(event.getNodeB().getName())) {

fpsText.setSize(20f);

fpsText.setText(“You hit the Target, Boom!”);

//instances.clear();



}





}

}



public boolean collide(PhysicsCollisionObject nodeA, PhysicsCollisionObject nodeB) {

//group 2 only randomly collides

if (Math.random() < 1f) {

return true;

} else {

return false;

}

}









public void onAction(String binding, boolean value, float tpf) {

if (binding.equals(“shoot”) && !value) {

Geometry bulletg = new Geometry(“bullet”, ball);

//bulletg.removeControl(statsView);

bulletg.setMaterial(mymat);

PhysicsNode bulletNode = new PhysicsNode(bulletg, bulletCollisionShape, 1);

bulletNode.setName(“ball”);

bulletNode.setLocalTranslation(cam.getLocation());



bulletNode.setLinearVelocity(cam.getDirection().mult(300));

rootNode.attachChild(bulletNode);

getPhysicsSpace().add(bulletNode);





} else if (binding.equals(“remove”) && !value) {

//rootNode.removeFromParent();



//ok here i need some code to delete the bullet which is thrown to space after collision

}

}







}

I’m not following you @artvfx

This thread is so old it probably predates the stable version of jME 1.0. Did you mean to post your reply elsewhere? If so, please start by explaining your problem, and also use code tags, thanks.

Ok here is the whole story



i want to create a target that i could hit it by bullet



but after collision i want my bullet to be destroyed ,other wise it will keep going to endlessly

simple after the collision i want it to be deleted or what ever.

i used one of those bullet samples,TestCcd.java, which comes with JME

There is an example for exactly this, “TestWalkingChar” update your jMP to the latest nightly version by enabling the nightly update center via Tools->Plugins->Settings.

Edit: link to thread

ok ill give it a try,thanks guys