将Android OpenGL上的触摸转换为射线/向量,并检查是否与平面相交。

huangapple go评论116阅读模式
英文:

Translate a touch on android-opengl into a ray/vector and check if it hits a plane

问题

I'm rather new to Android app development and using OpenGL ES. My basic goal is to create 4 simple squares in my Surface View. When the user clicks on the screen, I want to check which of the squares they clicked on (if any). This square should then be marked and change its color. When the user clicks on a second (different) square, I want to draw an arrow from the first square to the second one. I used the android tutorial for OpenGL ES as a starting point and tried to adapt it for my purpose.

I have problems checking whether the user has clicked on a rectangle. I've worked through many StackOverflow questions and other guides regarding OpenGL in Android and linear algebra in general. I found the following resources to be the most useful:

This is what I've understood so far: My rendered squares are defined in a Model-View-Projection Matrix. In order to check if the user clicked on any of these squares, I have to translate the click into a ray in world space coordinates. After that, I need to check if this ray collides with any of my squares, which all lie on the same plane.

Here is the part of the code where I've made the most edits:

  1. // Part of the MyGLRenderer class
  2. public class MyGLRenderer implements GLSurfaceView.Renderer {
  3. // ... (other code)
  4. public void checkCollision(float touchX, float touchY) {
  5. // Step 1: normalize coordinates
  6. // ... (other code)
  7. // Inverted matrices
  8. float[] invertedProjectionMatrix = new float[16];
  9. float[] invertedMViewMatrix = new float[16];
  10. Matrix.invertM(invertedProjectionMatrix, 0, mProjectionMatrix, 0);
  11. Matrix.invertM(invertedMViewMatrix, 0, mViewMatrix, 0);
  12. // Calculation Matrices
  13. float[] unviewMatrix = new float[16];
  14. float[] mouse_worldspace = new float[4];
  15. // Getting mouse position in world space
  16. // ... (other code)
  17. // Getting the camera position
  18. float[] cameraPosition = {0, 0, -3};
  19. // Subtract camera position from the mouse_worldspace
  20. float[] ray_unnormalized = new float[4];
  21. for (int i = 0; i < 3; i++) {
  22. ray_unnormalized[i] = mouse_worldspace[i] / mouse_worldspace[3] - cameraPosition[i];
  23. }
  24. // Normalize ray_vector
  25. // ... (other code)
  26. LinePlaneIntersection linePlaneIntersection = new LinePlaneIntersection();
  27. LinePlaneIntersection.Vector3D rv = new LinePlaneIntersection.Vector3D(ray_vector[0], ray_vector[1], ray_vector[2]);
  28. LinePlaneIntersection.Vector3D rp = new LinePlaneIntersection.Vector3D(mouse_worldspace[0], mouse_worldspace[1], mouse_worldspace[2]);
  29. LinePlaneIntersection.Vector3D pn = new LinePlaneIntersection.Vector3D(0.0, 0.0, 0.0);
  30. LinePlaneIntersection.Vector3D pp = new LinePlaneIntersection.Vector3D(0.0, 0.0, 1.0);
  31. LinePlaneIntersection.Vector3D ip = linePlaneIntersection.intersectPoint(rv, rp, pn, pp);
  32. Log.i(TAG, "checkCollision-intersection point: " + ip);
  33. }
  34. // ... (other code)
  35. }

I've also added a moveSquare method in the Square class to update the square's coordinates.

I'm not sure if my approach is correct or if I'm using the right transformations and steps. Additionally, I have questions about the naming of matrices (mMVPMatrix, mProjectionMatrix, mViewMatrix) and the purpose of the Projection Matrix.

I hope this provides a clear overview of my challenges. If more information is needed to understand the problem, please let me know. I appreciate any assistance and guidance.

英文:

im rather new to android app development/using OpenGL ES. My basic goal is to create 4 simple Squares in my Surface View, when the user clicks on the screen i want to check which of the squares he clicked (if any). This square should then be marked and change its color, when the user clicks on a second (different) square i want to draw an arrow from square1 to square2. I used the android tutorial for opengl es as a starting point and tried to adapt it for my purpose.


