您好我正在制作一个3D池游戏,我目前处于应用碰撞的状态,我正在使用openGL和C ++。我已经写了碰撞并且它正常工作。我所遇到的问题只与球类的速度有关,并且在碰撞时将力传递给其他球。
我有一个球类,用于包括母球在内的所有球。我有一个drawBall()函数:
void drawBall(Shader ourShader) {
extern GLfloat deltaTime;
a = F / radius;
v = v + (a * deltaTime);
ballPos = ballPos + (v*deltaTime) + (0.5f*a*deltaTime*deltaTime);
collision();
//F = glm::vec3(0.0f, 0.0f, 0.0f);
//ACTUAL DRAWING
glBindVertexArray(VAO);
glm::mat4 model;
model = glm::translate(model, ballPos);
model = glm::rotate(model, glm::radians(40.0f), glm::vec3(1.0f, 0.0f, 0.0f));
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
碰撞功能:
void collision() {
extern vector <Ball> ballCollection;
for (int i = 0; i < ballCollection.size(); i++) {
if (glm::distance(ballCollection.at(i).ballPos, ballPos) <= (2 * radius)) {
if (!glm::distance(ballCollection.at(i).ballPos, ballPos) == 0) {
extern GLfloat forceAmount;
if (isColliding == 0) {
glm::vec3 collPoint = glm::vec3((ballPos.x + ballCollection.at(i).ballPos.x) / 2, 0.0f, (ballPos.z + ballCollection.at(i).ballPos.z) / 2);
glm::vec3 collPointPerp = collPoint - ballPos;
glm::vec3 otherNew = collPointPerp;
glm::vec3 thisNew = glm::cross(collPointPerp, glm::vec3(0.0, 1.0, 0.0));
F = thisNew;
ballCollection.at(i).F = otherNew;
glm::vec3 newV;
glm::vec3 otherNewV;
newV.x = (v.x * (2 * ballCollection.at(i).radius * ballCollection.at(i).v.x)) / (radius + ballCollection.at(i).radius);
newV.z = (v.z * (2 * ballCollection.at(i).radius * ballCollection.at(i).v.z)) / (radius + ballCollection.at(i).radius);
newV.y = 0.0f;
otherNewV.x = (ballCollection.at(i).v.x * (2 * radius * v.x)) / (radius + ballCollection.at(i).radius);
otherNewV.z = (ballCollection.at(i).v.z * (2 * radius * v.z)) / (radius + ballCollection.at(i).radius);
otherNewV.y = 0.0f;
v.x = newV.x;
v.z = newV.z;
ballCollection.at(i).v.x = otherNewV.x;
ballCollection.at(i).v.z = otherNewV.z;
}
isColliding = 1;
ballCollection.at(i).isColliding = 1;
}
}
}
isColliding = 0;
这个calss在我的主要cpp中的一个单独的文件中。这有一个key_kallback函数:
void do_movement()
{
glm::vec3 cameraRight = glm::normalize(glm::cross(cameraFront, cameraUp));
GLfloat cameraSpeed = 50.0f;
glm::vec3 aboveBall = glm::vec3(ballCollection.at(15).ballPos.x, ballCollection.at(15).ballPos.y + 20.0f, ballCollection.at(15).ballPos.z);
glm::vec3 cameraFwd = aboveBall - cameraPos;
//cout << cameraFwd.x << "," << cameraFwd.y << "," << cameraFwd.z << endl;
if (keys[GLFW_KEY_W])
ballCollection.at(15).ballPos = ballCollection.at(15).ballPos + glm::vec3(0.0f, 0.0f, -0.1f);
if (keys[GLFW_KEY_S])
ballCollection.at(15).ballPos = ballCollection.at(15).ballPos + glm::vec3(0.0f, 0.0f, 0.1f);
if (keys[GLFW_KEY_A])
ballCollection.at(15).ballPos = ballCollection.at(15).ballPos + glm::vec3(-0.1f, 0.0f, 0.0f);
if (keys[GLFW_KEY_D])
ballCollection.at(15).ballPos = ballCollection.at(15).ballPos + glm::vec3(0.1f, 0.0f, 0.0f);
if (keys[GLFW_KEY_SPACE]) {
ballCollection.at(15).F = 10.0f*glm::normalize(cameraFwd);
}
if (keys[GLFW_KEY_E]) {
ballCollection.at(15).F = -10.0f * glm::normalize(cameraFwd);
}
}
然后在游戏循环中:
for (int i = 0; i < 16; i++) {
ballCollection.at(i).drawBall(ourShader);
}
cameraPos = ballCollection.at(15).ballPos + glm::vec3(0.0f, 20.0f, 20.0f);
do_movement();
我的问题是,当我用空间向主球施加力时,由于F值不断加到v,我的主球速度每帧增加。如果我在施加力后将F重新置于0,我就不能将力传递给其他球,因此它们的v为0并且在碰撞后它们不会移动。
非常感谢任何帮助,如果我需要额外的信息,请发表评论。
修改的
我意识到碰撞计算中有错误,应该是:
newV.x = (v.x + (2 * ballCollection.at(i).radius * ballCollection.at(i).v.x)) / (radius + ballCollection.at(i).radius);
newV.z = (v.z + (2 * ballCollection.at(i).radius * ballCollection.at(i).v.z)) / (radius + ballCollection.at(i).radius);
newV.y = 0.0f;
otherNewV.x = (ballCollection.at(i).v.x + (2 * radius * v.x)) / (radius + ballCollection.at(i).radius);
otherNewV.z = (ballCollection.at(i).v.z + (2 * radius * v.z)) / (radius + ballCollection.at(i).radius);
otherNewV.y = 0.0f;
现在,如果我在计算后让F中的F回到零,那么球会以恒定的速度移动,现在这很好。我现在的问题是,有时候碰撞会起作用,有时候球会飞走,有时击中第一个球很好,但如果第二个球击中另一个球则再次出现错误。我认为这是因为他们不断碰撞并计算他们的速度错误,但我无法弄清楚如何设置一个布尔只能碰撞一次,任何人都有任何想法?
修改的 我现在设法正确设置了布尔值。
答案 0 :(得分:0)
碰撞时,应施加到另一个球的力是速度矢量的大小。因此,如果你传递sqrt(v.x*v.x+v.y*v.y+v.z*v.z)
作为碰撞的初始力量,并在施加了你所说的力之后将F设置为零,那么你应该得到你想要的结果。