C++ 球体边界体碰撞OpenGL

C++ 球体边界体碰撞OpenGL,c++,collision-detection,C++,Collision Detection,我试图做一个台球台模拟,在检查球的半径和距离后,球会相互碰撞 我已经完成了大部分的设置和工作,但是我很困惑如何同时检查每个球。我现在有两个for循环,为每帧设置两个球,并检查它们的距离是否小于两个半径之和。所以它只会随机击中一些球,使它们碰撞 谁能帮我让所有的球在应该碰撞的时候碰撞而不是随机碰撞 以下是我的main.cpp: #pragma once // Math constants #define _USE_MATH_DEFINES #include <cmath> #inc

我试图做一个台球台模拟,在检查球的半径和距离后,球会相互碰撞

我已经完成了大部分的设置和工作,但是我很困惑如何同时检查每个球。我现在有两个for循环,为每帧设置两个球,并检查它们的距离是否小于两个半径之和。所以它只会随机击中一些球,使它们碰撞

谁能帮我让所有的球在应该碰撞的时候碰撞而不是随机碰撞

以下是我的main.cpp:

#pragma once
// Math constants
#define _USE_MATH_DEFINES
#include <cmath>  
#include <random>
#include<iterator>

// Std. Includes
#include <string>
#include <time.h>
#include <iostream>
#include <cstdio>
#include <ctime>
#include <chrono>
#include <thread>
using namespace std;

// GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/matrix_operation.hpp>
#include "glm/ext.hpp"

// Other Libs
#include "SOIL2/SOIL2.h"

// project includes
#include "Application.h"
#include "Shader.h"
#include "Mesh.h"
#include "Body.h"
#include "Particle.h"
#include "Force.h"
#include "RigidBody.h"
#include "Sphere.h"


// time
GLfloat deltaTime = 0.0f;
GLfloat lastFrame = 0.0f;

