Skip to content

Commit

Permalink
add bullet, fix incorrect mouse coordinates when pointing into void
Browse files Browse the repository at this point in the history
  • Loading branch information
stijnherfst committed Oct 10, 2019
1 parent d323968 commit cf003e1
Show file tree
Hide file tree
Showing 11 changed files with 206 additions and 34 deletions.
38 changes: 29 additions & 9 deletions Base/Map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
#include "Hierarchy.h"
#include "HiveWE.h"
#include "InputHandler.h"

#include "Physics.h"

void Map::load(const fs::path& path) {
physics.initialize();

hierarchy.map_directory = path;
filesystem_path = fs::absolute(path) / "";
name = (*--(--filesystem_path.end())).string();
Expand Down Expand Up @@ -65,7 +67,7 @@ void Map::load(const fs::path& path) {
// Doodads
doodads_slk = slk::SLK("Doodads/Doodads.slk");
doodads_meta_slk = slk::SLK("Doodads/DoodadMetaData.slk");

doodads_slk.substitute(world_edit_strings, "WorldEditStrings");
doodads_slk.substitute(world_edit_game_strings, "WorldEditStrings");

Expand Down Expand Up @@ -182,14 +184,15 @@ void Map::load(const fs::path& path) {

camera->reset();


loaded = true;
}

bool Map::save(const fs::path& path) {
if (!fs::equivalent(path, filesystem_path)) {
try {
fs::copy(filesystem_path, fs::absolute(path), fs::copy_options::recursive);
} catch (fs::filesystem_error& e) {
} catch (fs::filesystem_error & e) {
QMessageBox msgbox;
msgbox.setText(e.what());
msgbox.exec();
Expand Down Expand Up @@ -228,12 +231,26 @@ void Map::render(int width, int height) {

// Render Terrain
terrain.render();

// Map mouse coordinates to world coordinates
if (input_handler.mouse != input_handler.previous_mouse && input_handler.mouse.y() > 0) {
glm::vec3 window = glm::vec3(input_handler.mouse.x(), height - input_handler.mouse.y(), 0);
gl->glReadPixels(input_handler.mouse.x(), height - input_handler.mouse.y(), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &window.z);
input_handler.mouse_world = glm::unProject(window, camera->view, camera->projection, glm::vec4(0, 0, width, height));
if (input_handler.mouse != input_handler.previous_mouse) {
glm::vec3 window = { input_handler.mouse.x, height - input_handler.mouse.y, 1.f };
glm::vec3 pos = glm::unProject(window, camera->view, camera->projection, glm::vec4(0, 0, width, height));
glm::vec3 origin = camera->position - camera->direction * camera->distance;
glm::vec3 direction = glm::normalize(pos - cpos);
glm::vec3 toto = origin + direction * 200.f;

btVector3 from(origin.x, origin.y, origin.z);
btVector3 to(toto.x, toto.y, toto.z);

btCollisionWorld::AllHitsRayResultCallback res(from, to);
physics.dynamicsWorld->rayTest(from, to, res);
res.m_hitPointWorld.quickSort([from](btVector3& a, btVector3& b) -> bool { return a.distance(from) < b.distance(from); });

if (res.m_hitPointWorld.size()) {
auto& hit = res.m_hitPointWorld[0];
input_handler.mouse_world = glm::vec3(hit.x(), hit.y(), hit.z());
}
}

// Render Doodads
Expand All @@ -253,9 +270,12 @@ void Map::render(int width, int height) {
}

// Render all meshes
for (auto&& i : meshes) {
for (const auto& i : meshes) {
i->render();
}

physics.dynamicsWorld->debugDrawWorld();
physics.draw->render();

meshes.clear();
}
68 changes: 68 additions & 0 deletions Base/Physics.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include "physics.h"

#include "Camera.h"

PhysicsDebugDraw::PhysicsDebugDraw() : btIDebugDraw() {
gl->glCreateBuffers(1, &vertex_buffer);
shader = resource_manager.load<Shader>({ "Data/Shaders/physics_debug.vs", "Data/Shaders/physics_debug.fs" });
}

void PhysicsDebugDraw::drawLine(const btVector3& from, const btVector3& to, const btVector3& color) {
debug_vertices.push_back(from.x());
debug_vertices.push_back(from.y());
debug_vertices.push_back(from.z());
debug_vertices.push_back(to.x());
debug_vertices.push_back(to.y());
debug_vertices.push_back(to.z());
}

void PhysicsDebugDraw::drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color) {
}

void PhysicsDebugDraw::reportErrorWarning(const char* warningString) {}

void PhysicsDebugDraw::draw3dText(const btVector3& location, const char* textString) {
}

void PhysicsDebugDraw::setDebugMode(int debugMode) {}

int PhysicsDebugDraw::getDebugMode() const {
return DBG_DrawWireframe;
}

void PhysicsDebugDraw::clearLines() {
debug_vertices.clear();
}

void PhysicsDebugDraw::render() {
gl->glNamedBufferData(vertex_buffer, debug_vertices.size() * sizeof(float), debug_vertices.data(), GL_STATIC_DRAW);

shader->use();
//gl->glDisable(GL_DEPTH_TEST);

gl->glUniformMatrix4fv(1, 1, GL_FALSE, &camera->projection_view[0][0]);

gl->glEnableVertexAttribArray(0);
gl->glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
gl->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

gl->glDrawArrays(GL_LINES, 0, debug_vertices.size());

gl->glDisableVertexAttribArray(0);
gl->glEnable(GL_DEPTH_TEST);
}

void Physics::initialize() {
broadphase = new btDbvtBroadphase();
collisionConfiguration = new btDefaultCollisionConfiguration();
dispatcher = new btCollisionDispatcher(collisionConfiguration);
solver = new btSequentialImpulseConstraintSolver;
dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
dynamicsWorld->setGravity(btVector3(0, 0, gravity));

draw = new PhysicsDebugDraw;
draw->setDebugMode(draw->getDebugMode() | btIDebugDraw::DBG_DrawAabb);
dynamicsWorld->setDebugDrawer(draw);
}

Physics physics;
52 changes: 52 additions & 0 deletions Base/Physics.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#pragma once

#include "bullet/btBulletDynamicsCommon.h"
#include <vector>
#include "Shader.h"
#include <memory>

class PhysicsDebugDraw : public btIDebugDraw {
std::shared_ptr<Shader> shader;
GLuint vertex_buffer;


public:
std::vector<float> debug_vertices;
PhysicsDebugDraw();

virtual void drawLine(const btVector3& from, const btVector3& to, const btVector3& color) override;
virtual void drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color) override;
virtual void reportErrorWarning(const char* warningString) override;
virtual void draw3dText(const btVector3& location, const char* textString) override;
virtual void setDebugMode(int debugMode) override;
virtual int getDebugMode() const override;
virtual void clearLines() override;
void render();
};

struct Physics {
float gravity = -9.81f;

btBroadphaseInterface* broadphase;
btDefaultCollisionConfiguration* collisionConfiguration;
btCollisionDispatcher* dispatcher;
btSequentialImpulseConstraintSolver* solver;
btDiscreteDynamicsWorld* dynamicsWorld;


PhysicsDebugDraw* draw;


void initialize();

~Physics() {
delete dynamicsWorld;
delete solver;
delete collisionConfiguration;
delete dispatcher;
delete broadphase;
}
};

extern Physics physics;

21 changes: 16 additions & 5 deletions Base/Terrain.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@

#include <set>
#include <bitset>
#include <iostream>


#include "Terrain.h"
#include "Hierarchy.h"
#include "Camera.h"
#include "SLK.h"
#include "HiveWE.h"
#include "BinaryReader.h"
#include "BinaryWriter.h"
#include "Physics.h"

#include "btBulletDynamicsCommon.h"

using namespace std::literals::string_literals;

Expand Down Expand Up @@ -265,6 +266,16 @@ void Terrain::create() {
cliff_shader = resource_manager.load<Shader>({ "Data/Shaders/cliff.vs", "Data/Shaders/cliff.fs" });
water_shader = resource_manager.load<Shader>({ "Data/Shaders/water.vs", "Data/Shaders/water.fs" });

collision_shape = new btHeightfieldTerrainShape(width, height, ground_heights.data(), 0, -16.f, 16.f, 2 /*z*/, PHY_FLOAT, false);
if (collision_shape == nullptr) {
std::cout << "error\n";
}

btRigidBody* body = new btRigidBody(0, new btDefaultMotionState(), collision_shape);
body->getWorldTransform().setOrigin(btVector3(width / 2.f - 0.5f, height / 2.f - 0.5f, 4.f)); // Bullet centers the collision mesh automatically, we need to decenter it and place it under the player
body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT);
physics.dynamicsWorld->addRigidBody(body);

emit minimap_changed(minimap_image());
}

Expand Down Expand Up @@ -553,7 +564,7 @@ bool Terrain::is_corner_ramp_entrance(int x, int y) {
Corner& top_left = corners[x][y + 1];
Corner& top_right = corners[x + 1][y + 1];

return bottom_left.ramp && top_left.ramp&& bottom_right.ramp && top_right.ramp && !(bottom_left.layer_height == top_right.layer_height && top_left.layer_height == bottom_right.layer_height);
return bottom_left.ramp && top_left.ramp && bottom_right.ramp && top_right.ramp && !(bottom_left.layer_height == top_right.layer_height && top_left.layer_height == bottom_right.layer_height);
}

//bool Terrain::is_corner_cliff(int x, int y) {
Expand All @@ -579,7 +590,7 @@ Texture Terrain::minimap_image() {
color = ground_textures[real_tile_texture(i, j)]->minimap_color;
}

if (corners[i][j].water && corners[i][j].final_water_height() > corners[i][j].final_ground_height()) {
if (corners[i][j].water && corners[i][j].final_water_height() > corners[i][j].final_ground_height()) {
if (corners[i][j].final_water_height() - corners[i][j].final_ground_height() > 0.5f) {
color *= 0.5625f;
color += glm::vec4(0, 0, 80, 112);
Expand Down Expand Up @@ -756,7 +767,7 @@ void Terrain::update_cliff_meshes(const QRect& area) {

const bool facing_down = top_left.layer_height >= bottom_left.layer_height && top_right.layer_height >= bottom_right.layer_height;
const bool facing_left = bottom_right.layer_height >= bottom_left.layer_height && top_right.layer_height >= top_left.layer_height;

if (!(facing_down && j == 0) && !(!facing_down && j >= height - 2) && !(facing_left && i == 0) && !(!facing_left && i >= width - 2)) {
const bool br = bottom_left.ramp != bottom_right.ramp && top_left.ramp != top_right.ramp && !corners[i + bottom_right.ramp][j + (facing_down ? -1 : 1)].cliff;
const bool bo = bottom_left.ramp != top_left.ramp && bottom_right.ramp != top_right.ramp && !corners[i + (facing_left ? -1 : 1)][j + top_left.ramp].cliff;
Expand Down
5 changes: 4 additions & 1 deletion Base/Terrain.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "CliffMesh.h"
#include "Texture.h"
#include "BinaryReader.h"

#include <bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
#include "Shader.h"
#include "SLK.h"

Expand Down Expand Up @@ -71,6 +71,9 @@ class Terrain : public QObject {
std::vector<float> water_heights;
std::vector<unsigned char> water_exists_data;


btHeightfieldTerrainShape* collision_shape;

public:
char tileset;
std::vector<std::string> tileset_ids;
Expand Down
13 changes: 11 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ add_executable(HiveWE
Base/Triggers.cpp
Base/TriggerStrings.cpp
Base/Units.cpp
Base/Physics.cpp

Base/Brush/Brush.cpp
Base/Brush/DoodadBrush.cpp
Expand Down Expand Up @@ -95,6 +96,8 @@ add_executable(HiveWE

target_include_directories(HiveWE PRIVATE ${QSCINTILLA_INCLUDE_DIRS})
target_include_directories(HiveWE PRIVATE ${JPEG_INCLUDE_DIR}})
target_include_directories(HiveWE PRIVATE ${BULLET3_INCLUDE_DIR}})
target_include_directories(HiveWE PRIVATE "C:/vcpkg/installed/x64-windows/include/bullet")

target_include_directories(HiveWE PRIVATE "Base" "Base/Brush" "Base/File Formats" "Base/Resources" "Menus" "Menus/Custom Widgets")

Expand All @@ -105,8 +108,14 @@ target_link_libraries(HiveWE
soil2
stormlib::stormlib
casclib
"C:/vcpkg/packages/libjpeg-turbo_x64-windows/debug/lib/turbojpegd.lib"
"C:/vcpkg/packages/qscintilla_x64-windows/debug/lib/qscintilla2.lib"
"C:/vcpkg/packages/libjpeg-turbo_x64-windows/lib/turbojpeg.lib"
"C:/vcpkg/packages/qscintilla_x64-windows/lib/qscintilla2.lib"
"C:/vcpkg/packages/bullet3_x64-windows/lib/Bullet3Common.lib"
"C:/vcpkg/packages/bullet3_x64-windows/lib/BulletCollision.lib"
"C:/vcpkg/packages/bullet3_x64-windows/lib/BulletDynamics.lib"
"C:/vcpkg/packages/bullet3_x64-windows/lib/BulletInverseDynamics.lib"
"C:/vcpkg/packages/bullet3_x64-windows/lib/BulletSoftBody.lib"
"C:/vcpkg/packages/bullet3_x64-windows/lib/LinearMath.lib"
${JPEG_LIBRARIES}
qt-advanced-docking-system::qtadvanceddocking
)
Expand Down
22 changes: 8 additions & 14 deletions Camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,13 @@ void FPSCamera::update(const double delta) {
}

void FPSCamera::mouse_move_event(QMouseEvent* event) {
const double diffx = input_handler.mouse.x() - input_handler.previous_mouse.x();
const double diffy = input_handler.mouse.y() - input_handler.previous_mouse.y();
glm::vec2 diff = input_handler.mouse - input_handler.previous_mouse;

horizontal_angle += diffx * 0.012;
vertical_angle += -diffy * 0.012;
horizontal_angle += diff.x * 0.012;
vertical_angle += -diff.y * 0.012;
vertical_angle = std::max(-glm::pi<double>() / 2 + 0.001, std::min(vertical_angle, glm::pi<double>() / 2 - 0.001));

update(0);

input_handler.previous_mouse = event->globalPos();
}

void FPSCamera::mouse_scroll_event(QWheelEvent* event) {
Expand Down Expand Up @@ -107,22 +104,19 @@ void TPSCamera::update(double delta) {
}

void TPSCamera::mouse_move_event(QMouseEvent* event) {
const int diffx = input_handler.mouse.x() - input_handler.previous_mouse.x();
const int diffy = input_handler.mouse.y() - input_handler.previous_mouse.y();
glm::vec2 diff = input_handler.mouse - input_handler.previous_mouse;

if (rolling || (event->buttons() == Qt::RightButton && event->modifiers() & Qt::ControlModifier)) {
horizontal_angle += -diffx * 0.0025f;
vertical_angle += diffy * 0.0025f;
horizontal_angle += -diff.x * 0.0025f;
vertical_angle += diff.y * 0.0025f;
vertical_angle = std::max(-glm::pi<double>() / 2 + 0.001, std::min(vertical_angle, glm::pi<double>() / 2 - 0.001));
update(0);
} else if (event->buttons() == Qt::RightButton) {
position += X * (-diffx * 0.025f * (distance / 30.f));
position += forward * (-diffy * 0.025f * (distance / 30.f));
position += X * (-diff.x * 0.025f * (distance / 30.f));
position += forward * (-diff.y * 0.025f * (distance / 30.f));
position.z = map->terrain.interpolated_height(position.x, position.y);
update(0);
}

input_handler.previous_mouse = event->globalPos();
}

void TPSCamera::mouse_scroll_event(QWheelEvent* event) {
Expand Down
7 changes: 7 additions & 0 deletions Data/Shaders/physics_debug.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#version 450 core

out vec4 color;

void main() {
color = vec4(0, 1, 0, 1);
}
8 changes: 8 additions & 0 deletions Data/Shaders/physics_debug.vs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#version 450 core

layout (location = 0) in vec3 vPosition;
layout (location = 1) uniform mat4 MVP;

void main() {
gl_Position = MVP * vec4(vPosition, 1);
}
Loading

0 comments on commit cf003e1

Please sign in to comment.