Zoom in OpenGL ES 2.0 – desapareciendo objeto

Me gusta saber cómo ampliar correctamente OpenGL ES 2.0 . He dibujado con éxito un modelo, pero es bastante pequeño y no soy capaz de acercar este modelo. Lo que me gusta tener es el zoom "a través" de este modelo.

El modelo es un edificio con pisos diferentes – me gustaría ampliar a cada habitación de cada piso. Pero ya sea el objeto desaparece debido a la vista frustum o no soy capaz de llegar muy "cerca" de este objeto.

Estoy usando el gesto zoom-touch y obtener un valor "scale" – ¿qué debo hacer ahora con este valor?

Lo que he intentado hasta ahora:

Cambiar la distancia del plano cercano y del plano lejano y cambiar el valor de eyeZ dentro de Matrix.setLookAtM (….) pero lo que solo logro es alejar … desaparece al acercarme un poco … Así que No soy capaz de acercar a algunas partes especiales ("que" lejos ….)


¿Cómo puedo lograr esto?

Así que el mayor problema es el plano cercano combinado con el zoom a través de la EyeZ-Value. Simplemente no funciona. Si hago zoom, el objeto desaparece debido al plano cercano. Pero no veo ninguna lógica detrás de esto.

Actualmente estoy usando:

 /* * Set the camera position (View matrix) */ Matrix.setLookAtM(mViewMatrix, offset, eyeX, eyeY, eyeZ / mZoomLevel, centerX, centerY, centerZ, upX, upY, upZ); 

Donde mZoomLevel es el factor que obtengo a través del onTouch-Zooming.

Aquí se muestran todas mis Operaciones Matriciales:

 @Override public void onDrawFrame(GL10 unused) { LoggerHelper.calculateFPS(); /* * Draw background color */ GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); /* * scale model down to smaller values */ Matrix.setIdentityM(mModelMatrix, 0); Matrix.scaleM(mModelMatrix, 0, model3d.getRatio() * scaleFactor, model3d.getRatio() * scaleFactor, model3d.getRatio() * scaleFactor); /* * rotate and translate model in dependence to the user input */ Matrix.translateM(mModelMatrix, 0, translateX, translateY, translateZ); Helper.rotateModel(mModelMatrix, rotationX, rotationY, rotationZ, true, model3d.getWidth(), model3d.getLength(), model3d.getHeight()); /* * Set the camera position (View matrix) */ Matrix.setLookAtM(mViewMatrix, offset, eyeX, eyeY, eyeZ / mZoomLevel, centerX, centerY, centerZ, upX, upY, upZ); /* * combine the model with the view matrix */ Matrix.multiplyMM(mMVMatrix, 0, mViewMatrix, 0, mModelMatrix, 0); /* * this projection matrix is applied to object coordinates in the * onDrawFrame() method */ Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, 1, -1, nearPlaneDistance, farPlaneDistance); /* * Calculate the projection and view transformation */ float[] mMVPMatrix = new float[16]; Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVMatrix, 0); /* * all the drawing stuff inside the model-object (otherwise * translation/rotation wouldn't affect every object) */ model3d.draw(mMVPMatrix); 

}

Algunas variables importantes:

 private float nearPlaneDistance = 1f; private float farPlaneDistance = 200f; private float eyeZ = -1; 

He subido un proyecto ficticio con sólo la parte OpenGL en Github – en caso de que desee tener una mejor mirada en el código fuente

Lo que tengo:

Mi vista actual

Lo que necesito:

Mi vista deseada