I have problems checking whether the user has clicked on a rectangle.
I worked through quite a lot of stackoverflow questions and other guides regarding opengl in Android and linear Algebra in general. I found these to be the most useful:<br>
Opengl Tutorial <br>
Mouse picking with ray casting <br>
Implement Ray Picking <br>
<br>
This is what i got out of this so far: <br>
My rendered squares are defined in an Model-View-Projection Matrix, in order to check if the user clicked on of these square i have to translate the click into a ray in the world space coordinates. After that i would have to check if this ray collides with on of my squares, which all lie on the same plane. <br/>
<br/>

Here is where i edited the most, on surfaceCreated i add the four squares and move them to their positions. When the user taps on the screen the checkCollision-Method is called with the absolute screen coordinates. What i tried then was to translate the instructions from these posts:<br>
Implement Ray Picking <br>
Intersection of a line and a plane
<br>

  1. public class MyGLRenderer implements GLSurfaceView.Renderer {
  2. private static final String TAG = &quot;MyGLRenderer&quot;;
  3. private HashMap&lt;String, Square&gt; mySquares = new HashMap&lt;&gt;();
  4. // mMVPMatrix is an abbreviation for &quot;Model View Projection Matrix&quot;
  5. private final float[] mMVPMatrix = new float[16];
  6. private final float[] mProjectionMatrix = new float[16];
  7. private final float[] mViewMatrix = new float[16];
  8. private final float[] mRotationMatrix = new float[16];
  9. private int screenWidth = 0;
  10. private int screenHeight = 0;
  11. private float mAngle;
  12. private int square_number = 65;
  13. private final float[][] colors = {
  14. {0.29f, 0.57f, 1.0f, 1.0f},
  15. {0.8f, 0.0f, 0.0f, 1.0f},
  16. {0.13f, 0.8f, 0.0f, 1.0f},
  17. {1.0f, 0.84f, 0.0f, 1.0f}};
  18. public void onSurfaceCreated(GL10 unused, EGLConfig config) {
  19. // Set the background frame color
  20. GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  21. //Adding the 4 squares to the grid and move them to their positions
  22. String square_key = &quot;&quot;;
  23. square_key = addSquare();
  24. this.mySquares.get(square_key).moveSquare(0.5f, 0.5f);
  25. square_key = addSquare();
  26. this.mySquares.get(square_key).moveSquare(0.5f, -0.5f);
  27. square_key = addSquare();
  28. this.mySquares.get(square_key).moveSquare(-0.5f, 0.5f);
  29. square_key = addSquare();
  30. this.mySquares.get(square_key).moveSquare(-0.5f, -0.5f);
  31. }
  32. public void checkCollision(float touchX, float touchY) {
  33. //Step 1: normalize coordinates
  34. float[] touchClipMatrix = new float[]{
  35. 2.0f * touchX / this.screenWidth - 1.0f,
  36. 1.0f - touchY * 2 / this.screenHeight,
  37. 0,
  38. 1.0f
  39. };
  40. //inverted matrices
  41. float[] invertedProjectionMatrix = new float[16];
  42. float[] invertedMViewMatrix = new float[16];
  43. Matrix.invertM(invertedProjectionMatrix,0, mProjectionMatrix, 0);
  44. Matrix.invertM(invertedMViewMatrix,0, mViewMatrix, 0);
  45. //Calculation Matrices
  46. float[] unviewMatrix = new float[16];
  47. float[] mouse_worldspace = new float[4];
  48. //Getting mouse position in world space
  49. Matrix.multiplyMM(unviewMatrix, 0, invertedMViewMatrix, 0, invertedProjectionMatrix,0);
  50. Matrix.multiplyMV(mouse_worldspace, 0 , unviewMatrix, 0 , touchClipMatrix, 0);
  51. Log.i(TAG, &quot;checkCollision-touchClipMatrix: &quot;+ Arrays.toString(touchClipMatrix));
  52. Log.i(TAG, &quot;checkCollision-invertedProjectionMatrix: &quot;+ Arrays.toString(invertedProjectionMatrix));
  53. Log.i(TAG, &quot;checkCollision-invertedMViewMatrix: &quot;+ Arrays.toString(invertedMViewMatrix));
  54. Log.i(TAG, &quot;checkCollision-mouse_worldspace: &quot;+ Arrays.toString(mouse_worldspace));
  55. //Getting the camera position
  56. float [] cameraPosition = {0, 0, -3};
  57. //subtract camera position from the mouse_worldspace
  58. float [] ray_unnormalized = new float[4];
  59. for(int i = 0; i &lt; 3; i++){
  60. ray_unnormalized[i] = mouse_worldspace[i] / mouse_worldspace[3] - cameraPosition[i];
  61. }
  62. //normalize ray_vector
  63. float ray_length = Matrix.length(ray_unnormalized[0], ray_unnormalized[1], ray_unnormalized[2]);
  64. float [] ray_vector = new float[4];
  65. for(int i=0; i&lt;3; i++){
  66. ray_vector[i] = ray_unnormalized[i]/ray_length;
  67. }
  68. Log.i(TAG, &quot;checkCollision - ray_vector: &quot;+ Arrays.toString(ray_vector));
  69. LinePlaneIntersection linePlaneIntersection = new LinePlaneIntersection();
  70. LinePlaneIntersection.Vector3D rv = new LinePlaneIntersection.Vector3D(ray_vector[0], ray_vector[1], ray_vector[2]);
  71. LinePlaneIntersection.Vector3D rp = new LinePlaneIntersection.Vector3D(mouse_worldspace[0], mouse_worldspace[1], mouse_worldspace[2]);
  72. LinePlaneIntersection.Vector3D pn = new LinePlaneIntersection.Vector3D(0.0, 0.0, 0.0);
  73. LinePlaneIntersection.Vector3D pp = new LinePlaneIntersection.Vector3D(0.0, 0.0, 1.0);
  74. LinePlaneIntersection.Vector3D ip = linePlaneIntersection.intersectPoint(rv, rp, pn, pp);
  75. Log.i(TAG, &quot;checkCollision-intersection point: &quot;+ip);
  76. }
  77. public String addSquare() {
  78. String keyName = String.valueOf((char) this.square_number);
  79. this.mySquares.put(keyName, new Square(keyName, colors[this.square_number-65]));
  80. this.square_number += 1;
  81. return keyName;
  82. }
  83. public void logMatrices() {
  84. Log.i(TAG, &quot;MVPMatrice: &quot; + Arrays.toString(this.mMVPMatrix));
  85. Log.i(TAG, &quot;mProjectionMarice: &quot; + Arrays.toString(this.mProjectionMatrix));
  86. Log.i(TAG, &quot;mViewMatrice: &quot; + Arrays.toString(this.mViewMatrix));
  87. }
  88. @Override
  89. public void onDrawFrame(GL10 unused) {
  90. float[] scratch = new float[16];
  91. // Draw background color
  92. GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
  93. // Set the camera position (View matrix)
  94. //mySquare.moveSquare(0.25f, 0.25f);
  95. Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0.0f, 0f, 1.0f, 0.0f);
  96. // Matrix.scaleM(mViewMatrix, 0, 0.5f,0.5f,0);
  97. // Matrix.translateM(mViewMatrix, 0, 2f, 1f, 0);
  98. // Calculate the projection and view transformation
  99. Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
  100. // Create a rotation for the square
  101. Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0.0f, 1.0f);
  102. // Combine the rotation matrix with the projection and camera view
  103. // Note that the mMVPMatrix factor *must be first* in order
  104. // for the matrix multiplication product to be correct.
  105. Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0);
  106. // Draw squares
  107. for (Map.Entry&lt;String, Square&gt; s : this.mySquares.entrySet()) {
  108. s.getValue().draw(scratch);
  109. }
  110. }
  111. @Override
  112. public void onSurfaceChanged(GL10 unused, int width, int height) {
  113. this.screenWidth = width;
  114. this.screenHeight = height;
  115. // Adjust the viewport based on geometry changes,
  116. // such as screen rotation
  117. GLES20.glViewport(0, 0, width, height);
  118. float ratio = (float) width / height;
  119. // this projection matrix is applied to object coordinates
  120. // in the onDrawFrame() method
  121. Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
  122. }
  123. public static int loadShader(int type, String shaderCode) {
  124. // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
  125. // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
  126. int shader = GLES20.glCreateShader(type);
  127. // add the source code to the shader and compile it
  128. GLES20.glShaderSource(shader, shaderCode);
  129. GLES20.glCompileShader(shader);
  130. return shader;
  131. }
  132. public static void checkGlError(String glOperation) {
  133. int error;
  134. while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
  135. Log.e(TAG, glOperation + &quot;: glError &quot; + error);
  136. throw new RuntimeException(glOperation + &quot;: glError &quot; + error);
  137. }
  138. }
  139. }

