我正在开发一款Android应用程序,该应用程序使用手机传感器的相机方向移动3D对象。
我的项目基于以下教程:Libgdx tutorial以及您可以在此处下载的代码:source code。它运作良好。但是,我试图实现允许用户触摸3D立方体对象的功能,我失败了。 Intersector.intersectRayTriangles()始终返回false。
我是LibGDX和OpenGL的新手,所以我找不到解决方案。请帮我。提前谢谢。
本教程的所有者已经编写了一个方法来完成这项工作,但它不起作用。代码如下:
3D立方体对象( Cube.java ):
public class Cube extends Shape {
public static final float vertexData[] = { 0.5f, 0.5f, 0.5f, -0.5f, 0.5f,
0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f,
0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f,
0.5f, -0.5f,
0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f,
0.5f, 0.5f,
0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f,
0.5f, -0.5f,
-0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f,
-0.5f, 0.5f,
-0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, -0.5f,
-0.5f, 0.5f, };
public static final float texData[] = { 0.0f, 0.0f, // quad/face 0/Vertex 0
0.0f, 1.0f, // quad/face 0/Vertex 1
1.0f, 1.0f, // quad/face 0/Vertex 2
1.0f, 0.0f, // quad/face 0/Vertex 3
1.0f, 1.0f, // quad/face 1/Vertex 4
0.0f, 1.0f, // quad/face 1/Vertex 5
0.0f, 0.0f, // quad/face 1/Vertex 6
1.0f, 0.0f, // quad/face 1/Vertex 7
0.0f, 0.0f, // quad/face 2/Vertex 8
0.0f, 1.0f, // quad/face 2/Vertex 9
1.0f, 1.0f, // quad/face 2/Vertex 10
1.0f, 0.0f, // quad/face 2/Vertex 11
1.0f, 1.0f, // quad/face 3/Vertex 12
0.0f, 1.0f, // quad/face 3/Vertex 13
0.0f, 0.0f, // quad/face 3/Vertex 14
1.0f, 0.0f, // quad/face 3/Vertex 15
1.0f, 1.0f, // quad/face 4/Vertex 16
0.0f, 1.0f, // quad/face 4/Vertex 17
0.0f, 0.0f, // quad/face 4/Vertex 18
1.0f, 0.0f, // quad/face 4/Vertex 19
1.0f, 1.0f, // quad/face 5/Vertex 20
0.0f, 1.0f, // quad/face 5/Vertex 21
0.0f, 0.0f, // quad/face 5/Vertex 22
1.0f, 0.0f, // quad/face 5/Vertex 23
};
public static final short facesVerticesIndex[][] = { { 0, 1, 2, 3 },
{ 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 },
{ 16, 17, 18, 19 }, { 20, 21, 22, 23 } };
public final static VertexAttribute verticesAttributes[] = new VertexAttribute[] {
new VertexAttribute(Usage.Position, 3, "a_position"),
new VertexAttribute(Usage.ColorPacked, 4, "a_color"),
new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoords"), };
public Cube(Context context, String textFilename) {
super(context);
textureFilename = textFilename;
mesh = new Mesh[6];
// Load the Libgdx splash screen texture
texture = new Texture(Gdx.files.internal(textureFilename));
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
// Create the 6 faces of the Cube
for (int i = 0; i < 6; i++) {
mesh[i] = new Mesh(true, 24, 4, verticesAttributes);
int pIdx = 0;
int tIdx = 0;
float[] vertices = new float[144];
for (int j = 0; j < vertices.length; ) {
vertices[j++] = vertexData[pIdx++];
vertices[j++] = vertexData[pIdx++];
vertices[j++] = vertexData[pIdx++];
vertices[j++] = Color.toFloatBits(255, 255, 255, 255);
vertices[j++] = texData[tIdx++];
vertices[j++] = texData[tIdx++];
}
mesh[i].setVertices(vertices);
mesh[i].setIndices(Cube.facesVerticesIndex[i]);
}
intersectionIndices = new short[6][6];
for (int i = 0; i < 6; i++) {
short[] temp = new short[6];
for (int j = 0; j < facesVerticesIndex.length; j++) {
if (j <= 2) {
temp[j] = facesVerticesIndex[i][j];
}
if (j > 2) {
temp[3] = facesVerticesIndex[i][0];
temp[4] = facesVerticesIndex[i][2];
temp[5] = facesVerticesIndex[i][3];
}
}
intersectionIndices[i] = temp;
}
}
public void render() {
Gdx.gl10.glPushMatrix();
float[] infilter = { virX, virY, virZ };
float[] outfilter = this.filter.lowPass(infilter, 0.06f);
Gdx.gl10.glTranslatef(outfilter[0], outfilter[1], outfilter[2]);
Gdx.gl10.glRotatef(angle, xAxis, yAxis, zAxis);
Gdx.gl10.glScalef(scaleX, scaleY, scaleZ);
texture.bind();
for (int i = 0; i < 6; i++) {
mesh[i].render(GL10.GL_TRIANGLE_FAN, 0, 4);
}
texture.bind(0);
Gdx.gl11.glGetFloatv(GL11.GL_MODELVIEW_MATRIX, accModelView, 0);
if(this.index>0){
// modelView=new Matrix4(this.Parent.getShapes().get(this.index-1).accModelView).inv().val;
Matrix4.mul(modelView,accModelView);
}else{
modelView = accModelView;
}
Gdx.gl10.glPopMatrix();
}
}
我使用下面的方法来找到光线与立方体的交集:
public boolean isIntersected(Ray ray, float[] view) {
radius = (float) Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)
+ Math.pow(z, 2));
Matrix4.mul(view, modelView);
Matrix4 mat = new Matrix4(view);
float[] temp = new float[vertexData.length];
for (int i = 0; i < vertexData.length; i += 3) {
float[] vec = { vertexData[0 + i], vertexData[1 + i],
vertexData[2 + i], 1 };
Matrix4.mulVec(mat.val, vec);
temp[0 + i] = vec[0];
temp[1 + i] = vec[1];
temp[2 + i] = vec[2];
}
for(int i=0;i<temp.length;i++){
System.out.println(temp[i]);
}
Vector3 localIntersection = new Vector3();
Vector3 globalIntersection = new Vector3();
boolean intersectionOccured = false;
for (int j = 0; j < mesh.length; j++) {
if (Intersector.intersectRayTriangles(ray, temp,
intersectionIndices[j], 3, localIntersection)) {
intersectionOccured = true;
if (!(globalIntersection.isZero())) {
if (ray.origin.sub(localIntersection).len() < ray.origin
.sub(globalIntersection).len()) {
globalIntersection.set(localIntersection);
}
} else {
globalIntersection.set(localIntersection);
}
}
}
if (!globalIntersection.isZero() && intersectionOccured) {
listener.click(this, globalIntersection);
}
return false;
}
在Screen.java中,我收到了触摸点的位置并将其传递给上述方法:
public Screen(Context context) {
this.context = context;
this.eventHandler = new EventHandler() {
@Override
public boolean tap(float x, float y, int count, int button) {
Ray ray = camera.getPickRay(Gdx.input.getX(),
Gdx.input.getY(), 0, 0, Gdx.graphics.getWidth(),
Gdx.graphics.getHeight());
c.isIntersected(ray, camera.view.getValues());
return super.tap(x, y, count, button);
}
@Override
public boolean pan(float x, float y, float deltaX, float deltaY) {
return super.pan(x, y, deltaX, deltaY);
}
@Override
public boolean zoom(float initialDistance, float distance) {
return super.zoom(initialDistance, distance);
}
};
this.gestureDetector = new GestureDetector(this.eventHandler);
}