2011-10-26 60 views
2

我正在构建一个LWJGL程序,测试它是否在摄像头前方。我认为它正在工作,但我得到了很多不同的数字。我认为这是因为飞机永远持续下去,而且它们不是有限的广场。我会做什么来解决这个问题? (我也注意到,我的代码是相当缓慢,这可能是造成这???)这个光线投射算法是否正确?这是测试线/射线和立方体相交的正确方法吗?

这里是我的路口代码:

public static float getCubeInteresection(Cube b, Vector3f camera, Vector3f lookat) 
{ 
    Vector3f l = b.Location; 
    float boxs = 0.5f; 
    Plane3f[] bplanes = Plane3f.getBoxDefaults(l, boxs); 
    Vector3f result = null; 
    for (int t = 0; t < bplanes.length; t++) 
    { 
     Vector3f raytrace = getIntersection(camera, lookat,bplanes[t].Point0,bplanes[t].Point1,bplanes[t].Point2); 
     if (raytrace != null) 
     { 
      result = raytrace; 
      break; 
     } 
    } 
    if (result == null) 
     return -1.0f; //not hit, waste of time... lol 
    float x = (float) Math.pow(result.x - camera.x, 2); 
    float y = (float) Math.pow(result.y - camera.y, 2); 
    float z = (float) Math.pow(result.z - camera.z, 2); 
    float dist = (float) Math.sqrt(x + y + z); 
    return dist; 
} 
private static Vector3f getIntersection(Vector3f line12, Vector3f line22,Vector3f plane12, Vector3f plane22, Vector3f plane32) 
{ 
    javax.vecmath.Vector3f plane1 = new javax.vecmath.Vector3f(plane12.x,plane12.y,plane12.z); 
    javax.vecmath.Vector3f plane2 = new javax.vecmath.Vector3f(plane22.x,plane22.y,plane22.z); 
    javax.vecmath.Vector3f plane3 = new javax.vecmath.Vector3f(plane32.x,plane32.y,plane32.z); 
    javax.vecmath.Vector3f line1 = new javax.vecmath.Vector3f(line12.x,line12.y,line12.z); 
    javax.vecmath.Vector3f line2 = new javax.vecmath.Vector3f(line22.x,line22.y,line22.z); 
    javax.vecmath.Vector3f p1 = new javax.vecmath.Vector3f(plane1); 
    javax.vecmath.Vector3f p2 = new javax.vecmath.Vector3f(plane2); 
    javax.vecmath.Vector3f p3 = new javax.vecmath.Vector3f(plane3); 
    javax.vecmath.Vector3f p2minusp1 = new javax.vecmath.Vector3f(p2); 
    p2minusp1.sub(p1); 
    javax.vecmath.Vector3f p3minusp1 = new javax.vecmath.Vector3f(p3); 
    p3minusp1.sub(p1); 
    javax.vecmath.Vector3f normal = new javax.vecmath.Vector3f(); 
    normal.cross(p2minusp1, p3minusp1); 
    double d = -p1.dot(normal); 
    javax.vecmath.Vector3f i1 = new javax.vecmath.Vector3f(line1); 
    javax.vecmath.Vector3f direction = new javax.vecmath.Vector3f(line1); 
    direction.sub(line2); 
    double dot = direction.dot(normal); 
    if (dot == 0) return null; 
    double t = (-d - i1.dot(normal))/(dot); 
    javax.vecmath.Vector3f intersection = new javax.vecmath.Vector3f(line1); 
    javax.vecmath.Vector3f scaledDirection = new javax.vecmath.Vector3f(direction); 
    float scalent = (float)t; 
    scaledDirection.scale(scalent); 
    intersection.add(scaledDirection); 
    javax.vecmath.Vector3f intersectionPoint = new javax.vecmath.Vector3f(intersection); 
    return new Vector3f(intersectionPoint.x,intersectionPoint.y,intersectionPoint.z); 
} 

这里是我的立方体代码:

import org.lwjgl.util.vector.Vector3f; 

