160 lines
4.3 KiB
Plaintext
160 lines
4.3 KiB
Plaintext
#version 120
|
|
|
|
/*
|
|
Copyright (C) 2020 MaxED
|
|
|
|
This file is part of TrenchBroom.
|
|
|
|
TrenchBroom is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
TrenchBroom is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
uniform mat4 ModelMatrix;
|
|
uniform mat4 ViewMatrix;
|
|
uniform vec3 CameraPosition;
|
|
uniform vec3 CameraDirection;
|
|
uniform vec3 CameraRight;
|
|
uniform vec3 CameraUp;
|
|
|
|
// see Orientation enum in EntityModel.h
|
|
uniform int Orientation;
|
|
|
|
varying vec4 worldCoordinates;
|
|
|
|
mat4 getScaleMatrix() {
|
|
float sx = length(vec3(ModelMatrix[0]));
|
|
float sy = length(vec3(ModelMatrix[1]));
|
|
float sz = length(vec3(ModelMatrix[2]));
|
|
|
|
return mat4(
|
|
vec4(sx, 0.0, 0.0, 0.0),
|
|
vec4(0.0, sy, 0.0, 0.0),
|
|
vec4(0.0, 0.0, sz, 0.0),
|
|
vec4(0.0, 0.0, 0.0, 1.0)
|
|
);
|
|
}
|
|
|
|
mat4 getViewPlaneParallelUprightModelMatrix() {
|
|
// Faces view plane, up is towards the heavens.
|
|
vec3 right = CameraRight;
|
|
vec3 up = vec3(0.0, 0.0, 1.0);
|
|
vec3 normal = normalize(cross(right, up));
|
|
|
|
return mat4(
|
|
vec4(right, 0.0),
|
|
vec4(up, 0.0),
|
|
vec4(normal, 0.0),
|
|
ModelMatrix[3]
|
|
) * getScaleMatrix();
|
|
}
|
|
|
|
mat4 getFacingUprightModelMatrix() {
|
|
// Faces camera origin, up is towards the heavens.
|
|
vec3 toCam = CameraPosition - vec3(ModelMatrix[3]);
|
|
vec3 up = vec3(0.0, 0.0, 1.0);
|
|
vec3 right = normalize(cross(up, toCam));
|
|
vec3 normal = normalize(cross(right, up));
|
|
|
|
return mat4(
|
|
vec4(right, 0.0),
|
|
vec4(up, 0.0),
|
|
vec4(normal, 0.0),
|
|
ModelMatrix[3]
|
|
) * getScaleMatrix();
|
|
}
|
|
|
|
mat4 getViewPlaneParallelModelMatrix() {
|
|
// Faces view plane, up is towards the top of the screen.
|
|
vec3 normal = -CameraDirection;
|
|
vec3 right = CameraRight;
|
|
vec3 up = CameraUp;
|
|
|
|
return mat4(
|
|
vec4(right, 0.0),
|
|
vec4(up, 0.0),
|
|
vec4(normal, 0.0),
|
|
ModelMatrix[3]
|
|
) * getScaleMatrix();
|
|
}
|
|
|
|
float extractRollAngle(mat4 rotation) {
|
|
if (abs(rotation[0][2]) != 1.0) {
|
|
float theta = -asin(rotation[0][1]);
|
|
float cosTheta = cos(theta);
|
|
return atan(rotation[1][2] / cosTheta, rotation[2][2] / cosTheta);
|
|
} else if (rotation[0][2] == -1.0) {
|
|
return atan(rotation[1][0], rotation[2][0]);
|
|
} else {
|
|
return atan(-rotation[1][0], -rotation[2][0]);
|
|
}
|
|
}
|
|
|
|
mat4 getViewPlaneParallelOrientedModelMatrix() {
|
|
// Faces view plane, but obeys roll value.
|
|
|
|
mat4 transform = mat4(
|
|
ModelMatrix[0],
|
|
ModelMatrix[1],
|
|
ModelMatrix[2],
|
|
vec4(0.0, 0.0, 0.0, 1.0)
|
|
);
|
|
|
|
// the rotated unit vectors
|
|
vec3 x = normalize((transform * vec4(1.0, 0.0, 0.0, 1.0)).xyz);
|
|
vec3 y = normalize(cross((transform * vec4(0.0, 0.0, 1.0, 1.0)).xyz, x));
|
|
vec3 z = normalize(cross(x, y));
|
|
|
|
mat4 rotation = mat4(
|
|
vec4(x, 0.0),
|
|
vec4(y, 0.0),
|
|
vec4(z, 0.0),
|
|
vec4(0.0, 0.0, 0.0, 1.0)
|
|
);
|
|
|
|
float roll = extractRollAngle(rotation);
|
|
float s = sin(roll);
|
|
float c = cos(roll);
|
|
|
|
vec3 normal = -CameraDirection;
|
|
vec3 right = CameraRight * c + CameraUp * s;
|
|
vec3 up = CameraRight * -s + CameraUp * c;
|
|
|
|
return mat4(
|
|
vec4(right, 0.0),
|
|
vec4(up, 0.0),
|
|
vec4(normal, 0.0),
|
|
ModelMatrix[3]
|
|
) * getScaleMatrix();
|
|
}
|
|
|
|
mat4 getModelMatrix() {
|
|
if (Orientation == 0) {
|
|
return getViewPlaneParallelUprightModelMatrix();
|
|
} else if (Orientation == 1) {
|
|
return getFacingUprightModelMatrix();
|
|
} else if (Orientation == 2) {
|
|
return getViewPlaneParallelModelMatrix();
|
|
} else if (Orientation == 4) {
|
|
return getViewPlaneParallelOrientedModelMatrix();
|
|
}
|
|
|
|
// Pitch yaw roll are independent of camera.
|
|
return ModelMatrix;
|
|
}
|
|
|
|
void main(void) {
|
|
gl_Position = gl_ProjectionMatrix * ViewMatrix * getModelMatrix() * gl_Vertex;
|
|
worldCoordinates = ModelMatrix * gl_Vertex;
|
|
gl_TexCoord[0] = gl_MultiTexCoord0;
|
|
}
|