Initial commit
This commit is contained in:
172
core/transform.jai
Normal file
172
core/transform.jai
Normal file
@@ -0,0 +1,172 @@
|
||||
#import "Math";
|
||||
|
||||
Transform_Identity : Transform : .{ .{0,0,0}, .{0,0,0,1}, .{1,1,1}, Matrix4_Identity, Matrix4_Identity, false };
|
||||
|
||||
Transform :: struct {
|
||||
position: Vector3;
|
||||
orientation: Quaternion;
|
||||
scale : Vector3;
|
||||
|
||||
model_matrix: Matrix4 = Matrix4_Identity; @DontSerialize
|
||||
|
||||
world_matrix: Matrix4; @DontSerialize
|
||||
|
||||
dirty: bool; @DontSerialize
|
||||
}
|
||||
|
||||
create_identity_transform :: () -> Transform {
|
||||
transform : Transform;
|
||||
|
||||
transform.position = .{};
|
||||
transform.orientation = .{0,0,0,1};
|
||||
transform.scale = .{1,1,1};
|
||||
transform.model_matrix = Matrix4_Identity;
|
||||
|
||||
update_matrix(*transform);
|
||||
|
||||
return transform;
|
||||
}
|
||||
|
||||
make_matrix :: (position: Vector3, orientation: Quaternion, scale: Vector3) -> Matrix4 {
|
||||
trans_mat := make_translation_matrix4(position);
|
||||
scale_mat := make_scale_matrix4(scale);
|
||||
rot_mat := rotation_matrix(Matrix4, orientation);
|
||||
return trans_mat * rot_mat * scale_mat;
|
||||
}
|
||||
|
||||
create_transform :: (position: Vector3, orientation: Quaternion, scale: Vector3) -> Transform {
|
||||
transform : Transform;
|
||||
|
||||
transform.position = position;
|
||||
transform.orientation = orientation;
|
||||
transform.scale = scale;
|
||||
transform.model_matrix = make_matrix(position, orientation, scale);
|
||||
|
||||
return transform;
|
||||
}
|
||||
|
||||
update_matrix :: (transform: *Transform) {
|
||||
transform.model_matrix = make_matrix(transform.position, transform.orientation, transform.scale);
|
||||
transform.dirty = true;
|
||||
}
|
||||
|
||||
set_position :: (transform: *Transform, position: Vector3, calculate_matrix: bool = true) {
|
||||
transform.position = position;
|
||||
if calculate_matrix update_matrix(transform);
|
||||
}
|
||||
|
||||
set_position :: (transform: *Transform, x: float, y: float, z: float, calculate_matrix: bool = true) {
|
||||
transform.position.x = x;
|
||||
transform.position.y = y;
|
||||
transform.position.z = z;
|
||||
if calculate_matrix update_matrix(transform);
|
||||
}
|
||||
|
||||
translate :: (transform: *Transform, translation: Vector3, calculate_matrix: bool = true) {
|
||||
transform.position += translation;
|
||||
if calculate_matrix update_matrix(transform);
|
||||
}
|
||||
|
||||
euler_to_quaternion :: (yaw: float, pitch: float, roll: float) -> Quaternion {
|
||||
cy := cos(yaw * 0.5);
|
||||
sy := sin(yaw * 0.5);
|
||||
cp := cos(pitch * 0.5);
|
||||
sp := sin(pitch * 0.5);
|
||||
cr := cos(roll * 0.5);
|
||||
sr := sin(roll * 0.5);
|
||||
|
||||
q: Quaternion;
|
||||
q.w = cr * cp * cy + sr * sp * sy;
|
||||
q.x = sr * cp * cy - cr * sp * sy;
|
||||
q.y = cr * sp * cy + sr * cp * sy;
|
||||
q.z = cr * cp * sy - sr * sp * cy;
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
sign :: (val: $T) -> T {
|
||||
if val < 0 return -1.0;
|
||||
if val > 0 return 1.0;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
quaternion_to_euler_v3 :: (q: Quaternion) -> Vector3 {
|
||||
yaw, pitch, roll := quaternion_to_euler(q);
|
||||
|
||||
v : Vector3 = ---;
|
||||
v.x = yaw;
|
||||
v.y = pitch;
|
||||
v.z = roll;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
quaternion_to_euler :: (q: Quaternion) -> yaw: float, pitch: float, roll: float {
|
||||
yaw: float;
|
||||
pitch: float;
|
||||
roll: float;
|
||||
|
||||
sinr_cosp := 2.0 * (q.w * q.x + q.y * q.z);
|
||||
cosr_cosp := 1.0 - 2.0 * (q.x * q.x + q.y * q.y);
|
||||
roll = atan2(sinr_cosp, cosr_cosp);
|
||||
|
||||
// pitch (y-axis rotation)
|
||||
sinp := 2.0 * (q.w * q.y - q.z * q.x);
|
||||
if abs(sinp) >= 1.0
|
||||
pitch = sign(sinp) * (PI / 2); // use 90 degrees if out of range
|
||||
else
|
||||
pitch = asin(sinp);
|
||||
|
||||
// yaw (z-axis rotation)
|
||||
siny_cosp := 2.0 * (q.w * q.z + q.x * q.y);
|
||||
cosy_cosp := 1.0 - 2.0 * (q.y * q.y + q.z * q.z);
|
||||
yaw = atan2(siny_cosp, cosy_cosp);
|
||||
|
||||
return yaw, pitch, roll;
|
||||
}
|
||||
|
||||
set_rotation :: (transform: *Transform, orientation: Quaternion, calculate_matrix: bool = true) {
|
||||
transform.orientation = orientation;
|
||||
if calculate_matrix update_matrix(transform);
|
||||
}
|
||||
|
||||
set_rotation :: (transform: *Transform, euler_angles: Vector3, calculate_matrix: bool = true) {
|
||||
orientation := euler_to_quaternion(degrees_to_radians(euler_angles.y), degrees_to_radians(euler_angles.x), degrees_to_radians(euler_angles.z));
|
||||
transform.orientation = orientation;
|
||||
if calculate_matrix update_matrix(transform);
|
||||
}
|
||||
|
||||
set_scale :: (transform: *Transform, scale: Vector3, calculate_matrix: bool = true) {
|
||||
transform.scale = scale;
|
||||
if calculate_matrix update_matrix(transform);
|
||||
}
|
||||
|
||||
set_scale :: (transform: *Transform, scale: float, calculate_matrix: bool = true) {
|
||||
transform.scale = .{scale, scale, scale};
|
||||
if calculate_matrix update_matrix(transform);
|
||||
}
|
||||
|
||||
get_forward :: (transform: Transform) -> Vector3 {
|
||||
v := rotation_matrix(Matrix4, transform.orientation) * Vector4.{0,0,1,0};
|
||||
return .{v.x, v.y, v.z};
|
||||
}
|
||||
|
||||
get_right :: (transform: Transform) -> Vector3 {
|
||||
v := rotation_matrix(Matrix4, transform.orientation) * Vector4.{1,0,0,0};
|
||||
return .{v.x, v.y, v.z};
|
||||
}
|
||||
|
||||
get_up :: (transform: Transform) -> Vector3 {
|
||||
v := rotation_matrix(Matrix4, transform.orientation) * Vector4.{0,1,0,0};
|
||||
return .{v.x, v.y, v.z};
|
||||
}
|
||||
|
||||
get_position :: (transform: Transform) -> Vector3 {
|
||||
return .{transform.model_matrix._14, transform.model_matrix._24, transform.model_matrix._34};
|
||||
}
|
||||
|
||||
get_rotation :: (transform: Transform) -> Vector3 {
|
||||
|
||||
return .{transform.model_matrix._14, transform.model_matrix._24, transform.model_matrix._34};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user