diff options
author | reduz <reduzio@gmail.com> | 2022-07-20 01:11:13 +0200 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2022-07-23 14:00:01 +0200 |
commit | 455c06ecd466424cdf1b444a7c289b322390e795 (patch) | |
tree | 50c3f14dddba5e7dcd938450d360af2847be8e61 /core/io | |
parent | fe929d4787b2b11390891fb03da1dda78b18eb65 (diff) |
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
Diffstat (limited to 'core/io')
-rw-r--r-- | core/io/marshalls.cpp | 104 | ||||
-rw-r--r-- | core/io/resource_format_binary.cpp | 78 |
2 files changed, 182 insertions, 0 deletions
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 8ee19f274e..2f69c10218 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -285,6 +285,46 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } } break; + case Variant::VECTOR4: { + Vector4 val; + if (type & ENCODE_FLAG_64) { + ERR_FAIL_COND_V((size_t)len < sizeof(double) * 4, ERR_INVALID_DATA); + val.x = decode_double(&buf[0]); + val.y = decode_double(&buf[sizeof(double)]); + val.z = decode_double(&buf[sizeof(double) * 2]); + val.w = decode_double(&buf[sizeof(double) * 3]); + + if (r_len) { + (*r_len) += sizeof(double) * 4; + } + } else { + ERR_FAIL_COND_V((size_t)len < sizeof(float) * 4, ERR_INVALID_DATA); + val.x = decode_float(&buf[0]); + val.y = decode_float(&buf[sizeof(float)]); + val.z = decode_float(&buf[sizeof(float) * 2]); + val.w = decode_float(&buf[sizeof(float) * 3]); + + if (r_len) { + (*r_len) += sizeof(float) * 4; + } + } + r_variant = val; + + } break; + case Variant::VECTOR4I: { + ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA); + Vector4i val; + val.x = decode_uint32(&buf[0]); + val.y = decode_uint32(&buf[4]); + val.z = decode_uint32(&buf[8]); + val.w = decode_uint32(&buf[12]); + r_variant = val; + + if (r_len) { + (*r_len) += 4 * 4; + } + + } break; case Variant::TRANSFORM2D: { Transform2D val; if (type & ENCODE_FLAG_64) { @@ -457,6 +497,33 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int r_variant = val; } break; + case Variant::PROJECTION: { + Projection val; + if (type & ENCODE_FLAG_64) { + ERR_FAIL_COND_V((size_t)len < sizeof(double) * 16, ERR_INVALID_DATA); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + val.matrix[i][j] = decode_double(&buf[(i * 4 + j) * sizeof(double)]); + } + } + if (r_len) { + (*r_len) += sizeof(double) * 16; + } + } else { + ERR_FAIL_COND_V((size_t)len < sizeof(float) * 62, ERR_INVALID_DATA); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + val.matrix[i][j] = decode_float(&buf[(i * 4 + j) * sizeof(float)]); + } + } + + if (r_len) { + (*r_len) += sizeof(float) * 16; + } + } + r_variant = val; + + } break; // misc types case Variant::COLOR: { ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA); @@ -1286,6 +1353,30 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 6 * sizeof(real_t); } break; + case Variant::VECTOR4: { + if (buf) { + Vector4 v4 = p_variant; + encode_real(v4.x, &buf[0]); + encode_real(v4.y, &buf[sizeof(real_t)]); + encode_real(v4.z, &buf[sizeof(real_t) * 2]); + encode_real(v4.w, &buf[sizeof(real_t) * 3]); + } + + r_len += 4 * sizeof(real_t); + + } break; + case Variant::VECTOR4I: { + if (buf) { + Vector4i v4 = p_variant; + encode_uint32(v4.x, &buf[0]); + encode_uint32(v4.y, &buf[4]); + encode_uint32(v4.z, &buf[8]); + encode_uint32(v4.w, &buf[12]); + } + + r_len += 4 * 4; + + } break; case Variant::PLANE: { if (buf) { Plane p = p_variant; @@ -1354,6 +1445,19 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 12 * sizeof(real_t); } break; + case Variant::PROJECTION: { + if (buf) { + Projection val = p_variant; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + memcpy(&buf[(i * 4 + j) * sizeof(real_t)], &val.matrix[i][j], sizeof(real_t)); + } + } + } + + r_len += 16 * sizeof(real_t); + + } break; // misc types case Variant::COLOR: { diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 0f4bc1e19c..016302c653 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -81,6 +81,9 @@ enum { VARIANT_VECTOR3I = 47, VARIANT_PACKED_INT64_ARRAY = 48, VARIANT_PACKED_FLOAT64_ARRAY = 49, + VARIANT_VECTOR4 = 50, + VARIANT_VECTOR4I = 51, + VARIANT_PROJECTION = 52, OBJECT_EMPTY = 0, OBJECT_EXTERNAL_RESOURCE = 1, OBJECT_INTERNAL_RESOURCE = 2, @@ -237,6 +240,22 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { v.z = f->get_32(); r_v = v; } break; + case VARIANT_VECTOR4: { + Vector4 v; + v.x = f->get_real(); + v.y = f->get_real(); + v.z = f->get_real(); + v.w = f->get_real(); + r_v = v; + } break; + case VARIANT_VECTOR4I: { + Vector4i v; + v.x = f->get_32(); + v.y = f->get_32(); + v.z = f->get_32(); + v.w = f->get_32(); + r_v = v; + } break; case VARIANT_PLANE: { Plane v; v.normal.x = f->get_real(); @@ -306,6 +325,26 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { v.origin.z = f->get_real(); r_v = v; } break; + case VARIANT_PROJECTION: { + Projection v; + v.matrix[0].x = f->get_real(); + v.matrix[0].y = f->get_real(); + v.matrix[0].z = f->get_real(); + v.matrix[0].w = f->get_real(); + v.matrix[1].x = f->get_real(); + v.matrix[1].y = f->get_real(); + v.matrix[1].z = f->get_real(); + v.matrix[1].w = f->get_real(); + v.matrix[2].x = f->get_real(); + v.matrix[2].y = f->get_real(); + v.matrix[2].z = f->get_real(); + v.matrix[2].w = f->get_real(); + v.matrix[3].x = f->get_real(); + v.matrix[3].y = f->get_real(); + v.matrix[3].z = f->get_real(); + v.matrix[3].w = f->get_real(); + r_v = v; + } break; case VARIANT_COLOR: { Color v; // Colors should always be in single-precision. v.r = f->get_float(); @@ -1499,6 +1538,24 @@ void ResourceFormatSaverBinaryInstance::write_variant(Ref<FileAccess> f, const V f->store_32(val.z); } break; + case Variant::VECTOR4: { + f->store_32(VARIANT_VECTOR4); + Vector4 val = p_property; + f->store_real(val.x); + f->store_real(val.y); + f->store_real(val.z); + f->store_real(val.w); + + } break; + case Variant::VECTOR4I: { + f->store_32(VARIANT_VECTOR4I); + Vector4i val = p_property; + f->store_32(val.x); + f->store_32(val.y); + f->store_32(val.z); + f->store_32(val.w); + + } break; case Variant::PLANE: { f->store_32(VARIANT_PLANE); Plane val = p_property; @@ -1570,6 +1627,27 @@ void ResourceFormatSaverBinaryInstance::write_variant(Ref<FileAccess> f, const V f->store_real(val.origin.z); } break; + case Variant::PROJECTION: { + f->store_32(VARIANT_PROJECTION); + Projection val = p_property; + f->store_real(val.matrix[0].x); + f->store_real(val.matrix[0].y); + f->store_real(val.matrix[0].z); + f->store_real(val.matrix[0].w); + f->store_real(val.matrix[1].x); + f->store_real(val.matrix[1].y); + f->store_real(val.matrix[1].z); + f->store_real(val.matrix[1].w); + f->store_real(val.matrix[2].x); + f->store_real(val.matrix[2].y); + f->store_real(val.matrix[2].z); + f->store_real(val.matrix[2].w); + f->store_real(val.matrix[3].x); + f->store_real(val.matrix[3].y); + f->store_real(val.matrix[3].z); + f->store_real(val.matrix[3].w); + + } break; case Variant::COLOR: { f->store_32(VARIANT_COLOR); Color val = p_property; |