我在WPF窗口中使用SharpGL,并使用自定义着色器导航和绘制测量点云,以减少基于距离的点大小。一切运作良好,但我最近尝试添加选择最靠近鼠标点击投射光线的点的功能。我在此链接中使用了步骤0到4:http://antongerdelan.net/opengl/raycasting.html
我面临的问题是,射线似乎略微偏向相机矢量,导致我错过了我点击的点,只刮掉了它们的内边缘。我也是从相机位置开始绘制光线所以最初光线在移动相机之前应该显示为一个点(向下看轨迹线),但我可以看到它清晰地绘制在屏幕中间。这是一个屏幕截图,显示当我点击其中心时光线未点亮的位置:
这是我用来计算光线起点和终点坐标的代码:
public class BlockComment {
static StringReader test = new StringReader ( "This is test1;\nThis is test2;\n" +
"/*This is test3;\nThis is test4;*/\nThis is test5;" );
public static void main( String[] args ) throws IOException {
BufferedReader br = new BufferedReader( new SkipBlockComments( test ) );
String line;
while( (line = br.readLine()) != null ) {
System.out.println( line );
}
}
public static class SkipBlockComments extends FilterReader {
private boolean inBlock;
public SkipBlockComments( Reader r ) {
super( r );
if( !markSupported() ) throw new IllegalArgumentException();
}
@Override
public int read() throws IOException {
for( ;; ) {
int character = super.read();
if( !inBlock ) {
if( character == '/' && nextCharEquals( '*' ) ) {
inBlock = true;
} else {
return character;
}
} else {
if( character == '*' && nextCharEquals( '/' ) ) {
inBlock = false;
}
}
}
}
private boolean nextCharEquals( char c ) throws IOException {
mark( 1 );
if( super.read() == c )
return true;
reset();
return false;
}
@Override
public int read( char[] buf, int start, int length ) throws IOException {
int c = read();
if( c == -1 ) return -1;
buf[start] = (char) c;
return 1;
}
@Override
public int read( char[] buf ) throws IOException {
return read( buf, 0, 1 );
}
}
}
输出如下:
public void CreateVerticesForMouseCoord(OpenGL gl, float winx, float winy)
{
int[] viewport = new int[4];
gl.GetInteger(OpenGL.GL_VIEWPORT, viewport);
float window_width = viewport[2];
float window_height = viewport[3];
Console.WriteLine("Window size: " + window_width + "," + window_height);
vec4 clipPosition = new vec4(0.0f, 0.0f, 1.0f, 1.0f);
// Normalize the x and y coordinates
clipPosition.x = 2.0f * (winx / window_width) - 1.0f;
clipPosition.y = -2.0f * (winy / window_height) + 1.0f;
mat4 viewInv = glm.inverse(viewMatrix);
mat4 projInv = glm.inverse(projectionMatrix);
vec4 camPosition = projInv * clipPosition;
camPosition.w = 0;
camPosition.z = -1;
vec4 worldPosition = viewInv * camPosition;
vec4 camCamPos = new vec4(0.0f, 0.0f, 0.0f, 1.0f);
vec4 objCamPos = glm.inverse(viewMatrix) * camCamPos;
vec4 camCamDir = new vec4(0.0f, 0.0f, -1.0f, 0.0f);
vec4 objCamDir = glm.inverse(viewMatrix) * camCamDir;
float x1 = objCamPos.x + 30.0f * worldPosition.x;
float y1 = objCamPos.y + 30.0f * worldPosition.y;
float z1 = objCamPos.z + 30.0f * worldPosition.z;
float x2 = objCamPos.x - 0.0f * worldPosition.x;
float y2 = objCamPos.y - 0.0f * worldPosition.y;
float z2 = objCamPos.z - 0.0f * worldPosition.z;
Console.WriteLine("Screen coordinates: " + winx + ","+winy);
Console.WriteLine("Clip coordinates: " + clipPosition.x + "," + clipPosition.y + "," + clipPosition.z+ ","+ clipPosition.w);
Console.WriteLine("Camera coordinates: " + camPosition.x + "," + camPosition.y + "," + camPosition.z+","+ camPosition.w);
Console.WriteLine("World coordinates: " + worldPosition.x + "," + worldPosition.y + "," + worldPosition.z+","+ worldPosition.w);
Console.WriteLine("Camera Position: " + objCamPos.x + "," + objCamPos.y + "," + objCamPos.z + "," + objCamPos.w);
Console.WriteLine("Camera Direction: " + objCamDir.x + "," + objCamDir.y + "," + objCamDir.z + "," + objCamDir.w);
float[] mousePointArray = { x1, y1, z1, x2, y2, z2 };
距离我点击的屏幕中心越远,偏移看起来越大。我可以得到任何帮助,我可以很好地理解这一点,我花了两天时间阅读文章,摆弄代码无济于事。