-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathHelper.cpp
118 lines (94 loc) · 3.9 KB
/
Helper.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include "Helper.h"
#include <SOIL/SOIL.h>
#include <iostream>
glm::vec3 convert(const btVector3& v)
{
return glm::vec3(v.getX(), v.getY(), v.getZ());
}
btVector3 convert(glm::vec3 v)
{
return btVector3(v.x, v.y, v.z);
}
btQuaternion convert(glm::quat q)
{
return btQuaternion(q.x, q.y, q.z, q.w);
}
glm::quat convert(const btQuaternion& q)
{
return glm::quat(q.getW(), q.getX(), q.getY(), q.getZ());
}
GLuint loadTexture(const char* fileName, bool alpha)
{
int width, height;
unsigned char* image;
image = SOIL_load_image(fileName, &width, &height, 0, (alpha ?
SOIL_LOAD_RGBA : SOIL_LOAD_RGB));
if (image == NULL) {
std::cout << "Unable to open texture" << std::endl;
}
GLuint textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, (alpha ? GL_RGBA : GL_RGB),
width, height, 0, (alpha ? GL_RGBA : GL_RGB), GL_UNSIGNED_BYTE, image);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glBindTexture(GL_TEXTURE_2D, 0);
SOIL_free_image_data(image);
return textureID;
}
GLfloat lerp(GLfloat a, GLfloat b, GLfloat f)
{
return a + f * (b - a);
}
//https://github.com/opengl-tutorials/ogl/blob/master/misc05_picking/misc05_picking_BulletPhysics.cpp
void ScreenPosToWorldRay(
int mouseX, int mouseY, // Mouse position, in pixels, from bottom-left corner of the window
int screenWidth, int screenHeight, // Window size, in pixels
glm::mat4 ViewMatrix, // Camera position and orientation
glm::mat4 ProjectionMatrix, // Camera parameters (ratio, field of view, near and far planes)
glm::vec3& out_origin, // Ouput : Origin of the ray. /!\ Starts at the near plane, so if you want the ray to start at the camera's position instead, ignore this.
glm::vec3& out_direction // Ouput : Direction, in world space, of the ray that goes "through" the mouse.
)
{
// The ray Start and End positions, in Normalized Device Coordinates (Have you read Tutorial 4 ?)
glm::vec4 lRayStart_NDC(
((float)mouseX / (float)screenWidth - 0.5f) * 2.0f, // [0,1024] -> [-1,1]
((float)mouseY / (float)screenHeight - 0.5f) * 2.0f, // [0, 768] -> [-1,1]
-1.0, // The near plane maps to Z=-1 in Normalized Device Coordinates
1.0f
);
glm::vec4 lRayEnd_NDC(
((float)mouseX / (float)screenWidth - 0.5f) * 2.0f,
((float)mouseY / (float)screenHeight - 0.5f) * 2.0f,
0.0,
1.0f
);
// The Projection matrix goes from Camera Space to NDC.
// So inverse(ProjectionMatrix) goes from NDC to Camera Space.
glm::mat4 InverseProjectionMatrix = glm::inverse(ProjectionMatrix);
// The View Matrix goes from World Space to Camera Space.
// So inverse(ViewMatrix) goes from Camera Space to World Space.
glm::mat4 InverseViewMatrix = glm::inverse(ViewMatrix);
glm::vec4 lRayStart_camera = InverseProjectionMatrix * lRayStart_NDC;
lRayStart_camera /= lRayStart_camera.w;
glm::vec4 lRayStart_world = InverseViewMatrix * lRayStart_camera;
lRayStart_world /= lRayStart_world.w;
glm::vec4 lRayEnd_camera = InverseProjectionMatrix * lRayEnd_NDC;
lRayEnd_camera /= lRayEnd_camera.w;
glm::vec4 lRayEnd_world = InverseViewMatrix * lRayEnd_camera;
lRayEnd_world /= lRayEnd_world.w;
// Faster way (just one inverse)
//glm::mat4 M = glm::inverse(ProjectionMatrix * ViewMatrix);
//glm::vec4 lRayStart_world = M * lRayStart_NDC;
//lRayStart_world/=lRayStart_world.w;
//glm::vec4 lRayEnd_world = M * lRayEnd_NDC ;
//lRayEnd_world /=lRayEnd_world.w;
glm::vec3 lRayDir_world(lRayEnd_world - lRayStart_world);
lRayDir_world = glm::normalize(lRayDir_world);
out_origin = glm::vec3(lRayStart_world);
out_direction = glm::normalize(lRayDir_world);
}