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