[Forsaken]Remove Box’s middle lines to look like a WireBox possible?

Kinda solved: use WireBox and setLocalTranslation() or move() in jme3 at least revision 7291(due to some fix), however WireBox is not a collidable object (as per here ) therefore, I have to use Box :slight_smile: the middle lines remain though…

=========

Hi!

On the left, WireBox, on the right a Box

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

I can’t use WireBox because I need to pass a different center ie.

[java]Box b = new Box(new Vector3f(620, 80, -300), 100, 100, 100);[/java]

and WireBox doesn’t support that

Is there a builtin way (perhaps by selecting a certain material or passing certain Color to the material shader) to hide (or give 0 Alpha) only the middle lines in the Box ?

You can translate the wirebox, e.g. wireBoxGeom.move(), did you try that?

though it appears that if I do that it gets affected by transform of the parent, while if I use Box with center it doesn’t

considering that I want to make coords (just like with using Arrows except using Box-es instead)

like the coordinate axis from this link are done with Arrows

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:debugging

I can replace those with Box, and it’s ok though I have to adjust center to be on one of the edges of box…

with wirebox and setLocalTranslation (or move) trying to move the box such that its edge is at Vector3f.ZERO => fail due to parents’ transforms, but works well if parents have no transforms

ie.

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

in this screenie I put both Arrows and wireBoxes with localtranslation, and arrows look good but wireboxes are displaced as seen the blue and green ones

I am already trying to find a way to fix the position of the BitmapText that I’m trying to attach at the edge of the arrows saying “x”,“y” or “z” (coordinate axis) which is already failing for the same reason, because I use local translation to position them and for some reason they don’t end up at the edge of the box, even though locally the translations and box size are supposedly good (works if no parents are transformed, ie. for rootNode)

btw, looks like this with Box with center

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

PS: source code for the program in screenies (as eclipse project) is as downloadable zip link in this post:

http://hub.jmonkeyengine.org/groups/general-2/forum/topic/curvespline-scale-fail/#post-125198

EDIT: I changed the screenies and code due to a small bug in my code that didn’t move the boxes with their edge at the Vector3f.ZERO, everything still applies though.

Here is a simpler testcase, apparently the non-uniform scale messes up things

I have a magenta wireBox and a yellow Box

they are both in the same node “cosmos” which is transformed (rotation/translation & non-unform scale)

Press SPACE to toggle between cosmos’ uniform scale and non-uniform scale (initially it’s non-uniform, when you run program)

this is how it looks when non-uniform scale:

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


