Change physics properties for all instances of a node

I’ve been trying to make a world where the player can run around and place a bunch of objects (blocks for simplicity right now) that are unmoveable, can be jumped on, etc. (I’ve been making physics nodes w/ mass = 0 for this and it works like I want it to) Then I want to be able to press a button to change the mass of the objects so that they’re each their respective masses (say all are 1f for now) so that they behave as dynamic physics objects subject to forces from that point on.



I’m stuck on two things with this right now:

  1. I can change the mass from 1 to something larger just fine, but when I try to change from 0 to 1 (or any value that makes the object dynamic) the object becomes invisible until it is hit, and when it is hit, it just translates in 1 direction forever and passes through everything. I’ve been able to get it to move properly if I remove the node from the physics space, change the mass of the object, and place it back into the physics space, but it still remains invisible until hit. I’ve tried using some commands to update the physics space and bulletAppState, but nothing seems to help that.


  2. I can only seem to select the last instance of the node I created to manipulate the mass. Is there a way to select all instances of a node that was called the same thing, i.e. chairNode in a method called makeChair();, and is there also a way to see all the nodes that are in your physics space? (I want to implement a way to save/load a world that the player has built later on, and it’d be a quicker way to change certain objects’ properties)
  1. Objects with mass=0 should not be changed, they are registered differently in the physics system moving them or changing their properties will always end in strange results. Just replace it with a dynamic node.
  2. Just keep a list of your objects when you create them.

Yeah, I’m not quite sure how to make a list like that, which is why I hoped there was a built in one to the physics space. :frowning: I can make a list just fine as long as all objects are pre-defined, i.e. they aren’t dynamically defined by the player. I’ve been trying to make ‘counters’ for the numbers of the blocks in the physics space, but I’m unsure how to get a specific node and not just the node name into the function bulletAppState.getPhysicsSpace().remove(brickNode);



[java]

List brickNames;



/** This method creates one individual physical brick. /

protected void makeBrick(Vector3f location, int mass) {

/
* initializing the brick geometry that is reused later /

Geometry box_geo = new Geometry(“brick”, brick);

box_geo.setMaterial(wall_mat);

PhysicsNode brickNode = new PhysicsNode(

box_geo, // geometry

boxCollisionShape, // collision shape

mass); // mass

/
* position the brick and activate shadows */

brickNode.setLocalTranslation(location);

brickNode.setSleepingThresholds(0.5f, 0.5f);

brickNode.setName(“brick”);

brickNames.add(brickNode);

rootNode.attachChild(brickNode);

bulletAppState.getPhysicsSpace().add(brickNode);

}[/java]



Note, I was adding a counter to the brickNode.setName() method to alter the names of each brick. Also, with the List ‘brickNames’ implemented, the game crashes as soon as it tries to make a brick.

[java]

List bricks=new LinkedList();



/** This method creates one individual physical brick. /

protected void makeBrick(Vector3f location, int mass) {

/
* initializing the brick geometry that is reused later /

Geometry box_geo = new Geometry(“brick”, brick);

box_geo.setMaterial(wall_mat);

PhysicsNode brickNode = new PhysicsNode(

box_geo, // geometry

boxCollisionShape, // collision shape

mass); // mass

/
* position the brick and activate shadows */

brickNode.setLocalTranslation(location);

brickNode.setSleepingThresholds(0.5f, 0.5f);

brickNode.setName(“brick”);

brickNames.add(brickNode);

rootNode.attachChild(brickNode);

bulletAppState.getPhysicsSpace().add(brickNode);

bricks.add(brickNode);

}

[/java]

Well, I can remove all the bricks from the PhysicsSpace now, but that’s because the List is for objects, is there anyway to make a list for nodes, locations, vectors, spatials, etc.? I can’t seem to pull that information out of the object after I put it into that list. I know there’s a way to use arrays to do that, but the size of the array has to be set first and it seems like bad practice to make a new one with one size larger to transfer the old stuff plus one more entry in it…



One part has me confused too, if you put it something into the rootNode it has to be a spatial or a node, and into the physicsSpace it has to be a physicsNode, but as soon as I put it into the list it gets converted to an ‘object’, why?



I also probably shouldn’t have called what I wanted to transfer ‘objects’ but that was the best way I could think of to describe them. Maybe ‘item’ would have been better.

[java]List<PhysicsNode> list=new LinkedList<PhysicsNode>();[/java]

1 Like

Yay! That did the trick, and the code is about as efficient as I had originally hoped it could be! :smiley: Thanks again for your patience and help in seeing this matter through.



Here’s the code for anyone that’s interested:



[java] List bricks = new LinkedList();



public void initPhysics() {

int numObjects = bricks.size();

PhysicsNode oldBrick;

Vector3f brickLocation;

for (int j = 0; j < numObjects; j++){

oldBrick = bricks.get(j);

brickLocation = oldBrick.getWorldTranslation();

rootNode.detachChild(oldBrick);

bulletAppState.getPhysicsSpace().remove(oldBrick);

makeBrick(brickLocation, 1f);

}

}



/** This method creates one individual physical brick. /

protected void makeBrick(Vector3f location, float mass) {

/
* initializing the brick geometry that is reused later /

Geometry box_geo = new Geometry(“brick”, brick);

box_geo.setMaterial(wall_mat);

PhysicsNode brickNode = new PhysicsNode(

box_geo, // geometry

boxCollisionShape, // collision shape

mass); // mass

/
* position the brick and activate shadows */

brickNode.setLocalTranslation(location);

brickNode.setSleepingThresholds(0.5f, 0.5f);

brickNode.setName(“brick”);

rootNode.attachChild(brickNode);

bulletAppState.getPhysicsSpace().add(brickNode);

bricks.add(brickNode);

}



[/java]



Note: the initPhysics() method is utilized when a key is pressed by the user.