Una de mis soluciones (no funciona muy bien):

 public void setZoom(float zoom) { // this projection matrix is applied to object coordinates // in the onDrawFrame() method float ratio = (float) width / height; Matrix.frustumM(mProjectionMatrix, 0, -ratio / zoom, ratio / zoom, -1 / zoom, 1 / zoom, nearPlaneDistance, farPlaneDistance); } 

Pero este no es el mejor enfoque (ver comentarios debajo de esta respuesta)

Estoy confundido acerca de su "zoom" o que están confundidos al respecto. Cuando mueva la matriz View (cambiando eyeZ), no acercará o alejará, sólo moverá la cámara. Sí, mover la cámara más cerca de un objeto hará que se vea más grande (en caso de proyección en perspectiva), pero no es el zoom. Zoom que cambia la distancia focal o ángulo de visión de la cámara. Cambias la perspepectividad de tu cámara. Al igual que si tienes una cámara real, simplemente caminar hacia tu sujeto de fotografía es diferente de usar el zoom de la cámara (suponiendo que tiene un zoom mecánico).

Con el fin de realmente zoom en algo (si eso es realmente lo que quieres) tendrá que cambiar la "relación" en Matrix.frustumM. Así, puede hacer que los objetos se "hagan más grandes" en la pantalla sin tener que preocuparse por el objeto que está siendo cortado por el plano cercano. Sin embargo, también cambiará la perspectiva. Cuanto más zoom que más se verá como la proyección ortográfica.

Creo que lo que estás tratando de lograr es volar dentro de un modelo de un edificio. Para ello, no es necesario ajustar dinámicamente el zoom de la cámara. Pero es necesario ajustar los planos delantero y final.

Creo que sé cuál es la fuente de su confusión. Cuando cambia el plano cercano del tronco pero mantiene la relación fija, en realidad cambia el zoom y el ángulo de visión. Debido a que los valores focales xyy de la matriz de proyección se calculan por el plano cercano dividido por el izquierdo / derecho y el superior / inferior. La izquierda, derecha y arriba, abajo en Matrix.frustumM son en realidad las dimensiones del plano cercano.

Aquí está el código fuente de frustumM. Puede ver xyy que son el punto focal se calculan usando sólo el plano cercano y no el plano lejano. Si desea mantener el zoom o el ángulo de visión y cambiar el plano cercano, tendrá que multiplicar a la izquierda, a la derecha (ratio en su caso) y superior, inferior (1 en su caso) por la relación entre la profundidad original y la profundidad Nueva profundidad cercana.

 public static void frustumM(float[] m, int offset, float left, float right, float bottom, float top, float near, float far) { if (left == right) { throw new IllegalArgumentException("left == right"); } if (top == bottom) { throw new IllegalArgumentException("top == bottom"); } if (near == far) { throw new IllegalArgumentException("near == far"); } if (near <= 0.0f) { throw new IllegalArgumentException("near <= 0.0f"); } if (far <= 0.0f) { throw new IllegalArgumentException("far <= 0.0f"); } final float r_width = 1.0f / (right - left); final float r_height = 1.0f / (top - bottom); final float r_depth = 1.0f / (near - far); final float x = 2.0f * (near * r_width); final float y = 2.0f * (near * r_height); final float A = 2.0f * ((right + left) * r_width); final float B = (top + bottom) * r_height; final float C = (far + near) * r_depth; final float D = 2.0f * (far * near * r_depth); m[offset + 0] = x; m[offset + 5] = y; m[offset + 8] = A; m[offset + 9] = B; m[offset + 10] = C; m[offset + 14] = D; m[offset + 11] = -1.0f; m[offset + 1] = 0.0f; m[offset + 2] = 0.0f; m[offset + 3] = 0.0f; m[offset + 4] = 0.0f; m[offset + 6] = 0.0f; m[offset + 7] = 0.0f; m[offset + 12] = 0.0f; m[offset + 13] = 0.0f; m[offset + 15] = 0.0f; } 
  • Textura negra de OpenGL ES en Nexus S
  • Problema en OpenGLRenderer: ruta de acceso demasiado grande para que se preste a una textura
  • Android OpenGL ES - Cómo dibujar un polígono cóncavo lleno?
  • Android: LibGDX 2D consumo de memoria del juego
  • Screen Recorder Plugin para Android en Unity
  • AndEngine: colisión de dos sprites
  • Animación esquelética en GPU para Android OpenGL ES
  • Android OpenGL ES 2.0: ¿Es posible la sintaxis de "switch-case" en el fragmento de fragmento GLSL en el Samsung Galaxy S2?
  • Cómo lidiar con el límite de tamaño de textura de Android
  • Recursos para aprender desarrollando juegos con ndk + opengl en C ++?
  • Android SIGSEGV al dibujar ruta mediante aceleración de hardware
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.