OpenGL AABB碰撞检测问题求助:车辆与物体碰撞判断未生效
碰撞检测失效问题修复方案
核心问题排查
- 数组越界错误:你定义的
obj数组只有3个元素(索引0、1、2分别对应x、y、z坐标),但在drawRandomObjects函数中使用了obj[3],越界访问会读取垃圾值,导致障碍物实际渲染位置完全不符合预期 - 碰撞检测坐标不匹配:你在场景中渲染了两个偏移后的障碍物(左障碍物坐标为
(obj[0]-4, obj[1]+1, obj[2]-100),右障碍物坐标为(obj[0]+4, obj[1]+1, obj[2]-130)),但checkCollision函数只和原始的obj原点坐标比对,永远不会匹配到实际渲染的障碍物 - 缺少车厢碰撞检测:车辆分为车头、车厢两部分,当前只检测了车头的碰撞,车厢和障碍物接触不会触发判定
- 车厢AABB参数缺失:你没有定义车厢的尺寸参数,碰撞检测无法计算车厢的包围盒范围
修复后的代码调整
1. 补充车厢尺寸参数
在全局变量部分添加:
float carBackSizeX = 2; float carBackSizeY = 2; float carBackSizeZ = 2;
说明:车厢绘制用的是glutWireCube(4),原始半长为2,无缩放所以三个轴半长均为2
2. 修复drawRandomObjects的数组越界
把函数内所有obj[3]替换为obj[2]:
// 左物体 glTranslatef(obj[0] - 4, obj[1] + 1, obj[2] - 100); // 右物体 glTranslatef(obj[0] + 4, obj[1] + 1, obj[2] - 130);
3. 重写checkCollision碰撞检测逻辑
// 封装单个AABB碰撞判断逻辑,参数为两个物体的中心坐标和三个轴的半长 bool aabbCollide(float aX, float aY, float aZ, float aHalfX, float aHalfY, float aHalfZ, float bX, float bY, float bZ, float bHalfX, float bHalfY, float bHalfZ) { return (aX - aHalfX <= bX + bHalfX && aX + aHalfX >= bX - bHalfX) && (aY - aHalfY <= bY + bHalfY && aY + aHalfY >= bY - bHalfY) && (aZ - aHalfZ <= bZ + bHalfZ && aZ + aHalfZ >= bZ - bHalfZ); } bool checkCollision(){ // 左障碍物参数 float leftObjX = obj[0] - 4; float leftObjY = obj[1] + 1; float leftObjZ = obj[2] - 100; // 右障碍物参数 float rightObjX = obj[0] + 4; float rightObjY = obj[1] + 1; float rightObjZ = obj[2] - 130; // 检测车头和两个障碍物的碰撞 if (aabbCollide(carFront[0], carFront[1], carFront[2], carFrontSizeX, carFrontSizeY, carFrontSizeZ, leftObjX, leftObjY, leftObjZ, objSizeX, objSizeY, objSizeZ) || aabbCollide(carFront[0], carFront[1], carFront[2], carFrontSizeX, carFrontSizeY, carFrontSizeZ, rightObjX, rightObjY, rightObjZ, objSizeX, objSizeY, objSizeZ)) { return true; } // 检测车厢和两个障碍物的碰撞 if (aabbCollide(carBack[0], carBack[1], carBack[2], carBackSizeX, carBackSizeY, carBackSizeZ, leftObjX, leftObjY, leftObjZ, objSizeX, objSizeY, objSizeZ) || aabbCollide(carBack[0], carBack[1], carBack[2], carBackSizeX, carBackSizeY, carBackSizeZ, rightObjX, rightObjY, rightObjZ, objSizeX, objSizeY, objSizeZ)) { return true; } return false; }
优化建议
后续如果需要添加更多随机障碍物,建议定义结构体存储所有障碍物的坐标、尺寸,遍历数组做碰撞检测,避免硬编码每个障碍物的参数。
内容的提问来源于stack exchange,提问作者no_worries
相关产品推荐
相关产品推荐

