All my walls return to origin…

I have a setup with some walls, up to 6 walls form a Cellnode (class node) that acts as the parent of the walls. Now i want to set up those walls as solid – in real, this is of course a routine doing this with all walls –

[java]
public void setWall(ImageID imgID, DIR cd, boolean hard)
{
// this returns an AbstractBox-derived Mesh. In principle
// it is a box that can have 0-6 walls (well, in fact up to 8, but
// lets stay 3D) and you can configure for each if it is
// the inside or outside and give them arbitrary offsets…
// without ‘addControl’, it works pretty well.
CellMesh wall = super.setWall(imgID, cd, null);
// this sets up my testing RBC
RigidBodyControl r = new RigidBodyControl(0.0f);

if (wall.hasOne())
{
	// walls obj-param is assured to be the Geometry
	Geometry geom = (Geometry) wall.getOParam();
	// now this line causes the problem
	geom.addControl(r);
	ManagedApplication.getPhysics().getPhysicsSpace().add(r);
	return;
}
ManagedApplication.getPhysics().getPhysicsSpace().remove(r);

}
[/java]

So the problem is: as soon as i execute geom.addControl®, my up till there in correct placement setup walls all return to the origin, just offsettet by their relation to Cellnode, so it seems that this command moves the cellnode (walls parent) back to the origin. cellnode has been moved with the move()-command for this node.

To test if this has something to do with my CellMesh, i’ve temporarily rewritten the fn to the following:
[java]
// (…)

if (wall.hasOne())
{
	// i create a new box-shape…
	Geometry geom = new Geometry("", new Box(0.5f, 0.5f, 0.5f));
	// …give it a green hue…
	geom.setMaterial(Manager.getColormark(ColorRGBA.Green));
	// …and move the box to the center of the CellNode node.
	node.attachChild(geom);
	// if i leave out the following line, i get one green box at the center of
	// each cellnode, but if i execute it, i get all green boxes at world's origin. 
	geom.addControl(r);
	ManagedApplication.getPhysics().getPhysicsSpace().add(r);
	return;
}

// (…)

[/java]

While the change moves the green boxes, the walls stay in place, so it does not move CellNode but allways the object it is added as control. Is this just gravity to the supermassive Black Hole at sector 0/0/0 or what could cause this behaviour…?

No, its normal. :slight_smile: Bullet doesn’t have nodes so the location is applied to the world location of the spatial. You can apply it to the local location but that can be confusing as objects that are not visibly together can collide. This is written in the manual btw.

Manuals are uncool^^ … OK, this one must have surpassed me, perhaps there should be a hint at the beginning of the physics tutorials also… :smiley:

Nevertheless, this is my current solution… seems to work…

[java]

import com.jme3.bullet.objects.PhysicsRigidBody;
import com.jme3.math.Transform;
import com.jme3.scene.Node;
import com.jme3.util.SafeArrayList;

/**

  • PhysicsNode extends JME3-Node by the capability of local

  • tranformed BulletPhysics bodies.

  • @author .rhavin for ShadowTec media

  • @version 0.3.0
    /
    class PhysicsNode extends Node
    {
    /
    *

    • For easier used-side retrievement of attached controls,
    • we also grant acces to the list by a given StingID. For
    • perfomance reasons, this is just informational and there
    • may be multiple bodies with the same name. */
      protected class RigRef
      {
      public String id = null;
      PhysicsRigidBody body = null;
      }

    // this is our list of attached PhysicsRigidBodies
    protected SafeArrayList childsPhy
    = new SafeArrayList(RigRef.class);

    public PhysicsNode(){}

    /**

    • Attach a PhysicsRigidBody to this node. The body

    • will follow the translation of this node. It needs

    • to have a spatial attached.

    • @param child PhysicsRigidBody to add to this node

    • @return int index the body has been added to.
      */
      public int attachPhysicsBody(PhysicsRigidBody child, String strID)
      {
      if (child == null)
      throw new IllegalArgumentException(“child cannot be null”);

      if (child.getUserObject()==null)
      throw new IllegalArgumentException(“child has no spatial attached”);

      RigRef ref = new RigRef();
      ref.body = child;
      ref.id = strID;

      childsPhy.add(ref);

      // as physics cant have parent nodes applied to their transform,
      // we transform them now into world
      Transform t = getWorldTransform();
      child.setPhysicsLocation(t.getTranslation());
      child.setPhysicsRotation(t.getRotation());

      return childsPhy.size();
      }

    /**

    • Remove the given body from this nodes list.
    • @param child PhysicsRigidBody to remove from this node.
    • @return int original index of this body in the nodes list or -1.
      */
      public int detachPhysicsBody(PhysicsRigidBody child)
      {
      if (child == null)
      throw new IllegalArgumentException(“child cannot be null”);
      int index = childsPhy.indexOf(child);
      if (index == -1)
      return -1;
      detachPhysicsBodyAt(index);
      return index;
      }

    /**

    • Remove identified bodies from this nodes list.
    • @param id The String identifier.
    • @param justfirst if set to true, just the first identified
    • body is removed.
    • @return number of removed bodies.
      */
      public int detachPhysicsBody(String id, boolean justfirst)
      {
      int ret = 0;
      int idx = childsPhy.size();
      RigRef ref = null;
      while (idx–>0)
      {
      ref = childsPhy.get(idx);
      if (ref.id != id)
      continue;
      childsPhy.remove(ref);
      ret++;
      if (justfirst)
      return 1;
      }
      return ret;
      }

    /**

    • Remove the given body from this node.
    • @param index the index of the PhysicsRigidBody in the nodes list.
    • @return the detached PhysicsRigidBody or null if none has been found.
      */
      public PhysicsRigidBody detachPhysicsBodyAt(int index)
      {return childsPhy.remove(index).body;}

    /**

    • Remove all bodies from this node.
      */
      public void detachAllPhysicsBodies()
      {
      for (int i = children.size()-1; i>=0; i–)
      {detachPhysicsBodyAt(i);}
      }

    /**

    • This intercepts JME3 Nodes setTransformRefresh() to apply
    • the changes in transformation to all attached PhysicBodies.
      */
      @Override
      protected void setTransformRefresh()
      {
      super.setTransformRefresh();
      Transform t = getWorldTransform();
      for (RigRef ref : childsPhy.getArray())
      {
      ref.body.setPhysicsLocation(t.getTranslation());
      ref.body.setPhysicsRotation(t.getRotation());
      }
      }
      }

