Вопрос расчета скорости в физике пула

Привет, я делаю 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 к нулю в классе, шар будет двигаться с постоянной скоростью, что пока хорошо. Моя проблема сейчас заключается в том, что иногда столкновение срабатывает, иногда шары разлетаются, иногда удар по первому шару — это хорошо, но если второй мяч ударяет по другому, то это снова неправильно. Я думаю, что это происходит потому, что они продолжают сталкиваться и неправильно вычисляют свою скорость, но я не могу понять, как настроить логическое значение для столкновения только один раз, у кого-нибудь есть идеи?

РЕДАКТИРОВАТЬ
Теперь мне удалось правильно настроить логическое значение.

1

Решение

При столкновении сила, которая должна быть применена к другому шару, является величиной вектора скорости. Так что, если вы пройдете в sqrt(v.x*v.x+v.y*v.y+v.z*v.z) в качестве начальной силы столкновения и установки F на ноль после применения силы, как вы заявили, вы должны получить желаемые результаты.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]