// main function
int main()
{
// create application
Application app = Application::Application();
app.initRender();
Application::camera.setCameraPosition(glm::vec3(0.0f, 10.0f, 50.0f));

// create ground plane
Mesh plane = Mesh::Mesh(Mesh::QUAD);
// scale it up x5
plane.scale(glm::vec3(40.0f, 5.0f, 40.0f));
Shader lambert = Shader("C:/Users/Euan/Desktop/project2/resources/shaders/physics.vert", 
"C:/Users/Euan/Desktop/project2/resources/shaders/physics.frag");
plane.setShader(lambert);

//Create Sphere
Mesh sphere = Mesh::Mesh("resources/models/sphere.obj");

//Gravity
Gravity g = Gravity(glm::vec3(0.0f, -9.8f, 0.0f));

//Spheres vector
std::vector<Sphere>spheres;

//Amount of balls
int balls = 100;

//Create 100 balls and set them with random velocities in x and y
for (int i = 0; i < balls; i++)
{
    Sphere s;
    int pos_z = (rand() % 80) - 40;
    int pos_x = (rand() % 80) - 40;
    int vel_z = (rand() % 20) - 10;
    int vel_x = (rand() % 20) - 10;
    s.setMesh(sphere);
    s.getMesh().setShader(Shader("resources/physics.vert", "resources/physics.frag"));
    s.translate(glm::vec3(pos_x, 0.5f, pos_z));
    s.scale(glm::vec3(0.5f, 0.5f, 0.5f));
    //s.rotate((GLfloat)M_PI_2, glm::vec3(1.0f, 0.0f, 0.0f));
    s.setVel(glm::vec3(vel_x, 0.0f, vel_z));
    s.setCor(1.0f);
    s.addForce(&g);
    spheres.push_back(s);
}

//Table walls
glm::vec3 table(40.0f, 0.5f, 40.0f);

// time
GLfloat t = 0.0;
GLfloat dt = 1.0f / 60.0f;
GLfloat currentTime = (GLfloat)glfwGetTime();
GLfloat accumulator = 0.0;

float m = 1.0f;

// Game loop
while (!glfwWindowShouldClose(app.getWindow()))
{
    // Set frame time
    GLfloat newTime = (GLfloat)glfwGetTime();
    GLfloat frameTime = newTime - currentTime;
    currentTime = newTime;
    accumulator += frameTime;


    /*
    **  INTERACTION
    */
    // Manage interaction
    app.doMovement(dt);

    while (accumulator >= dt)
    {

        /*
        **  SIMULATION
        */

        //Loop through all balls and send them in their directions
        for (unsigned int i = 0; i < spheres.size(); i++)
        {
            spheres[i].setAcc(spheres[i].applyForces(spheres[i].getPos(), spheres[i].getVel(), t, 
dt));
            spheres[i].setAngVel(spheres[i].getAngVel() + dt * spheres[i].getAngAcc());
            glm::mat3 angVelSkew = glm::matrixCross3(spheres[i].getAngVel());
            glm::mat3 R = glm::mat3(spheres[i].getRotate());
            R += dt * angVelSkew * R;
            R = glm::orthonormalize(R);
            spheres[i].setRotate(glm::mat4(R));
            spheres[i].setVel(spheres[i].getVel() + spheres[i].getAcc() * dt);
            spheres[i].translate(dt * spheres[i].getVel());


            //Keep ball above table
            if (spheres[i].getPos().y < table.y)
            {
                spheres[i].setPos(1, table.y);
                spheres[i].setVel(glm::vec3(spheres[i].getVel().x * spheres[i].getCor(), 
spheres[i].getVel().y * -spheres[i].getCor(), spheres[i].getVel().z * spheres[i].getCor()));
            }
            if (spheres[i].getPos().y > table.y)
            {
                spheres[i].setPos(1, table.y);
            }

            //Colliding with x sides of table
            if (spheres[i].getPos().x > table.x - .5f)
            {

                spheres[i].setPos(0, table.x - .5f);
                spheres[i].setVel(glm::vec3(spheres[i].getVel().x * -spheres[i].getCor() / 1.5f, 
spheres[i].getVel().y * spheres[i].getCor() / 1.5f, spheres[i].getVel().z * spheres[i].getCor() / 
1.5f));
            }
            if (spheres[i].getPos().x < -table.x + .5f)
            {
                spheres[i].setPos(0, -table.x + .5f);
                spheres[i].setVel(glm::vec3(spheres[i].getVel().x * -spheres[i].getCor() / 1.5f, 
spheres[i].getVel().y * spheres[i].getCor() / 1.5f, spheres[i].getVel().z * spheres[i].getCor() / 
1.5f));

            }

            //Colliding with y sides of table
            if (spheres[i].getPos().z < -table.z + .5f)
            {
                spheres[i].setPos(2, -table.z + .5f);
                spheres[i].setVel(glm::vec3((spheres[i].getVel().x * spheres[i].getCor() / 1.5f, 
spheres[i].getVel().y * spheres[i].getCor() / 1.5f, spheres[i].getVel().z * -spheres[i].getCor() / 
1.5f)));
            }
            if (spheres[i].getPos().z > table.z - .5f)
            {
                spheres[i].setPos(2, table.z - .5f);
                spheres[i].setVel(glm::vec3((spheres[i].getVel().x * spheres[i].getCor() / 1.5f, 
spheres[i].getVel().y * spheres[i].getCor() / 1.5f, spheres[i].getVel().z * -spheres[i].getCor() / 
1.5f)));
            }

            //Reduce speed of balls over time
            float x = spheres[i].getVel().x;
            float y = spheres[i].getVel().y;
            float z = spheres[i].getVel().z;
            glm::vec3 vec = glm::vec3(x / 1.005f, y, z / 1.005f);
            spheres[i].setVel(vec);

        }


        //Check for collisions with radius of two balls
        for (size_t i = 0; i < spheres.size(); i++)
        {
            for (size_t j = i + 1; j < spheres.size(); j++)
            {
                float d = glm::distance(spheres[i].getPos(), spheres[j].getPos());
        
                float radiusI = spheres[i].getScale()[0][0];
                float radiusJ = spheres[j].getScale()[0][0];
        
                if (d <= radiusI + radiusJ)
                {
                    spheres[i].setVel(-spheres[j].getVel());
                    spheres[j].setVel(-spheres[i].getVel());
                }
            }
        }           

        accumulator -= dt;
        t += dt;

    }

    /*
    **  RENDER
    */
    // clear buffer
    app.clear();

    // draw groud plane
    app.draw(plane);

    for each (Sphere s in spheres)
    {
        app.draw(s.getMesh());
    }

    app.display();
}

app.terminate();

return EXIT_SUCCESS;
}
#pragma一次
//数学常数
#定义使用数学定义
#包括
#包括
#包括
//标准包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
//GLM
#包括
#包括
#包括
#包括
#包括“glm/ext.hpp”
//其他LIB
#包括“SOIL2/SOIL2.h”
//项目包括
#包括“Application.h”
#包括“Shader.h”
#包括“Mesh.h”
#包括“Body.h”
#包括“Particle.h”
#包括“Force.h”
#包括“RigidBody.h”
#包括“Sphere.h”
//时间
GLfloat deltaTime=0.0f;
GLfloat lastFrame=0.0f;
//主要功能
int main()
{
//创建应用程序
应用程序app=Application::Application();
app.initRender();
应用:camera.setCameraPosition(glm::vec3(0.0f、10.0f、50.0f));
//创建地平面
网格平面=网格::网格(网格::四边形);
//放大到x5
平面比例(glm::vec3(40.0f,5.0f,40.0f));
Shader lambert=Shader(“C:/Users/Euan/Desktop/project2/resources/shaders/physics.vert”,
“C:/Users/Euan/Desktop/project2/resources/shaders/physics.frag”);
平面切割器(兰伯特);
//创建球体
Mesh-sphere=Mesh::Mesh(“资源/模型/sphere.obj”);
//重力
重力g=重力(glm::vec3(0.0f,-9.8f,0.0f));
//球面矢量
向量球;
//球的数量
int=100;
//创建100个球,并在x和y方向以随机速度设置它们
对于(int i=0;i=dt)
{
/*
**模拟
*/
//在所有球上打圈,并将它们送入各自的方向
for(无符号整数i=0;itable.y)
{
球体[i].setPos(1,表.y);
}
//与桌子的x边碰撞
if(球体[i].getPos().x>table.x-.5f)
{
球体[i].setPos(0,表x-.5f);
球体[i].setVel(glm::vec3(球体[i].getVel().x*-spheres[i].getCor()/1.5f,
球体[i].getVel().y*球体[i].getCor()/1.5f,球体[i].getVel().z*球体[i].getCor()/
1.5f);
}
if(球体[i].getPos().x<-table.x+.5f)
{
球体[i].setPos(0,-table.x+.5f);
球体[i].setVel(glm::vec3(球体[i].getVel().x*-spheres[i].getCor()/1.5f,
球体[i].getVel().y*球体[i].getCor()/1.5f,球体[i].getVel().z*球体[i].getCor()/
1.5f);
}
//与桌子的y边碰撞
if(球体[i].getPos().z<-table.z+.5f)
{
球体[i].setPos(2,-表z+.5f);
球体[i].setVel(glm::vec3((球体[i].getVel().x*spheres[i].getCor()/1.5f,
球体[i].getVel().y*球体[i].getCor()/1.5f,球体[i].getVel().z*-spheres[i].getCor()/
1.5f),;
}
if(球体[i].getPos().z>table.z-.5f)
{
球体[i].setPos(2,表z-.5f);
球体[i].setVel(glm::vec3((球体[i].getVel().x*spheres[i].getCor()/1.5f,
球体[i].getVel().y*球体[i].getCor()/1.5f,球体[i].getVel().z*-spheres[i].getCor()/
1.5f),;
}
//随着时间的推移降低球的速度
float x=球体[i].getVel().x;
float y=spheres[i].getVel().y;
float z=spheres[i].getVel().z;
//Check for collisions with radius of two balls
    for (size_t i = 0; i < spheres.size(); i++)
    {
        for (size_t j = i + 1; j < spheres.size(); j++)
        {
            float d = glm::distance(spheres[i].getPos(), spheres[j].getPos());

            float radiusI = spheres[i].getScale()[0][0];
            float radiusJ = spheres[j].getScale()[0][0];

            if (d <= radiusI + radiusJ)
            {
                spheres[i].setVel(-spheres[j].getVel());
                spheres[j].setVel(-spheres[i].getVel());
            }
        }
    }