Issue With Rockets Not Colliding With Other Objects #451
|
Hello all, I have made much progress with my game that I have started adding rockets to it, however, I am having an issue regarding firing the rockets within the physics world. Whenever I fire a rocket in the original position, everything operates fine and I have no issues, however, after the object is moved simply just to the right or left a little, the rigid body doesn't update with the graphics. The odd thing is if I fire a rocket at the prior position where the rocket last was, the object moves. Thus telling me that the rigid body isn't updating with the graphics even though it does when I simply push objects. I'm kind of at a loss so if anyone can give any pointers or has the time to help it is greatly appreciated. Attached is a recording showing off the issue I'm having: Screen Recording 2026-08-03 145156.zip In addition, here are the main files in which physics and graphics are processed where I am experiencing the issues. "logic_for_game.cpp" #include "logic_for_game.h"
std::vector<PHYSICS_OBJ> rockets;
class CustomOverlapCallback : public reactphysics3d::OverlapCallback
{
public:
bool overlap_occured;
// body that represents the one we want to look for
reactphysics3d::Body* rigid_body_we_want_to_test;
CustomOverlapCallback(PHYSICS_OBJ player_arg) : rigid_body_we_want_to_test(player_arg.rigid_body), overlap_occured(false)
{
}
CustomOverlapCallback(reactphysics3d::RigidBody* player_arg) : rigid_body_we_want_to_test(player_arg), overlap_occured(false)
{
}
// Override the original function that was stored in the OverlapCallback Class
virtual void onOverlap(CallbackData& callbackData) override
{
// set overlap occurred to false to prevent it from carrying over a false true
overlap_occured = false;
// for loop that iterates through all overlapping pairs within callback data/physics world
for (unsigned int overlapping_pairs_iterator = 0; overlapping_pairs_iterator < callbackData.getNbOverlappingPairs(); overlapping_pairs_iterator++)
{
// grab each individual overlapping body with callback data and overlapping pair index
reactphysics3d::OverlapCallback::OverlapPair overlapping_pair = callbackData.getOverlappingPair(overlapping_pairs_iterator);
// grab the first body within the overlapping pair
reactphysics3d::Body* first_body = overlapping_pair.getBody1();
// grab the second body within the overlapping pair
reactphysics3d::Body* second_body = overlapping_pair.getBody2();
// if first body is the desired body, then the non-desired body is the second body, if not, then the first body is the non-desired body
reactphysics3d::Body* non_desired_body = (first_body == rigid_body_we_want_to_test) ? second_body : first_body;
// if the non-desired body is not equal to the body we want to test, then a overlap has occured, meaning both bodies are not the desired body
if (non_desired_body != rigid_body_we_want_to_test)
{
// overlap has occured
overlap_occured = true;
// exit out of the loop early
return;
}
}
}
};
int key_pressed_counter = 0;
int time_key_can_be_held = 100;
const reactphysics3d::decimal ts = 1.0f / 60.0f;
reactphysics3d::PhysicsCommon physCom;
reactphysics3d::PhysicsWorld* physWorld = physCom.createPhysicsWorld();
//float amount_of_fov = 60.0f;
float amount_of_fov = 80.0f;
glm::vec3 model_position(-1.0f, 5.0f, 0.0f);
glm::vec3 cube_position_1(-1.0f, 1.0f, 0.0f);
glm::vec3 cube_position_2(0.0f, 1.0f, 0.0f);
glm::vec3 floor_position(0.0f, 0.0f, 0.0f);
int orthographic_matrix = 30;
glm::vec3 world_position_of_camera(0.0f, 0.0f, 15.0f);
glm::vec3 directional_lighting_facing_direction(-2.0f, 4.0f, -1.0f);
glm::vec3 shadow_map_facing_position(20.0f, 40.0f, 20.0f);
glm::vec3 rocket_vector;
float model_scale_size = 0.5f;
float near_plane_shadow = 0.1f, far_plane_shadow = 150.0f;
float ambient_color_values[3] =
{
0.3f, 0.3f, 0.3f
};
float diffuse_color_values[3]
{
0.6f, 0.6f, 0.6f
};
float specular_color_values[3]
{
1.0f, 1.0f, 1.0f
};
// CREATE RIDGID BODIES FOR EACH OBJECT WITHIN OUR PHYSICS WORLD
reactphysics3d::Vector3 HalfSpace(1.5, 1.5, 1.5);
reactphysics3d::Vector3 FloorHalfSpace(50.0, 0.0, 50.0);
PHYSICS_OBJ cube1(physCom, physWorld, "BOX", HalfSpace, reactphysics3d::Vector3(cube_position_1.x, cube_position_1.y, cube_position_1.z));
PHYSICS_OBJ cube2(physCom, physWorld, "BOX", HalfSpace, reactphysics3d::Vector3(cube_position_2.x, cube_position_2.y, cube_position_2.z));
//PHYSICS_OBJ player(physCom, physWorld, "CAPSULE", 0.6, 0.8, reactphysics3d::Vector3(0.0, 0.0, 0.0));
PHYSICS_OBJ player(physCom, physWorld, "CAPSULE", 0.2, 0.8, reactphysics3d::Vector3(0.0, 0.0, 0.0));
const int num_of_plane_vertices = 6;
const int num_of_plane_triangles = 2;
float plane_vertices[3 * num_of_plane_vertices] =
{
50.0f, -0.5f, 50.0f,
-50.0f, -0.5f, 50.0f,
-50.0f, -0.5f, -50.0f,
50.0f, -0.5f, 50.0f,
-50.0f, -0.5f, -50.0f,
50.0f, -0.5f, -50.0f
};
unsigned int plane_indices[6] = { 0, 1, 2, 3, 4, 5, };
reactphysics3d::TriangleVertexArray plane_vertex_array = reactphysics3d::TriangleVertexArray(num_of_plane_vertices, plane_vertices,
3 * sizeof(float), 2, plane_indices, 3 * sizeof( unsigned int), reactphysics3d::TriangleVertexArray::VertexDataType::VERTEX_FLOAT_TYPE,
reactphysics3d::TriangleVertexArray::IndexDataType::INDEX_INTEGER_TYPE);
PHYSICS_OBJ floor_test(physCom, physWorld, "CONCAVE_MESH", plane_vertex_array, reactphysics3d::Vector3(floor_position.x, floor_position.y, floor_position.z));
RENDER_OBJECT_OBJ *render_obj;
RENDER_OBJECT_OBJ *render_obj_plane;
RENDER_OBJECT_OBJ *skybox_obj;
RENDER_OBJECT_OBJ *model_obj;
RENDER_OBJECT_OBJ *model_obj_2;
SHADOW_MAP_OBJ *shadow_map;
CAM_OBJ *camera_obj;
GAME_OBJ::GAME_OBJ(unsigned int width_of_window, unsigned int height_of_window)
: Width_Of_Screen(width_of_window), Height_Of_Screen(height_of_window)
{
// where the last yaw position that was grabbed from the callback function is stored
float last_mouse_yaw_position = Width_Of_Screen / 2.0f;
// where the last pitch position that was grabbed from the callback function is stored
float last_mouse_pitch_position = Height_Of_Screen / 2.0f;
}
GAME_OBJ::~GAME_OBJ()
{
delete render_obj;
delete render_obj_plane;
delete skybox_obj;
delete model_obj;
delete model_obj_2;
delete shadow_map;
delete camera_obj;
}
void GAME_OBJ::Initalize_Game()
{
cube1.rigid_body->setType(reactphysics3d::BodyType::DYNAMIC);
cube2.rigid_body->setType(reactphysics3d::BodyType::DYNAMIC);
player.rigid_body->setType(reactphysics3d::BodyType::DYNAMIC);
floor_test.rigid_body->setType(reactphysics3d::BodyType::STATIC);
player.rigid_body->setLinearDamping(0.5);
player.rigid_body->setAngularDamping(0.5);
// THIS AFFECTS A LOT OF THE PHYSICS IN THE WORLD
//physWorld->setGravity(reactphysics3d::Vector3(0.0, -0.07, 0.0));
physWorld->setGravity(reactphysics3d::Vector3(0.0, -0.8, 0.0));
//RESOURCE_MANAGER::Shader_Load("shaders/3D_TEST.vert", "shaders/3D_TEST.frag", nullptr, "test");
//RESOURCE_MANAGER::Shader_Load("shaders/BLINN_PHONG_LIGHTING.vert", "shaders/BLINN_PHONG_LIGHTING.frag", nullptr, "test");
RESOURCE_MANAGER::Shader_Load("shaders/BLINN_PHONG_LIGHTING_W_SHADOW_MAPPING.vert", "shaders/BLINN_PHONG_LIGHTING_W_SHADOW_MAPPING.frag", nullptr, "test");
RESOURCE_MANAGER::Shader_Load("shaders/skybox.vert", "shaders/skybox.frag", nullptr, "skybox_test");
//RESOURCE_MANAGER::Shader_Load("shaders/model_test.vert", "shaders/model_test.frag", nullptr, "model_test");
RESOURCE_MANAGER::Shader_Load("shaders/BLINN_PHONG_LIGHTING_W_SHADOW_MAPPING.vert", "shaders/BLINN_PHONG_LIGHTING_W_SHADOW_MAPPING.frag", nullptr, "model_test");
RESOURCE_MANAGER::Shader_Load("shaders/DEPTH_SHADER.vert", "shaders/DEPTH_SHADER.frag", nullptr, "depth_map_shader");
RESOURCE_MANAGER::Texture_Load("assets/PTP-Pattern_03-128x128.png", false, "texture");
RESOURCE_MANAGER::Texture_Load("assets/PTP-Tile_05-128x128.png", false, "texture_2");
//RESOURCE_MANAGER::Texture_Load("assets/arcade_carpet_2_512.png", false, "texture_2");
RESOURCE_MANAGER::Skybox_Textures_Load("assets/Classic", false, "skybox");
RESOURCE_MANAGER::Skybox_Textures_Load("assets/Empty_Space", false, "skybox_2");
render_obj = new RENDER_OBJECT_OBJ(RESOURCE_MANAGER::Shader_Get("model_test"), CUBE);
render_obj_plane = new RENDER_OBJECT_OBJ(RESOURCE_MANAGER::Shader_Get("model_test"), PLANE);
skybox_obj = new RENDER_OBJECT_OBJ(RESOURCE_MANAGER::Shader_Get("skybox_test"), SKYBOX);
//model_obj = new RENDER_OBJECT_OBJ(RESOURCE_MANAGER::Shader_Get("model_test"), MODEL, "assets/Models/Counter-Terrorists_GIGN/COUNTER-TERRORIST_GIGN.obj", "quad_damage", false);
model_obj = new RENDER_OBJECT_OBJ(RESOURCE_MANAGER::Shader_Get("model_test"), MODEL, "assets/Models/Dust2/Dust2.obj", "quad_damage", false);
model_obj_2 = new RENDER_OBJECT_OBJ(RESOURCE_MANAGER::Shader_Get("model_test"), MODEL, "assets/Models/B.D. Joe/B.D. Joe.obj", "quad_damage", false);
shadow_map = new SHADOW_MAP_OBJ(1024, 1024);
camera_obj = new CAM_OBJ(glm::vec3(1.0f, 5.0f, 0.0f));
}
void GAME_OBJ::Render_Game()
{
ImGui::Text("DEBUG");
ImGui::Text("World View Settings");
ImGui::SliderFloat("FOV", &amount_of_fov, 60.0f, 120.0f);
ImGui::SliderFloat("World X Position", &world_position_of_camera.x, -100.0f, 100.0f);
ImGui::SliderFloat("World Y Position", &world_position_of_camera.y, -100.0f, 100.0f);
ImGui::SliderFloat("World Z Position", &world_position_of_camera.z, -100.0f, 100.0f);
ImGui::Text("Lighting Settings");
ImGui::SliderFloat("Light X Direction", &directional_lighting_facing_direction.x, -50.0f, 0.0f);
ImGui::SliderFloat("Light Y Direction", &directional_lighting_facing_direction.y, -50.0f, 50.0f);
ImGui::SliderFloat("Light Z Direction", &directional_lighting_facing_direction.z, -50.0f, 0.0f);
// To store color picker values, you need a 3-value float array
//ImGui::SliderFloat3("test", a, 0.0f, 1.0f);
ImGui::SetNextItemWidth(200.0f);
ImGui::ColorPicker3("Ambient Color", ambient_color_values);
ImGui::SetNextItemWidth(200.0f);
ImGui::ColorPicker3("Diffuse Color", diffuse_color_values);
ImGui::SetNextItemWidth(200.0f);
ImGui::ColorPicker3("Specular Color", specular_color_values);
ImGui::SetNextItemWidth(200.0f);
ImGui::SliderInt("Ortographic Matrix Size", &orthographic_matrix, 10, 100);
ImGui::SetNextItemWidth(200.0f);
ImGui::SliderFloat("NEAR_SHADOW_PLANE", &near_plane_shadow, -100.0f, 100.0f);
ImGui::SliderFloat("FAR_SHADOW_PLANE", &far_plane_shadow, -100.0f, 100.0f);
ImGui::SetNextItemWidth(200.0f);
//ImGui::SliderFloat("Model X Direction", &model_position.x, -50.0f, 50.0f);
//ImGui::SliderFloat("Model Y Direction", &model_position.y, -50.0f, 50.0f);
//ImGui::SliderFloat("Model Z Direction", &model_position.z, -50.0f, 50.0f);
//ImGui::SetNextItemWidth(200.0f);
//ImGui::SliderFloat("Model Scale Size", &model_scale_size, -100.0f, 100.0f);
//ImGui::SetNextItemWidth(200.0f);
//ImGui::SliderFloat("CUBE 1 X Direction", &cube_position_1.x, -50.0f, 50.0f);
//ImGui::SliderFloat("CUBE 1 Y Direction", &cube_position_1.y, -50.0f, 50.0f);
//ImGui::SliderFloat("CUBE 1 Z Direction", &cube_position_1.z, -50.0f, 50.0f);
ImGui::SetNextItemWidth(200.0f);
ImGui::SliderFloat("CUBE 2 X Direction", &cube_position_2.x, -50.0f, 50.0f);
ImGui::SliderFloat("CUBE 2 Y Direction", &cube_position_2.y, -50.0f, 50.0f);
ImGui::SliderFloat("CUBE 2 Z Direction", &cube_position_2.z, -50.0f, 50.0f);
ImGui::SetNextItemWidth(200.0f);
// draw cross hair using im gui library
auto cross = ImGui::GetBackgroundDrawList();
cross->AddCircle(ImVec2((this->Width_Of_Screen / 2 ) - 5, (this->Height_Of_Screen / 2)), 25, IM_COL32(0, 255, 0, 255), 100.0f, 1.0f);
glm::mat4 view_matrix = camera_obj->Obtain_View_Matrix();
//glm::mat4 orthographic_light_perspective_matrix = glm::ortho(-(static_cast<float>(orthographic_matrix)), (static_cast<float>(orthographic_matrix)), -(static_cast<float>(orthographic_matrix)), (static_cast<float>(orthographic_matrix)), near_plane_shadow, far_plane_shadow);
glm::mat4 orthographic_light_perspective_matrix = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, 0.1f, 150.0f);
glm::mat4 light_view_matrix = glm::lookAt(directional_lighting_facing_direction * -1.0f, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 perspective_matrix = glm::perspective(glm::radians(amount_of_fov), static_cast<float>(this->Width_Of_Screen) / static_cast<float>(this->Height_Of_Screen), 0.1f, 100.0f);
glm::mat4 light_matrix_for_shadow_mapping = orthographic_light_perspective_matrix * light_view_matrix;
light_matrix_for_shadow_mapping = orthographic_light_perspective_matrix * light_view_matrix;
// transforming this 4x4 matrix to a 3x3 with no values in the 4th column to prevent w coordinate from making translations
glm::mat4 skybox_view_matrix = glm::mat4(glm::mat3(view_matrix));
RESOURCE_MANAGER::Shader_Get("depth_map_shader").Activate();
render_obj->object_shader_obj = RESOURCE_MANAGER::Shader_Get("depth_map_shader");
render_obj_plane->object_shader_obj = RESOURCE_MANAGER::Shader_Get("depth_map_shader");
//model_obj->object_shader_obj = RESOURCE_MANAGER::Shader_Get("depth_map_shader");
//model_obj_2->object_shader_obj = RESOURCE_MANAGER::Shader_Get("depth_map_shader");
RESOURCE_MANAGER::Shader_Get("depth_map_shader").Activate().uniform_matrix_4("light_matrix_for_shadow_mapping", light_matrix_for_shadow_mapping);
// set viewport to shadow map's texture dimensions
glViewport(0, 0, shadow_map->width_of_texture, shadow_map->height_of_texture);
// bind depth framebuffer object
glBindFramebuffer(GL_FRAMEBUFFER, shadow_map->depth_map_frame_buffer_object);
// clear depth buffer
glClear(GL_DEPTH_BUFFER_BIT);
render_obj_plane->Render_and_Draw_Object(RESOURCE_MANAGER::Texture_Get("texture_2"), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f));
render_obj->Render_and_Draw_Object(RESOURCE_MANAGER::Texture_Get("texture"), glm::vec3(cube_position_1), glm::vec3(0.5), (100 * glfwGetTime()));
render_obj->Render_and_Draw_Object(RESOURCE_MANAGER::Texture_Get("texture"), glm::vec3(cube_position_2), glm::vec3(0.5f), (100 * glfwGetTime()));
//render_obj->Render_and_Draw_Object(RESOURCE_MANAGER::Texture_Get("texture"), glm::vec3(cube_position_2), glm::vec3(0.5f), (100 * glfwGetTime()));
//model_obj_2->Render_and_Draw_Object(glm::vec3(model_position), glm::vec3(model_scale_size), (100 * glfwGetTime()));
//model_obj->Render_and_Draw_Object(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f), -90.0f, glm::vec3(1.0f, 0.0f, 0.0f));
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, this->Width_Of_Screen, this->Height_Of_Screen);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
RESOURCE_MANAGER::Shader_Get("model_test").Activate();
render_obj->object_shader_obj = RESOURCE_MANAGER::Shader_Get("model_test");
render_obj_plane->object_shader_obj = RESOURCE_MANAGER::Shader_Get("model_test");
model_obj->object_shader_obj = RESOURCE_MANAGER::Shader_Get("model_test");
model_obj_2->object_shader_obj = RESOURCE_MANAGER::Shader_Get("model_test");
// SEND MODEL MATRICES HERE
// you must specify the index of the color picker array individually to send the values via a uniform
// remember that within the uniform vector member functions within a SHADER_OBJ they are overloaded to either take a glm vector or individual x, y, or z float values
RESOURCE_MANAGER::Shader_Get("model_test").uniform_vector_3("directional_lighting_obj.light_direction", directional_lighting_facing_direction);
glActiveTexture(GL_TEXTURE18);
glBindTexture(GL_TEXTURE_2D, shadow_map->texture_ID);
RESOURCE_MANAGER::Shader_Get("model_test").uniform_integer("shadowDepthMapTexture", 18);
RESOURCE_MANAGER::Shader_Get("model_test").uniform_matrix_4("light_matrix_for_shadow_mapping", light_matrix_for_shadow_mapping);
RESOURCE_MANAGER::Shader_Get("model_test").uniform_matrix_4("view_matrix", view_matrix);
RESOURCE_MANAGER::Shader_Get("model_test").uniform_matrix_4("perspective_matrix", perspective_matrix);
RESOURCE_MANAGER::Shader_Get("model_test").uniform_vector_3("camera_world_position", world_position_of_camera);
RESOURCE_MANAGER::Shader_Get("model_test").uniform_vector_3("directional_lighting_obj.ambient_color", ambient_color_values[0], ambient_color_values[1], ambient_color_values[2]);
RESOURCE_MANAGER::Shader_Get("model_test").uniform_vector_3("directional_lighting_obj.diffuse_color", diffuse_color_values[0], diffuse_color_values[1], diffuse_color_values[2]);
RESOURCE_MANAGER::Shader_Get("model_test").uniform_vector_3("directional_lighting_obj.specular_color", specular_color_values[0], specular_color_values[1], specular_color_values[2]);
// enable depth function so that it passes vertices that are equal to depth buffer's content
glDepthFunc(GL_LEQUAL);
skybox_obj->Render_and_Draw_Object(RESOURCE_MANAGER::Skybox_Textures_Get("skybox_2"));
// set depth func back to original state which is GL_LESS
glDepthFunc(GL_LESS);
// PUT SKYBOX MATRICES HERE
RESOURCE_MANAGER::Shader_Get("skybox_test").uniform_matrix_4("skybox_view_matrix", skybox_view_matrix);
RESOURCE_MANAGER::Shader_Get("skybox_test").uniform_matrix_4("perspective_matrix", perspective_matrix);
//model_obj_2->Render_and_Draw_Object(glm::vec3(model_position), glm::vec3(model_scale_size), (100 * glfwGetTime()));
render_obj_plane->Render_and_Draw_Object(RESOURCE_MANAGER::Texture_Get("texture_2"), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f));
render_obj->Render_and_Draw_Object(RESOURCE_MANAGER::Texture_Get("texture"), glm::vec3(cube_position_1), glm::vec3(0.5f), (100 * glfwGetTime()));
render_obj->Render_and_Draw_Object(RESOURCE_MANAGER::Texture_Get("texture"), glm::vec3(cube_position_2), glm::vec3(0.5f), (100 * glfwGetTime()));
//render_obj->Render_and_Draw_Object(RESOURCE_MANAGER::Texture_Get("texture"), glm::vec3(rocket_vector += camera_obj->obj_cam_front_view), glm::vec3(0.5f));
render_obj->Render_and_Draw_Object(RESOURCE_MANAGER::Texture_Get("texture"), glm::vec3(rocket_vector), glm::vec3(0.5f));
//model_obj_2->Render_and_Draw_Object(glm::vec3(model_position), glm::vec3(model_scale_size), (100 * glfwGetTime()));
//model_obj->Render_and_Draw_Object(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f), -90.0f, glm::vec3(1.0f, 0.0f, 0.0f));
//model_obj->Render_and_Draw_Object(glm::vec3(-1.0f, 0.0f, -0.5f), glm::vec3(1.0f), (100 * glfwGetTime()));
//model_obj->Render_and_Draw_Object(glm::vec3(2.0f, 0.0f, 1.0f), glm::vec3(1.0f), (100 * glfwGetTime()));
//model_obj->Render_and_Draw_Object(glm::vec3(-2.0f, 0.0f, -1.0f), glm::vec3(1.0f), (100 * glfwGetTime()));
}
void GAME_OBJ::Process_User_Input(float delta_time)
{
if (this->Key_Pressed_Buffer[GLFW_KEY_W])
{
if (camera_obj->obj_pitch == -89.0f || camera_obj->obj_pitch == -88.0f)
{
camera_obj->obj_cam_pos += camera_obj->obj_cam_front_view * (camera_obj->obj_cam_speed + 1);
const reactphysics3d::Transform& transf = player.rigid_body->getTransform();
const reactphysics3d::Vector3 posit = transf.getPosition();
reactphysics3d::Vector3 temp_vec(camera_obj->obj_cam_pos.x, posit.y, camera_obj->obj_cam_pos.z);
reactphysics3d::Quaternion temp_quart = reactphysics3d::Quaternion::identity();
reactphysics3d::Transform temp_trans(temp_vec, temp_quart);
player.rigid_body->setTransform(temp_trans);
}
camera_obj->obj_cam_pos += camera_obj->obj_cam_front_view * camera_obj->obj_cam_speed;
const reactphysics3d::Transform& transf = player.rigid_body->getTransform();
const reactphysics3d::Vector3 posit = transf.getPosition();
reactphysics3d::Vector3 temp_vec(camera_obj->obj_cam_pos.x, posit.y, camera_obj->obj_cam_pos.z);
reactphysics3d::Quaternion temp_quart = reactphysics3d::Quaternion::identity();
reactphysics3d::Transform temp_trans(temp_vec, temp_quart);
player.rigid_body->setTransform(temp_trans);
}
if (this->Key_Pressed_Buffer[GLFW_KEY_A])
{
camera_obj->obj_cam_pos -= camera_obj->obj_cam_right * camera_obj->obj_cam_speed;
const reactphysics3d::Transform& transf = player.rigid_body->getTransform();
const reactphysics3d::Vector3 posit = transf.getPosition();
reactphysics3d::Vector3 temp_vec(camera_obj->obj_cam_pos.x, posit.y, camera_obj->obj_cam_pos.z);
reactphysics3d::Quaternion temp_quart = reactphysics3d::Quaternion::identity();
reactphysics3d::Transform temp_trans(temp_vec, temp_quart);
player.rigid_body->setTransform(temp_trans);
}
if (this->Key_Pressed_Buffer[GLFW_KEY_S])
{
camera_obj->obj_cam_pos -= camera_obj->obj_cam_front_view * camera_obj->obj_cam_speed;
const reactphysics3d::Transform& transf = player.rigid_body->getTransform();
const reactphysics3d::Vector3 posit = transf.getPosition();
reactphysics3d::Vector3 temp_vec(camera_obj->obj_cam_pos.x, posit.y, camera_obj->obj_cam_pos.z);
reactphysics3d::Quaternion temp_quart = reactphysics3d::Quaternion::identity();
reactphysics3d::Transform temp_trans(temp_vec, temp_quart);
player.rigid_body->setTransform(temp_trans);
if (camera_obj->obj_pitch == -89.0f)
{
camera_obj->obj_cam_pos -= camera_obj->obj_cam_front_view * (camera_obj->obj_cam_speed + 1);
const reactphysics3d::Vector3 posit = transf.getPosition();
const reactphysics3d::Transform& transf = player.rigid_body->getTransform();
reactphysics3d::Vector3 temp_vec(camera_obj->obj_cam_pos.x, posit.y, camera_obj->obj_cam_pos.z);
reactphysics3d::Quaternion temp_quart = reactphysics3d::Quaternion::identity();
reactphysics3d::Transform temp_trans(temp_vec, temp_quart);
player.rigid_body->setTransform(temp_trans);
}
}
if (this->Key_Pressed_Buffer[GLFW_KEY_D])
{
camera_obj->obj_cam_pos += camera_obj->obj_cam_right * camera_obj->obj_cam_speed;
const reactphysics3d::Transform& transf = player.rigid_body->getTransform();
const reactphysics3d::Vector3 posit = transf.getPosition();
reactphysics3d::Vector3 temp_vec(camera_obj->obj_cam_pos.x, posit.y, camera_obj->obj_cam_pos.z);
reactphysics3d::Quaternion temp_quart = reactphysics3d::Quaternion::identity();
reactphysics3d::Transform temp_trans(temp_vec, temp_quart);
player.rigid_body->setTransform(temp_trans);
}
if (this->Key_Pressed_Buffer[GLFW_KEY_SPACE])
{
if (key_pressed_counter < time_key_can_be_held)
{
const reactphysics3d::Transform& transf = player.rigid_body->getTransform();
const reactphysics3d::Vector3 posit = transf.getPosition();
reactphysics3d::Vector3 temp_vec(posit.x, posit.y + 0.07, posit.z);
reactphysics3d::Quaternion temp_quart = reactphysics3d::Quaternion::identity();
reactphysics3d::Transform temp_trans(temp_vec, temp_quart);
player.rigid_body->setTransform(temp_trans);
key_pressed_counter++;
}
}
// ORIGINAL POSITION OF LEFT CLICK
/*
// PROCESS MOUSE BUTTON INPUT
if (this->Mouse_Button_Pressed_Buffer[GLFW_MOUSE_BUTTON_LEFT])
{
//std::cout << camera_obj->obj_cam_pos.x << "," << camera_obj->obj_cam_pos.y << "," << camera_obj->obj_cam_pos.z << std::endl;
//std::cout << camera_obj->obj_cam_pos.x + camera_obj->obj_cam_front_view.x << "," << camera_obj->obj_cam_pos.y + camera_obj->obj_cam_front_view.y << "," << camera_obj->obj_cam_pos.z + camera_obj->obj_cam_front_view.z << std::endl;
// ADD THE CAM POS AND FRONT VIEW POS SO THE ROCKET COMES OUT CORRECTLY
PHYSICS_OBJ rocket(physCom, physWorld, "BOX", reactphysics3d::Vector3(0.2, 0.2, 0.2), reactphysics3d::Vector3(camera_obj->obj_cam_pos.x + (camera_obj->obj_cam_front_view.x * 4), camera_obj->obj_cam_pos.y + (camera_obj->obj_cam_front_view.y * 4), camera_obj->obj_cam_pos.z + (camera_obj->obj_cam_front_view.z * 4)));
//PHYSICS_OBJ rocket(physCom, physWorld, "SHPERE", 2.0, reactphysics3d::Vector3(camera_obj->obj_cam_pos.x + (camera_obj->obj_cam_front_view.x * 10), camera_obj->obj_cam_pos.y + (camera_obj->obj_cam_front_view.y * 10), camera_obj->obj_cam_pos.z + (camera_obj->obj_cam_front_view.z * 10)));
//rocket.rigid_body->setType(reactphysics3d::BodyType::DYNAMIC);
//CustomOverlapCallback rocket_callback(rocket);
rocket.rigid_body->setMass(0.0);
//physWorld->testOverlap(rocket.rigid_body, rocket_callback);
//rocket.rigid_body->setLinearVelocity(reactphysics3d::Vector3(camera_obj->obj_cam_front_view.x * 80, camera_obj->obj_cam_front_view.y * 80, camera_obj->obj_cam_front_view.z * 80));
rocket.rigid_body->setLinearVelocity(reactphysics3d::Vector3(camera_obj->obj_cam_front_view.x * 10, camera_obj->obj_cam_front_view.y * 10, camera_obj->obj_cam_front_view.z * 10));
//reactphysics3d::Transform trans = rocket.rigid_body->getTransform();
//rocket_vector = glm::vec3(camera_obj->obj_cam_pos.x + (camera_obj->obj_cam_front_view.x * 4), camera_obj->obj_cam_pos.y + (camera_obj->obj_cam_front_view.y * 4), camera_obj->obj_cam_pos.z + (camera_obj->obj_cam_front_view.z * 4));
//trans.setPosition(reactphysics3d::Vector3(rocket_vector.x += camera_obj->obj_cam_front_view.x, rocket_vector.y += camera_obj->obj_cam_front_view.y, rocket_vector.z += camera_obj->obj_cam_front_view.z));
rockets.push_back(rocket);
if (rocket_callback.overlap_occured)
{
//rocket.~PHYSICS_OBJ();
physWorld->destroyRigidBody(rocket.rigid_body);
std::cout << "Rocket Overlap" << std::endl;
}
else
{
std::cout << "No Rocket Overlap" << std::endl;
}
}
*/
CustomOverlapCallback overlap_callback(player);
physWorld->testOverlap(player.rigid_body, overlap_callback);
if (!this->Key_Pressed_Buffer[GLFW_KEY_SPACE] && overlap_callback.overlap_occured)
{
//std::cout << "player has hit ground" << std::endl;
key_pressed_counter = 0;
}
// subtracts the difference of the yaw position last stored and the current yaw position that was called.
float mouse_yaw_offset = last_mouse_yaw_position - flt_raw_mouse_yaw;
// subtracts the difference of the pitch position last stored and the current pitch position that was called.
float mouse_pitch_offset = flt_raw_mouse_pitch - last_mouse_pitch_position;
// set the yaw position that was just called as the last yaw position
// this gets us set up for the next time this function is called
last_mouse_yaw_position = flt_raw_mouse_yaw;
// sets the pitch position that was just called as the last pitch position
// this gets us set up for the next time this function is called
last_mouse_pitch_position = flt_raw_mouse_pitch;
camera_obj->MOUSE(mouse_yaw_offset, mouse_pitch_offset);
Mouse_Velocity_Physics(GAME_OBJ::Mouse_Moved);
}
void GAME_OBJ::Update_Game(float delta_time)
{
/**
// IF SLIDER IS MOVED; UPDATE CUBE PHYSICS
if (ImGui::SliderFloat("CUBE 1 X Direction", &cube_position_1.x, -50.0f, 50.0f))
{
//const reactphysics3d::Transform& transf = bod_rigid->getTransform();
const reactphysics3d::Transform& transf = cube1.rigid_body->getTransform();
const reactphysics3d::Vector3 posit = transf.getPosition();
reactphysics3d::Vector3 temp_vec(cube_position_1.x, posit.y, posit.z);
reactphysics3d::Quaternion temp_quart = reactphysics3d::Quaternion::identity();
reactphysics3d::Transform temp_trans(temp_vec, temp_quart);
//bod_rigid->setTransform(temp_trans);
player.rigid_body->setTransform(temp_trans);
}
if (ImGui::SliderFloat("CUBE 1 Y Direction", &cube_position_1.y, -50.0f, 50.0f))
{
//const reactphysics3d::Transform& transf = bod_rigid->getTransform();
const reactphysics3d::Transform& transf = cube1.rigid_body->getTransform();
const reactphysics3d::Vector3 posit = transf.getPosition();
reactphysics3d::Vector3 temp_vec(posit.x, cube_position_1.y, posit.z);
reactphysics3d::Quaternion temp_quart = reactphysics3d::Quaternion::identity();
reactphysics3d::Transform temp_trans(temp_vec, temp_quart);
//bod_rigid->setTransform(temp_trans);
player.rigid_body->setTransform(temp_trans);
}
if (ImGui::SliderFloat("CUBE 1 Z Direction", &cube_position_1.z, -50.0f, 50.0f))
{
//const reactphysics3d::Transform& transf = bod_rigid->getTransform();
const reactphysics3d::Transform& transf = cube1.rigid_body->getTransform();
const reactphysics3d::Vector3 posit = transf.getPosition();
reactphysics3d::Vector3 temp_vec(posit.x, posit.y, cube_position_1.z);
reactphysics3d::Quaternion temp_quart = reactphysics3d::Quaternion::identity();
reactphysics3d::Transform temp_trans(temp_vec, temp_quart);
//bod_rigid->setTransform(temp_trans);
player.rigid_body->setTransform(temp_trans);
}
*/
// ORIGINAL POSITION OF PROCESS USER INPUT
// ISSUE WITH ROCKETS IS DUE TO PHYSICS WORLD NOT UPDATING PROPERLY
GAME_OBJ::Process_User_Input(delta_time);
// USE THIS TO PREVENT THE PHYSICS ENGINE FROM GIVING TOO MUCH "BOUNCINESS" WITHIN ITS PHYSICS SIM
if (physWorld->testOverlap(floor_test.rigid_body, player.rigid_body))
{
//std::cout << "player on floor" << std::endl;
player.rigid_body->setLinearVelocity(reactphysics3d::Vector3(0.0, 0.0, 0.0));
player.rigid_body->setAngularVelocity(reactphysics3d::Vector3(0.0, 0.0, 0.0));
}
if (!physWorld->testOverlap(floor_test.rigid_body, player.rigid_body))
{
//std::cout << "player not on floor" << std::endl;
}
// Original Position Of Mouse Velocity Physics
Mouse_Velocity_Physics(GAME_OBJ::Mouse_Moved);
// ORIGINAL POSITION OF UPDATING PHYSICS WORLD
// update physics world
physWorld->update(ts);
// Original Position Of Cubes
// get updated position of the body
const reactphysics3d::Transform& transf = cube1.rigid_body->getTransform();
const reactphysics3d::Vector3 posit = transf.getPosition();
cube_position_1 = glm::vec3(posit.x, posit.y, posit.z);
const reactphysics3d::Transform& transf2 = cube2.rigid_body->getTransform();
const reactphysics3d::Vector3 posit2 = transf2.getPosition();
cube_position_2 = glm::vec3(posit2.x, posit2.y, posit2.z);
const reactphysics3d::Transform& transf4 = player.rigid_body->getTransform();
const reactphysics3d::Vector3 posit4 = transf4.getPosition();
camera_obj->obj_cam_pos.x = posit4.x;
camera_obj->obj_cam_pos.y = posit4.y;
camera_obj->obj_cam_pos.z = posit4.z;
for (auto rocket = rockets.begin(); rocket < rockets.end(); ++rocket)
{
PHYSICS_OBJ& temp_rocket = *rocket;
reactphysics3d::Transform trans_rocket_gl(temp_rocket.rigid_body->getTransform());
reactphysics3d::Vector3 vector_rocket_gl(trans_rocket_gl.getPosition());
rocket_vector.x = vector_rocket_gl.x;
rocket_vector.y = vector_rocket_gl.y;
rocket_vector.z = vector_rocket_gl.z;
}
// PROCESS MOUSE BUTTON INPUT
if (this->Mouse_Button_Pressed_Buffer[GLFW_MOUSE_BUTTON_LEFT])
{
//std::cout << camera_obj->obj_cam_pos.x << "," << camera_obj->obj_cam_pos.y << "," << camera_obj->obj_cam_pos.z << std::endl;
//std::cout << camera_obj->obj_cam_pos.x + camera_obj->obj_cam_front_view.x << "," << camera_obj->obj_cam_pos.y + camera_obj->obj_cam_front_view.y << "," << camera_obj->obj_cam_pos.z + camera_obj->obj_cam_front_view.z << std::endl;
// ADD THE CAM POS AND FRONT VIEW POS SO THE ROCKET COMES OUT CORRECTLY
PHYSICS_OBJ rocket(physCom, physWorld, "BOX", reactphysics3d::Vector3(0.2, 0.2, 0.2), reactphysics3d::Vector3(camera_obj->obj_cam_pos.x + (camera_obj->obj_cam_front_view.x * 4), camera_obj->obj_cam_pos.y + (camera_obj->obj_cam_front_view.y * 4), camera_obj->obj_cam_pos.z + (camera_obj->obj_cam_front_view.z * 4)));
//PHYSICS_OBJ rocket(physCom, physWorld, "SHPERE", 2.0, reactphysics3d::Vector3(camera_obj->obj_cam_pos.x + (camera_obj->obj_cam_front_view.x * 10), camera_obj->obj_cam_pos.y + (camera_obj->obj_cam_front_view.y * 10), camera_obj->obj_cam_pos.z + (camera_obj->obj_cam_front_view.z * 10)));
//rocket.rigid_body->setType(reactphysics3d::BodyType::DYNAMIC);
//CustomOverlapCallback rocket_callback(rocket);
rocket.rigid_body->setMass(0.0);
//physWorld->testOverlap(rocket.rigid_body, rocket_callback);
//rocket.rigid_body->setLinearVelocity(reactphysics3d::Vector3(camera_obj->obj_cam_front_view.x * 80, camera_obj->obj_cam_front_view.y * 80, camera_obj->obj_cam_front_view.z * 80));
rocket.rigid_body->setLinearVelocity(reactphysics3d::Vector3(camera_obj->obj_cam_front_view.x * 10, camera_obj->obj_cam_front_view.y * 10, camera_obj->obj_cam_front_view.z * 10));
//reactphysics3d::Transform trans = rocket.rigid_body->getTransform();
//rocket_vector = glm::vec3(camera_obj->obj_cam_pos.x + (camera_obj->obj_cam_front_view.x * 4), camera_obj->obj_cam_pos.y + (camera_obj->obj_cam_front_view.y * 4), camera_obj->obj_cam_pos.z + (camera_obj->obj_cam_front_view.z * 4));
//trans.setPosition(reactphysics3d::Vector3(rocket_vector.x += camera_obj->obj_cam_front_view.x, rocket_vector.y += camera_obj->obj_cam_front_view.y, rocket_vector.z += camera_obj->obj_cam_front_view.z));
rockets.push_back(rocket);
}
}
// CURRENTLY TESTING FUNCTION
void GAME_OBJ::Mouse_Velocity_Physics(bool mouse_moved_argument)
{
if (mouse_moved_argument)
{
if (this->Key_Pressed_Buffer[GLFW_KEY_SPACE] && this->Key_Pressed_Buffer[GLFW_KEY_W] && this->Key_Pressed_Buffer[GLFW_KEY_A])
{
if (key_pressed_counter < time_key_can_be_held)
{
player.rigid_body->applyLocalForceAtCenterOfMass(reactphysics3d::Vector3(camera_obj->obj_cam_front_view.x * 7, 0.0, camera_obj->obj_cam_front_view.z * 7));
}
}
if (this->Key_Pressed_Buffer[GLFW_KEY_SPACE] && this->Key_Pressed_Buffer[GLFW_KEY_W] && this->Key_Pressed_Buffer[GLFW_KEY_D])
{
if (key_pressed_counter < time_key_can_be_held)
{
player.rigid_body->applyLocalForceAtCenterOfMass(reactphysics3d::Vector3(camera_obj->obj_cam_front_view.x * 7, 0.0, camera_obj->obj_cam_front_view.z * 7));
}
}
}
/*
if (!this->Key_Pressed_Buffer[GLFW_KEY_SPACE] && this->Key_Pressed_Buffer[GLFW_KEY_W] && this->Key_Pressed_Buffer[GLFW_KEY_D] && physWorld->testOverlap(floor_test.rigid_body, player.rigid_body))
{
key_pressed_counter = 0;
}
if (!this->Key_Pressed_Buffer[GLFW_KEY_SPACE] && this->Key_Pressed_Buffer[GLFW_KEY_W] && this->Key_Pressed_Buffer[GLFW_KEY_A] && physWorld->testOverlap(floor_test.rigid_body, player.rigid_body))
{
key_pressed_counter = 0;
}
*/
CustomOverlapCallback overlap_callback(player);
physWorld->testOverlap(player.rigid_body, overlap_callback);
if (!this->Key_Pressed_Buffer[GLFW_KEY_SPACE] && this->Key_Pressed_Buffer[GLFW_KEY_W] && this->Key_Pressed_Buffer[GLFW_KEY_D] && overlap_callback.overlap_occured)
{
key_pressed_counter = 0;
}
if (!this->Key_Pressed_Buffer[GLFW_KEY_SPACE] && this->Key_Pressed_Buffer[GLFW_KEY_W] && this->Key_Pressed_Buffer[GLFW_KEY_A] && overlap_callback.overlap_occured)
{
key_pressed_counter = 0;
}
}
"logic_for_game.h" #ifndef LOGIC_FOR_GAME_HEADER
#define LOGIC_FOR_GAME_HEADER
#include "IM_GUI_OBJ.h"
#include "logic_for_game.h"
#include "resource_manager.h"
#include "render_object.h"
#include "process_shadow_map.h"
#include "cam.h"
#include "physics_object.h"
#include <reactphysics3d/reactphysics3d.h>
#include <reactphysics3d/collision/OverlapCallback.h>
#include <iostream>
// Game class that stores all game related states/functionality
class GAME_OBJ
{
public:
GAME_OBJ(unsigned int width_of_window, unsigned int height_of_window); // constructor with arguments required to create a GAME_OBJ object
~GAME_OBJ(); // deconstructor of GAME_OBJ
bool Key_Pressed_Buffer[1024]; // buffer that stores key's that are pressed by player
bool Processed_Keys[1024]; // buffer that stores key's that have been processed
bool Mouse_Button_Pressed_Buffer[1024]; // buffer that stores button's that are pressed by player
bool Processed_Mouse_Button[1024]; // buffer that stores buttons that have been processed
bool Mouse_Moved; // boolean value that tells if mouse has moved or not
unsigned int Width_Of_Screen, Height_Of_Screen; // stores the width and height of the actual game window
// where the last yaw position that was grabbed from the callback function is stored
float last_mouse_yaw_position;
// where the last pitch position that was grabbed from the callback function is stored
float last_mouse_pitch_position;
float flt_raw_mouse_yaw;
float flt_raw_mouse_pitch;
void Process_User_Input(float delta_time); // function that processes keys/movement done by player
// initalize the current state of the game (load all the shaders, textures, and levels)
void Initalize_Game();
void Update_Game(float delta_time); // updates game to reflect prior user/movement and state of ball
void Mouse_Velocity_Physics(bool mouse_moved_argument);
void Render_Game(); // renders the game on the players screen
};
#endif // !LOGIC_FOR_GAME_HEADER
"physics_object.h" #ifndef PHYSICS_OBJECT_HEADER
#define PHYSICS_OBJECT_HEADER
#include <reactphysics3d/reactphysics3d.h>
#include <iostream>
#include <string>
class PHYSICS_OBJ
{
public:
PHYSICS_OBJ(reactphysics3d::PhysicsCommon& physComArgument, reactphysics3d::PhysicsWorld* physWorldArgument, std::string colliderType, reactphysics3d::Vector3 halfway_argument, reactphysics3d::Vector3 initial_position_argument);
PHYSICS_OBJ(reactphysics3d::PhysicsCommon& physComArgument, reactphysics3d::PhysicsWorld* physWorldArgument, std::string colliderType, float radius_argument, float height_argument, reactphysics3d::Vector3 initial_position_argument);
PHYSICS_OBJ(reactphysics3d::PhysicsCommon& physComArgument, reactphysics3d::PhysicsWorld* physWorldArgument, std::string colliderType, float radius_argument, reactphysics3d::Vector3 initial_position_argument);
PHYSICS_OBJ(reactphysics3d::PhysicsCommon& physComArgument, reactphysics3d::PhysicsWorld* physWorldArgument, std::string colliderType, reactphysics3d::TriangleVertexArray& vertex_array, reactphysics3d::Vector3 initial_position_argument);
PHYSICS_OBJ();
~PHYSICS_OBJ();
reactphysics3d::Collider* collider;
reactphysics3d::Material material;
reactphysics3d::Vector3 position_of_physics_object;
reactphysics3d::RigidBody* rigid_body;
reactphysics3d::Quaternion quarternion;
reactphysics3d::Transform transform;
std::vector<reactphysics3d::Message> messages;
};
#endif // !PHYISCS_OBJECT_HEADER
"physics_object.cpp" #include "physics_object.h"
PHYSICS_OBJ::PHYSICS_OBJ(reactphysics3d::PhysicsCommon& physComArgument, reactphysics3d::PhysicsWorld* physWorldArgument, std::string colliderType, reactphysics3d::Vector3 halfway_argument, reactphysics3d::Vector3 initial_position_argument) : material(material)
{
this->quarternion = reactphysics3d::Quaternion::identity();
this->transform.setPosition(initial_position_argument);
this->position_of_physics_object = initial_position_argument;
this->transform.setOrientation(this->quarternion);
this->rigid_body = physWorldArgument->createRigidBody(this->transform);
if (colliderType == "BOX")
{
reactphysics3d::BoxShape* BoxCollision = physComArgument.createBoxShape(halfway_argument);
this->collider = this->rigid_body->addCollider(BoxCollision, transform);
reactphysics3d::Material &temp_material = this->collider->getMaterial();
this->material = temp_material;
}
}
PHYSICS_OBJ::PHYSICS_OBJ(reactphysics3d::PhysicsCommon& physComArgument, reactphysics3d::PhysicsWorld* physWorldArgument, std::string colliderType, float radius_argument, float height_argument, reactphysics3d::Vector3 initial_position_argument) : material(material)
{
this->quarternion = reactphysics3d::Quaternion::identity();
this->transform.setPosition(initial_position_argument);
this->transform.setOrientation(this->quarternion);
this->rigid_body = physWorldArgument->createRigidBody(this->transform);
if (colliderType == "CAPSULE")
{
reactphysics3d::CapsuleShape* CapsuleCollision = physComArgument.createCapsuleShape(radius_argument, height_argument);
this->collider = this->rigid_body->addCollider(CapsuleCollision, transform);
reactphysics3d::Material& temp_material = this->collider->getMaterial();
this->material = temp_material;
}
}
PHYSICS_OBJ::PHYSICS_OBJ(reactphysics3d::PhysicsCommon& physComArgument, reactphysics3d::PhysicsWorld* physWorldArgument, std::string colliderType, float radius_argument, reactphysics3d::Vector3 initial_position_argument) : material(material)
{
this->quarternion = reactphysics3d::Quaternion::identity();
this->transform.setPosition(initial_position_argument);
this->transform.setOrientation(this->quarternion);
this->rigid_body = physWorldArgument->createRigidBody(this->transform);
if (colliderType == "SPHERE")
{
reactphysics3d::SphereShape* SphereCollision = physComArgument.createSphereShape(radius_argument);
this->collider = this->rigid_body->addCollider(SphereCollision, transform);
reactphysics3d::Material& temp_material = this->collider->getMaterial();
this->material = temp_material;
}
}
PHYSICS_OBJ::PHYSICS_OBJ(reactphysics3d::PhysicsCommon& physComArgument, reactphysics3d::PhysicsWorld* physWorldArgument, std::string colliderType, reactphysics3d::TriangleVertexArray& vertex_array, reactphysics3d::Vector3 initial_position_argument) : material(material)
{
this->quarternion = reactphysics3d::Quaternion::identity();
this->transform.setPosition(initial_position_argument);
this->transform.setOrientation(this->quarternion);
this->rigid_body = physWorldArgument->createRigidBody(this->transform);
if (colliderType == "CONCAVE_MESH")
{
reactphysics3d::TriangleMesh* mesh = physComArgument.createTriangleMesh(vertex_array, this->messages);
reactphysics3d::ConcaveMeshShape* ConcaveCollision = physComArgument.createConcaveMeshShape(mesh);
this->collider = this->rigid_body->addCollider(ConcaveCollision, transform);
reactphysics3d::Material& temp_material = this->collider->getMaterial();
this->material = temp_material;
}
}
PHYSICS_OBJ::~PHYSICS_OBJ()
{
}
"main.cpp" //#include "imgui/imgui.h"
//#include "imgui/imgui_impl_opengl3.h"
//#include "imgui/imgui_impl_glfw.h"
#include <glad/glad.h> // include GLAD; a lib that loads the addresses of OpenGL function pointers
#include <GLFW/glfw3.h> // include glfw3; a lib that ties OpenGL to a window and callback functions within a window
#include <iostream> // include iostream to send default output to the terminal
#include "resource_manager.h"
#include "logic_for_game.h"
#include "IM_GUI_OBJ.h"
// our boolean variable for the mouse callback when the window is created for the first time
bool inital_mouse_win = true;
// prototype call-back glfw functions; baically you can call these whatever you want and then tie them to actual GLFW lib callback-functions along with the GLFWwindow pointer variable you created
/*
this function contains a glfw window pointer parameter, the width of the window, and the height of the window
the idea is this, you tie this function to the glfw framebuffer size callback function and whenever the window
is resized by a user, it will set the glviewport to those new window dimensions
*/
void glfw_callback_window_resize(GLFWwindow* glfw_window_argument, int width_resize_of_window, int height_resize_of_window);
/*
this function contains a glfw window pointer parameter, an input (or key that was pressed) parameter, an input_scan_code parameter, an action parameter, and a mode parameter
the idea is you tie this function to the glfw set key callback function and if the glfw window detects any key is pressed by the user, the function we created will go through
and process the logic that is defined within the glfw_callback_keyboard_input function
each argument after the window parameter ties to a "key property" that is grabbed from the glfw set key call back function.
input: the key that was pressed or released by the user
input_scan_code : the system-specific scancode of a key; basically it is a unchanging number that represents the physical location of the key on a keyboard
and not the character. Meaning it will get the actual location of the key on the keyboard, i.e. the position of 'd' will never change depending on the language
layout that the user chooses for thier OS.
Think of this like a MAC Address rather than an IP Address, a computer's IP address can change due to many factors but a computer's NIC MAC Address will never
change (for the most part unless you like change the NIC).
input_action: detects the action of the key that was just pressed; states like GLFW_PRESS, GLFW_RELEASE, and GLFW_REPEAT are some of the states that a key can be in.
input_mode: this detects which "modifier keys" where held down, these include the shift key, control key, caps lock key, alt key, num lock key, etc.
*/
void glfw_callback_keyboard_input(GLFWwindow* glfw_window_argument, int input, int input_scan_code, int input_action, int input_mode);
/*
this function contains a glfw window pointer parameter, an raw_mouse_yaw parameter, and a raw_mouse_ptich parameter
this callback function are whenever the game detects mouse input, it calls this function and sends the yaw and pitch
data to their relative parameters
*/
void mouse_functionality(GLFWwindow* win, double raw_mouse_yaw, double raw_mouse_pitch);
/*
this function contains a glfw window pointer parameter, an input paramter, an action parameter, and a "mod" parameter
input: the button on the mouse that was pressed or released by the user
input_action: detects the action of the button that was just pressed; states like GLFW_PRESS, GLFW_RELEASE, and GLFW_REPEAT are some of the states that a key can be in.
mods: not sure it's in the GLFW documentation within the example
*/
void mouse_input(GLFWwindow* glfw_window_argument, int input, int input_action, int mods);
// create a constant global variable that stores the desired width of the screen
const unsigned int WIDTH_OF_SCREEN = 1920;
// create a constant global variable that stores the desired height of the screen
const unsigned int HEIGHT_OF_SCREEN = 1080;
GAME_OBJ game (WIDTH_OF_SCREEN, HEIGHT_OF_SCREEN);
int main(int integer_arg, char* character_c_string_arg[]) // main function of C++; take in two arguments, a integer argument, and a char pointer array argument (essetially a c-string pointer)
{
// initalize glfw
glfwInit();
// provide window hints to glfw to let it know what version of OpenGL we are working in (OpenGL ver. 3.30 aka 3.3)
// this specifies the major version
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
// this specifies the minor version
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// tell glfw that we are only using the core profile of OpenGL and not other profiles
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// create the window pointer variable which takes our screen dimension global constant variables as well as a string for the name of the window in our OS
GLFWwindow* glfw_window = glfwCreateWindow(WIDTH_OF_SCREEN, HEIGHT_OF_SCREEN, "Breakout Capstone", nullptr, nullptr);
// this makes the window specified within the function the current window within the calling thread; what I believe this means is that anything that is drawn,
// bound, and or done within OpenGL and GLFW will end up on this specific window.
glfwMakeContextCurrent(glfw_window);
// load all OpenGL function pointer with GLAD, use this statement to intalize glad, if it comes back as false, we send default output to the screen saying a failure has occured
// the gladLoadGLLoader function is a int value that I think is what we are using as our boolean statment value; the GLADloadproc is a void function that does what the name specifies
// and the glfwGetProcAddress attempts to get the location of the GLADloadproc function
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Cannot Initalize GLAD: Terminating Application Now" << std::endl;
// return standard error and end the main function (return -1)
return -1;
}
// this is a GLFW function that ties to the function we defined to process the given keyboard input
/*
think of a callback function like this; whenever a specified event in the window happens i.e.
a key is pressed, graphics application window is resized by the user or OS, mouse has moved, etc.
glfw recognizes this and then calls the function that is assigned to that callback.
*/
glfwSetKeyCallback(glfw_window, glfw_callback_keyboard_input);
// this is a GLFW function that ties to the function we defined to process the given mouse button input
glfwSetMouseButtonCallback(glfw_window, mouse_input);
// this is a GLFW function that ties the function we defined whenver the window gets resized
glfwSetFramebufferSizeCallback(glfw_window, glfw_callback_window_resize);
// this is a GLFW function that captures your raw mouse movements and sends the data to this callback function
glfwSetCursorPosCallback(glfw_window, mouse_functionality);
// this is a GLFW function disables the cursor icon when on this window
glfwSetInputMode(glfw_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
// ADD IMGUI window and io after callback functions to both capture mouse and use im_gui
IM_GUI_OBJ im_gui_win(glfw_window);
ImGuiIO& im_gui_input_output = ImGui::GetIO();
// specify the viewport dimensions (how we view our renderings/game environment)
// we set them to be the same size as the window itself
glViewport(0, 0, WIDTH_OF_SCREEN, HEIGHT_OF_SCREEN);
glEnable(GL_DEPTH_TEST);
game.Initalize_Game();
// delta time variable
float dTime = 0.0;
// last frame variable
float lFrame = 0.0;
// render loop that is the main loop for our game
// while !glfwWindowShouldClose(window) means while glfw window is not closed, process source code inside loop
while (!glfwWindowShouldClose(glfw_window))
{
game.Mouse_Moved = false;
// get current frame to calculate delta time with glfwGetTime(); this gets the current time since the window was open
float cFrame = glfwGetTime();
// calculate delta time by subtracting the currrent frame by the last frame. So the first calculation is like (0.01 - 0.00 = 0.01; delta time = 0.01)
dTime = cFrame - lFrame;
// set the last frame variable as the same value as the current frame variable which will equal the float value of glfwGetTime
// think of it like your current frame will be the last frame within the render loop as the curret frame is always increasing in value/time
lFrame = cFrame;
// glfw function that processes any events that happen within the glfw window; thus enabling our callback functions defined prior
glfwPollEvents();
// setup new IMGUI FRAME's with OpenGL, GLFW, and IMGUI
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
// TEMPORARY, SHOW DEMO WINDOW
//ImGui::ShowDemoWindow();
ImGui::Text("FPS %.1f", im_gui_input_output.Framerate);
// calculate delta time by subtracting the currrent frame by the last frame. So the first calculation is like (0.01 - 0.00 = 0.01; delta time = 0.01)
dTime = cFrame - lFrame;
// set the last frame variable as the same value as the current frame variable which will equal the float value of glfwGetTime
// think of it like your current frame will be the last frame within the render loop as the curret frame is always increasing in value/time
lFrame = cFrame;
// render stuff
// glClearColor is an OpenGL function that changes our background/default color buffer to the set color within this function
glClearColor(1.0f, 0.5f, 0.5f, 1.0f);
// glClear is an OpenGL function that clears the specifed buffer with a buffer bit
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
game.Update_Game(dTime);
//game.Update_Game(dTime);
game.Render_Game();
// render IMGUI window
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
/*
glfwSwapBuffers is a glfw function that swaps the front and back buffers of the glfw window specified
DOUBLE-BUFFER CONCEPT:
When an OpenGL project that uses a single buffer to draw an image may result in the image flickering
due to the concept that an image drawn is not instant but rather drawn per pixel in the orientation
left to right, top to bottom. Due to this, many artifacts are produced.
To prevent this, windows use a double-buffer for rendering. The front buffer contains the final output
image that is diplayed within the windowed screen. While the back buffer does all of the drawing rendering
commands. Once all the rendering commands are complete, the back buffer is swapped to the front buffer.
*/
glfwSwapBuffers(glfw_window);
}
RESOURCE_MANAGER::Clear_All_Resources();
// glfwTerminate is a glfw function that clears all windows and glfw relevant resouces
glfwTerminate();
// end of main function
return 0;
}
/*
this function contains a glfw window pointer parameter, the width of the window, and the height of the window
the idea is this, you tie this function to the glfw framebuffer size callback function and whenever the window
is resized by a user, it will set the glviewport to those new window dimensions
*/
void glfw_callback_window_resize(GLFWwindow* glfw_window_argument, int width_resize_of_window, int height_resize_of_window)
{
glViewport(0, 0, width_resize_of_window, height_resize_of_window);
}
// PROTOTYPE FUNCTION DEFINITIONS
/*
this function contains a glfw window pointer parameter, an input (or key that was pressed) parameter, an input_scan_code parameter, an action parameter, and a mode parameter
the idea is you tie this function to the glfw set key callback function and if the glfw window detects any key is pressed by the user, the function we created will go through
and process the logic that is defined within the glfw_callback_keyboard_input function
each argument after the window parameter ties to a "key property" that is grabbed from the glfw set key call back function.
input: the key that was pressed or released by the user
input_scan_code : the system-specific scancode of a key; basically it is a unchanging number that represents the physical location of the key on a keyboard
and not the character. Meaning it will get the actual location of the key on the keyboard, i.e. the position of 'd' will never change depending on the language
layout that the user chooses for thier OS.
Think of this like a MAC Address rather than an IP Address, a computer's IP address can change due to many factors but a computer's NIC MAC Address will never
change (for the most part unless you like change the NIC).
input_action: detects the action of the key that was just pressed; states like GLFW_PRESS, GLFW_RELEASE, and GLFW_REPEAT are some of the states that a key can be in.
input_mode: this detects which "modifier keys" where held down, these include the shift key, control key, caps lock key, alt key, num lock key, etc.
*/
void glfw_callback_keyboard_input(GLFWwindow* glfw_window_argument, int input, int input_scan_code, int input_action, int input_mode)
{
// if the callback function detects that the escape key is in the state of being pressed, the window will be closed
if (input == GLFW_KEY_ESCAPE && input_action == GLFW_PRESS)
{
// send default output to terminal stating that window was closed via escape key
std::cout << "GLFW WINDOW CLOSED: REASON: USER PRESSED ESCAPE KEY" << std::endl;
// glfw function that sets the window should close glfw function to true, thus closing the window
glfwSetWindowShouldClose(glfw_window_argument, true);
}
if (input == GLFW_KEY_L && input_action == GLFW_PRESS)
{
// this is a GLFW function disables the cursor icon when on this window
glfwSetInputMode(glfw_window_argument, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
}
if (input == GLFW_KEY_P && input_action == GLFW_PRESS)
{
// this is a GLFW function disables the cursor icon when on this window
glfwSetInputMode(glfw_window_argument, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
}
// if our input is greater than or equal to 0 (which I guess means 1 if we are thinking about how arrays work) and less than 1024, process input
if (input >= 0 && input < 1024)
{
// if our input_action detects the key to be pressed, set our Key_Pressed_Buffer boolean array data member within the GAME_OBJ to true; and store the key within the Key_Pressed_Buffer array data member of the GAME_OBJ using input as the index
if (input_action == GLFW_PRESS)
{
game.Key_Pressed_Buffer[input] = true;
}
// else if our input_action detects the key was released, set our Key_Pressed_Buffer boolean array data member within the GAME_OBJ to false; and store the key within the Key_Pressed_Buffer array data member of the GAME_OBJ using input as the index
// in addition, set our Processed_Keys boolean array data member within GAME_OBJ to false and store the key within the Processed_Key array data member of the GAME_OBJ using input as the index
else if (input_action == GLFW_RELEASE)
{
game.Key_Pressed_Buffer[input] = false;
game.Processed_Keys[input] = false;
}
}
}
void mouse_input(GLFWwindow* glfw_window_argument, int input, int input_action, int mods)
{
// if our input is greater than or equal to 0 (which I guess means 1 if we are thinking about how arrays work) and less than 1024, process input
if (input >= 0 && input < 1024)
{
// if our input_action detects the button to be pressed, set our Mouse_Button_Pressed_Buffer boolean array data member within the GAME_OBJ to true; and store the button within the Mouse_Button_Pressed_Buffer array data member of the GAME_OBJ using input as the index
if (input_action == GLFW_PRESS)
{
game.Mouse_Button_Pressed_Buffer[input] = true;
}
// else if our action detects the button was released, set our Mouse_Button_Pressed_Buffer boolean array data member within the GAME_OBJ to false; and store the button within the Mouse_Button_Pressed_Buffer array data member of the GAME_OBJ using input as the index
// in addition, set our Processed_Mouse_Button boolean array data member within GAME_OBJ to false and store the key within the Processed_Mouse_Button array data member of the GAME_OBJ using input as the index
else if (input_action == GLFW_RELEASE)
{
game.Mouse_Button_Pressed_Buffer[input] = false;
game.Processed_Mouse_Button[input] = false;
}
}
}
void mouse_functionality(GLFWwindow* win, double raw_mouse_yaw, double raw_mouse_pitch)
{
// convert raw mouse yaw from callback function to float instead of double
game.flt_raw_mouse_yaw = static_cast<float>(raw_mouse_yaw);
// conver raw mouse pitch from callback function to float instead of double
game.flt_raw_mouse_pitch = static_cast<float>(raw_mouse_pitch);
// if this is the first time this window has been open set the last_mouse_yaw_position equal to the flt_raw_mouse_yaw and last_mouse_pitch_position equal to flt_raw_mouse_pitch to prevent that large jerk from the inital window
if (inital_mouse_win)
{
game.last_mouse_yaw_position = game.flt_raw_mouse_yaw;
game.last_mouse_pitch_position = game.flt_raw_mouse_pitch;
// set initial_mouse_win to false to allow us to caclulate the difference between last_mouse_position and flt_raw_mouse so that the result isn't always 0
inital_mouse_win = false;
}
game.Mouse_Moved = true;
}If you've reached this far thank you again for your time. |
Replies: 2 comments 1 reply
|
Hey Antonio! Really cool progress on your game. The reason your rockets' rigid bodies aren't moving with the graphics (and why shooting at the prior position still triggers collisions) comes down to a classic ReactPhysics3D setup issue: the rigid body type. Here is what's happening under the hood and how to fix it: 1. The RigidBody is
|
|
Hello all, I have figured out the issue, this was primarily with the transformation of the collider. I was using the rigid body transformation rather than a new one. Here is an example of the what I changed PHYSICS_OBJ::PHYSICS_OBJ(reactphysics3d::PhysicsCommon& physComArgument, reactphysics3d::PhysicsWorld* physWorldArgument, std::string colliderType, reactphysics3d::Vector3 halfway_argument, reactphysics3d::Vector3 initial_position_argument) : material(material)
{
this->quarternion = reactphysics3d::Quaternion::identity();
this->transform.setPosition(initial_position_argument);
this->position_of_physics_object = initial_position_argument;
this->transform.setOrientation(this->quarternion);
this->rigid_body = physWorldArgument->createRigidBody(this->transform);
if (colliderType == "BOX")
{
reactphysics3d::BoxShape* BoxCollision = physComArgument.createBoxShape(halfway_argument);
// create local transformation matrix for the rigid body collider position
//reactphysics3d::Transform collider_local;
reactphysics3d::Transform collider_transform = reactphysics3d::Transform::identity();
// set the position relative to inside the object itself i.e. local origin
//transform_local.setPosition(reactphysics3d::Vector3(0.0, 0.0, 0.0));
// set a orientation local to the collider transformation matrix
collider_transform.setOrientation(reactphysics3d::Quaternion::identity());
// REMEMBER THIS TRANSFORMATION MATRIX IS FOR THE COLLIDER NOT FOR THE POSITION OF THE RIGID BODY ITSELF
// THE RIGID BODY SHOULD BE OF LOCAL ORIGIN
this->collider = this->rigid_body->addCollider(BoxCollision, collider_transform);
reactphysics3d::Material &temp_material = this->collider->getMaterial();
this->material = temp_material;
}
}
But the extra additions from @AntonAzer also helped me with future issues that may come up as well as a better way to render the rockets. Thanks again guys |
Hello all, I have figured out the issue, this was primarily with the transformation of the collider. I was using the rigid body transformation rather than a new one.
Here is an example of the what I changed