나는 안드로이드 애플 리케이션에서 광선 따기를 구현하려고하고 있으며 참조 가이드로 http://android-raypick.blogspot.ca/2012/04/first-i-want-to-state-this-is-my-first.html을 사용 해왔다. 클래스를 가져오고 사이트의 일부 클래스를 복사하면 코드에 오류가 발생합니다. 그들은 어디에 코드를 넣을 지 잘 설명하지 못합니다. 나는 모든 것을 최신 OpenGL 버전으로 변환 할 것이고, 나중에 작업 코드를 얻고 이해하려고 노력할 것입니다. 많은 코드가 있지만 내가 가지고있는 것을 나열 할 것입니다. 이 게시물이 중복 될 수도 있지만 필자는 웹 전체를 둘러 보았고이 주제에 대한 정보를 많이 찾았지만 이미 예제로 사용할 수는 없으며 이해하기 위해 혼란 스러울 수는 없습니다.OpenGL에서 1 안드로이드 애플 리케이션을위한 광선 선택 도구를 구현하려고합니다
public class CadActivity extends ActionBarActivity {
GLSurfaceView cadLayout;
TextView xV = (TextView) findViewById(R.id.x);
TextView yV = (TextView) findViewById(R.id.y);
TextView zV = (TextView) findViewById(R.id.z);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
cadLayout= new CadGlSurfaceView(this);
cadLayout.setGLWrapper(new GLSurfaceView.GLWrapper() {
@Override
public GL wrap(GL gl) {
return new MatrixTrackingGL(gl);
}
});
setContentView(R.layout.activity_cad);
RelativeLayout v = (RelativeLayout) findViewById(R.id.surfacegl);
v.addView(cadLayout);
}
위 코드는 GL 래퍼의 주요 활동입니다. 이 다음 코드 내 렌더러입니다
public class CadGlSurfaceView extends GLSurfaceView {
float x,y,sX,sY,fX,fY;
CadActivity main;
public CadGlSurfaceView(Context context) {
super(context);
setRenderer(new CadRenderer());
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getActionMasked();
x = event.getX();
y = event.getY();
switch(action){
case MotionEvent.ACTION_DOWN:
x = event.getX();
y = event.getY();
sX = event.getX();
sY = event.getY();
return true;
case MotionEvent.ACTION_MOVE:
x = event.getX();
y = event.getY();
return true;
case MotionEvent.ACTION_UP:
x = event.getX();
y = event.getY();
fX = event.getX();
fY = event.getY();
return true;
}
return true;
}
}
:
이 코드는 아래에있는 내 GLSurfaceView입니다
public class CadRenderer implements GLSurfaceView.Renderer {
private GlObjects objects;
MatrixGrabber matrixGrabber = new MatrixGrabber();
public CadRenderer(){
objects = new GlObjects();
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig eglconfig) {
gl.glDisable(GL10.GL_DITHER);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);
gl.glClearColor(.8f,0f,.2f,1f);
gl.glClearDepthf(1f);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0,0,width,height);
int[] viewport = {0, 0, width, height};
float ratio = (float) width/height;
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustumf(-ratio,ratio,-1,1f,1,25);
matrixGrabber.getCurrentState(gl);
matrixGrabber.mModelView;
matrixGrabber.mProjection;
}
@Override
public void onDrawFrame(GL10 gl) {
gl.glDisable(GL10.GL_DITHER);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
GLU.gluLookAt(gl,0,0,-5,0,0,0,0,2,0);
objects.draw(gl);
}
}
matrixGrabber.mModelView; matrixGrabber.mProjection; 이 두 코드에는 (Not a Statement) 빨간 선이 있습니다.
이것은 내 대상입니다. 나는 선을 그어서 몇 가지를 바꿀 필요가 있음을 알게 될 것입니다.
public class GlObjects {
private float vertices[]={
0f,1f,
1f,-1f,
-1f,-1f
};
private short pIndex[]={0,1,2};
private ShortBuffer pBuff;
private FloatBuffer vertBuff;
public GlObjects(){
ByteBuffer bBuff = ByteBuffer.allocateDirect(vertices.length*4);
bBuff.order(ByteOrder.nativeOrder());
vertBuff = bBuff.asFloatBuffer();
vertBuff.put(vertices);
vertBuff.position(0);
ByteBuffer pbBuff = ByteBuffer.allocateDirect(pIndex.length*2);
pbBuff.order(ByteOrder.nativeOrder());
pBuff = pbBuff.asShortBuffer();
pBuff.put(pIndex);
pBuff.position(0);
}
public void draw(GL10 gl){
gl.glFrontFace(GL10.GL_CW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(2,GL10.GL_FLOAT,0,vertBuff);
gl.glDrawElements(GL10.GL_TRIANGLES,pIndex.length,GL10.GL_UNSIGNED_SHORT,pBuff);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
이것은 웹 사이트의 레이 클래스입니다.
public class Ray {
public Ray(GL10 gl, int width, int height, float xTouch, float yTouch) {
MatrixGrabber matrixGrabber = new MatrixGrabber();
matrixGrabber.getCurrentState(gl);
int[] viewport = {0, 0, width, height};
float[] nearCoOrds = new float[3];
float[] farCoOrds = new float[3];
float[] temp = new float[4];
float[] temp2 = new float[4];
// get the near and far ords for the click
float winx = xTouch, winy =(float)viewport[3] - yTouch;
// Log.d(TAG, "modelView is =" + Arrays.toString(matrixGrabber.mModelView));
// Log.d(TAG, "projection view is =" + Arrays.toString(matrixGrabber.mProjection));
int result = GLU.gluUnProject(winx, winy, 1.0f, matrixGrabber.mModelView, 0,
matrixGrabber.mProjection, 0, viewport, 0, temp, 0);
Matrix.multiplyMV(temp2, 0, matrixGrabber.mModelView, 0, temp, 0);
if(result == GL10.GL_TRUE){
nearCoOrds[0] = temp2[0]/temp2[3];
nearCoOrds[1] = temp2[1]/temp2[3];
nearCoOrds[2] = temp2[2]/temp2[3];
}
result = GLU.gluUnProject(winx, winy, 0, matrixGrabber.mModelView, 0,
matrixGrabber.mProjection, 0, viewport, 0, temp, 0);
Matrix.multiplyMV(temp2,0,matrixGrabber.mModelView, 0, temp, 0);
if(result == GL10.GL_TRUE){
farCoOrds[0] = temp2[0]/temp2[3];
farCoOrds[1] = temp2[1]/temp2[3];
farCoOrds[2] = temp2[2]/temp2[3];
}
this.P0 = farCoOrds;
this.P1 = nearCoOrds;
}
}
this.P0 = farCoOrds; this.P1 = nearCoOrds; 아래에 빨간색 선이 표시되어 있습니다 (기호를 해결할 수 없음).
이 웹 사이트에서 삼각형 클래스는 다음과 같습니다
public class Triangle {
public float[] V0;
public float[] V1;
public float[] V2;
public Triangle(float[] V0, float[] V1, float[] V2){
this.V0 =V0;
this.V1 = V1;
this.V2 = V2;
}
private static final float SMALL_NUM = 0.00000001f; // anything that avoids division overflow
// intersectRayAndTriangle(): intersect a ray with a 3D triangle
// Input: a ray R, and a triangle T
// Output: *I = intersection point (when it exists)
// Return: -1 = triangle is degenerate (a segment or point)
// 0 = disjoint (no intersect)
// 1 = intersect in unique point I1
// 2 = are in the same plane
public static int intersectRayAndTriangle(Ray R, Triangle T, float[] I)
{
float[] u, v, n; // triangle vectors
float[] dir, w0, w; // ray vectors
float r, a, b; // params to calc ray-plane intersect
// get triangle edge vectors and plane normal
u = Vector.minus(T.V1, T.V0);
v = Vector.minus(T.V2, T.V0);
n = Vector.crossProduct(u, v); // cross product
if (Arrays.equals(n, new float[]{0.0f, 0.0f, 0.0f})){ // triangle is degenerate
return -1; // do not deal with this case
}
dir = Vector.minus(R.P1, R.P0); // ray direction vector
w0 = Vector.minus(R.P0 , T.V0);
a = - Vector.dot(n,w0);
b = Vector.dot(n,dir);
if (Math.abs(b) < SMALL_NUM) { // ray is parallel to triangle plane
if (a == 0){ // ray lies in triangle plane
return 2;
}else{
return 0; // ray disjoint from plane
}
}
// get intersect point of ray with triangle plane
r = a/b;
if (r < 0.0f){ // ray goes away from triangle
return 0; // => no intersect
}
// for a segment, also test if (r > 1.0) => no intersect
float[] tempI = Vector.addition(R.P0, Vector.scalarProduct(r, dir));
// intersect point of ray and plane
I[0] = tempI[0];
I[1] = tempI[1];
I[2] = tempI[2];
// is I inside T?
float uu, uv, vv, wu, wv, D;
uu = Vector.dot(u,u);
uv = Vector.dot(u,v);
vv = Vector.dot(v,v);
w = Vector.minus(I, T.V0);
wu = Vector.dot(w,u);
wv = Vector.dot(w,v);
D = (uv * uv) - (uu * vv);
// get and test parametric coords
float s, t;
s = ((uv * wv) - (vv * wu))/D;
if (s < 0.0f || s > 1.0f) // I is outside T
return 0;
t = (uv * wu - uu * wv)/D;
if (t < 0.0f || (s + t) > 1.0f) // I is outside T
return 0;
return 1; // I is in T
}
}
는 다음 웹 사이트에서 벡터 클래스를 지속.
public class Vector {
// dot product (3D) which allows vector operations in arguments
public static float dot(float[] u,float[] v) {
return ((u[X] * v[X]) + (u[Y] * v[Y]) + (u[Z] * v[Z]));
}
public static float[] minus(float[] u, float[] v){
return new float[]{u[X]-v[X],u[Y]-v[Y],u[Z]-v[Z]};
}
public static float[] addition(float[] u, float[] v){
return new float[]{u[X]+v[X],u[Y]+v[Y],u[Z]+v[Z]};
}
//scalar product
public static float[] scalarProduct(float r, float[] u){
return new float[]{u[X]*r,u[Y]*r,u[Z]*r};
}
// (cross product)
public static float[] crossProduct(float[] u, float[] v){
return new float[]{(u[Y]*v[Z]) - (u[Z]*v[Y]),(u[Z]*v[X]) - (u[X]*v[Z]),(u[X]*v[Y]) - (u[Y]*v
[X])};
}
//mangnatude or length
public static float length(float[] u){
return (float) Math.abs(Math.sqrt((u[X] *u[X]) + (u[Y] *u[Y]) + (u[Z] *u[Z])));
}
public static final int X = 0;
public static final int Y = 1;
public static final int Z = 2;
}
마찬가지로 저는 실제 예제를 얻고이 코드를 구현하는 방법을 이해하고 있다고 말했습니다.