public class Plane3f 
{ 
public Vector3f Point0; 
public Vector3f Point1; 
public Vector3f Point2; 
public Plane3f(Vector3f p0, Vector3f p1, Vector3f p2) 
{ 
    Point0 = p0; 
    Point1 = p1; 
    Point2 = p2; 
} 
public static Plane3f[] getBoxDefaults(Vector3f l, float boxs) 
{ 
    Plane3f[] plane = new Plane3f[24]; 
    Vector3f p0p0 = new Vector3f(-boxs + l.x, -boxs + l.y, boxs + l.z); 
    Vector3f p0p1 = new Vector3f(boxs + l.x, -boxs + l.y, boxs + l.z); 
    Vector3f p0p2 = new Vector3f(boxs + l.x, boxs + l.y, boxs + l.z); 
    //Vector3f p0p3 = new Vector3f(-boxs + l.x, boxs + l.y, boxs + l.z); 
    Plane3f p0 = new Plane3f(p0p0, p0p1, p0p2); 

    Vector3f p1p0 = new Vector3f(-boxs + l.x, -boxs + l.y, -boxs + l.z); 
    Vector3f p1p1 = new Vector3f(-boxs + l.x, boxs + l.y, -boxs + l.z); 
    Vector3f p1p2 = new Vector3f(boxs + l.x, boxs + l.y, -boxs + l.z); 
    //Vector3f p1p3 = new Vector3f(boxs + l.x, -boxs + l.y, -boxs + l.z); 
    Plane3f p1 = new Plane3f(p1p0, p1p1, p1p2); 

    Vector3f p2p0 = new Vector3f(-boxs + l.x, boxs + l.y, -boxs + l.z); 
    Vector3f p2p1 = new Vector3f(-boxs + l.x, boxs + l.y, boxs + l.z); 
    Vector3f p2p2 = new Vector3f(boxs + l.x, boxs + l.y, boxs + l.z); 
    //Vector3f p2p3 = new Vector3f(boxs + l.x, boxs + l.y, -boxs + l.z); 
    Plane3f p2 = new Plane3f(p2p0, p2p1, p2p2); 

    Vector3f p3p0 = new Vector3f(-boxs + l.x, -boxs + l.y, -boxs + l.z); 
    Vector3f p3p1 = new Vector3f(boxs + l.x, -boxs + l.y, -boxs + l.z); 
    Vector3f p3p2 = new Vector3f(boxs + l.x, -boxs + l.y, boxs + l.z); 
    Plane3f p3 = new Plane3f(p3p0, p3p1, p3p2); 

    Vector3f p4p0 = new Vector3f(boxs + l.x, -boxs + l.y, -boxs + l.z); 
    Vector3f p4p1 = new Vector3f(boxs + l.x, boxs + l.y, -boxs + l.z); 
    Vector3f p4p2 = new Vector3f(boxs + l.x, boxs + l.y, boxs + l.z); 
    Plane3f p4 = new Plane3f(p4p0, p4p1, p4p2); 

    Vector3f p5p0 = new Vector3f(-boxs + l.x, -boxs + l.y, -boxs + l.z); 
    Vector3f p5p1 = new Vector3f(-boxs + l.x, -boxs + l.y, boxs + l.z); 
    Vector3f p5p2 = new Vector3f(-boxs + l.x, boxs + l.y, boxs + l.z); 
    Plane3f p5 = new Plane3f(p5p0, p5p1, p5p2); 
    plane[0] = p0; 
    plane[1] = p1; 
    plane[2] = p2; 
    plane[3] = p3; 
    plane[4] = p4; 
    plane[5] = p5; 
    return plane; 
} 

控制台的输出:

摄像机:(0.0,0.0,6.0)注视(行尾):(124.33239,274.9127,-1000.5496)距离(从 “getBlockInteresection” 返回):2.6099026立方体的位置:6 ,7,8

+0

你是什么意思的“我得到很多不同的数字”?您的输出仅显示一个交叉点。 – NickLH

+0

对不起,我的意思是每次场景更新时,我都会得到不同的数字(数字意思是从getBlockIntersection返回的距离),我正在移动相机的lookat,但实际位置仍然固定。 – seesharper

+0

你的相机和lookat变量都被传递给你的十字路口代码,所以如果你改变其中任何一个,你就会得到不同的数字。 – NickLH

回答

1

我不得不处理这跟我的比赛,但是在光线投射和视锥剔除是两回事。对大量物体执行取决于剔除的代价通常较高,而且准确性也较差,但它更简单,并且可能对您的程序很好。

如果你只需要知道,如果立方体中视,你可以在链接中使用该功能。这将测试立方体是否位于视锥体内部,而不仅仅位于视锥体的前方,因此如果立方体位于前方但远离侧边则会返回错误。

否则,您将需要编写使用新鲜glortho和gldeproject一个光线投射算法。

http://www.crownandcutlass.com/features/technicaldetails/frustum.html