Archived
Added MathUtils class, reworked matrix4x4 and camera
This commit is contained in:
+183
-11
@@ -1,17 +1,189 @@
|
||||
public class Worldbuilder.Camera : Object {
|
||||
/**
|
||||
* The position of the camera
|
||||
*/
|
||||
public Vector3 position { get; set; }
|
||||
using GL;
|
||||
|
||||
namespace Worldbuilder.Core {
|
||||
|
||||
/**
|
||||
* The direction the camera is facing.
|
||||
* Encapsulates a camera object. A camera contains a projection matrix and a view matrix.
|
||||
*
|
||||
* The main purpose of this class is to provide equivalents of legacy OpenGL functions
|
||||
* removed in modern OpenGL. Advanced features like quaternion-based rotations are beyond
|
||||
* the scope of this project.
|
||||
*/
|
||||
public Vector3 direction { get; set; }
|
||||
public class Camera : Object {
|
||||
private Matrix4x4 projection_matrix;
|
||||
private Matrix4x4 view_matrix;
|
||||
private Matrix4x4 result_matrix;
|
||||
private Matrix4x4 total_matrix;
|
||||
|
||||
public Camera (Vector3 position = Vector3 (), Vector3 direction = Vector3 (0, 0, -1)) {
|
||||
this.position = position;
|
||||
this.direction = direction;
|
||||
/**
|
||||
* Instantiates a camera object.
|
||||
*
|
||||
* The projection and view matrices are set to the identity matrix.
|
||||
*/
|
||||
public Camera() {
|
||||
reset();
|
||||
}
|
||||
|
||||
private void update() {
|
||||
result_matrix = projection_matrix;
|
||||
result_matrix.multiply(view_matrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets both the projection matrix and the view matrix.
|
||||
*/
|
||||
public void reset() {
|
||||
reset_projection();
|
||||
reset_view();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the projection matrix, setting it to the identity matrix.
|
||||
*/
|
||||
public void reset_projection() {
|
||||
projection_matrix = Matrix4x4.identity();
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the view matrix, setting it to the identity matrix.
|
||||
*/
|
||||
public void reset_view() {
|
||||
view_matrix = Matrix4x4.identity();
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the camera to the next model object that will be drawn, by
|
||||
* multiplying the current projection and view matrices by the model matrix
|
||||
* passed to the function (which specifies the offset and rotation of the model
|
||||
* relative to the camera), and binds the matrix data to the specified
|
||||
* shader uniform variable.
|
||||
*
|
||||
* @param uniform_id The shader uniform variable to bind to
|
||||
* @param model_matrix The model matrix
|
||||
*/
|
||||
public void apply(int uniform_id, ref Matrix4x4 model_matrix) {
|
||||
total_matrix = result_matrix;
|
||||
total_matrix.multiply(model_matrix);
|
||||
glUniformMatrix4fv(uniform_id, 1, (GL.GLboolean)false, total_matrix.data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a perspective projection. The previous projection matrix is ignored and overwritten.
|
||||
*
|
||||
* Replicates the effects of the legacy ``glFrustum`` function within this camera.
|
||||
* Refer to that function for the complete description of the projection parameters.
|
||||
*
|
||||
* @param left The coordinate of the left vertical clipping plane.
|
||||
* @param right The coordinate of the right vertical clipping plane.
|
||||
* @param bottom The coordinate of the bottom horizontal clipping plane.
|
||||
* @param top The coordinate of the top horizontal clipping plane.
|
||||
* @param near The coordinate of the near vertical clipping plane. Must be positive.
|
||||
* @param far The coordinate of the far vertical clipping plane. Must be positive.
|
||||
*/
|
||||
public void set_frustum_projection(
|
||||
float left,
|
||||
float right,
|
||||
float bottom,
|
||||
float top,
|
||||
float near, float far
|
||||
) {
|
||||
projection_matrix = Matrix4x4.from_data(
|
||||
2f * near / (right - left), 0, (right + left) / (right - left), 0,
|
||||
0, 2f * near / (top - bottom), (top + bottom) / (top - bottom), 0,
|
||||
0, 0, -(far + near) / (far - near), -2f * far * near / (far - near),
|
||||
0, 0, -1, 0
|
||||
);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a symmetrical perspective projection. The previous projection matrix is ignored and overwritten.
|
||||
*
|
||||
* Replicates the effects of the legacy ``gluPerspective`` function within this camera.
|
||||
* Refer to that function for the complete description of the projection parameters.
|
||||
*
|
||||
* @param fovy_deg The field of view angle, in degrees, in the y direction.
|
||||
* @param aspect The aspect ratio that determines the field of view in the x direction.
|
||||
* The aspect ratio is the ratio of x (width) to y (height).
|
||||
* @param near The coordinate of the near vertical clipping plane. Must be positive.
|
||||
* @param far The coordinate of the far vertical clipping plane. Must be positive.
|
||||
*/
|
||||
public void set_perspective_projection(float fovy_deg, float aspect, float near, float far) {
|
||||
var f = 1 / Math.tanf(MathUtils.DegToRad(fovy_deg / 2));
|
||||
|
||||
projection_matrix = Matrix4x4.from_data(
|
||||
f / aspect, 0, 0, 0,
|
||||
0, f, 0, 0,
|
||||
0, 0, -(far + near) / (far - near), -2f * far * near / (far - near),
|
||||
0, 0, -1, 0
|
||||
);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up an orthogonal projection. The previous projection matrix is ignored and overwritten.
|
||||
*
|
||||
* Replicates the effects of the legacy ``glOrtho`` function within this camera.
|
||||
* Refer to that function for the complete description of the projection parameters.
|
||||
*
|
||||
* @param left The coordinate of the left vertical clipping plane.
|
||||
* @param right The coordinate of the right vertical clipping plane.
|
||||
* @param bottom The coordinate of the bottom horizontal clipping plane.
|
||||
* @param top The coordinate of the top horizontal clipping plane.
|
||||
* @param near The coordinate of the near vertical clipping plane.
|
||||
* @param far The coordinate of the far vertical clipping plane.
|
||||
*/
|
||||
public void set_ortho_projection(
|
||||
float left,
|
||||
float right,
|
||||
float bottom,
|
||||
float top,
|
||||
float near, float far
|
||||
) {
|
||||
projection_matrix = Matrix4x4.from_data(
|
||||
2f / (right - left), 0, 0, (right + left) / (right - left),
|
||||
0, 2f / (top - bottom), 0, (top + bottom) / (top - bottom),
|
||||
0, 0, -2f * far * near / (far - near), -(far + near) / (far - near),
|
||||
0, 0, 0, 1
|
||||
);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Replicates the effects of the legacy ``gluLookAt`` function within this camera.
|
||||
* Refer to that function for the complete description of how the camera is positioned.
|
||||
*
|
||||
* @param eye The 3D position of the camera
|
||||
* @param center The 3D position of the point the camera is looking at
|
||||
* @param up The up-direction
|
||||
*/
|
||||
public void look_at(ref Vector3 eye, ref Vector3 center, ref Vector3 up) {
|
||||
Vector3 l = center;
|
||||
l.subtract(eye);
|
||||
l.normalized();
|
||||
|
||||
Vector3 uptemp = up;
|
||||
uptemp.normalized();
|
||||
|
||||
Vector3 s = l.cross(uptemp);
|
||||
Vector3 u = s.cross(l);
|
||||
|
||||
view_matrix = Matrix4x4.from_data(
|
||||
s.x, s.y, s.z, 0,
|
||||
u.x, u.y, u.z, 0,
|
||||
-l.x, -l.y, -l.z, 0,
|
||||
0, 0, 0, 1
|
||||
);
|
||||
|
||||
Vector3 translation = Vector3();
|
||||
translation.subtract(eye);
|
||||
view_matrix = view_matrix.translate(translation.x, translation.y, translation.z);
|
||||
update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
namespace Worldbuilder.Core
|
||||
{
|
||||
public class MathUtils : Object
|
||||
{
|
||||
public static float DegToRad(float deg)
|
||||
{
|
||||
return deg * (float)Math.PI / 180f;
|
||||
}
|
||||
}
|
||||
}
|
||||
+28
-1
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* A 4-by-4 matrix useful in OpenGL matrix operations.
|
||||
*/
|
||||
public struct Worldbuilder.Matrix4x4
|
||||
public struct Worldbuilder.Core.Matrix4x4
|
||||
{
|
||||
public float data[4*4];
|
||||
|
||||
@@ -17,6 +17,33 @@ public struct Worldbuilder.Matrix4x4
|
||||
this (1.0f);
|
||||
}
|
||||
|
||||
public Matrix4x4.from_data(
|
||||
float a11, float a12, float a13, float a14,
|
||||
float a21, float a22, float a23, float a24,
|
||||
float a31, float a32, float a33, float a34,
|
||||
float a41, float a42, float a43, float a44)
|
||||
{
|
||||
data[0] = a11;
|
||||
data[1] = a21;
|
||||
data[2] = a31;
|
||||
data[3] = a41;
|
||||
|
||||
data[4] = a12;
|
||||
data[5] = a22;
|
||||
data[6] = a32;
|
||||
data[7] = a42;
|
||||
|
||||
data[8] = a13;
|
||||
data[9] = a23;
|
||||
data[10] = a33;
|
||||
data[11] = a43;
|
||||
|
||||
data[12] = a14;
|
||||
data[13] = a24;
|
||||
data[14] = a34;
|
||||
data[15] = a44;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a perspective transform.
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
public class Worldbuilder.Texture2D : Object {
|
||||
public class Worldbuilder.Core.Texture2D : Object {
|
||||
public string path { get; construct; }
|
||||
public GL.uint id { get; private set; }
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
public struct Worldbuilder.Vector2 {
|
||||
public struct Worldbuilder.Core.Vector2 {
|
||||
public float x;
|
||||
public float y;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
public struct Worldbuilder.Vector3 {
|
||||
|
||||
public struct Worldbuilder.Core.Vector3 {
|
||||
public float x;
|
||||
public float y;
|
||||
public float z;
|
||||
@@ -41,4 +42,3 @@ public struct Worldbuilder.Vector3 {
|
||||
return @"<$x,$y,$z>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ worldbuilder_sources = [
|
||||
'window.vala',
|
||||
'scene_renderer.vala',
|
||||
|
||||
'core/math.vala',
|
||||
'core/vector3.vala',
|
||||
'core/matrix4x4.vala',
|
||||
'core/vector2.vala',
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
<property name="content">
|
||||
<object class="AdwNavigationSplitView" id="split_view">
|
||||
<property name="show-content">content</property>
|
||||
<property name="sidebar">
|
||||
<object class="AdwNavigationPage">
|
||||
<property name="title" translatable="yes">Sidebar</property>
|
||||
|
||||
Reference in New Issue
Block a user