WireBox collisions detected on the inside instead of the outside (like for Box) jme3 r7293

EDIT: forgot to mention that I had to undo the r7291 fix for this, else the local position of the purple marker is not in the right place (but the fix doesn’t appear to fix the WireBox issue I point at here)

the direction of the normal CollisionResult.getContactNormal() is in the opposite direction for WireBox when compared with same size Box, that is, as if the collisions are detected inside the WireBox, on the inside surface, and that is why the normal is perpendicular on that surface

or something similar

in this screen, the Ray is passing thru the WireBox and hitting the red Arrow:

http://i.imgur.com/ZjoBy.jpg

see this post for all the details/testcase/screenies:

http://hub.jmonkeyengine.org/groups/general-2/forum/topic/remove-boxs-middle-lines-to-look-like-a-wirebox-possible/#post-125746

probably I shouldn’t have made a new topic… also unsure where I should post bug reports (I feel it was a bad idea to post bugs in Contributions before, ?)

I post the code for the screenie in this post, as follows (if you want to enable the Box[yellow] instead of the WireBox[purple box] the just comment one of these lines) :

[java]cosmos.attachChild(wireboxGeo);

// cosmos.attachChild(boxGeom);[/java]

[java]package org.jme3.forum;

import java.util.prefs.BackingStoreException;

import com.jme3.app.SimpleApplication;

import com.jme3.collision.CollisionResult;

import com.jme3.collision.CollisionResults;

import com.jme3.font.BitmapFont;

import com.jme3.font.BitmapText;

import com.jme3.input.KeyInput;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.KeyTrigger;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.FastMath;

import com.jme3.math.Quaternion;

import com.jme3.math.Ray;

import com.jme3.math.Vector2f;

import com.jme3.math.Vector3f;

import com.jme3.renderer.queue.RenderQueue.Bucket;

import com.jme3.scene.Geometry;

import com.jme3.scene.Node;

import com.jme3.scene.control.BillboardControl;

import com.jme3.scene.debug.Arrow;

import com.jme3.scene.debug.WireBox;

import com.jme3.scene.shape.Box;

import com.jme3.system.AppSettings;

