Archived
Added MathUtils class, reworked matrix4x4 and camera
This commit is contained in:
+185
-13
@@ -1,17 +1,189 @@
|
|||||||
public class Worldbuilder.Camera : Object {
|
using GL;
|
||||||
/**
|
|
||||||
* The position of the camera
|
|
||||||
*/
|
|
||||||
public Vector3 position { get; set; }
|
|
||||||
|
|
||||||
|
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;
|
||||||
public Camera (Vector3 position = Vector3 (), Vector3 direction = Vector3 (0, 0, -1)) {
|
private Matrix4x4 view_matrix;
|
||||||
this.position = position;
|
private Matrix4x4 result_matrix;
|
||||||
this.direction = direction;
|
private Matrix4x4 total_matrix;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* A 4-by-4 matrix useful in OpenGL matrix operations.
|
||||||
*/
|
*/
|
||||||
public struct Worldbuilder.Matrix4x4
|
public struct Worldbuilder.Core.Matrix4x4
|
||||||
{
|
{
|
||||||
public float data[4*4];
|
public float data[4*4];
|
||||||
|
|
||||||
@@ -17,6 +17,33 @@ public struct Worldbuilder.Matrix4x4
|
|||||||
this (1.0f);
|
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.
|
* 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 string path { get; construct; }
|
||||||
public GL.uint id { get; private set; }
|
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 x;
|
||||||
public float y;
|
public float y;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
public struct Worldbuilder.Vector3 {
|
|
||||||
|
public struct Worldbuilder.Core.Vector3 {
|
||||||
public float x;
|
public float x;
|
||||||
public float y;
|
public float y;
|
||||||
public float z;
|
public float z;
|
||||||
@@ -41,4 +42,3 @@ public struct Worldbuilder.Vector3 {
|
|||||||
return @"<$x,$y,$z>";
|
return @"<$x,$y,$z>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ worldbuilder_sources = [
|
|||||||
'window.vala',
|
'window.vala',
|
||||||
'scene_renderer.vala',
|
'scene_renderer.vala',
|
||||||
|
|
||||||
|
'core/math.vala',
|
||||||
'core/vector3.vala',
|
'core/vector3.vala',
|
||||||
'core/matrix4x4.vala',
|
'core/matrix4x4.vala',
|
||||||
'core/vector2.vala',
|
'core/vector2.vala',
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
<property name="content">
|
<property name="content">
|
||||||
<object class="AdwNavigationSplitView" id="split_view">
|
<object class="AdwNavigationSplitView" id="split_view">
|
||||||
<property name="show-content">content</property>
|
|
||||||
<property name="sidebar">
|
<property name="sidebar">
|
||||||
<object class="AdwNavigationPage">
|
<object class="AdwNavigationPage">
|
||||||
<property name="title" translatable="yes">Sidebar</property>
|
<property name="title" translatable="yes">Sidebar</property>
|
||||||
|
|||||||
Reference in New Issue
Block a user