[/java]

If you attach your nodes to the scene graph and position your entities (set transforms) first, then attach the RigidBodyControls, and add them to the physics space. This will ensure the Physics controls are added where the spatial is located.

Then you don’t need to call setphysicslocation/rotation

Thats what i tried originally, but when i moved the nodes, the RBCs didnt follow, so thats why i came up with this approach.

If you want to move the physics objects like spatials (setLocal…) then you need to make them kinematic. If you do that they will take on the location and rotation of the spatial. Obviously you lose all physics effects on the objects but they still work on the other objects. But as you said, manuals and javadoc are boring :stuck_out_tongue:
The content of this post is meant to be read as a straight information or question without an implicit dismissive stance or interest in having the other party feel offended unless there’s emotes that hint otherwise or there’s an increased use of exclamation marks and all-capital words.

@normen said: If you want to move the physics objects like spatials (setLocal..) then you need to make them kinematic.

With the same setting, i get…

Rootnode->Cellnode(class Node)->CellMesh
setKinematic(true): ~34 fps, geometry needs to have material attached
Rootnode->Cellnode(class PhysicsNode)->CellMesh
attachPhysicsBody(): ~64 fps, materialless geometry possible

A “materialless” geometry is never possible, an “attachPhysicsBody” method exists nowhere in jME3, your “test” is somehow flawed.
The content of this post is meant to be read as a straight information or question without an implicit dismissive stance or interest in having the other party feel offended unless there’s emotes that hint otherwise or there’s an increased use of exclamation marks and all-capital words.

@normen said: A "materialless" geometry is never possible, an "attachPhysicsBody" method exists nowhere in jME3,

Line 38 in my code… and a Geometry without Material is all thats needed if you’re just interested in its bounds…

If the physics control is not attached to a scene its not updated, maybe that explains your difference? A geometry without material and with a physics control will fail if the control is supposed to do anything. Else just use the base physics objects if you don’t want to attach them to a spatial. I really think its time for you to read the manual instead of me reading your code I guess, there seems to be a lot of preconceptions.
The content of this post is meant to be read as a straight information or question without an implicit dismissive stance or interest in having the other party feel offended unless there’s emotes that hint otherwise or there’s an increased use of exclamation marks and all-capital words.

Well, contrary to some of my pattering i actually read much of the documentation, its just that sometimes i also just read the sourcecode and – sometimes – just happen to miss a detail.

In this concrete scenario, i have some kind of hypercube – you’ve seen cube2? – so just imagine a CellMesh and its derived TexturedMesh as a construct that derives from AbstractBox and provides a kind of translation into 3D. So i can easily say something like:

[java]

Node group = (…)

TexturedCell tc = new TexturedCell(/scaling, position etc./);
tc.setWall(ImageID.SANDBLOCKS, CellMesh.DIR.TOP, true);
tc.setWall(ImageID.GLASSWALL, CellMesh.DIR.ANA, true);
tc.setWall(ImageID.REDCARPET, CellMesh.DIR.RIGHT, false);
group.attachChild(tc.getNode());
[/java]

And so get a box that has a solid (true) sandblock-textured wall in the top (if dimension top-bottom is currently translatet into 3D), a solid glasswall in the ana (if dimension ana-kata is translated) and a non-solid (false) redcarpet at the right (if right-left is currently translated). The node returned with tc.getNode() is a PhysicsNode (see code) As each TexturedCell may have up to 16 different Materials (one for each side in and out), the CellMesh dynamically creates a mesh for every Material. As the in- and outside may have arbitrary offsets (so the cell is a box with a given wallthickness), those walls may overlap to reduce need of additional triangles at joists and connections, where 3 cells come together. And as Physics cant overlap (it would be nice to have a collisiongroup that collides with all else but does not check on itself…), the CellMesh provides an additional Geometry that does not depend on material (rendering) but on solidness (physics). It is never rendered so it does not need any material.

I just tried it with some bouncing balls, and it works. And if i move the cell, i also move the walls attached. so currently i cant see anything that could rise problems. So if u see one, please tell me…