I added a moveSquare-Methode, because all squares have the same coordinates when initialized. I'm not sure if this is the right way to do it, please tell me if this is wrong/messes up the other calculations.

  1. public class Square {
  2. private String squareID;
  3. private final String vertexShaderCode =
  4. // This matrix member variable provides a hook to manipulate
  5. // the coordinates of the objects that use this vertex shader
  6. &quot;uniform mat4 uMVPMatrix;&quot; +
  7. &quot;attribute vec4 squarePosition;&quot; +
  8. &quot;void main() {&quot; +
  9. // The matrix must be included as a modifier of gl_Position.
  10. // Note that the uMVPMatrix factor *must be first* in order
  11. // for the matrix multiplication product to be correct.
  12. &quot; gl_Position = uMVPMatrix * squarePosition;&quot; +
  13. &quot;}&quot;;
  14. private final String fragmentShaderCode =
  15. &quot;precision mediump float;&quot; +
  16. &quot;uniform vec4 squareColor;&quot; +
  17. &quot;void main() {&quot; +
  18. &quot; gl_FragColor = squareColor;&quot; +
  19. &quot;}&quot;;
  20. private FloatBuffer vertexBuffer;
  21. private ShortBuffer drawListBuffer;
  22. private int mProgram;
  23. private int mPositionHandle;
  24. private int mColorHandle;
  25. private int mMVPMatrixHandle;
  26. private static final String TAG = &quot;Square&quot;;
  27. // number of coordinates per vertex in this array
  28. static final int COORDS_PER_VERTEX = 3;
  29. private float squareCoords[] = {
  30. -0.1f, 0.1f, 0.0f, // top left
  31. -0.1f, -0.1f, 0.0f, // bottom left
  32. 0.1f, -0.1f, 0.0f, // bottom right
  33. 0.1f, 0.1f, 0.0f}; // top right
  34. private final short drawOrder[] = {0, 1, 2, 0, 2, 3}; // order to draw vertices
  35. private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
  36. //Fallback color
  37. private float color[] = {0.2f, 0.709803922f, 0.898039216f, 1.0f};
  38. /**
  39. * Sets up the drawing object data for use in an OpenGL ES context.
  40. */
  41. public Square(String id, float [] color) {
  42. this.squareID = id;
  43. if(color.length == 4) {
  44. this.color = color;
  45. }
  46. //Buffers need to updated with the new square coordinates
  47. updateBuffers();
  48. //Shaders (should) only be prepared once when initializing a square
  49. prepareShadersAndOpenGL();
  50. }
  51. private void prepareShadersAndOpenGL() {
  52. // prepare shaders and OpenGL program
  53. int vertexShader = MyGLRenderer.loadShader(
  54. GLES20.GL_VERTEX_SHADER,
  55. vertexShaderCode);
  56. int fragmentShader = MyGLRenderer.loadShader(
  57. GLES20.GL_FRAGMENT_SHADER,
  58. fragmentShaderCode);
  59. mProgram = GLES20.glCreateProgram(); // create empty OpenGL Program
  60. GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
  61. GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
  62. GLES20.glLinkProgram(mProgram); // create OpenGL program executables
  63. }
  64. public void updateBuffers() {
  65. // initialize vertex byte buffer for shape coordinates
  66. ByteBuffer bb = ByteBuffer.allocateDirect(
  67. // (# of coordinate values * 4 bytes per float)
  68. squareCoords.length * 4);
  69. bb.order(ByteOrder.nativeOrder());
  70. vertexBuffer = bb.asFloatBuffer();
  71. vertexBuffer.put(squareCoords);
  72. vertexBuffer.position(0);
  73. // initialize byte buffer for the draw list
  74. ByteBuffer dlb = ByteBuffer.allocateDirect(
  75. // (# of coordinate values * 2 bytes per short)
  76. drawOrder.length * 2);
  77. dlb.order(ByteOrder.nativeOrder());
  78. drawListBuffer = dlb.asShortBuffer();
  79. drawListBuffer.put(drawOrder);
  80. drawListBuffer.position(0);
  81. }
  82. //Updating the square coordinates and updating to buffers
  83. public void moveSquare(float deltaX, float deltaY) {
  84. this.squareCoords[0] += deltaX;
  85. this.squareCoords[3] += deltaX;
  86. this.squareCoords[6] += deltaX;
  87. this.squareCoords[9] += deltaX;
  88. this.squareCoords[1] += deltaY;
  89. this.squareCoords[4] += deltaY;
  90. this.squareCoords[7] += deltaY;
  91. this.squareCoords[10] += deltaY;
  92. updateBuffers();
  93. }
  94. /**
  95. * Encapsulates the OpenGL ES instructions for drawing this shape.
  96. *
  97. * @param mvpMatrix - The Model View Project matrix in which to draw
  98. * this shape.
  99. */
  100. public void draw(float[] mvpMatrix) {
  101. // Add program to OpenGL environment
  102. // Log.i(TAG, &quot;Square (&quot;+squareID+&quot;) mProgram: &quot;+mProgram);
  103. GLES20.glUseProgram(mProgram);
  104. // get handle to vertex shader&#39;s vPosition member
  105. mPositionHandle = GLES20.glGetAttribLocation(mProgram, &quot;squarePosition&quot;);
  106. // Enable a handle to the triangle vertices
  107. GLES20.glEnableVertexAttribArray(mPositionHandle);
  108. // Prepare the triangle coordinate data
  109. GLES20.glVertexAttribPointer(
  110. mPositionHandle, COORDS_PER_VERTEX,
  111. GLES20.GL_FLOAT, false,
  112. vertexStride, vertexBuffer);
  113. // get handle to fragment shader&#39;s vColor member
  114. mColorHandle = GLES20.glGetUniformLocation(mProgram, &quot;squareColor&quot;);
  115. // Set color for drawing the triangle
  116. GLES20.glUniform4fv(mColorHandle, 1, color, 0);
  117. // get handle to shape&#39;s transformation matrix
  118. mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, &quot;uMVPMatrix&quot;);
  119. // MyGLRenderer.checkGlError(&quot;glGetUniformLocation&quot;);
  120. // Apply the projection and view transformation
  121. GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
  122. // MyGLRenderer.checkGlError(&quot;glUniformMatrix4fv&quot;);
  123. // Draw the square
  124. GLES20.glDrawElements(
  125. GLES20.GL_TRIANGLES, drawOrder.length,
  126. GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
  127. // Disable vertex array
  128. GLES20.glDisableVertexAttribArray(mPositionHandle);
  129. }
  130. }
  1. public class MyGLSurfaceView extends GLSurfaceView {
  2. private final MyGLRenderer mRenderer;
  3. private static final String TAG = &quot;MyGLSurfaceView&quot;;
  4. private final float TOUCH_SCALE_FACTOR = 180.0f / 320;
  5. public MyGLSurfaceView(Context context) {
  6. super(context);
  7. // Create an OpenGL ES 2.0 context.
  8. setEGLContextClientVersion(2);
  9. // Set the Renderer for drawing on the GLSurfaceView
  10. mRenderer = new MyGLRenderer();
  11. setRenderer(mRenderer);
  12. // Render the view only when there is a change in the drawing data
  13. setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
  14. }
  15. @Override
  16. public boolean onTouchEvent(MotionEvent e) {
  17. // MotionEvent reports input details from the touch screen
  18. // and other input controls. In this case, you are only
  19. // interested in events where the touch position changed.
  20. float x = e.getX();
  21. float y = e.getY();
  22. switch (e.getAction()) {
  23. case MotionEvent.ACTION_DOWN:
  24. mRenderer.logMatrices();
  25. mRenderer.checkCollision(x, y);
  26. // mRenderer.setAngle(mRenderer.getAngle()+45f);
  27. requestRender();
  28. }
  29. return true;
  30. }
  31. }

