Okay, I took your test case and modified it a bit to closer match what I'm doing. I'm currently unable to replicate the calcMinDistance issue with this, but it is showing the AABB issue. The main difference with what you did and what I'm doing is that I'm converting the touch to a concrete position inside the world and checking a ray from there, rather than just a ray straight from the camera position. This should be the same as checking the collision between two objects in the world, regardless of the camera.
I'll have to leave it for today, but here's the code I have right now. Maybe this will help find the issue with AABB. I'll try to figure out the calcMinDistance issue tomorrow.
package com.example.scaletest;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.Window;
import com.threed.jpct.Camera;
import com.threed.jpct.Config;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.GenericVertexController;
import com.threed.jpct.Interact2D;
import com.threed.jpct.Light;
import com.threed.jpct.Logger;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.RGBColor;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureInfo;
import com.threed.jpct.TextureManager;
import com.threed.jpct.World;
import com.threed.jpct.util.BitmapHelper;
/**
*
* @author EgonOlsen
* @edited voronwe13
*/
public class ScaleActivity extends Activity {
private GLSurfaceView mGLView;
private MyRenderer renderer = null;
private FrameBuffer fb = null;
private World world = null;
private RGBColor back = new RGBColor(50, 50, 100);
private float touchScale = 0;
private boolean clicked = false;
private float xpos = -1;
private float ypos = -1;
private Object3D square = null;
private Light sun = null;
//private MyVertexController mvc = new MyVertexController();
private static SimpleVector ul = new SimpleVector();
private static SimpleVector ur = new SimpleVector();
private static SimpleVector bl = new SimpleVector();
private static SimpleVector br = new SimpleVector();
private static final SimpleVector downvec = new SimpleVector(0,0,1);
private static final float objwidth = 700, objheight = 700;
private static float fov, viewwidth, viewheight;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGLView = new GLSurfaceView(getApplication());
mGLView.setEGLContextClientVersion(2);
renderer = new MyRenderer();
mGLView.setRenderer(renderer);
setContentView(mGLView);
}
@Override
protected void onPause() {
super.onPause();
mGLView.onPause();
System.exit(0);
}
@Override
protected void onResume() {
super.onResume();
mGLView.onResume();
}
@Override
protected void onStop() {
super.onStop();
}
public boolean onTouchEvent(MotionEvent me) {
if (me.getAction() == MotionEvent.ACTION_DOWN) {
xpos = me.getX();
ypos = me.getY();
clicked = true;
return true;
}
if (me.getAction() == MotionEvent.ACTION_UP) {
xpos = -1;
ypos = -1;
touchScale = 0;
return true;
}
if (me.getAction() == MotionEvent.ACTION_MOVE) {
float xd = me.getX() - xpos;
xpos = me.getX();
ypos = me.getY();
touchScale = xd;
if (touchScale != 0) {
if (touchScale < 0) {
touchScale = 0.99f;
} else {
touchScale = 1.01f;
}
}
return true;
}
return super.onTouchEvent(me);
}
protected boolean isFullscreenOpaque() {
return true;
}
class MyRenderer implements GLSurfaceView.Renderer {
public MyRenderer() {
//
}
public void onSurfaceChanged(GL10 gl, int w, int h) {
if (fb != null) {
fb.dispose();
}
fb = new FrameBuffer(w, h);
viewwidth = w;
viewheight = h;
world = new World();
world.setAmbientLight(200, 200, 200);
Config.farPlane = 10000;
// Create a texture out of the icon...:-)
Texture texture = new Texture(BitmapHelper.rescale(BitmapHelper.convert(getResources().getDrawable(R.drawable.ic_launcher)), 64, 64));
TextureManager.getInstance().addTexture("texture", texture);
TextureInfo ti = new TextureInfo(TextureManager.getInstance().getTextureID("texture"));
square = createTile(0,0,objwidth,objheight);
square.calcTextureWrapSpherical();
square.setTexture(ti);
square.compile(true);
square.build();
//square.getMesh().setVertexController(mvc, true);
world.addObject(square);
Camera cam = world.getCamera();
fov = cam.getFOV();
cam.moveCamera(Camera.CAMERA_MOVEOUT, 3*objwidth/fov);
cam.moveCamera(Camera.CAMERA_MOVEDOWN, objheight/2);
cam.moveCamera(Camera.CAMERA_MOVERIGHT, objwidth/2);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
public void onDrawFrame(GL10 gl) {
if (touchScale != 0) {
//mvc.setScale(touchScale);
//square.getMesh().applyVertexController();
//square.touch();
touchScale = 0;
}
if (clicked) {
clicked = false;
// Calculate minimal distance
int yOffset = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
SimpleVector touchpos = new SimpleVector();
convertPosition(xpos, ypos, -10, touchpos);
Logger.log("touch position"+touchpos+", direction: "+downvec.toString());
float min = square.calcMinDistance(touchpos, downvec, 10000);
if (min != Object3D.COLLISION_NONE) {
Logger.log("Distance: " + min);
} else {
Logger.log("Missed!");
}
// Calculate minimal distance to AABB
min = square.rayIntersectsAABB(touchpos, downvec);
if (min != Object3D.RAY_MISSES_BOX) {
Logger.log("Distance to AABB: " + min);
} else {
Logger.log("Missed AABB!");
}
}
fb.clear(back);
world.renderScene(fb);
world.draw(fb);
fb.display();
}
}
//creates a tile of a specific size and location
public static Object3D createTile(float left, float top, float right, float bottom){
Object3D tileobj = new Object3D(2);
float offset = 0;
float u0 = 0;
float u1 = 1;
float v0 = 0;
float v1 = 1;
ul.set(left, top, 0);
ur.set(right, top, 0);
bl.set(left, bottom, 0);
br.set(right, bottom, 0);
tileobj.addTriangle(ul, u0, v0, bl, u0, v1, br, u1, v1);
tileobj.addTriangle(ul, u0, v0, br, u1, v1, ur, u1, v0);
return tileobj;
}
//converts a position from screen dimensions to world space, assuming a camera looking
//down the positive z-axis with camera oriented with -y (or (0,-1,0)) as up (the default orientation
//for jpct's camera).
public void convertPosition(float startx, float starty, float z, SimpleVector tofill) {
SimpleVector campos = world.getCamera().getPosition();
float adjfactor = (z-campos.z)*fov/viewwidth;
tofill.set((startx-viewwidth/2)*adjfactor + campos.x, (starty-viewheight/2)*adjfactor + campos.y, z);
}
// private static class MyVertexController extends GenericVertexController {
//
// private static final long serialVersionUID = 1L;
// private float scale;
//
// public void setScale(float scale) {
// this.scale = scale;
// }
//
// @Override
// public void apply() {
// SimpleVector[] source = this.getSourceMesh();
// SimpleVector[] dest = this.getDestinationMesh();
//
// for (int i = 0; i < source.length; i++) {
// SimpleVector s = source[i];
// s.scalarMul(scale);
// dest[i].set(s);
// }
// }
// }
}