Android 是否有可能在OpenGL中单击立方体的哪个曲面?
我已经创建了一个立方体,它的旋转非常完美。我的任务是你点击哪个旋转立方体。例如,如果你点击立方体表面的红色,我会赢,但我找不到立方体点击的表面视图 已编辑Android 是否有可能在OpenGL中单击立方体的哪个曲面?,android,opengl-es,coordinate-transformation,Android,Opengl Es,Coordinate Transformation,我已经创建了一个立方体,它的旋转非常完美。我的任务是你点击哪个旋转立方体。例如,如果你点击立方体表面的红色,我会赢,但我找不到立方体点击的表面视图 已编辑 我想要我接触的地方的表面 以下是我的渲染器代码: public void onDrawFrame(GL10 arg0) { // GLES20.glEnable(GLES20.GL_TEXTURE_CUBE_MAP); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BI
我想要我接触的地方的表面 以下是我的渲染器代码:
public void onDrawFrame(GL10 arg0) {
// GLES20.glEnable(GLES20.GL_TEXTURE_CUBE_MAP);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
GLES20.glUseProgram(iProgId);
cubeBuffer.position(0);
GLES20.glVertexAttribPointer(iPosition, 3, GLES20.GL_FLOAT, false, 0, cubeBuffer);
GLES20.glEnableVertexAttribArray(iPosition);
texBuffer.position(0);
GLES20.glVertexAttribPointer(iTexCoords, 3, GLES20.GL_FLOAT, false, 0, texBuffer);
GLES20.glEnableVertexAttribArray(iTexCoords);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_CUBE_MAP, iTexId);
GLES20.glUniform1i(iTexLoc, 0);
// Draw a cube.
// Translate the cube into the screen.
Matrix.setIdentityM(m_fIdentity, 0);
// Matrix.translateM(m_fIdentity, 0, 0.0f, 0.8f, -3.5f);
// Set a matrix that contains the current rotation.
Matrix.setIdentityM(mCurrentRotation, 0);
Matrix.rotateM(mCurrentRotation, 0, mDeltaX, 1.0f, 0.0f, 0.0f);
Matrix.rotateM(mCurrentRotation, 0, mDeltaY, 0.0f, 1.0f, 0.0f);
Matrix.rotateM(mCurrentRotation, 0, mDeltaZ, 0.0f, 0.0f, 1.0f);
mDeltaX = 0.0f;
mDeltaY = 0.0f;
mDeltaZ = 0.0f;
// Multiply the current rotation by the accumulated rotation, and then set the accumulated
// rotation to the result.
Matrix.multiplyMM(mTemporaryMatrix, 0, mCurrentRotation, 0, mAccumulatedRotation, 0);
System.arraycopy(mTemporaryMatrix, 0, mAccumulatedRotation, 0, 16);
// Rotate the cube taking the overall rotation into account.
Matrix.multiplyMM(mTemporaryMatrix, 0, m_fIdentity, 0, mAccumulatedRotation, 0);
System.arraycopy(mTemporaryMatrix, 0, m_fIdentity, 0, 16);
Matrix.multiplyMM(m_fVPMatrix, 0, m_fViewMatrix, 0, m_fIdentity, 0);
Matrix.multiplyMM(m_fVPMatrix, 0, m_fProjMatrix, 0, m_fVPMatrix, 0);
Ray ray = null;
if (mDeltaX != -99) {
ray = new Ray(arg0, width, height, mDeltaX, mDeltaY);
}
mDeltaX = -99;
// Matrix.translateM(m_fVPMatrix, 0, 0, 0, 1);
GLES20.glUniformMatrix4fv(iVPMatrix, 1, false, m_fVPMatrix, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 36, GLES20.GL_UNSIGNED_SHORT, indexBuffer);
// GLES20.glDisable(GLES20.GL_TEXTURE_CUBE_MAP);
}
最常见和最现代的方法可能是光线相交 我以为你有很多立方体
如果必须通过在视图端口上选择一个点来找到场景表面上的一个点,则必须找到一种相反的方法。
识别对象曲面的常用方法是定义具有起点和方向的光线,并找到光线第一次击中的曲面。视线就是这样的光线,因为它有一个起点和一个方向,但如何通过视线定义光线取决于场景的投影类型。
当在眼睛空间中的坐标被线性映射到标准化设备坐标时,在相机平截头体(一个截断的棱锥体)中的眼睛空间坐标被映射到一个立方体(标准化设备坐标)。
在这两种情况下,首先必须将视口位置转换为规格化(XY)设备坐标,范围为(-1,-1)到(1,1)。这是一个简单的线性映射:
w = with of the viewport
h = height of the viewport
x = X position of the mouse
y = Y position ot the mouse
ndc_x = 2.0 * x/w - 1.0;
ndc_y = 1.0 - 2.0 * y/h; // invert Y axis
在视图空间中的正交投影处定义视线光线
光线的起点可以通过使用逆投影矩阵,在近平面(z=0)上的标准化设备坐标中变换视口的点来计算
R0_view = inverse( projection-matrix ) * (ndc_x, ndc_y, 0.0, 1.0)
视线的方向是进入视图端口的方向(0,0,-1)
在视图空间中的透视投影处定义视线光线
视线的起点是摄影机位置,在视图空间中为(0,0,0)
R0_view = (0.0, 0.0, 0.0)
视线的方向可以通过逆投影矩阵在归一化设备坐标中变换光线上的任何点来计算
D_view = normalize( inverse( projection-matrix ) * (ndc_x, ndc_y, 0.0, 1.0) )
从视图坐标转换为世界坐标
要从视图空间转换到世界空间,必须通过逆视图矩阵变换视图空间坐标
R0_world = inverse( view-matrix ) * R0_view
R1_world = inverse( view-matrix ) * (R0_view + D_view)
D_world = normalize(R1_world - R0_world)
查找光线与基本体的交点
要查找被光线击中的曲面,必须计算每个曲面(基本体)与光线的交点与光线起点之间的距离。碰撞距离(在光线方向)最小的曲面
要查找光线与三角形基本体交点的距离,必须执行以下步骤:
NV
)和平面上的点(P0
)定义。如果三角形由3个点a
、B
和C
给出,则平面可按如下方式计算:
P0 = A
NV = normalize( cross( B-A, C-A ) )
光线与平面的交点通过替换光线的方程式来计算P_isect=dist*D+R0
进入平面方程dot(P_isect-P0,NV)=0
内容如下:
P_isect = R0 + D * dist_isect
dist_isect = dot( P0 - R0, NV ) / dot( D, NV )
测试交点是否在光线方向:
如果“距离”大于或等于0.0,则交点位于光线方向
测试交点是否在三角形轮廓内或三角形轮廓上
要确定,如果一个点位于三角形内,则必须测试从角点到交点的线是否位于连接到角点的To支腿之间:
bool PointInOrOn( P1, P2, A, B )
{
CP1 = cross( B - A, P1 - A )
CP2 = cross( B - A, P2 - A )
return dot( CP1, CP2 ) >= 0
}
bool PointInOrOnTriangle( P, A, B, C )
{
return PointInOrOn( P, A, B, C ) &&
PointInOrOn( P, B, C, A ) &&
PointInOrOn( P, C, A, B )
}
以下问题的答案对于解决该问题也很有意义:
glArrayType=typeof Float32Array=“未定义”?Float32Array:(WebGLFloatArray的类型!=“未定义”?WebGLFloatArray:Array);
函数标识MT44(){
var m=新的Glarray类型(16);
m[0]=1;m[1]=0;m[2]=0;m[3]=0;
m[4]=0;m[5]=1;m[6]=0;m[7]=0;
m[8]=0;m[9]=0;m[10]=1;m[11]=0;
m[12]=0;m[13]=0;m[14]=0;m[15]=1;
返回m;
};
函数旋转轴(matA、angRad、轴){
var-aMap=[[1,2],[2,0],[0,1];
var a0=aMap[axis][0],a1=aMap[axis][1];
var sinAng=Math.sin(angRad),cosAng=Math.cos(angRad);
var matB=新Glarray类型(16);
对于(var i=0;i<16;++i)matB[i]=matA[i];
对于(var i=0;i<3;
bool PointInOrOn( P1, P2, A, B )
{
CP1 = cross( B - A, P1 - A )
CP2 = cross( B - A, P2 - A )
return dot( CP1, CP2 ) >= 0
}
bool PointInOrOnTriangle( P, A, B, C )
{
return PointInOrOn( P, A, B, C ) &&
PointInOrOn( P, B, C, A ) &&
PointInOrOn( P, C, A, B )
}