public class NonUniformScaleFail2 extends SimpleApplication {

private Node markNode;

private final ColorRGBA markColor = ColorRGBA.Magenta;

public static void main(String[] args) throws BackingStoreException {

NonUniformScaleFail2 app = new NonUniformScaleFail2();

AppSettings aps = new AppSettings(true);

aps.load(aps.getTitle());

aps.setVSync(true);

app.setSettings(aps);

app.setShowSettings(false);

app.start();

}

private Node cosmos;

private final static String mapChangeScale = “mapChangeScale”;

private BitmapText chgScaleText;

/**

  • node relationship: rootNode->markParent->markNode (the magenta Arrow)
  • rootNode->cosmos->Box,WireBox rootNode is never transformed, for
  • simplicity or something where markParent & cosmos are transformed

    /

    protected void initMark() {

    // Node toNode =

    // new Node();

    markNode = new Node(“markNode”);

    putArrow(Vector3f.UNIT_Z, markLen, 3, markColor, markNode, “mark”,

    Vector3f.ZERO, markColor);

    Node markParent = new Node(“markParent”);

    markParent.attachChild(markNode);

    markParent.setLocalTranslation(900f, 1200f, -300f);

    markParent.setLocalScale(8f, 1.9f, 3f);

    markParent.setLocalRotation(new Quaternion().fromAngles(

    FastMath.DEG_TO_RAD * 159, FastMath.DEG_TO_RAD * 18,

    FastMath.DEG_TO_RAD * 310));

    markParent.attachChild(textMe(markParent.getName(), markColor));

    attachCoordinateAxes(Vector3f.ZERO, markParent, markColor);

    rootNode.attachChild(markParent);

    }

    @Override

    public void simpleInitApp() {

    flyCam.setMoveSpeed(2000f);

    setDisplayStatView(false);

    cam.setLocation(new Vector3f(2749.566f, 1039.3307f, -6154.8726f));

    cam.setRotation(new Quaternion(-0.18015513f, -0.44012898f,

    -0.09062232f, 0.8749961f));

    Vector3f boxSize = new Vector3f(100, 100, 500);

    Box boxMesh = new Box(boxSize, boxSize.getX(), boxSize.getY(),

    boxSize.getZ());

    WireBox wireboxMesh = new WireBox(boxSize.getX(), boxSize.getY(),

    boxSize.getZ());

    Geometry wireboxGeo = new Geometry(“wire”, wireboxMesh);

    Geometry boxGeom = new Geometry(“Box”, boxMesh);

    Material boxMat = new Material(assetManager,

    “Common/MatDefs/Misc/WireColor.j3md”);

    boxMat.setColor(“m_Color”, ColorRGBA.Yellow);

    boxGeom.setMaterial(boxMat);

    Material wireboxMat = new Material(assetManager,

    “Common/MatDefs/Misc/WireColor.j3md”);

    wireboxMat.setColor(“m_Color”, ColorRGBA.Magenta);

    wireboxGeo.setMaterial(wireboxMat);

    cosmos = new Node(“cosmos”);

    // rootNode.setLocalScale(2, 3, 4);

    rootNode.attachChild(cosmos);

    // XXX: attach only one of the following two boxes to see collision

    // normal being inverse for wirebox and normal for Box

    cosmos.attachChild(wireboxGeo);

    // cosmos.attachChild(boxGeom);

    transformCosmos(false);// I even transform before, just in case

    // Vector3f furtherZ = Vector3f.UNIT_Z.mult(100f);

    // Vector3f furtherZ = new Vector3f(100f, 500f, -200f);

    // wireboxGeo.setLocalTranslation(boxSize.add(furtherZ));

    // boxGeom.setLocalTranslation(furtherZ);

    // this local transform(above) if affected by parents’ transforms

    // but the Box’s specified center in Mesh isn’t(?) so it appears

    attachCoordinateAxes(Vector3f.ZERO, cosmos, ColorRGBA.Pink);

    attachCoordinateAxes(Vector3f.ZERO, rootNode, ColorRGBA.Pink);

    cam.setFrustumFar(115000.0f);

    cam.lookAt(boxGeom.localToWorld(boxMesh.getCenter(), null),

    Vector3f.UNIT_Y);

    ColorRGBA rootColor = ColorRGBA.White;

    ColorRGBA cosmosColor = ColorRGBA.White;

    rootNode.attachChild(textMe(rootNode.getName(), rootColor));

    cosmos.attachChild(textMe(cosmos.getName(), cosmosColor));

    inputManager.addMapping(mapChangeScale, new KeyTrigger(

    KeyInput.KEY_SPACE));

    inputManager.addListener(actionListener, mapChangeScale);

    chgScaleText = new BitmapText(guiFont, false);

    chgScaleText.setSize(guiFont.getCharSet().getRenderedSize());

    chgScaleText.setLocalTranslation(180, chgScaleText.getLineHeight(), 0);

    chgScaleText

    .setText(“Press SPACE to toggle between unform & non-uniform scales”);

    guiNode.attachChild(chgScaleText);

    initCrossHairs();

    initMark();

    }

    /

  • (non-Javadoc)

    *
  • @see com.jme3.app.SimpleApplication#simpleUpdate(float)

    */

    @Override

    public void simpleUpdate(float tpf) {

    Vector2f middleOfScreen = new Vector2f(cam.getWidth() / 2,

    cam.getHeight() / 2);

    Vector3f origin = cam.getWorldCoordinates(middleOfScreen,

    // inputManager.getCursorPosition(),

    0.0f);

    Vector3f direction = cam.getWorldCoordinates(middleOfScreen,

    // inputManager.getCursorPosition(),

    0.3f).subtractLocal(origin).normalizeLocal();

    Ray ray = new Ray(origin, direction);

    CollisionResults results = new CollisionResults();

    cosmos.collideWith(ray, results);

    if (results.size() > 0) {

    CollisionResult closest = results.getClosestCollision();

    Vector3f worldContact = closest.getContactPoint();

    Vector3f normNormal = closest.getContactNormal();

    Quaternion q = new Quaternion();

    q.lookAt(

    // mark.getParent().worldToLocal(

    // normNormal,

    // null ),

    normNormal, Vector3f.UNIT_Y);

    Quaternion parentRotInversion = markNode.getParent()

    .getWorldRotation().inverse();

    // q.multLocal( parentRotInversion );

    q = parentRotInversion.mult(q);

    markNode.setLocalRotation(q);

    Vector3f localContact = markNode.getParent().worldToLocal(

    worldContact, null);

    // Vector3f localPointOnNormal =

    // worldContact.add( normNormal.mult( 1000f

    // // getting far point for low precision

    // ) );

    Vector3f parentScale = markNode.getParent().getWorldScale().clone();

    markNode.setLocalScale(Vector3f.UNIT_XYZ.divide(parentScale));

    // XXX: when non-uniform scale fix code is applied, this fails?:

    markNode.setLocalTranslation(localContact);

    }

    }