and this is how it looks when uniform scale (only the scale is changed!):
http://i.imgur.com/9LK9j.jpg
[java]package org.jme3.forum;
import java.util.prefs.BackingStoreException;
import com.jme3.app.SimpleApplication;
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.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 NonUniformScaleFail1 extends SimpleApplication {
public static void main(String[] args) throws BackingStoreException {
NonUniformScaleFail1 app = new NonUniformScaleFail1();
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";
@Override
public void simpleInitApp() {
flyCam.setMoveSpeed(8000f);
setDisplayStatView(false);
// cam.setLocation(new Vector3f(-33895.375f, 29396.385f, 3382.8933f));
// cam.setLocation(new Vector3f(4813.2046f, 5973.672f, 2885.9922f));
cam.setLocation(new Vector3f(3298.2444f, 1466.7349f, 1392.3257f));
cam.setRotation(new Quaternion(-0.04414007f, 0.90469253f,
-0.096791066f, -0.4125707f));
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);
cosmos.attachChild(wireboxGeo);
cosmos.attachChild(boxGeom);
transformCosmos(false);// I even transform before, just in case
wireboxGeo.setLocalTranslation(boxSize);
// 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);
BitmapText 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);
}
private final ActionListener actionListener = new ActionListener() {
@Override
public void onAction(String name, boolean isPressed, float tpf) {
if ((mapChangeScale == name) && (isPressed)) {
if (cosmos.getLocalScale().getX() != cosmos.getLocalScale()
.getY()) {
// was non-uniform
// make it uniform
transformCosmos(true);
} else {
// make cosmos' scale non-uniform
transformCosmos(false);
}
}
}
};
/**
*
*/
private void transformCosmos(boolean uniform) {
cosmos.setLocalTranslation(0, 0, -4000);
cosmos.setLocalRotation(new Quaternion().fromAngles(
FastMath.DEG_TO_RAD * 100, FastMath.DEG_TO_RAD * 23,
FastMath.DEG_TO_RAD * 230));
//
if (uniform) {
// XXX: this uniform scale is ok though
cosmos.setLocalScale(2.78f);
} else {
// XXX: non uniform scale messes up things
cosmos.setLocalScale(6.1f, 8.2f, 10.3f);
}
//
}
private static final float lineWidth = 5f;
private static final float lineLen = 400f;
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]
apparently I've hit the same issue (with non-uniform scale vs uniform scale difference) that I talked in this thread:
http://hub.jmonkeyengine.org/groups/general-2/forum/topic/curvespline-scale-fail/
I think I am failing to understand and do something (because I doubt there's a jme3 bug here somehow) when the scale is non-uniform, but for the life of me I cannot figure it out(?!)
======
Also if I comment/remove the translation line for the wireBox
[java]wireboxGeo.setLocalTranslation( boxSize );[/java]
that line, then the wirebox is always with its center in the origin of its parent node (named "cosmos" here)
no matter if scale of "cosmos" is uniform or non-uniform

non-uniform scale:
http://i.imgur.com/dkvna.jpg
uniform scale:
http://i.imgur.com/d036A.jpg

This issue should be fixed now. Apparently the Transform class was not applying the scale and rotation in the right order

1 Like

You are a god! I cannot tell you how happy I am. Thank you so much!! An amazing fix (though it’s too hard for me to understand lol)

I’ll leave the link here for future reference:

https://code.google.com/p/jmonkeyengine/source/detail?r=7291

I’ll also recheck other threads and see if this fixed their issue and properly mark them as solved or something, hooray! good god… :slight_smile:

EDIT: ignore this, apparently it’s my code, I’m not calculating right, how to inverse transform the parent’s world transform and have this inverse applied as a local transform to the markNode…



I’m not sure if it’s my code, trying to find out, but in a totally different program, this fix did fix the scales of ie. my customized coords axis based on Arrows and Boxes but it messed up my Marker which I put as a normal (Arrow) at the point of collision with the Ray coming from camera,

in other words, before this fix (ie. if I undo it) my mark’s local translation (which is based on worldToLocal of its parent) works flawlessly, but after the fix it appears the translation is not in place now and it’s also scaled a lot, that is, I move a few pixels and it moves a lot more (but it’s also not in the right place), here’s a screenie, I’d post the code now but it’s in many classes, I’ll try to do a simpler testcase and see if maybe it was my calculations…

the magenta Arrow is the Mark and it’s supposed to be exactly where the crosshairs are, as a normal on the contact point (works when fix is undid)

http://i.imgur.com/55FOk.jpg

I’ll try to add the Mark feature to the code in this topic and I’ll post a new post(?) xD

Simple: in this post:

EDIT3: ignore only Problem 2, due to WireBox is not a collidable object (as per this post)

EDIT2: apparently I can’t think right, ignore EDIT1, still do look at Problem 1, it might still be worldToLocal … I mean if I do this:

[java]Vector3f localContact = markNode.getParent().worldToLocal(

worldContact, null);

markNode.setLocalTranslation(localContact);[/java]

shouldn’t markNode’s world position be exactly at worldContact? if a markNode’s child is at child’s local translation 0,0,0 then would this child’s world position be worldContact ? if yes, if it should then it’s jme3 issue, else… I fail (again! geez) it’s my code; NOTE: when the fix is undone then it’s “yes” to what I just said, always.

EDIT1: ignore 1. (aka Problem 1) below - if I comment out this line it works, thus it’s not worldToLocal or anything jme related: [java]// markParent.setLocalScale(8f, 1.9f, 3f);[/java]


1. possibly worldToLocal or transformInverseVector don't compute right with the new fix ? (OR bug in my code? but only affected by the fix)
2. WireBox collisions with Ray happen on the inside of this wirebox (as opposed to outside of it, as it works for Box)? (regardless of new fix)
=========
Detailed:
Ok here's the testcase(at the end of post) with a collision marker, steps to test:
Problem 1: when the non-uniform scale fix is applied (jme3 r7291 that is) I seem to fail to properly position it with setLocalTranslation (but clearly I need to consider something like some scale) though the same code when the fix is undone works fine, marker is properly positioned.
EDIT:The thing is, that while I obtain a world coord for the collision, I am trying to use that to position the marker markNode, which has parents rootNode->markParent, but markParent has transforms (rot/scale/transl) and so I am trying to apply some local transforms for my markNode such its transforms and parent's transforms nullify making it seem as if markNode is untransformed and so I can apply that world coord properly...
steps to test:
a) run the code without the r7291 fix notice how the marker (purple arrow) is properly positioned at the collision point (and this unchanged: is always perpendicular on the yellow box (Box not WireBox) no matter on what surface the middle of the screen(crosshairs) are pointing at)
http://i.imgur.com/4bXkb.jpg
b) apply the r7291 fix and run the code again and notice that the marker's position is off and it moves scaled (though its orientation is the same, ie. only the local translation needs to be fixed)
http://i.imgur.com/Zc99r.jpg
Problem 2: apparently unrelated, I noticed that the WireBox 's collision normal is apparently opposite than what it should be, at least when compared with Box; I think the collision happens on the inner sides of the wireBox(?? unsure)
steps to test:
undo the r7291 fix,
a) then run the code (should be only the Box attached to rootNode, not the wireBox, by default)
ie.
[java]// cosmos.attachChild( wireboxGeo );
cosmos.attachChild( boxGeom );[/java]
notice the normal is working fine (see first screenie in this post)
b) now change the code to attach only the wireBox and not the Box ie.
[java] cosmos.attachChild( wireboxGeo );
//cosmos.attachChild( boxGeom );[/java]
now you notice the purple wire box
the marker normal appears to be detected as if the r7291 fix was already there in place, but it's not, and the normal and box are inconsistent OR something else I can't understand
c) apply the r7291 fix and redo a) then b)
I really don't understand what is happening now, but the marker's position is again off and the normal seems to be in opposite direction than if it were a Box instead of WireBox
http://i.imgur.com/G0BMi.jpg
=========
Bottom line:
1. the changes in jme3 r7291 either must be applied somewhere else also ie. worldToLocal, OR I need to change my code (which was previously wrongly calculating the mark's position and worked perfectly with the unfixed bug) to recalculate considering the new fix, therefore this is just a bug in my own code
2. WireBox and Box 's normal don't seem to be the same, the CollisionResult.getContactNormal() that is; this appears to be a bug with that method (?)
[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
wireboxGeo.setLocalTranslation(boxSize);
// this local transform(above) is 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 :)
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]

I made a simpler testcase about the worldToLocal not working right with the r7291 fix here:

http://hub.jmonkeyengine.org/groups/general-2/forum/topic/worldtolocal-not-working-right-with-the-jme3-r7291-fix/

so, ignore everything in this current thread, which was supposed to be about how to make a Box look like a WireBox…