I know this is quite a lot to read through, so I will try to express my main questions/issues:

  1. Is my idea correct in general or am I using the wrong transformations/steps?
  2. Does the squareCoord-Array in the Square-class represent my Model-Matrix and at which point are these converted into world-coordinates?
  3. Why is the matrix that i give to the draw-Method in the square-class called mMVPMatrix, for me this implies that this matrix contains all three Matrices (Model, View, Projection). But at the point I'm calling the draw-Method I've just multiplied the Projection- with the View-Matrix, so where should the Model-Part come from? Am I missing something here or am I mixing up the terms for the matrices?
  4. I'm still trying to understand what the Projection-Matrix does/describes. I understood that it basicly defines the area that shall be rendered, everything thats not in this area will not show up on the screen. Is this area always relative to the camera(View) Position?
    <br>
    <br>

I hope i explained my problem(s) properly, maybe there is even a simpler solution for my problem in general. Thanks in advance to all who have read so far. I hope someone can help me with this

PS: This is my first question on Stackoverflow and my spelling might not be perfect, so sorry for that. If you are missing information to understand the problem / answer one of my questions just ask, I will try to add them as quickly as possible.


Here is some debug information:

  • Recognized touch on position x=940.94604| y=407.9297
  • MVPMatrix: [-4.4, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 2.5, 1.0, 0.0, 0.0, -3.0, 3.0]
  • mProjectionMarix: [4.4, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, -2.5, -1.0, 0.0, 0.0, -10.5, 0.0]
  • mViewMatrix: [-1.0, 0.0, -0.0, 0.0, 0.0, 1.0, -0.0, 0.0, 0.0, -0.0, -1.0, 0.0, 0.0, 0.0, -3.0, 1.0]
  • checkCollision-touchClipMatrix: [0.7424927, 0.48493725, -3.0, 1.0]
  • checkCollision-invertedProjectionMatrix: [0.22727272, -0.0, -0.0, -0.0, -0.0, 0.3333333, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0952381, -0.0, -0.0, -1.0, 0.23809522]
  • checkCollision-invertedMViewMatrix: [-1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, -0.0, -3.0, 1.0]
  • checkCollision-unview-Matrix[-0.22727272, 0.0, 0.0, 0.0, 0.0, 0.3333333, 0.0, 0.0, 0.0, 0.0, 0.2857143, -0.0952381, 0.0, -0.0, 0.28571433, 0.23809522]
  • checkCollision-mouse_worldspace: [-0.16874833, 0.16164574, -0.5714286, 0.52380955]
  • checkCollision-ray_unnormalized: [-0.3221559, 0.3085964, 1.9090909, 0.0]
  • checkCollision-ray_length: 1.9605213
  • checkCollision - ray_vector: [-0.16432154, 0.15740527, 0.9737669, 0.0]
  • checkCollision-intersection point: (NaN, NaN, NaN)

