@t0neg0d said:
2. I don't know if this is on all devices, but on my tablet, application scaling seems to break ray casting.
Just to be complete, here is what I did to make it work:
1.) In simpleInitApp, store the initial width and height from appsettings
2.) when a touch event happens and you want to use the touch x / y for something like ray casting, adjust the x and y location by the ratio of the original width and height.
When setFixedSize is used from within onCreate in MainActivity, it does not notify jME until the 2nd jME render frame. The first frame creates the surface view and runs the app’s simpleInitApp. The second frame is when the surfaceview notifies jME that the surface size has changed. That’s when the onSurfaceChanged is fired and the appsettings are adjusted (along with camera, etc.). This means you can grab the settings from within simpleInitApp which is run before the resolution is changed. Then, you can adjust the touch location when you need to later.
[java]
public class Main extends SimpleApplication {
private int displayWidth;
private int displayHeight;
@Override
public void simpleInitApp() {
displayWidth = settings.getWidth();
displayHeight = settings.getHeight();
}
// called from some inputListener (ie. onTouchEvent)
private void pickObject() {
CollisionResults results;
Vector2f curClick2d = new Vector2f();
logger.log(Level.INFO, "display width: {0}, height: {1}",
new Object[]{displayWidth, displayHeight});
logger.log(Level.INFO, "settings width: {0}, height: {1}",
new Object[]{settings.getWidth(), settings.getHeight()});
curClick2d.x = inputManager.getCursorPosition().x * ((float)settings.getWidth() / (float)displayWidth);
curClick2d.y = inputManager.getCursorPosition().y * ((float)settings.getHeight() / (float)displayHeight);
logger.log(Level.INFO, "curClick2d: {0}", curClick2d);
// Pick Root Node (3D)
Vector3f click3d = cam.getWorldCoordinates(
new Vector2f(curClick2d.x, curClick2d.y), 0f).clone();
Vector3f dir = cam.getWorldCoordinates(
new Vector2f(curClick2d.x, curClick2d.y), 1f).subtractLocal(click3d).normalizeLocal();
Ray ray = new Ray(click3d, dir);
results = new CollisionResults();
rootNode.collideWith(ray, results);
logger.log(Level.INFO, "3D result size: {0}", results.size());
if (results.size() > 0){
for (int i=0; i<results.size(); i++) {
CollisionResult result = results.getCollision(i);
Geometry geo = result.getGeometry();
logger.log(Level.INFO, "3D object: {0}, at x: {1}, distance: {2}",
new Object[]{geo.getName(), result.getContactPoint(), result.getDistance()});
}
} else {
logger.log(Level.INFO, "no 3D hits found start: {0}, dir: {1}",
new Object[]{click3d, dir});
}
// Pick Gui Node (2D)
Vector3f start = new Vector3f(curClick2d.x, curClick2d.y, 10f);
dir = Vector3f.UNIT_Z.negate();
ray = new Ray(start, dir);
results = new CollisionResults();
guiNode.collideWith(ray, results);
logger.log(Level.INFO, "2D result size: {0}", results.size());
if (results.size() > 0){
for (int i=0; i<results.size(); i++) {
CollisionResult result = results.getCollision(i);
Geometry geo = result.getGeometry();
logger.log(Level.INFO, "2D object: {0}, at x: {1}, distance: {2}",
new Object[]{geo.getName(), result.getContactPoint(), result.getDistance()});
}
} else {
logger.log(Level.INFO, "no 2D hits found");
}
}
[/java]