diff options
author | RĂ©mi Verschelde <remi@verschelde.fr> | 2022-08-22 19:29:21 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-22 19:29:21 +0200 |
commit | 7b4927bb5ff8440a33043cf32c1163e2fe0830d1 (patch) | |
tree | 17425564f02d69fa536a413fa51077fc16837ff2 /scene | |
parent | acd8fb7bf01973fe0981012ff6707fbaafdf6c77 (diff) | |
parent | 61522d849149fe439f4435ec901689c809fea860 (diff) |
Merge pull request #60309 from The-O-King/oct
Diffstat (limited to 'scene')
-rw-r--r-- | scene/3d/soft_dynamic_body_3d.cpp | 6 | ||||
-rw-r--r-- | scene/3d/sprite_3d.cpp | 31 | ||||
-rw-r--r-- | scene/resources/mesh.cpp | 149 |
3 files changed, 63 insertions, 123 deletions
diff --git a/scene/3d/soft_dynamic_body_3d.cpp b/scene/3d/soft_dynamic_body_3d.cpp index 15f050defb..c9eafc77e0 100644 --- a/scene/3d/soft_dynamic_body_3d.cpp +++ b/scene/3d/soft_dynamic_body_3d.cpp @@ -88,10 +88,10 @@ void SoftDynamicBodyRenderingServerHandler::set_normal(int p_vertex_id, const vo memcpy(&n, p_vector3, sizeof(Vector3)); n *= Vector3(0.5, 0.5, 0.5); n += Vector3(0.5, 0.5, 0.5); + Vector2 res = n.octahedron_encode(); uint32_t value = 0; - value |= CLAMP(int(n.x * 1023.0), 0, 1023); - value |= CLAMP(int(n.y * 1023.0), 0, 1023) << 10; - value |= CLAMP(int(n.z * 1023.0), 0, 1023) << 20; + value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535); + value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16; memcpy(&write_buffer[p_vertex_id * stride + offset_normal], &value, sizeof(uint32_t)); } diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index ef2b9e1ce5..42ed502e18 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -562,23 +562,21 @@ void Sprite3D::_draw() { { Vector3 n = normal * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5); + Vector2 res = n.octahedron_encode(); uint32_t value = 0; - value |= CLAMP(int(n.x * 1023.0), 0, 1023); - value |= CLAMP(int(n.y * 1023.0), 0, 1023) << 10; - value |= CLAMP(int(n.z * 1023.0), 0, 1023) << 20; + value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535); + value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16; v_normal = value; } uint32_t v_tangent; { Plane t = tangent; + Vector2 res = t.normal.octahedron_tangent_encode(t.d); uint32_t value = 0; - value |= CLAMP(int((t.normal.x * 0.5 + 0.5) * 1023.0), 0, 1023); - value |= CLAMP(int((t.normal.y * 0.5 + 0.5) * 1023.0), 0, 1023) << 10; - value |= CLAMP(int((t.normal.z * 0.5 + 0.5) * 1023.0), 0, 1023) << 20; - if (t.d > 0) { - value |= 3UL << 30; - } + value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535); + value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16; + v_tangent = value; } @@ -929,23 +927,20 @@ void AnimatedSprite3D::_draw() { { Vector3 n = normal * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5); + Vector2 res = n.octahedron_encode(); uint32_t value = 0; - value |= CLAMP(int(n.x * 1023.0), 0, 1023); - value |= CLAMP(int(n.y * 1023.0), 0, 1023) << 10; - value |= CLAMP(int(n.z * 1023.0), 0, 1023) << 20; + value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535); + value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16; v_normal = value; } uint32_t v_tangent; { Plane t = tangent; + Vector2 res = t.normal.octahedron_tangent_encode(t.d); uint32_t value = 0; - value |= CLAMP(int((t.normal.x * 0.5 + 0.5) * 1023.0), 0, 1023); - value |= CLAMP(int((t.normal.y * 0.5 + 0.5) * 1023.0), 0, 1023) << 10; - value |= CLAMP(int((t.normal.z * 0.5 + 0.5) * 1023.0), 0, 1023) << 20; - if (t.d > 0) { - value |= 3UL << 30; - } + value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535); + value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16; v_tangent = value; } diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 89ffa37067..1f75d4a323 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -865,27 +865,6 @@ static Mesh::PrimitiveType _old_primitives[7] = { }; #endif // DISABLE_DEPRECATED -// Convert Octahedron-mapped normalized vector back to Cartesian -// Assumes normalized format (elements of v within range [-1, 1]) -Vector3 _oct_to_norm(const Vector2 v) { - Vector3 res(v.x, v.y, 1 - (Math::absf(v.x) + Math::absf(v.y))); - float t = MAX(-res.z, 0.0f); - res.x += t * -SIGN(res.x); - res.y += t * -SIGN(res.y); - return res.normalized(); -} - -// Convert Octahedron-mapped normalized tangent vector back to Cartesian -// out_sign provides the direction for the original cartesian tangent -// Assumes normalized format (elements of v within range [-1, 1]) -Vector3 _oct_to_tangent(const Vector2 v, float *out_sign) { - Vector2 v_decompressed = v; - v_decompressed.y = Math::absf(v_decompressed.y) * 2 - 1; - Vector3 res = _oct_to_norm(v_decompressed); - *out_sign = SIGN(v[1]); - return res; -} - void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_old_format, uint32_t p_new_format, uint32_t p_elements, Vector<uint8_t> &vertex_data, Vector<uint8_t> &attribute_data, Vector<uint8_t> &skin_data) { uint32_t dst_vertex_stride; uint32_t dst_attribute_stride; @@ -956,127 +935,93 @@ void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_old_forma if ((p_old_format & OLD_ARRAY_COMPRESS_NORMAL) && (p_old_format & OLD_ARRAY_FORMAT_TANGENT) && (p_old_format & OLD_ARRAY_COMPRESS_TANGENT)) { for (uint32_t i = 0; i < p_elements; i++) { const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; - const Vector2 src_vec(src[0] / 127.0f, src[1] / 127.0f); - - const Vector3 res = _oct_to_norm(src_vec) * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5); - *dst = 0; - *dst |= CLAMP(int(res.x * 1023.0f), 0, 1023); - *dst |= CLAMP(int(res.y * 1023.0f), 0, 1023) << 10; - *dst |= CLAMP(int(res.z * 1023.0f), 0, 1023) << 20; + int16_t *dst = (int16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + + dst[0] = (int16_t)CLAMP(src[0] / 127.0f * 32767, -32768, 32767); + dst[1] = (int16_t)CLAMP(src[1] / 127.0f * 32767, -32768, 32767); } - src_offset += sizeof(int8_t) * 2; + src_offset += sizeof(int16_t) * 2; } else { for (uint32_t i = 0; i < p_elements; i++) { const int16_t *src = (const int16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; - const Vector2 src_vec(src[0] / 32767.0f, src[1] / 32767.0f); - - const Vector3 res = _oct_to_norm(src_vec) * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5); - *dst = 0; - *dst |= CLAMP(int(res.x * 1023.0f), 0, 1023); - *dst |= CLAMP(int(res.y * 1023.0f), 0, 1023) << 10; - *dst |= CLAMP(int(res.z * 1023.0f), 0, 1023) << 20; + int16_t *dst = (int16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + + dst[0] = src[0]; + dst[1] = src[1]; } src_offset += sizeof(int16_t) * 2; } } else { // No Octahedral compression if (p_old_format & OLD_ARRAY_COMPRESS_NORMAL) { - const float multiplier = 1.f / 127.f * 1023.0f; - for (uint32_t i = 0; i < p_elements; i++) { const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + const Vector3 original_normal(src[0], src[1], src[2]); + Vector2 res = original_normal.octahedron_encode(); - *dst = 0; - *dst |= CLAMP(int(src[0] * multiplier), 0, 1023); - *dst |= CLAMP(int(src[1] * multiplier), 0, 1023) << 10; - *dst |= CLAMP(int(src[2] * multiplier), 0, 1023) << 20; + uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535); + dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535); } - src_offset += sizeof(uint32_t); + src_offset += sizeof(uint16_t) * 2; } else { for (uint32_t i = 0; i < p_elements; i++) { const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + const Vector3 original_normal(src[0], src[1], src[2]); + Vector2 res = original_normal.octahedron_encode(); - *dst = 0; - *dst |= CLAMP(int(src[0] * 1023.0), 0, 1023); - *dst |= CLAMP(int(src[1] * 1023.0), 0, 1023) << 10; - *dst |= CLAMP(int(src[2] * 1023.0), 0, 1023) << 20; + uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535); + dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535); } - src_offset += sizeof(float) * 3; + src_offset += sizeof(uint16_t) * 2; } } } break; case OLD_ARRAY_TANGENT: { if (p_old_format & OLD_ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) { - if (p_old_format & OLD_ARRAY_COMPRESS_TANGENT) { // int8 + if (p_old_format & OLD_ARRAY_COMPRESS_TANGENT) { // int8 SNORM -> uint16 UNORM for (uint32_t i = 0; i < p_elements; i++) { const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; - const Vector2 src_vec(src[0] / 127.0f, src[1] / 127.0f); - float out_sign; - const Vector3 res = _oct_to_tangent(src_vec, &out_sign) * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5); - - *dst = 0; - *dst |= CLAMP(int(res.x * 1023.0), 0, 1023); - *dst |= CLAMP(int(res.y * 1023.0), 0, 1023) << 10; - *dst |= CLAMP(int(res.z * 1023.0), 0, 1023) << 20; - if (out_sign > 0) { - *dst |= 3 << 30; - } + uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; + + dst[0] = (uint16_t)CLAMP((src[0] / 127.0f * .5f + .5f) * 65535, 0, 65535); + dst[1] = (uint16_t)CLAMP((src[1] / 127.0f * .5f + .5f) * 65535, 0, 65535); } - src_offset += sizeof(int8_t) * 2; - } else { // int16 + src_offset += sizeof(uint16_t) * 2; + } else { // int16 SNORM -> uint16 UNORM for (uint32_t i = 0; i < p_elements; i++) { const int16_t *src = (const int16_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; - const Vector2 src_vec(src[0] / 32767.0f, src[1] / 32767.0f); - float out_sign; - Vector3 res = _oct_to_tangent(src_vec, &out_sign) * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5); - - *dst = 0; - *dst |= CLAMP(int(res.x * 1023.0), 0, 1023); - *dst |= CLAMP(int(res.y * 1023.0), 0, 1023) << 10; - *dst |= CLAMP(int(res.z * 1023.0), 0, 1023) << 20; - if (out_sign > 0) { - *dst |= 3 << 30; - } + uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; + + dst[0] = (uint16_t)CLAMP((src[0] / 32767.0f * .5f + .5f) * 65535, 0, 65535); + dst[1] = (uint16_t)CLAMP((src[1] / 32767.0f * .5f + .5f) * 65535, 0, 65535); } - src_offset += sizeof(int16_t) * 2; + src_offset += sizeof(uint16_t) * 2; } } else { // No Octahedral compression if (p_old_format & OLD_ARRAY_COMPRESS_TANGENT) { - const float multiplier = 1.f / 127.f * 1023.0f; - for (uint32_t i = 0; i < p_elements; i++) { const int8_t *src = (const int8_t *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; - - *dst = 0; - *dst |= CLAMP(int(src[0] * multiplier), 0, 1023); - *dst |= CLAMP(int(src[1] * multiplier), 0, 1023) << 10; - *dst |= CLAMP(int(src[2] * multiplier), 0, 1023) << 20; - if (src[3] > 0) { - *dst |= 3 << 30; - } + const Vector3 original_tangent(src[0], src[1], src[2]); + Vector2 res = original_tangent.octahedron_tangent_encode(src[3]); + + uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535); + dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535); } - src_offset += sizeof(uint32_t); + src_offset += sizeof(uint16_t) * 2; } else { for (uint32_t i = 0; i < p_elements; i++) { const float *src = (const float *)&src_vertex_ptr[i * src_vertex_stride + src_offset]; - uint32_t *dst = (uint32_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_TANGENT]]; - - *dst = 0; - *dst |= CLAMP(int(src[0] * 1023.0), 0, 1023); - *dst |= CLAMP(int(src[1] * 1023.0), 0, 1023) << 10; - *dst |= CLAMP(int(src[2] * 1023.0), 0, 1023) << 20; - if (src[3] > 0) { - *dst |= 3 << 30; - } + const Vector3 original_tangent(src[0], src[1], src[2]); + Vector2 res = original_tangent.octahedron_tangent_encode(src[3]); + + uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_vertex_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; + dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535); + dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535); } - src_offset += sizeof(float) * 4; + src_offset += sizeof(uint16_t) * 2; } } } break; |