答案1

得分: 1

The computation of ray_unnormalized seems to be wrong. You cannot subtract Homogeneous coordinates the way you do. Konvert the mouse_worldspace to a Cartesian coordinate. The Cartesian coordinate are the Quotients of the x, y, and z component and the w component (see Perspective divide).

The ray direction is the vector from the Cartesian camera position to the Cartesian mouse position:

  1. //Getting the camera position
  2. float [] cameraPosition = {0, 0, -6};
  3. //subtract camera position from the mouse_worldspace
  4. float [] ray_unnormalized = new float[4];
  5. for(int i = 0; i < 3; i++){
  6. ray_unnormalized[i] = mouse_worldspace[i] / mouse_worldspace[3] - cameraPosition[i];
  7. }
英文:

The computation of ray_unnormalized seems to be wrong. You cannot subtract Homogeneous coordinates the way you do. Konvert the mouse_worldspace to a Cartesian coordinate. The Cartesian coordinate are the Quotients of the x, y, and z component and the w component (see Perspective divide).
The ray direction is the vector from the Cartesian camera position to the Cartesian mouse position:

  1. //Getting the camera position
  2. float [] cameraPosition = {0, 0, -6};
  3. //subtract camera position from the mouse_worldspace
  4. float [] ray_unnormalized = new float[4];
  5. for(int i = 0; i &lt; 3; i++){
  6. ray_unnormalized[i] = mouse_worldspace[i] / mouse_worldspace[3] - cameraPosition[i];
  7. }

huangapple
  • 本文由 发表于 2020年8月27日 21:27:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/63617053.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定