    private void initCrossHairs() {

    guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");

    BitmapText ch = new BitmapText(guiFont, false);

    ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);

    ch.setText("+"); // fake crosshairs :slight_smile:

    ch.setLocalTranslation(

    // center

    settings.getWidth() / 2
  • guiFont.getCharSet().getRenderedSize() / 3 * 2,

    settings.getHeight() / 2 + ch.getLineHeight() / 2, 0);

    guiNode.attachChild(ch);

    }

    private final ActionListener actionListener = new ActionListener() {

    @Override

    public void onAction(String name, boolean isPressed, float tpf) {

    if ((mapChangeScale == name) && (isPressed)) {

    if (cosmos.getLocalScale().equals(nonUniformScale)) {

    // was non-uniform

    // make it uniform

    transformCosmos(true);

    } else {

    // make cosmos’ scale non-uniform

    transformCosmos(false);

    }

    chgScaleText.setText(“cosmos’ world scale now:”
  • cosmos.getWorldScale());

    }

    }

    };

    private final float uniformScale = 3f;

    private final Vector3f nonUniformScale = new Vector3f(3f, 1f, 3f);

    /**

    *

    */

    private void transformCosmos(boolean uniform) {

    // cosmos.setLocalTranslation(1000, 2000, -4000);

    // cosmos.setLocalRotation(new Quaternion().fromAngles(

    // FastMath.DEG_TO_RAD * 100, FastMath.DEG_TO_RAD * 23,

    // FastMath.DEG_TO_RAD * 230));

    //

if (uniform) {
// cosmos.getWorldTransform();// checkDoTransformUpdate
System.out.println("setting cosmos's local scale to:"
+ uniformScale);
cosmos.setLocalScale(uniformScale);
// cosmos.getWorldTransform();// checkDoTransformUpdate
} else {
// cosmos.getWorldTransform();// checkDoTransformUpdate
System.out.println("setting cosmos's local scale to:"
+ nonUniformScale);
cosmos.setLocalScale(nonUniformScale);
// cosmos.getWorldTransform();// checkDoTransformUpdate
}
//
}
private static final float lineWidth = 5f;
private static final float lineLen = 400f;
private static final float markLen = lineLen * 4;
private void attachCoordinateAxes(Vector3f pos, Node toNode,
ColorRGBA textColor) {
putArrow(Vector3f.UNIT_X, lineLen, lineWidth, ColorRGBA.Red, toNode,
"x", pos, textColor);
putArrow(Vector3f.UNIT_Y, lineLen, lineWidth, ColorRGBA.Green, toNode,
"y", pos, textColor);
putArrow(Vector3f.UNIT_Z, lineLen, lineWidth, ColorRGBA.Blue, toNode,
"z", pos, textColor);
toNode.attachChild(gimmeBox("origin" + " for `" + toNode.getName()
+ "`", lineWidth, ColorRGBA.Cyan));
}
private Geometry putArrow(Vector3f direction, float lineLen1,
float lineWidth1, ColorRGBA color, Node onNode, String name,
Vector3f pos, ColorRGBA textColor) {
String for1 = " for `" + onNode.getName() + "`";
Vector3f dir = direction.normalize();
//
make Box
System.out.println("box dir:" + dir);
Vector3f boxSize = dir.mult(lineLen1);
System.out.println("box size:" + boxSize);
// WireBox wireBoxMesh =
// new WireBox(
// lineWidth1
// + boxSize.getX()
// / 2,
// lineWidth1
// + boxSize.getY()
// / 2,
// lineWidth1
// + boxSize.getZ()
// / 2 );
Box boxMesh = new Box(boxSize.divide(
// center
2), lineWidth1 + boxSize.getX() / 2, lineWidth1
+ boxSize.getY() / 2, lineWidth1 + boxSize.getZ() / 2);// only
// for
// Box
System.out.println("box center=" + boxSize.divide(2));
System.out.println("x=" + lineWidth1 + "/" + boxSize.getX() / 2);
System.out.println("xE=" + boxMesh.getXExtent());
Geometry boxGeo = new Geometry("Box axis " + name + for1, boxMesh);
// boxGeo.move( boxSize.divide( 2 ) );
// boxGeo.setLocalTranslation( boxSize.divide( 2 ) );
// boxGeo.move( offset )
// Quaternion boxRotation =
// new Quaternion();
// boxRotation.lookAt(
// dir,
// Vector3f.UNIT_Y );
// boxGeo.setLocalRotation( boxRotation );//this doesn't work like for
// Arrow
Material boxMat = new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md");
boxMat.setColor("Color", color);
boxMat.getAdditionalRenderState().setWireframe(true);
boxGeo.setMaterial(boxMat);
onNode.attachChild(boxGeo);
//
make Arrow
Vector3f arrowExtent = dir.mult(lineLen1);
Arrow arrowMesh = new Arrow(arrowExtent);// only for Arrow
arrowMesh.setLineWidth(lineWidth1);// only for Arrow
Geometry arrowGeo = new Geometry("Arrow axis " + name + for1, arrowMesh);
Material arrowMat = boxMat.clone();
arrowMat.getAdditionalRenderState().setWireframe(true);
arrowGeo.setMaterial(arrowMat);
arrowGeo.setLocalTranslation(pos);// only for Arrow
onNode.attachChild(arrowGeo);
//
make text
Node txtNode = textMe(name, color
// textColor
);
Vector3f boxEdge = new Vector3f(
(boxMesh.getXExtent() - lineWidth1) * 2,
(boxMesh.getYExtent() - lineWidth1) * 2,
(boxMesh.getZExtent() - lineWidth1) * 2);
System.out.println("boxEdge=" + boxEdge + " boxPos now="
+ boxGeo.getLocalTranslation());
Geometry whiteTip = gimmeBox("whiteTip " + name + for1, lineWidth1,
ColorRGBA.White);
whiteTip.setLocalTranslation(boxEdge);
onNode.attachChild(whiteTip);
txtNode.setLocalTranslation(boxEdge);
onNode.attachChild(txtNode);
return boxGeo;
}
private Geometry gimmeBox(String name, float extent, ColorRGBA color) {
Box b = new Box(extent, extent, extent);
Geometry g = new Geometry(name, b);
Material m = new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md");
m.setColor("Color", color);
g.setMaterial(m);
return g;
}
private Node textMe(String theText, ColorRGBA color) {
Node r = new Node();
BitmapFont fnt = assetManager.loadFont("Interface/Fonts/Default.fnt");
BitmapText txt = new BitmapText(fnt, false);
// txt.setBox( new Rectangle(
// 0,
// 0,
// 16,
// 3 ) );
txt.setQueueBucket(Bucket.Transparent);
txt.setSize(110.5f);
txt.setText(theText);
txt.setColor(color);
// txt.setAlignment( Align.Center );
r.attachChild(txt);
r.addControl(new BillboardControl());
return r;
}
}
[/java]

Normal succession of forums would be:


  • you are not sure if the problem is in jme:

    Troubleshooting


  • you are 100% sure the problem is in jme and have substantial things to say about it:

    Developers Discussion


  • you have made 100% sure (e.g. by talking to the devs before) that the problem is in jme and you have created a patch file that you can post to fix the problem:

    Contributions Depot



    Cheers,

    Normen
1 Like

Thank you for that! Well I made quite some booboos then, … maybe I can’t undo them, but I’ll make sure to follow these guidelines in the future. Much appreciated!

WireBox is what it says, a wire box. It has no surface. Also, being that lines are infinitely thin, those cannot collide either.

In other words, WireBox is not a collidable object

1 Like