Revert "BLI: Use BLI_math_matrix_type.hh instead of BLI_math_float4x4.hh"

This reverts commit 52de84b0db.

had some build issues on windows i can't quickly resolve, revert for
now while we fix the problems
This commit is contained in:
Ray molenkamp 2023-02-02 11:46:23 -07:00
parent f31ad5d98b
commit b5e00a1482
104 changed files with 1287 additions and 827 deletions

View File

@ -6,7 +6,8 @@
#pragma once
#include "BLI_math_matrix.hh"
#include "BLI_float3x3.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_span.hh"
struct Depsgraph;
@ -37,7 +38,7 @@ struct GeometryDeformation {
return translation;
}
const float3x3 &deform_mat = this->deform_mats[position_i];
return math::transform_point(math::invert(deform_mat), translation);
return deform_mat.inverted() * translation;
}
};

View File

@ -13,9 +13,10 @@
#include "BLI_bounds_types.hh"
#include "BLI_cache_mutex.hh"
#include "BLI_float3x3.hh"
#include "BLI_float4x4.hh"
#include "BLI_generic_virtual_array.hh"
#include "BLI_index_mask.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_offset_indices.hh"
#include "BLI_shared_cache.hh"

View File

@ -2,7 +2,7 @@
#pragma once
#include "BLI_math_matrix_types.hh"
#include "BLI_float4x4.hh"
#include "BKE_geometry_set.hh"

View File

@ -19,7 +19,7 @@
#include <mutex>
#include "BLI_math_matrix_types.hh"
#include "BLI_float4x4.hh"
#include "BLI_vector.hh"
#include "BLI_vector_set.hh"

View File

@ -8,7 +8,7 @@
*/
#include "BLI_array.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_float4x4.hh"
#include "BLI_mesh_boolean.hh"
#include "BLI_span.hh"

View File

@ -161,7 +161,7 @@ bool BKE_volume_save(const struct Volume *volume,
* file or copy shared grids to make them writeable. */
#ifdef __cplusplus
# include "BLI_math_matrix_types.hh"
# include "BLI_float4x4.hh"
# include "BLI_math_vector_types.hh"
# include "BLI_string_ref.hh"

View File

@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_array.hh"
#include "BLI_math_matrix.hh"
#include "BLI_set.hh"
#include "BLI_task.hh"
@ -184,26 +183,25 @@ static void fill_mesh_positions(const int main_point_num,
{
if (profile_point_num == 1) {
for (const int i_ring : IndexRange(main_point_num)) {
float4x4 point_matrix = math::from_orthonormal_axes<float4x4>(
float4x4 point_matrix = float4x4::from_normalized_axis_data(
main_positions[i_ring], normals[i_ring], tangents[i_ring]);
if (!radii.is_empty()) {
point_matrix = math::scale(point_matrix, float3(radii[i_ring]));
point_matrix.apply_scale(radii[i_ring]);
}
mesh_positions[i_ring] = math::transform_point(point_matrix, profile_positions.first());
mesh_positions[i_ring] = point_matrix * profile_positions.first();
}
}
else {
for (const int i_ring : IndexRange(main_point_num)) {
float4x4 point_matrix = math::from_orthonormal_axes<float4x4>(
float4x4 point_matrix = float4x4::from_normalized_axis_data(
main_positions[i_ring], normals[i_ring], tangents[i_ring]);
if (!radii.is_empty()) {
point_matrix = math::scale(point_matrix, float3(radii[i_ring]));
point_matrix.apply_scale(radii[i_ring]);
}
const int ring_vert_start = i_ring * profile_point_num;
for (const int i_profile : IndexRange(profile_point_num)) {
mesh_positions[ring_vert_start + i_profile] = math::transform_point(
point_matrix, profile_positions[i_profile]);
mesh_positions[ring_vert_start + i_profile] = point_matrix * profile_positions[i_profile];
}
}
}

View File

@ -17,7 +17,7 @@
#include "BLI_index_range.hh"
#include "BLI_listbase.h"
#include "BLI_math_base.h"
#include "BLI_math_matrix.hh"
#include "BLI_math_vector.hh"
#include "BLI_rand.hh"
#include "BLI_span.hh"
#include "BLI_string.h"
@ -411,15 +411,15 @@ void curves_copy_parameters(const Curves &src, Curves &dst)
CurvesSurfaceTransforms::CurvesSurfaceTransforms(const Object &curves_ob, const Object *surface_ob)
{
this->curves_to_world = float4x4_view(curves_ob.object_to_world);
this->world_to_curves = math::invert(this->curves_to_world);
this->curves_to_world = curves_ob.object_to_world;
this->world_to_curves = this->curves_to_world.inverted();
if (surface_ob != nullptr) {
this->surface_to_world = float4x4_view(surface_ob->object_to_world);
this->world_to_surface = math::invert(this->surface_to_world);
this->surface_to_world = surface_ob->object_to_world;
this->world_to_surface = this->surface_to_world.inverted();
this->surface_to_curves = this->world_to_curves * this->surface_to_world;
this->curves_to_surface = this->world_to_surface * this->curves_to_world;
this->surface_to_curves_normal = math::transpose(math::invert(this->surface_to_curves));
this->surface_to_curves_normal = this->surface_to_curves.inverted().transposed();
}
}

View File

@ -13,7 +13,6 @@
#include "BLI_bounds.hh"
#include "BLI_index_mask_ops.hh"
#include "BLI_length_parameterize.hh"
#include "BLI_math_matrix.hh"
#include "BLI_math_rotation_legacy.hh"
#include "BLI_task.hh"
@ -988,7 +987,7 @@ static void transform_positions(MutableSpan<float3> positions, const float4x4 &m
{
threading::parallel_for(positions.index_range(), 1024, [&](const IndexRange range) {
for (float3 &position : positions.slice(range)) {
position = math::transform_point(matrix, position);
position = matrix * position;
}
});
}

View File

@ -2,9 +2,9 @@
#include <mutex>
#include "BLI_float4x4.hh"
#include "BLI_index_mask.hh"
#include "BLI_map.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_rand.hh"
#include "BLI_set.hh"
#include "BLI_span.hh"
@ -117,12 +117,12 @@ namespace blender::bke {
static float3 get_transform_position(const float4x4 &transform)
{
return transform.location();
return transform.translation();
}
static void set_transform_position(float4x4 &transform, const float3 position)
{
transform.location() = position;
copy_v3_v3(transform.values[3], position);
}
class InstancePositionAttributeProvider final : public BuiltinAttributeProvider {

View File

@ -78,7 +78,7 @@ static void geometry_set_collect_recursive_collection_instance(
const Collection &collection, const float4x4 &transform, Vector<GeometryInstanceGroup> &r_sets)
{
float4x4 offset_matrix = float4x4::identity();
offset_matrix.location() -= float3(collection.instance_offset);
sub_v3_v3(offset_matrix.values[3], collection.instance_offset);
const float4x4 instance_transform = transform * offset_matrix;
geometry_set_collect_recursive_collection(collection, instance_transform, r_sets);
}
@ -98,7 +98,7 @@ static void geometry_set_collect_recursive_collection(const Collection &collecti
LISTBASE_FOREACH (const CollectionObject *, collection_object, &collection.gobject) {
BLI_assert(collection_object->ob != nullptr);
const Object &object = *collection_object->ob;
const float4x4 object_transform = transform * float4x4_view(object.object_to_world);
const float4x4 object_transform = transform * object.object_to_world;
geometry_set_collect_recursive_object(object, object_transform, r_sets);
}
LISTBASE_FOREACH (const CollectionChild *, collection_child, &collection.children) {
@ -220,9 +220,9 @@ void Instances::ensure_geometry_instances()
Collection &collection = reference.collection();
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (&collection, object) {
const int handle = instances->add_reference(*object);
instances->add_instance(handle, float4x4(object->object_to_world));
instances->add_instance(handle, object->object_to_world);
float4x4 &transform = instances->transforms().last();
transform.location() -= collection.instance_offset;
sub_v3_v3(transform.values[3], collection.instance_offset);
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
instances->ensure_geometry_instances();

View File

@ -17,8 +17,9 @@
#include "BLI_alloca.h"
#include "BLI_array.hh"
#include "BLI_float4x4.hh"
#include "BLI_math.h"
#include "BLI_math_matrix.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_mesh_boolean.hh"
#include "BLI_mesh_intersect.hh"
#include "BLI_span.hh"
@ -44,7 +45,7 @@ static float4x4 clean_transform(const float4x4 &mat)
const float fuzz = 1e-6f;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
float f = mat[i][j];
float f = mat.values[i][j];
if (fabsf(f) <= fuzz) {
f = 0.0f;
}
@ -54,7 +55,7 @@ static float4x4 clean_transform(const float4x4 &mat)
else if (fabsf(f + 1.0f) <= fuzz) {
f = -1.0f;
}
cleaned[i][j] = f;
cleaned.values[i][j] = f;
}
}
return cleaned;
@ -280,7 +281,7 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
* of the target, multiply each transform by the inverse of the
* target matrix. Exact Boolean works better if these matrices are 'cleaned'
* -- see the comment for the `clean_transform` function, above. */
const float4x4 inv_target_mat = math::invert(clean_transform(target_transform));
const float4x4 inv_target_mat = clean_transform(target_transform).inverted();
/* For each input `Mesh`, make `Vert`s and `Face`s for the corresponding
* vertices and `MPoly`s, and keep track of the original indices (using the
@ -297,7 +298,7 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
const float4x4 objn_mat = (obmats[mi] == nullptr) ? float4x4::identity() :
clean_transform(*obmats[mi]);
r_info->to_target_transform[mi] = inv_target_mat * objn_mat;
r_info->has_negative_transform[mi] = math::is_negative(objn_mat);
r_info->has_negative_transform[mi] = objn_mat.is_negative();
/* All meshes 1 and up will be transformed into the local space of operand 0.
* Historical behavior of the modifier has been to flip the faces of any meshes
@ -326,7 +327,7 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
else {
threading::parallel_for(vert_positions.index_range(), 2048, [&](IndexRange range) {
for (int i : range) {
float3 co = math::transform_point(r_info->to_target_transform[mi], vert_positions[i]);
float3 co = r_info->to_target_transform[mi] * vert_positions[i];
mpq3 mco = mpq3(co.x, co.y, co.z);
double3 dco(mco[0].get_d(), mco[1].get_d(), mco[2].get_d());
verts[i] = new Vert(mco, dco, NO_INDEX, i);
@ -564,8 +565,8 @@ static void get_poly2d_cos(const Mesh *me,
axis_dominant_v3_to_m3(r_axis_mat, axis_dominant);
for (const int i : poly_loops.index_range()) {
float3 co = positions[poly_loops[i].v];
co = math::transform_point(trans_mat, co);
*reinterpret_cast<float2 *>(&cos_2d[i]) = (float3x3(r_axis_mat) * co).xy();
co = trans_mat * co;
mul_v2_m3v3(cos_2d[i], r_axis_mat, co);
}
}

View File

@ -15,9 +15,9 @@
#include "BLI_string_utf8.h"
#include "BLI_array.hh"
#include "BLI_float4x4.hh"
#include "BLI_math.h"
#include "BLI_math_matrix.hh"
#include "BLI_math_vector.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_rand.h"
#include "BLI_span.hh"
#include "BLI_vector.hh"
@ -956,11 +956,11 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx,
case InstanceReference::Type::Object: {
Object &object = reference.object();
float matrix[4][4];
mul_m4_m4m4(matrix, parent_transform, instance_offset_matrices[i].ptr());
mul_m4_m4m4(matrix, parent_transform, instance_offset_matrices[i].values);
make_dupli(ctx_for_instance, &object, matrix, id, &geometry_set, i);
float space_matrix[4][4];
mul_m4_m4m4(space_matrix, instance_offset_matrices[i].ptr(), object.world_to_object);
mul_m4_m4m4(space_matrix, instance_offset_matrices[i].values, object.world_to_object);
mul_m4_m4_pre(space_matrix, parent_transform);
make_recursive_duplis(ctx_for_instance, &object, space_matrix, id, &geometry_set, i);
break;
@ -970,7 +970,7 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx,
float collection_matrix[4][4];
unit_m4(collection_matrix);
sub_v3_v3(collection_matrix[3], collection.instance_offset);
mul_m4_m4_pre(collection_matrix, instance_offset_matrices[i].ptr());
mul_m4_m4_pre(collection_matrix, instance_offset_matrices[i].values);
mul_m4_m4_pre(collection_matrix, parent_transform);
DupliContext sub_ctx;
@ -1002,7 +1002,7 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx,
}
case InstanceReference::Type::GeometrySet: {
float new_transform[4][4];
mul_m4_m4m4(new_transform, parent_transform, instance_offset_matrices[i].ptr());
mul_m4_m4m4(new_transform, parent_transform, instance_offset_matrices[i].values);
DupliContext sub_ctx;
if (copy_dupli_context(&sub_ctx,

View File

@ -1,7 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_math_matrix.hh"
#include "pbvh_uv_islands.hh"
#include <optional>
@ -1245,14 +1243,14 @@ UVBorderCorner::UVBorderCorner(UVBorderEdge *first, UVBorderEdge *second, float
float2 UVBorderCorner::uv(float factor, float min_uv_distance)
{
using namespace blender::math;
float2 origin = first->get_uv_vertex(1)->uv;
float angle_between = angle * factor;
float desired_len = max_ff(second->length() * factor + first->length() * (1.0 - factor),
min_uv_distance);
float2 v = normalize(first->get_uv_vertex(0)->uv - origin);
float2 v = first->get_uv_vertex(0)->uv - origin;
normalize_v2(v);
float2x2 rot_mat = from_rotation<float2x2>(AngleRadian(angle_between));
float3x3 rot_mat = float3x3::from_rotation(angle_between);
float2 rotated = rot_mat * v;
float2 result = rotated * desired_len + first->get_uv_vertex(1)->uv;
return result;

View File

@ -24,9 +24,9 @@
#include "BLI_array.hh"
#include "BLI_edgehash.h"
#include "BLI_float3x3.hh"
#include "BLI_map.hh"
#include "BLI_math.h"
#include "BLI_math_matrix_types.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_rect.h"
#include "BLI_vector.hh"

View File

@ -14,11 +14,11 @@
#include "BLI_compiler_compat.h"
#include "BLI_fileops.h"
#include "BLI_float4x4.hh"
#include "BLI_ghash.h"
#include "BLI_index_range.hh"
#include "BLI_map.hh"
#include "BLI_math.h"
#include "BLI_math_matrix_types.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_path_util.h"
#include "BLI_string.h"
@ -1651,7 +1651,7 @@ openvdb::GridBase::ConstPtr BKE_volume_grid_shallow_transform(openvdb::GridBase:
const blender::float4x4 &transform)
{
openvdb::math::Transform::Ptr grid_transform = grid->transform().copy();
grid_transform->postMult(openvdb::Mat4d((float *)transform.ptr()));
grid_transform->postMult(openvdb::Mat4d((float *)transform.values));
/* Create a transformed grid. The underlying tree is shared. */
return grid->copyGridReplacingTransform(grid_transform);

View File

@ -0,0 +1,215 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include <cmath>
#include <cstdint>
#include "BLI_assert.h"
#include "BLI_math_base.h"
#include "BLI_math_matrix.h"
#include "BLI_math_vector.h"
#include "BLI_math_vector_types.hh"
namespace blender {
struct float3x3 {
/* A 3x3 matrix in column major order. */
float values[3][3];
float3x3() = default;
float3x3(const float *matrix)
{
memcpy(values, matrix, sizeof(float) * 3 * 3);
}
float3x3(const float matrix[3][3]) : float3x3(static_cast<const float *>(matrix[0]))
{
}
static float3x3 zero()
{
float3x3 result;
zero_m3(result.values);
return result;
}
static float3x3 identity()
{
float3x3 result;
unit_m3(result.values);
return result;
}
static float3x3 from_translation(const float2 translation)
{
float3x3 result = identity();
result.values[2][0] = translation.x;
result.values[2][1] = translation.y;
return result;
}
static float3x3 from_rotation(float rotation)
{
float3x3 result = zero();
const float cosine = std::cos(rotation);
const float sine = std::sin(rotation);
result.values[0][0] = cosine;
result.values[0][1] = sine;
result.values[1][0] = -sine;
result.values[1][1] = cosine;
result.values[2][2] = 1.0f;
return result;
}
static float3x3 from_scale(const float2 scale)
{
float3x3 result = zero();
result.values[0][0] = scale.x;
result.values[1][1] = scale.y;
result.values[2][2] = 1.0f;
return result;
}
static float3x3 from_translation_rotation_scale(const float2 translation,
float rotation,
const float2 scale)
{
float3x3 result;
const float cosine = std::cos(rotation);
const float sine = std::sin(rotation);
result.values[0][0] = scale.x * cosine;
result.values[0][1] = scale.x * sine;
result.values[0][2] = 0.0f;
result.values[1][0] = scale.y * -sine;
result.values[1][1] = scale.y * cosine;
result.values[1][2] = 0.0f;
result.values[2][0] = translation.x;
result.values[2][1] = translation.y;
result.values[2][2] = 1.0f;
return result;
}
static float3x3 from_normalized_axes(const float2 translation,
const float2 horizontal,
const float2 vertical)
{
BLI_ASSERT_UNIT_V2(horizontal);
BLI_ASSERT_UNIT_V2(vertical);
float3x3 result;
result.values[0][0] = horizontal.x;
result.values[0][1] = horizontal.y;
result.values[0][2] = 0.0f;
result.values[1][0] = vertical.x;
result.values[1][1] = vertical.y;
result.values[1][2] = 0.0f;
result.values[2][0] = translation.x;
result.values[2][1] = translation.y;
result.values[2][2] = 1.0f;
return result;
}
/* Construct a transformation that is pivoted around the given origin point. So for instance,
* from_origin_transformation(from_rotation(M_PI_2), float2(0.0f, 2.0f))
* will construct a transformation representing a 90 degree rotation around the point (0, 2). */
static float3x3 from_origin_transformation(const float3x3 &transformation, const float2 origin)
{
return from_translation(origin) * transformation * from_translation(-origin);
}
operator float *()
{
return &values[0][0];
}
operator const float *() const
{
return &values[0][0];
}
float *operator[](const int64_t index)
{
BLI_assert(index >= 0);
BLI_assert(index < 3);
return &values[index][0];
}
const float *operator[](const int64_t index) const
{
BLI_assert(index >= 0);
BLI_assert(index < 3);
return &values[index][0];
}
using c_style_float3x3 = float[3][3];
c_style_float3x3 &ptr()
{
return values;
}
const c_style_float3x3 &ptr() const
{
return values;
}
friend float3x3 operator*(const float3x3 &a, const float3x3 &b)
{
float3x3 result;
mul_m3_m3m3(result.values, a.values, b.values);
return result;
}
friend float3 operator*(const float3x3 &a, const float3 &b)
{
float3 result;
mul_v3_m3v3(result, a.values, b);
return result;
}
void operator*=(const float3x3 &other)
{
mul_m3_m3_post(values, other.values);
}
friend float2 operator*(const float3x3 &transformation, const float2 &vector)
{
float2 result;
mul_v2_m3v2(result, transformation.values, vector);
return result;
}
friend float2 operator*(const float3x3 &transformation, const float (*vector)[2])
{
return transformation * float2(vector);
}
float3x3 transposed() const
{
float3x3 result;
transpose_m3_m3(result.values, values);
return result;
}
float3x3 inverted() const
{
float3x3 result;
invert_m3_m3(result.values, values);
return result;
}
float2 scale_2d() const
{
float2 scale;
mat3_to_size_2d(scale, values);
return scale;
}
friend bool operator==(const float3x3 &a, const float3x3 &b)
{
return equals_m3m3(a.values, b.values);
}
};
} // namespace blender

View File

@ -0,0 +1,280 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "BLI_math_matrix.h"
#include "BLI_math_vector.h"
#include "BLI_math_vector.hh"
#include "BLI_math_vector_types.hh"
namespace blender {
struct float4x4 {
float values[4][4];
float4x4() = default;
float4x4(const float *matrix)
{
memcpy(values, matrix, sizeof(float) * 16);
}
float4x4(const float matrix[4][4]) : float4x4(static_cast<const float *>(matrix[0]))
{
}
/* Assumes an XYZ euler order. */
static float4x4 from_loc_eul_scale(const float3 location,
const float3 rotation,
const float3 scale)
{
float4x4 mat;
loc_eul_size_to_mat4(mat.values, location, rotation, scale);
return mat;
}
static float4x4 from_location(const float3 location)
{
float4x4 mat = float4x4::identity();
copy_v3_v3(mat.values[3], location);
return mat;
}
static float4x4 from_normalized_axis_data(const float3 location,
const float3 forward,
const float3 up)
{
BLI_ASSERT_UNIT_V3(forward);
BLI_ASSERT_UNIT_V3(up);
/* Negate the cross product so that the resulting matrix has determinant 1 (instead of -1).
* Without the negation, the result would be a so called improper rotation. That means it
* contains a reflection. Such an improper rotation matrix could not be converted to another
* representation of a rotation such as euler angles. */
const float3 cross = -math::cross(forward, up);
float4x4 matrix;
matrix.values[0][0] = forward.x;
matrix.values[1][0] = cross.x;
matrix.values[2][0] = up.x;
matrix.values[3][0] = location.x;
matrix.values[0][1] = forward.y;
matrix.values[1][1] = cross.y;
matrix.values[2][1] = up.y;
matrix.values[3][1] = location.y;
matrix.values[0][2] = forward.z;
matrix.values[1][2] = cross.z;
matrix.values[2][2] = up.z;
matrix.values[3][2] = location.z;
matrix.values[0][3] = 0.0f;
matrix.values[1][3] = 0.0f;
matrix.values[2][3] = 0.0f;
matrix.values[3][3] = 1.0f;
return matrix;
}
static float4x4 identity()
{
float4x4 mat;
unit_m4(mat.values);
return mat;
}
operator float *()
{
return &values[0][0];
}
operator const float *() const
{
return &values[0][0];
}
float *operator[](const int64_t index)
{
BLI_assert(index >= 0);
BLI_assert(index < 4);
return &values[index][0];
}
const float *operator[](const int64_t index) const
{
BLI_assert(index >= 0);
BLI_assert(index < 4);
return &values[index][0];
}
using c_style_float4x4 = float[4][4];
c_style_float4x4 &ptr()
{
return values;
}
const c_style_float4x4 &ptr() const
{
return values;
}
friend float4x4 operator*(const float4x4 &a, const float4x4 &b)
{
float4x4 result;
mul_m4_m4m4(result.values, a.values, b.values);
return result;
}
void operator*=(const float4x4 &other)
{
mul_m4_m4_post(values, other.values);
}
/**
* This also applies the translation on the vector. Use `m.ref_3x3() * v` if that is not
* intended.
*/
friend float3 operator*(const float4x4 &m, const float3 &v)
{
float3 result;
mul_v3_m4v3(result, m.values, v);
return result;
}
friend float3 operator*(const float4x4 &m, const float (*v)[3])
{
return m * float3(v);
}
friend bool operator==(const float4x4 &a, const float4x4 &b)
{
return equals_m4m4(a.ptr(), b.ptr());
}
friend bool operator!=(const float4x4 &a, const float4x4 &b)
{
return !(a == b);
}
float3 translation() const
{
return float3(values[3]);
}
/* Assumes XYZ rotation order. */
float3 to_euler() const
{
float3 euler;
mat4_to_eul(euler, values);
return euler;
}
float3 scale() const
{
float3 scale;
mat4_to_size(scale, values);
return scale;
}
void apply_scale(const float scale)
{
values[0][0] *= scale;
values[0][1] *= scale;
values[0][2] *= scale;
values[1][0] *= scale;
values[1][1] *= scale;
values[1][2] *= scale;
values[2][0] *= scale;
values[2][1] *= scale;
values[2][2] *= scale;
}
float4x4 inverted() const
{
float4x4 result;
invert_m4_m4(result.values, values);
return result;
}
/**
* Matrix inversion can be implemented more efficiently for affine matrices.
*/
float4x4 inverted_affine() const
{
BLI_assert(values[0][3] == 0.0f && values[1][3] == 0.0f && values[2][3] == 0.0f &&
values[3][3] == 1.0f);
return this->inverted();
}
float4x4 transposed() const
{
float4x4 result;
transpose_m4_m4(result.values, values);
return result;
}
float4x4 inverted_transposed_affine() const
{
return this->inverted_affine().transposed();
}
struct float3x3_ref {
const float4x4 &data;
friend float3 operator*(const float3x3_ref &m, const float3 &v)
{
float3 result;
mul_v3_mat3_m4v3(result, m.data.values, v);
return result;
}
};
float3x3_ref ref_3x3() const
{
return {*this};
}
static float4x4 interpolate(const float4x4 &a, const float4x4 &b, float t)
{
float result[4][4];
interp_m4_m4m4(result, a.values, b.values, t);
return result;
}
bool is_negative() const
{
return is_negative_m4(ptr());
}
uint64_t hash() const
{
uint64_t h = 435109;
for (int i = 0; i < 16; i++) {
float value = (static_cast<const float *>(values[0]))[i];
h = h * 33 + *reinterpret_cast<const uint32_t *>(&value);
}
return h;
}
friend std::ostream &operator<<(std::ostream &stream, const float4x4 &mat)
{
char fchar[16];
stream << "(\n";
for (int i = 0; i < 4; i++) {
stream << "(";
for (int j = 0; j < 4; j++) {
snprintf(fchar, sizeof(fchar), "%11.6f", mat[j][i]);
stream << fchar;
if (j != 3) {
stream << ", ";
}
}
stream << ")\n";
}
stream << ")\n";
return stream;
}
};
} // namespace blender

View File

@ -176,7 +176,7 @@ template<typename T, int Size>
/**
* Create a translation only matrix. Matrix dimensions should be at least 4 col x 3 row.
*/
template<typename MatT> [[nodiscard]] MatT from_location(const typename MatT::loc_type &location);
template<typename MatT> [[nodiscard]] MatT from_location(const typename MatT::vec3_type &location);
/**
* Create a matrix whose diagonal is defined by the given scale vector.
@ -201,14 +201,14 @@ template<typename MatT, typename RotationT, typename VectorT>
* Create a transform matrix with translation and rotation applied in this order.
*/
template<typename MatT, typename RotationT>
[[nodiscard]] MatT from_loc_rot(const typename MatT::loc_type &location,
[[nodiscard]] MatT from_loc_rot(const typename MatT::vec3_type &location,
const RotationT &rotation);
/**
* Create a transform matrix with translation, rotation and scale applied in this order.
*/
template<typename MatT, typename RotationT, int ScaleDim>
[[nodiscard]] MatT from_loc_rot_scale(const typename MatT::loc_type &location,
[[nodiscard]] MatT from_loc_rot_scale(const typename MatT::vec3_type &location,
const RotationT &rotation,
const VecBase<typename MatT::base_type, ScaleDim> &scale);
@ -229,14 +229,6 @@ template<typename MatT, typename VectorT>
const VectorT forward,
const VectorT up);
/**
* Construct a transformation that is pivoted around the given origin point. So for instance,
* from_origin_transform<MatT>(from_rotation(M_PI_2), float2(0.0f, 2.0f))
* will construct a transformation representing a 90 degree rotation around the point (0, 2).
*/
template<typename MatT, typename VectorT>
[[nodiscard]] MatT from_origin_transform(const MatT &transform, const VectorT origin);
/** \} */
/* -------------------------------------------------------------------- */
@ -267,8 +259,6 @@ template<typename T, bool Normalized = false>
*/
template<bool AllowNegativeScale = false, typename T, int NumCol, int NumRow>
[[nodiscard]] inline VecBase<T, 3> to_scale(const MatBase<T, NumCol, NumRow> &mat);
template<bool AllowNegativeScale = false, typename T>
[[nodiscard]] inline VecBase<T, 2> to_scale(const MatBase<T, 2, 2> &mat);
/**
* Decompose a matrix into location, rotation, and scale components.
@ -474,9 +464,6 @@ inline bool is_zero(const MatBase<T, NumCol, NumRow> &mat)
/* Implementation details. */
namespace detail {
template<typename T, int NumCol, int NumRow>
[[nodiscard]] MatBase<T, NumCol, NumRow> from_rotation(const AngleRadian<T> &rotation);
template<typename T, int NumCol, int NumRow>
[[nodiscard]] MatBase<T, NumCol, NumRow> from_rotation(const EulerXYZ<T> &rotation);
@ -811,7 +798,7 @@ MatBase<T, NumCol, NumRow> from_rotation(const EulerXYZ<T> &rotation)
DoublePrecision sc = si * ch;
DoublePrecision ss = si * sh;
MatT mat = MatT::identity();
MatT mat;
mat[0][0] = T(cj * ch);
mat[1][0] = T(sj * sc - cs);
mat[2][0] = T(sj * cc + ss);
@ -846,7 +833,7 @@ MatBase<T, NumCol, NumRow> from_rotation(const Quaternion<T> &rotation)
DoublePrecision qbc = q2 * q3;
DoublePrecision qcc = q3 * q3;
MatT mat = MatT::identity();
MatT mat;
mat[0][0] = T(1.0 - qbb - qcc);
mat[0][1] = T(qdc + qab);
mat[0][2] = T(-qdb + qac);
@ -890,25 +877,7 @@ MatBase<T, NumCol, NumRow> from_rotation(const AxisAngle<T> &rotation)
return mat;
}
template<typename T, int NumCol, int NumRow>
MatBase<T, NumCol, NumRow> from_rotation(const AngleRadian<T> &rotation)
{
using MatT = MatBase<T, NumCol, NumRow>;
T ci = math::cos(rotation.value);
T si = math::sin(rotation.value);
MatT mat = MatT::identity();
mat[0][0] = ci;
mat[1][0] = -si;
mat[0][1] = si;
mat[1][1] = ci;
return mat;
}
/* Using explicit template instantiations in order to reduce compilation time. */
extern template MatBase<float, 2, 2> from_rotation(const AngleRadian<float> &rotation);
extern template MatBase<float, 3, 3> from_rotation(const AngleRadian<float> &rotation);
extern template MatBase<float, 3, 3> from_rotation(const EulerXYZ<float> &rotation);
extern template MatBase<float, 4, 4> from_rotation(const EulerXYZ<float> &rotation);
extern template MatBase<float, 3, 3> from_rotation(const Quaternion<float> &rotation);
@ -971,18 +940,6 @@ template<bool AllowNegativeScale, typename T, int NumCol, int NumRow>
return result;
}
template<bool AllowNegativeScale, typename T>
[[nodiscard]] inline VecBase<T, 2> to_scale(const MatBase<T, 2, 2> &mat)
{
VecBase<T, 2> result = {length(mat.x), length(mat.y)};
if constexpr (AllowNegativeScale) {
if (UNLIKELY(is_negative(mat))) {
result = -result;
}
}
return result;
}
/* Implementation details. Use `to_euler` and `to_quaternion` instead. */
namespace detail {
@ -1025,7 +982,7 @@ inline void to_loc_rot_scale(const MatBase<T, 4, 4> &mat,
to_rot_scale<AllowNegativeScale>(MatBase<T, 3, 3>(mat), r_rotation, r_scale);
}
template<typename MatT> [[nodiscard]] MatT from_location(const typename MatT::loc_type &location)
template<typename MatT> [[nodiscard]] MatT from_location(const typename MatT::vec3_type &location)
{
MatT mat = MatT::identity();
mat.location() = location;
@ -1056,23 +1013,22 @@ template<typename MatT, typename RotationT, typename VectorT>
}
template<typename MatT, typename RotationT, int ScaleDim>
[[nodiscard]] MatT from_loc_rot_scale(const typename MatT::loc_type &location,
[[nodiscard]] MatT from_loc_rot_scale(const typename MatT::vec3_type &location,
const RotationT &rotation,
const VecBase<typename MatT::base_type, ScaleDim> &scale)
{
using MatRotT =
MatBase<typename MatT::base_type, MatT::loc_type::type_length, MatT::loc_type::type_length>;
MatT mat = MatT(from_rot_scale<MatRotT>(rotation, scale));
using Mat3x3 = MatBase<typename MatT::base_type, 3, 3>;
MatT mat = MatT(from_rot_scale<Mat3x3>(rotation, scale));
mat.location() = location;
return mat;
}
template<typename MatT, typename RotationT>
[[nodiscard]] MatT from_loc_rot(const typename MatT::loc_type &location, const RotationT &rotation)
[[nodiscard]] MatT from_loc_rot(const typename MatT::vec3_type &location,
const RotationT &rotation)
{
using MatRotT =
MatBase<typename MatT::base_type, MatT::loc_type::type_length, MatT::loc_type::type_length>;
MatT mat = MatT(from_rotation<MatRotT>(rotation));
using Mat3x3 = MatBase<typename MatT::base_type, 3, 3>;
MatT mat = MatT(from_rotation<Mat3x3>(rotation));
mat.location() = location;
return mat;
}
@ -1103,12 +1059,6 @@ template<typename MatT, typename VectorT>
return matrix;
}
template<typename MatT, typename VectorT>
[[nodiscard]] MatT from_origin_transform(const MatT &transform, const VectorT origin)
{
return from_location<MatT>(origin) * transform * from_location<MatT>(-origin);
}
template<typename T>
VecBase<T, 3> transform_point(const MatBase<T, 3, 3> &mat, const VecBase<T, 3> &point)
{

View File

@ -30,6 +30,8 @@
* defined outside of the class in the `blender::math` namespace.
*/
#define __BLI_MATH_MATRIX_TYPES_HH__
#include <array>
#include <cmath>
#include <iostream>
@ -77,7 +79,6 @@ struct alignas(Alignment) MatBase : public vec_struct_base<VecBase<T, NumRow>, N
using vec3_type = VecBase<T, 3>;
using col_type = VecBase<T, NumRow>;
using row_type = VecBase<T, NumCol>;
using loc_type = VecBase<T, (NumRow < NumCol) ? NumRow : (NumRow - 1)>;
static constexpr int min_dim = (NumRow < NumCol) ? NumRow : NumCol;
static constexpr int col_len = NumCol;
static constexpr int row_len = NumRow;
@ -257,11 +258,11 @@ struct alignas(Alignment) MatBase : public vec_struct_base<VecBase<T, NumRow>, N
return *reinterpret_cast<vec3_type *>(&(*this)[2]);
}
loc_type &location()
vec3_type &location()
{
BLI_STATIC_ASSERT(NumCol >= 3, "Wrong Matrix dimension");
BLI_STATIC_ASSERT(NumRow >= 2, "Wrong Matrix dimension");
return *reinterpret_cast<loc_type *>(&(*this)[NumCol - 1]);
BLI_STATIC_ASSERT(NumCol >= 4, "Wrong Matrix dimension");
BLI_STATIC_ASSERT(NumRow >= 3, "Wrong Matrix dimension");
return *reinterpret_cast<vec3_type *>(&(*this)[3]);
}
const vec3_type &x_axis() const
@ -285,11 +286,11 @@ struct alignas(Alignment) MatBase : public vec_struct_base<VecBase<T, NumRow>, N
return *reinterpret_cast<const vec3_type *>(&(*this)[2]);
}
const loc_type &location() const
const vec3_type &location() const
{
BLI_STATIC_ASSERT(NumCol >= 3, "Wrong Matrix dimension");
BLI_STATIC_ASSERT(NumRow >= 2, "Wrong Matrix dimension");
return *reinterpret_cast<const loc_type *>(&(*this)[NumCol - 1]);
BLI_STATIC_ASSERT(NumCol >= 4, "Wrong Matrix dimension");
BLI_STATIC_ASSERT(NumRow >= 3, "Wrong Matrix dimension");
return *reinterpret_cast<const vec3_type *>(&(*this)[3]);
}
/** Matrix operators. */
@ -480,7 +481,7 @@ struct alignas(Alignment) MatBase : public vec_struct_base<VecBase<T, NumRow>, N
{
uint64_t h = 435109;
unroll<NumCol * NumRow>([&](auto i) {
T value = (reinterpret_cast<const T *>(this))[i];
T value = (static_cast<const T *>(this))[i];
h = h * 33 + *reinterpret_cast<const as_uint_type<T> *>(&value);
});
return h;

View File

@ -24,35 +24,6 @@ namespace detail {
template<typename T> struct AxisAngle;
template<typename T> struct Quaternion;
template<typename T> struct AngleRadian {
T value;
AngleRadian() = default;
AngleRadian(const T &radian) : value(radian){};
/** Static functions. */
static AngleRadian identity()
{
return 0;
}
/** Conversions. */
explicit operator T() const
{
return value;
}
/** Operators. */
friend std::ostream &operator<<(std::ostream &stream, const AngleRadian &rot)
{
return stream << "AngleRadian(" << rot.value << ")";
}
};
template<typename T> struct EulerXYZ {
T x, y, z;
@ -263,7 +234,6 @@ template<typename U> struct AssertUnitEpsilon<detail::Quaternion<U>> {
};
/* Most common used types. */
using AngleRadian = math::detail::AngleRadian<float>;
using EulerXYZ = math::detail::EulerXYZ<float>;
using Quaternion = math::detail::Quaternion<float>;
using AxisAngle = math::detail::AxisAngle<float>;

View File

@ -218,6 +218,8 @@ set(SRC
BLI_fileops.hh
BLI_fileops_types.h
BLI_filereader.h
BLI_float3x3.hh
BLI_float4x4.hh
BLI_fnmatch.h
BLI_function_ref.hh
BLI_generic_array.hh
@ -467,6 +469,7 @@ if(WITH_GTESTS)
tests/BLI_edgehash_test.cc
tests/BLI_expr_pylike_eval_test.cc
tests/BLI_fileops_test.cc
tests/BLI_float3x3_test.cc
tests/BLI_function_ref_test.cc
tests/BLI_generic_array_test.cc
tests/BLI_generic_span_test.cc

View File

@ -3,7 +3,7 @@
#include "BLI_color.hh"
#include "BLI_cpp_type_make.hh"
#include "BLI_cpp_types_make.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_float4x4.hh"
#include "BLI_math_vector_types.hh"
namespace blender {

View File

@ -427,8 +427,6 @@ template void normalized_to_eul2(const double3x3 &mat,
template detail::Quaternion<float> normalized_to_quat_with_checks(const float3x3 &mat);
template detail::Quaternion<double> normalized_to_quat_with_checks(const double3x3 &mat);
template MatBase<float, 2, 2> from_rotation(const detail::AngleRadian<float> &rotation);
template MatBase<float, 3, 3> from_rotation(const detail::AngleRadian<float> &rotation);
template MatBase<float, 3, 3> from_rotation(const detail::EulerXYZ<float> &rotation);
template MatBase<float, 4, 4> from_rotation(const detail::EulerXYZ<float> &rotation);
template MatBase<float, 3, 3> from_rotation(const detail::Quaternion<float> &rotation);

View File

@ -0,0 +1,135 @@
/* SPDX-License-Identifier: Apache-2.0 */
#include "testing/testing.h"
#include "BLI_float3x3.hh"
#include "BLI_math_base.h"
#include "BLI_math_vector_types.hh"
namespace blender::tests {
TEST(float3x3, Identity)
{
float2 point(1.0f, 2.0f);
float3x3 transformation = float3x3::identity();
float2 result = transformation * point;
EXPECT_EQ(result, point);
}
TEST(float3x3, Translation)
{
float2 point(1.0f, 2.0f);
float3x3 transformation = float3x3::from_translation(float2(5.0f, 3.0f));
float2 result = transformation * point;
EXPECT_FLOAT_EQ(result[0], 6.0f);
EXPECT_FLOAT_EQ(result[1], 5.0f);
}
TEST(float3x3, Rotation)
{
float2 point(1.0f, 2.0f);
float3x3 transformation = float3x3::from_rotation(M_PI_2);
float2 result = transformation * point;
EXPECT_FLOAT_EQ(result[0], -2.0f);
EXPECT_FLOAT_EQ(result[1], 1.0f);
}
TEST(float3x3, Scale)
{
float2 point(1.0f, 2.0f);
float3x3 transformation = float3x3::from_scale(float2(2.0f, 3.0f));
float2 result = transformation * point;
EXPECT_FLOAT_EQ(result[0], 2.0f);
EXPECT_FLOAT_EQ(result[1], 6.0f);
}
TEST(float3x3, TranslationRotationScale)
{
float2 point(1.0f, 2.0f);
float3x3 transformation = float3x3::from_translation_rotation_scale(
float2(1.0f, 3.0f), M_PI_2, float2(2.0f, 3.0f));
float2 result = transformation * point;
EXPECT_FLOAT_EQ(result[0], -5.0f);
EXPECT_FLOAT_EQ(result[1], 5.0f);
}
TEST(float3x3, NormalizedAxes)
{
float2 point(1.0f, 2.0f);
/* The horizontal is aligned with (1, 1) and vertical is aligned with (-1, 1), in other words, a
* Pi / 4 rotation. */
float value = std::sqrt(2.0f) / 2.0f;
float3x3 transformation = float3x3::from_normalized_axes(
float2(1.0f, 3.0f), float2(value), float2(-value, value));
float2 result = transformation * point;
float3x3 expected_transformation = float3x3::from_translation_rotation_scale(
float2(1.0f, 3.0f), M_PI_4, float2(1.0f));
float2 expected = expected_transformation * point;
EXPECT_FLOAT_EQ(result[0], expected[0]);
EXPECT_FLOAT_EQ(result[1], expected[1]);
}
TEST(float3x3, PostTransformationMultiplication)
{
float2 point(1.0f, 2.0f);
float3x3 translation = float3x3::from_translation(float2(5.0f, 3.0f));
float3x3 rotation = float3x3::from_rotation(M_PI_2);
float3x3 transformation = translation * rotation;
float2 result = transformation * point;
EXPECT_FLOAT_EQ(result[0], 3.0f);
EXPECT_FLOAT_EQ(result[1], 4.0f);
}
TEST(float3x3, PreTransformationMultiplication)
{
float2 point(1.0f, 2.0f);
float3x3 translation = float3x3::from_translation(float2(5.0f, 3.0f));
float3x3 rotation = float3x3::from_rotation(M_PI_2);
float3x3 transformation = rotation * translation;
float2 result = transformation * point;
EXPECT_FLOAT_EQ(result[0], -5.0f);
EXPECT_FLOAT_EQ(result[1], 6.0f);
}
TEST(float3x3, TransformationMultiplicationAssignment)
{
float2 point(1.0f, 2.0f);
float3x3 transformation = float3x3::from_translation(float2(5.0f, 3.0f));
transformation *= float3x3::from_rotation(M_PI_2);
float2 result = transformation * point;
EXPECT_FLOAT_EQ(result[0], 3.0f);
EXPECT_FLOAT_EQ(result[1], 4.0f);
}
TEST(float3x3, Inverted)
{
float2 point(1.0f, 2.0f);
float3x3 transformation = float3x3::from_translation_rotation_scale(
float2(1.0f, 3.0f), M_PI_4, float2(1.0f));
transformation *= transformation.inverted();
float2 result = transformation * point;
EXPECT_FLOAT_EQ(result[0], 1.0f);
EXPECT_FLOAT_EQ(result[1], 2.0f);
}
TEST(float3x3, Origin)
{
float2 point(1.0f, 2.0f);
float3x3 rotation = float3x3::from_rotation(M_PI_2);
float3x3 transformation = float3x3::from_origin_transformation(rotation, float2(0.0f, 2.0f));
float2 result = transformation * point;
EXPECT_FLOAT_EQ(result[0], 0.0f);
EXPECT_FLOAT_EQ(result[1], 3.0f);
}
TEST(float3x3, GetScale2D)
{
float2 scale(2.0f, 3.0f);
float3x3 transformation = float3x3::from_scale(scale);
EXPECT_EQ(scale, transformation.scale_2d());
}
} // namespace blender::tests

View File

@ -4,7 +4,7 @@
#include <cstdint>
#include "BLI_math_matrix_types.hh"
#include "BLI_float3x3.hh"
#include "BLI_math_vector_types.hh"
namespace blender::realtime_compositor {

View File

@ -2,7 +2,7 @@
#pragma once
#include "BLI_math_matrix_types.hh"
#include "BLI_float3x3.hh"
#include "BLI_math_vector_types.hh"
#include "GPU_shader.h"

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_math_matrix_types.hh"
#include "BLI_float3x3.hh"
#include "BLI_math_vector_types.hh"
#include "COM_domain.hh"

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_math_matrix.hh"
#include "BLI_float3x3.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_utildefines.h"
#include "GPU_shader.h"
@ -37,16 +38,16 @@ void RealizeOnDomainOperation::execute()
GPU_shader_bind(shader);
/* Transform the input space into the domain space. */
const float3x3 local_transformation = math::invert(domain_.transformation) *
const float3x3 local_transformation = domain_.transformation.inverted() *
input.domain().transformation;
/* Set the origin of the transformation to be the center of the domain. */
const float3x3 transformation = math::from_origin_transform<float3x3>(
const float3x3 transformation = float3x3::from_origin_transformation(
local_transformation, float2(domain_.size) / 2.0f);
/* Invert the transformation because the shader transforms the domain coordinates instead of the
* input image itself and thus expect the inverse. */
const float3x3 inverse_transformation = math::invert(transformation);
const float3x3 inverse_transformation = transformation.inverted();
GPU_shader_uniform_mat3_as_mat4(shader, "inverse_transformation", inverse_transformation.ptr());

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_math_matrix_types.hh"
#include "BLI_float3x3.hh"
#include "BLI_math_vector_types.hh"
#include "GPU_shader.h"

View File

@ -104,10 +104,10 @@ void Camera::sync()
else {
data.viewmat = float4x4::identity();
data.viewinv = float4x4::identity();
data.winmat = math::projection::perspective(-0.1f, 0.1f, -0.1f, 0.1f, 0.1f, 1.0f);
data.wininv = math::invert(data.winmat);
perspective_m4(data.winmat.ptr(), -0.1f, 0.1f, -0.1f, 0.1f, 0.1f, 1.0f);
data.wininv = data.winmat.inverted();
data.persmat = data.winmat * data.viewmat;
data.persinv = math::invert(data.persmat);
data.persinv = data.persmat.inverted();
data.uv_scale = float2(1.0f);
data.uv_bias = float2(0.0f);
}

View File

@ -13,48 +13,38 @@ namespace blender::eevee {
class Instance;
inline float4x4 cubeface_mat(int face)
{
switch (face) {
default:
case 0:
/* Pos X */
return float4x4({0.0f, 0.0f, -1.0f, 0.0f},
{0.0f, -1.0f, 0.0f, 0.0f},
{-1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f});
case 1:
/* Neg X */
return float4x4({0.0f, 0.0f, 1.0f, 0.0f},
{0.0f, -1.0f, 0.0f, 0.0f},
{1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f});
case 2:
/* Pos Y */
return float4x4({1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, -1.0f, 0.0f},
{0.0f, 1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f});
case 3:
/* Neg Y */
return float4x4({1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 1.0f, 0.0f},
{0.0f, -1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f});
case 4:
/* Pos Z */
return float4x4({1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, -1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, -1.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f});
case 5:
/* Neg Z */
return float4x4({-1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, -1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f});
}
}
inline constexpr float cubeface_mat[6][4][4] = {
/* Pos X */
{{0.0f, 0.0f, -1.0f, 0.0f},
{0.0f, -1.0f, 0.0f, 0.0f},
{-1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f}},
/* Neg X */
{{0.0f, 0.0f, 1.0f, 0.0f},
{0.0f, -1.0f, 0.0f, 0.0f},
{1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f}},
/* Pos Y */
{{1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, -1.0f, 0.0f},
{0.0f, 1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f}},
/* Neg Y */
{{1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 1.0f, 0.0f},
{0.0f, -1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f}},
/* Pos Z */
{{1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, -1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, -1.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f}},
/* Neg Z */
{{-1.0f, 0.0f, 0.0f, 0.0f},
{0.0f, -1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 1.0f}},
};
inline void cubeface_winmat_get(float4x4 &winmat, float near, float far)
{
@ -127,11 +117,11 @@ class Camera {
}
const float3 &position() const
{
return data_.viewinv.location();
return *reinterpret_cast<const float3 *>(data_.viewinv[3]);
}
const float3 &forward() const
{
return data_.viewinv.z_axis();
return *reinterpret_cast<const float3 *>(data_.viewinv[2]);
}
};

View File

@ -27,7 +27,7 @@ void WorldPipeline::sync(GPUMaterial *gpumat)
Manager &manager = *inst_.manager;
RenderBuffers &rbufs = inst_.render_buffers;
ResourceHandle handle = manager.resource_handle(float4x4::identity());
ResourceHandle handle = manager.resource_handle(float4x4::identity().ptr());
world_ps_.init();
world_ps_.state_set(DRW_STATE_WRITE_COLOR);

View File

@ -604,10 +604,10 @@ struct LightData {
#define _spot_bias object_mat[3][3]
/** Aliases for axes. */
#ifndef USE_GPU_SHADER_CREATE_INFO
# define _right object_mat[0].xyz()
# define _up object_mat[1].xyz()
# define _back object_mat[2].xyz()
# define _position object_mat[3].xyz()
# define _right object_mat[0]
# define _up object_mat[1]
# define _back object_mat[2]
# define _position object_mat[3]
#else
# define _right object_mat[0].xyz
# define _up object_mat[1].xyz

View File

@ -106,18 +106,16 @@ bool VelocityModule::step_object_sync(Object *ob,
vel.obj.ofs[step_] = object_steps_usage[step_]++;
vel.obj.resource_id = resource_handle.resource_index();
vel.id = (ID *)ob->data;
object_steps[step_]->get_or_resize(vel.obj.ofs[step_]) = float4x4_view(ob->object_to_world);
object_steps[step_]->get_or_resize(vel.obj.ofs[step_]) = ob->object_to_world;
if (step_ == STEP_CURRENT) {
/* Replace invalid steps. Can happen if object was hidden in one of those steps. */
if (vel.obj.ofs[STEP_PREVIOUS] == -1) {
vel.obj.ofs[STEP_PREVIOUS] = object_steps_usage[STEP_PREVIOUS]++;
object_steps[STEP_PREVIOUS]->get_or_resize(vel.obj.ofs[STEP_PREVIOUS]) = float4x4_view(
ob->object_to_world);
object_steps[STEP_PREVIOUS]->get_or_resize(vel.obj.ofs[STEP_PREVIOUS]) = ob->object_to_world;
}
if (vel.obj.ofs[STEP_NEXT] == -1) {
vel.obj.ofs[STEP_NEXT] = object_steps_usage[STEP_NEXT]++;
object_steps[STEP_NEXT]->get_or_resize(vel.obj.ofs[STEP_NEXT]) = float4x4_view(
ob->object_to_world);
object_steps[STEP_NEXT]->get_or_resize(vel.obj.ofs[STEP_NEXT]) = ob->object_to_world;
}
}

View File

@ -39,7 +39,7 @@ class ShadingView {
/** Static string pointer. Used as debug name and as UUID for texture pool. */
const char *name_;
/** Matrix to apply to the viewmat. */
const float4x4 &face_matrix_;
const float (*face_matrix_)[4];
/** Raytracing persistent buffers. Only opaque and refraction can have surface tracing. */
// RaytraceBuffer rt_buffer_opaque_;
@ -65,7 +65,7 @@ class ShadingView {
bool is_enabled_ = false;
public:
ShadingView(Instance &inst, const char *name, const float4x4 &face_matrix)
ShadingView(Instance &inst, const char *name, const float (*face_matrix)[4])
: inst_(inst), name_(name), face_matrix_(face_matrix), render_view_new_(name){};
~ShadingView(){};
@ -107,12 +107,12 @@ class MainView {
public:
MainView(Instance &inst)
: shading_views_0(inst, "posX_view", cubeface_mat(0)),
shading_views_1(inst, "negX_view", cubeface_mat(1)),
shading_views_2(inst, "posY_view", cubeface_mat(2)),
shading_views_3(inst, "negY_view", cubeface_mat(3)),
shading_views_4(inst, "posZ_view", cubeface_mat(4)),
shading_views_5(inst, "negZ_view", cubeface_mat(5))
: shading_views_0(inst, "posX_view", cubeface_mat[0]),
shading_views_1(inst, "negX_view", cubeface_mat[1]),
shading_views_2(inst, "posY_view", cubeface_mat[2]),
shading_views_3(inst, "negY_view", cubeface_mat[3]),
shading_views_4(inst, "posZ_view", cubeface_mat[4]),
shading_views_5(inst, "negZ_view", cubeface_mat[5])
{
}

View File

@ -11,7 +11,7 @@
#include "IMB_imbuf_types.h"
#include "BLI_math_matrix_types.hh"
#include "BLI_float4x4.hh"
#include "BLI_math_vector_types.hh"
#include "image_batches.hh"
@ -62,9 +62,9 @@ template<size_t Divisions> class ScreenTileTextures {
{
/* determine uv_area of the region. */
Vector<TextureInfo *> unassigned_textures;
float4x4 mat = math::invert(float4x4(instance_data->ss_to_texture));
float2 region_uv_min = math::transform_point(mat, float3(0.0f, 0.0f, 0.0f)).xy();
float2 region_uv_max = math::transform_point(mat, float3(1.0f, 1.0f, 0.0f)).xy();
float4x4 mat = float4x4(instance_data->ss_to_texture).inverted();
float2 region_uv_min = float2(mat * float3(0.0f, 0.0f, 0.0f));
float2 region_uv_max = float2(mat * float3(1.0f, 1.0f, 0.0f));
float2 region_uv_span = region_uv_max - region_uv_min;
/* Calculate uv coordinates of each vert in the grid of textures. */

View File

@ -7,7 +7,7 @@
#pragma once
#include "BLI_math_matrix.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_rect.h"
#include "GPU_batch.h"
@ -75,8 +75,8 @@ struct TextureInfo {
{
float3 bottom_left_uv = float3(clipping_uv_bounds.xmin, clipping_uv_bounds.ymin, 0.0f);
float3 top_right_uv = float3(clipping_uv_bounds.xmax, clipping_uv_bounds.ymax, 0.0f);
float3 bottom_left_region = math::transform_point(uv_to_region, bottom_left_uv);
float3 top_right_region = math::transform_point(uv_to_region, top_right_uv);
float3 bottom_left_region = uv_to_region * bottom_left_uv;
float3 top_right_region = uv_to_region * top_right_uv;
BLI_rctf_init(&clipping_bounds,
bottom_left_region.x,
top_right_region.x,

View File

@ -639,7 +639,7 @@ static void workbench_render_to_image(void *vedata,
float4x4 winmat, viewmat, viewinv;
RE_GetCameraWindow(engine->re, camera_ob, winmat.ptr());
RE_GetCameraModelMatrix(engine->re, camera_ob, viewinv.ptr());
viewmat = math::invert(viewinv);
viewmat = viewinv.inverted();
DRWView *view = DRW_view_create(viewmat.ptr(), winmat.ptr(), nullptr, nullptr, nullptr);
DRW_view_default_set(view);

View File

@ -56,7 +56,7 @@ static LightData get_light_data_from_studio_solidlight(const SolidLight *sl,
{
LightData light = {};
if (sl && sl->flag) {
float3 direction = math::transform_direction(world_shading_rotation, float3(sl->vec));
float3 direction = world_shading_rotation.ref_3x3() * float3(sl->vec);
light.direction = float4(direction, 0.0f);
/* We should pre-divide the power by PI but that makes the lights really dim. */
light.specular_color = float4(float3(sl->spec), 0.0f);

View File

@ -187,7 +187,7 @@ bool ShadowPass::ShadowView::debug_object_culling(Object *ob)
float4 plane = extruded_frustum_.planes[p];
bool separating_axis = true;
for (float3 corner : _bbox->vec) {
corner = math::transform_point(float4x4(ob->object_to_world), corner);
corner = float4x4(ob->object_to_world) * corner;
float signed_distance = math::dot(corner, float3(plane)) - plane.w;
if (signed_distance <= 0) {
separating_axis = false;
@ -352,8 +352,7 @@ void ShadowPass::init(const SceneState &scene_state, SceneResources &resources)
/* Shadow direction. */
float4x4 view_matrix;
DRW_view_viewmat_get(NULL, view_matrix.ptr(), false);
resources.world_buf.shadow_direction_vs = float4(
math::transform_direction(view_matrix, direction_ws));
resources.world_buf.shadow_direction_vs = float4(view_matrix.ref_3x3() * direction_ws);
/* Clamp to avoid overshadowing and shading errors. */
float focus = clamp_f(scene.display.shadow_focus, 0.0001f, 0.99999f);

View File

@ -367,8 +367,7 @@ std::string PushConstant::serialize() const
BLI_assert_unreachable();
break;
case Type::FloatValue:
ss << float4x4(
(&float4_value)[0], (&float4_value)[1], (&float4_value)[2], (&float4_value)[3]);
ss << *reinterpret_cast<const float4x4 *>(&float4_value);
break;
case Type::FloatReference:
ss << *float4x4_ref;

View File

@ -9,7 +9,6 @@
#include "BKE_object.h"
#include "BLI_link_utils.h"
#include "BLI_math_matrix.hh"
#include "GPU_batch.h"
#include "GPU_capabilities.h"
#include "GPU_debug.h"
@ -99,7 +98,7 @@ void DebugDraw::modelmat_reset()
void DebugDraw::modelmat_set(const float modelmat[4][4])
{
model_mat_ = float4x4_view(modelmat);
model_mat_ = modelmat;
}
GPUStorageBuf *DebugDraw::gpu_draw_buf_get()
@ -138,9 +137,9 @@ void DebugDraw::draw_polygon(Span<float3> poly_verts, float4 color)
BLI_assert(!poly_verts.is_empty());
uint col = color_pack(color);
float3 v0 = math::transform_point(model_mat_, poly_verts.last());
float3 v0 = model_mat_ * poly_verts.last();
for (auto vert : poly_verts) {
float3 v1 = math::transform_point(model_mat_, vert);
float3 v1 = model_mat_ * vert;
draw_line(v0, v1, col);
v0 = v1;
}
@ -329,8 +328,8 @@ void DebugDraw::draw_line(float3 v1, float3 v2, uint color)
DebugDrawBuf &buf = cpu_draw_buf_;
uint index = buf.command.vertex_len;
if (index + 2 < DRW_DEBUG_DRAW_VERT_MAX) {
buf.verts[index + 0] = vert_pack(math::transform_point(model_mat_, v1), color);
buf.verts[index + 1] = vert_pack(math::transform_point(model_mat_, v2), color);
buf.verts[index + 0] = vert_pack(model_mat_ * v1, color);
buf.verts[index + 1] = vert_pack(model_mat_ * v2, color);
buf.command.vertex_len += 2;
}
}
@ -705,7 +704,7 @@ void DRW_debug_m4(const float m[4][4])
if (!GPU_shader_storage_buffer_objects_support()) {
return;
}
reinterpret_cast<blender::draw::DebugDraw *>(DST.debug)->draw_matrix(float4x4(m));
reinterpret_cast<blender::draw::DebugDraw *>(DST.debug)->draw_matrix(m);
}
void DRW_debug_m4_as_bbox(const float m[4][4], bool invert, const float color[4])
@ -713,9 +712,9 @@ void DRW_debug_m4_as_bbox(const float m[4][4], bool invert, const float color[4]
if (!GPU_shader_storage_buffer_objects_support()) {
return;
}
blender::float4x4 m4(m);
blender::float4x4 m4 = m;
if (invert) {
m4 = blender::math::invert(m4);
m4 = m4.inverted();
}
reinterpret_cast<blender::draw::DebugDraw *>(DST.debug)->draw_matrix_as_bbox(m4, color);
}

View File

@ -439,22 +439,15 @@ struct DRWPass {
#define MAX_CULLED_VIEWS 32
struct DRWView {
/**
* These float4x4 (as well as the ViewMatrices) have alignment requirements in C++
* (see math::MatBase) that isn't fulfilled in C. So they need to be manually aligned.
* Since the DRWView are allocated using BLI_memblock, the chunks are given to be 16 bytes
* aligned (equal to the alignment of float4x4). We then assert that the DRWView itself is 16
* bytes aligned.
*/
float4x4 persmat;
float4x4 persinv;
ViewMatrices storage;
/** Parent view if this is a sub view. NULL otherwise. */
struct DRWView *parent;
ViewMatrices storage;
float4 clip_planes[6];
float4x4 persmat;
float4x4 persinv;
/** Number of active clip planes. */
int clip_planes_len;
/** Does culling result needs to be updated. */
@ -470,8 +463,6 @@ struct DRWView {
DRWCallVisibilityFn *visibility_fn;
void *user_data;
};
/* Needed to assert that alignment is the same in C++ and C. */
BLI_STATIC_ASSERT_ALIGN(DRWView, 16);
/* ------------ Data Chunks --------------- */
/**

View File

@ -698,7 +698,7 @@ static void drw_call_obinfos_init(DRWObjectInfos *ob_infos, Object *ob)
drw_call_calc_orco(ob, ob_infos->orcotexfac);
/* Random float value. */
uint random = (DST.dupli_source) ?
DST.dupli_source->random_id :
DST.dupli_source->random_id :
/* TODO(fclem): this is rather costly to do at runtime. Maybe we can
* put it in ob->runtime and make depsgraph ensure it is up to date. */
BLI_hash_int_2d(BLI_hash_string(ob->id.name + 2), 0);
@ -2169,14 +2169,14 @@ static void draw_view_matrix_state_update(DRWView *view,
{
ViewMatrices *storage = &view->storage;
copy_m4_m4(storage->viewmat.ptr(), viewmat);
invert_m4_m4(storage->viewinv.ptr(), storage->viewmat.ptr());
copy_m4_m4(storage->viewmat.values, viewmat);
invert_m4_m4(storage->viewinv.values, storage->viewmat.values);
copy_m4_m4(storage->winmat.ptr(), winmat);
invert_m4_m4(storage->wininv.ptr(), storage->winmat.ptr());
copy_m4_m4(storage->winmat.values, winmat);
invert_m4_m4(storage->wininv.values, storage->winmat.values);
mul_m4_m4m4(view->persmat.ptr(), winmat, viewmat);
invert_m4_m4(view->persinv.ptr(), view->persmat.ptr());
mul_m4_m4m4(view->persmat.values, winmat, viewmat);
invert_m4_m4(view->persinv.values, view->persmat.values);
}
DRWView *DRW_view_create(const float viewmat[4][4],
@ -2280,7 +2280,7 @@ void DRW_view_update(DRWView *view,
invert_m4_m4(wininv, winmat);
}
else {
copy_m4_m4(wininv, view->storage.wininv.ptr());
copy_m4_m4(wininv, view->storage.wininv.values);
}
float viewinv[4][4];
@ -2289,11 +2289,11 @@ void DRW_view_update(DRWView *view,
invert_m4_m4(viewinv, viewmat);
}
else {
copy_m4_m4(viewinv, view->storage.viewinv.ptr());
copy_m4_m4(viewinv, view->storage.viewinv.values);
}
draw_frustum_boundbox_calc(viewinv, winmat, &view->frustum_corners);
draw_frustum_culling_planes_calc(view->persmat.ptr(), view->frustum_planes);
draw_frustum_culling_planes_calc(view->persmat.values, view->frustum_planes);
draw_frustum_bound_sphere_calc(
&view->frustum_corners, viewinv, winmat, wininv, &view->frustum_bsphere);
@ -2377,20 +2377,20 @@ void DRW_view_viewmat_get(const DRWView *view, float mat[4][4], bool inverse)
{
view = (view) ? view : DST.view_default;
const ViewMatrices *storage = &view->storage;
copy_m4_m4(mat, (inverse) ? storage->viewinv.ptr() : storage->viewmat.ptr());
copy_m4_m4(mat, (inverse) ? storage->viewinv.values : storage->viewmat.values);
}
void DRW_view_winmat_get(const DRWView *view, float mat[4][4], bool inverse)
{
view = (view) ? view : DST.view_default;
const ViewMatrices *storage = &view->storage;
copy_m4_m4(mat, (inverse) ? storage->wininv.ptr() : storage->winmat.ptr());
copy_m4_m4(mat, (inverse) ? storage->wininv.values : storage->winmat.values);
}
void DRW_view_persmat_get(const DRWView *view, float mat[4][4], bool inverse)
{
view = (view) ? view : DST.view_default;
copy_m4_m4(mat, (inverse) ? view->persinv.ptr() : view->persmat.ptr());
copy_m4_m4(mat, (inverse) ? view->persinv.values : view->persmat.values);
}
/** \} */

View File

@ -10,8 +10,6 @@
* Each of them are reference by resource index (#ResourceHandle).
*/
#include "BLI_math_matrix.hh"
#include "BKE_curve.h"
#include "BKE_duplilist.h"
#include "BKE_mesh.h"
@ -33,14 +31,14 @@
inline void ObjectMatrices::sync(const Object &object)
{
model.view() = blender::float4x4_view(object.object_to_world);
model_inverse.view() = blender::float4x4_view(object.world_to_object);
model = object.object_to_world;
model_inverse = object.world_to_object;
}
inline void ObjectMatrices::sync(const float4x4 &model_matrix)
{
model = model_matrix;
model_inverse = blender::math::invert(model_matrix);
model_inverse = model_matrix.inverted();
}
inline std::ostream &operator<<(std::ostream &stream, const ObjectMatrices &matrices)

View File

@ -6,7 +6,6 @@
*/
#include "BLI_math_geom.h"
#include "BLI_math_matrix.hh"
#include "GPU_compute.h"
#include "GPU_debug.h"
@ -19,9 +18,9 @@ namespace blender::draw {
void View::sync(const float4x4 &view_mat, const float4x4 &win_mat, int view_id)
{
data_[view_id].viewmat = view_mat;
data_[view_id].viewinv = math::invert(view_mat);
data_[view_id].viewinv = view_mat.inverted();
data_[view_id].winmat = win_mat;
data_[view_id].wininv = math::invert(win_mat);
data_[view_id].wininv = win_mat.inverted();
is_inverted_ = (is_negative_m4(view_mat.ptr()) == is_negative_m4(win_mat.ptr()));
@ -263,7 +262,7 @@ void View::compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, bool d
#ifdef DEBUG
if (debug_freeze) {
float4x4 persmat = data_freeze_[0].winmat * data_freeze_[0].viewmat;
drw_debug_matrix_as_bbox(math::invert(persmat), float4(0, 1, 0, 1));
drw_debug_matrix_as_bbox(persmat.inverted(), float4(0, 1, 0, 1));
}
#endif
frozen_ = debug_freeze;

View File

@ -2,8 +2,6 @@
#include "testing/testing.h"
#include "BLI_math_matrix.hh"
#include "draw_manager.hh"
#include "draw_pass.hh"
#include "draw_shader.h"
@ -267,8 +265,10 @@ static void test_draw_resource_id_gen()
Manager drw;
float4x4 obmat_1 = math::from_scale<float4x4>(float3(-0.5f));
float4x4 obmat_2 = math::from_scale<float4x4>(float3(0.5f));
float4x4 obmat_1 = float4x4::identity();
float4x4 obmat_2 = float4x4::identity();
obmat_1.apply_scale(-0.5f);
obmat_2.apply_scale(0.5f);
drw.begin_sync();
ResourceHandle handle1 = drw.resource_handle(obmat_1);
@ -339,8 +339,10 @@ static void test_draw_visibility()
Manager drw;
float4x4 obmat_1 = math::from_scale<float4x4>(float3(-0.5f));
float4x4 obmat_2 = math::from_scale<float4x4>(float3(0.5f));
float4x4 obmat_1 = float4x4::identity();
float4x4 obmat_2 = float4x4::identity();
obmat_1.apply_scale(-0.5f);
obmat_2.apply_scale(0.5f);
drw.begin_sync(); /* Default {0} always visible. */
drw.resource_handle(obmat_1); /* No bounds, always visible. */
@ -370,8 +372,10 @@ DRAW_TEST(draw_visibility)
static void test_draw_manager_sync()
{
float4x4 obmat_1 = math::from_scale<float4x4>(float3(-0.5f));
float4x4 obmat_2 = math::from_scale<float4x4>(float3(0.5f));
float4x4 obmat_1 = float4x4::identity();
float4x4 obmat_2 = float4x4::identity();
obmat_1.apply_scale(-0.5f);
obmat_2.apply_scale(0.5f);
/* TODO find a way to create a minimum object to test resource handle creation on it. */
Manager drw;

View File

@ -10,7 +10,6 @@
#include "BLI_devirtualize_parameters.hh"
#include "BLI_index_mask_ops.hh"
#include "BLI_kdtree.h"
#include "BLI_math_matrix.hh"
#include "BLI_rand.hh"
#include "BLI_utildefines.h"
#include "BLI_vector_set.hh"
@ -315,7 +314,7 @@ static void try_convert_single_object(Object &curves_ob,
const IndexRange points = points_by_curve[curve_i];
const float3 &root_pos_cu = positions_cu[points.first()];
const float3 root_pos_su = math::transform_point(transforms.curves_to_surface, root_pos_cu);
const float3 root_pos_su = transforms.curves_to_surface * root_pos_cu;
BVHTreeNearest nearest;
nearest.dist_sq = FLT_MAX;
@ -347,15 +346,15 @@ static void try_convert_single_object(Object &curves_ob,
float4x4 hair_to_surface_mat;
psys_mat_hair_to_object(
&surface_ob, &surface_me, PART_FROM_FACE, &particle, hair_to_surface_mat.ptr());
&surface_ob, &surface_me, PART_FROM_FACE, &particle, hair_to_surface_mat.values);
/* In theory, #psys_mat_hair_to_object should handle this, but it doesn't right now. */
hair_to_surface_mat.location() = root_pos_su;
const float4x4 surface_to_hair_mat = math::invert(hair_to_surface_mat);
copy_v3_v3(hair_to_surface_mat.values[3], root_pos_su);
const float4x4 surface_to_hair_mat = hair_to_surface_mat.inverted();
for (const int key_i : hair_keys.index_range()) {
const float3 &key_pos_cu = positions_cu[points[key_i]];
const float3 key_pos_su = math::transform_point(transforms.curves_to_surface, key_pos_cu);
const float3 key_pos_ha = math::transform_point(surface_to_hair_mat, key_pos_su);
const float3 key_pos_su = transforms.curves_to_surface * key_pos_cu;
const float3 key_pos_ha = surface_to_hair_mat * key_pos_su;
HairKey &key = hair_keys[key_i];
copy_v3_v3(key.co, key_pos_ha);
@ -458,8 +457,8 @@ static bke::CurvesGeometry particles_to_curves(Object &object, ParticleSystem &p
bke::CurvesGeometry curves(points_num, curves_num);
curves.offsets_for_write().copy_from(curve_offsets);
const float4x4 object_to_world_mat(object.object_to_world);
const float4x4 world_to_object_mat = math::invert(object_to_world_mat);
const float4x4 object_to_world_mat = object.object_to_world;
const float4x4 world_to_object_mat = object_to_world_mat.inverted();
MutableSpan<float3> positions = curves.positions_for_write();
const OffsetIndices points_by_curve = curves.points_by_curve();
@ -475,7 +474,7 @@ static bke::CurvesGeometry particles_to_curves(Object &object, ParticleSystem &p
const Span<ParticleCacheKey> keys{hair_cache[hair_i], points.size()};
for (const int key_i : keys.index_range()) {
const float3 key_pos_wo = keys[key_i].co;
positions[points[key_i]] = math::transform_point(world_to_object_mat, key_pos_wo);
positions[points[key_i]] = world_to_object_mat * key_pos_wo;
}
}
});
@ -594,8 +593,8 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob,
const IndexRange points = points_by_curve[curve_i];
const int first_point_i = points.first();
const float3 old_first_point_pos_cu = positions_cu[first_point_i];
const float3 old_first_point_pos_su = math::transform_point(transforms.curves_to_surface,
old_first_point_pos_cu);
const float3 old_first_point_pos_su = transforms.curves_to_surface *
old_first_point_pos_cu;
BVHTreeNearest nearest;
nearest.index = -1;
@ -611,8 +610,8 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob,
}
const float3 new_first_point_pos_su = nearest.co;
const float3 new_first_point_pos_cu = math::transform_point(transforms.surface_to_curves,
new_first_point_pos_su);
const float3 new_first_point_pos_cu = transforms.surface_to_curves *
new_first_point_pos_su;
const float3 pos_diff_cu = new_first_point_pos_cu - old_first_point_pos_cu;
for (float3 &pos_cu : positions_cu.slice(points)) {
@ -669,8 +668,8 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob,
float3 new_first_point_pos_su;
interp_v3_v3v3v3(new_first_point_pos_su, p0_su, p1_su, p2_su, bary_coords);
const float3 new_first_point_pos_cu = math::transform_point(transforms.surface_to_curves,
new_first_point_pos_su);
const float3 new_first_point_pos_cu = transforms.surface_to_curves *
new_first_point_pos_su;
const float3 pos_diff_cu = new_first_point_pos_cu - old_first_point_pos_cu;
for (float3 &pos_cu : positions_cu.slice(points)) {

View File

@ -25,7 +25,7 @@
#include "BLI_array.hh"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_math_matrix.hh"
#include "BLI_math_vector.hh"
#include "BLI_utildefines.h"
#include "BLI_vector.hh"
@ -647,7 +647,7 @@ static void transform_positions(blender::MutableSpan<blender::float3> positions,
using namespace blender;
threading::parallel_for(positions.index_range(), 1024, [&](const IndexRange range) {
for (float3 &position : positions.slice(range)) {
position = math::transform_point(matrix, position);
position = matrix * position;
}
});
}
@ -944,7 +944,7 @@ static int apply_objects_internal(bContext *C,
}
else if (ob->type == OB_CURVES) {
Curves &curves = *static_cast<Curves *>(ob->data);
curves.geometry.wrap().transform(float4x4(mat));
curves.geometry.wrap().transform(mat);
curves.geometry.wrap().calculate_bezier_auto_handles();
}
else if (ob->type == OB_POINTCLOUD) {

View File

@ -4,8 +4,8 @@
#include "curves_sculpt_intern.hh"
#include "BLI_float4x4.hh"
#include "BLI_kdtree.h"
#include "BLI_math_matrix.hh"
#include "BLI_rand.hh"
#include "BLI_vector.hh"
@ -266,17 +266,15 @@ struct AddOperationExecutor {
float3 ray_start_wo, ray_end_wo;
ED_view3d_win_to_segment_clipped(
ctx_.depsgraph, ctx_.region, ctx_.v3d, brush_pos_re_, ray_start_wo, ray_end_wo, true);
const float3 ray_start_cu = math::transform_point(transforms_.world_to_curves, ray_start_wo);
const float3 ray_end_cu = math::transform_point(transforms_.world_to_curves, ray_end_wo);
const float3 ray_start_cu = transforms_.world_to_curves * ray_start_wo;
const float3 ray_end_cu = transforms_.world_to_curves * ray_end_wo;
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
eCurvesSymmetryType(curves_id_orig_->symmetry));
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
const float4x4 transform = transforms_.curves_to_surface * brush_transform;
this->sample_in_center(r_sampled_uvs,
math::transform_point(transform, ray_start_cu),
math::transform_point(transform, ray_end_cu));
this->sample_in_center(r_sampled_uvs, transform * ray_start_cu, transform * ray_end_cu);
}
}
@ -350,12 +348,10 @@ struct AddOperationExecutor {
float3 start_wo, end_wo;
ED_view3d_win_to_segment_clipped(
ctx_.depsgraph, ctx_.region, ctx_.v3d, pos_re, start_wo, end_wo, true);
const float3 start_cu = math::transform_point(transforms_.world_to_curves, start_wo);
const float3 start_cu_tx = math::transform_point(brush_transform, start_cu);
const float3 end_cu = math::transform_point(transforms_.world_to_curves, end_wo);
const float3 end_cu_tx = math::transform_point(brush_transform, end_cu);
r_start_su = math::transform_point(transforms_.curves_to_surface, start_cu_tx);
r_end_su = math::transform_point(transforms_.curves_to_surface, end_cu_tx);
const float3 start_cu = brush_transform * (transforms_.world_to_curves * start_wo);
const float3 end_cu = brush_transform * (transforms_.world_to_curves * end_wo);
r_start_su = transforms_.curves_to_surface * start_cu;
r_end_su = transforms_.curves_to_surface * end_cu;
},
use_front_face_,
add_amount_,
@ -397,20 +393,17 @@ struct AddOperationExecutor {
view_ray_end_wo,
true);
const float3 view_ray_start_cu = math::transform_point(transforms_.world_to_curves,
view_ray_start_wo);
const float3 view_ray_end_cu = math::transform_point(transforms_.world_to_curves,
view_ray_end_wo);
const float3 view_ray_start_cu = transforms_.world_to_curves * view_ray_start_wo;
const float3 view_ray_end_cu = transforms_.world_to_curves * view_ray_end_wo;
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
eCurvesSymmetryType(curves_id_orig_->symmetry));
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
const float4x4 transform = transforms_.curves_to_surface * brush_transform;
const float3 brush_pos_su = math::transform_point(transform, brush_3d->position_cu);
const float3 view_direction_su = math::normalize(
math::transform_point(transform, view_ray_end_cu) -
math::transform_point(transform, view_ray_start_cu));
const float3 brush_pos_su = transform * brush_3d->position_cu;
const float3 view_direction_su = math::normalize(transform * view_ray_end_cu -
transform * view_ray_start_cu);
const float brush_radius_su = transform_brush_radius(
transform, brush_3d->position_cu, brush_3d->radius_cu);

View File

@ -58,10 +58,10 @@ static std::optional<float3> find_curves_brush_position(const CurvesGeometry &cu
const float brush_inner_radius_sq_re = pow2f(brush_inner_radius_re);
float4x4 projection;
ED_view3d_ob_project_mat_get(&rv3d, &object, projection.ptr());
ED_view3d_ob_project_mat_get(&rv3d, &object, projection.values);
float2 brush_pos_re;
ED_view3d_project_float_v2_m4(&region, ray_start_cu, brush_pos_re, projection.ptr());
ED_view3d_project_float_v2_m4(&region, ray_start_cu, brush_pos_re, projection.values);
const float max_depth_sq_cu = math::distance_squared(ray_start_cu, ray_end_cu);
@ -112,7 +112,7 @@ static std::optional<float3> find_curves_brush_position(const CurvesGeometry &cu
}
float2 pos_re;
ED_view3d_project_float_v2_m4(&region, pos_cu, pos_re, projection.ptr());
ED_view3d_project_float_v2_m4(&region, pos_cu, pos_re, projection.values);
BrushPositionCandidate candidate;
candidate.position_cu = pos_cu;
@ -128,8 +128,8 @@ static std::optional<float3> find_curves_brush_position(const CurvesGeometry &cu
const float3 &p2_cu = positions[segment_i + 1];
float2 p1_re, p2_re;
ED_view3d_project_float_v2_m4(&region, p1_cu, p1_re, projection.ptr());
ED_view3d_project_float_v2_m4(&region, p2_cu, p2_re, projection.ptr());
ED_view3d_project_float_v2_m4(&region, p1_cu, p1_re, projection.values);
ED_view3d_project_float_v2_m4(&region, p2_cu, p2_re, projection.values);
float2 closest_re;
const float lambda = closest_to_line_segment_v2(
@ -187,17 +187,16 @@ std::optional<CurvesBrush3D> sample_curves_3d_brush(const Depsgraph &depsgraph,
/* Shorten ray when the surface object is hit. */
if (surface_object_eval != nullptr) {
const float4x4 surface_to_world_mat(surface_object->object_to_world);
const float4x4 world_to_surface_mat = math::invert(surface_to_world_mat);
const float4x4 surface_to_world_mat = surface_object->object_to_world;
const float4x4 world_to_surface_mat = surface_to_world_mat.inverted();
Mesh *surface_eval = BKE_object_get_evaluated_mesh(surface_object_eval);
BVHTreeFromMesh surface_bvh;
BKE_bvhtree_from_mesh_get(&surface_bvh, surface_eval, BVHTREE_FROM_LOOPTRI, 2);
BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh); });
const float3 center_ray_start_su = math::transform_point(world_to_surface_mat,
center_ray_start_wo);
float3 center_ray_end_su = math::transform_point(world_to_surface_mat, center_ray_end_wo);
const float3 center_ray_start_su = world_to_surface_mat * center_ray_start_wo;
float3 center_ray_end_su = world_to_surface_mat * center_ray_end_wo;
const float3 center_ray_direction_su = math::normalize(center_ray_end_su -
center_ray_start_su);
@ -216,17 +215,16 @@ std::optional<CurvesBrush3D> sample_curves_3d_brush(const Depsgraph &depsgraph,
if (math::distance(center_ray_start_su, center_ray_end_su) >
math::distance(center_ray_start_su, hit_position_su)) {
center_ray_end_su = hit_position_su;
center_ray_end_wo = math::transform_point(surface_to_world_mat, center_ray_end_su);
center_ray_end_wo = surface_to_world_mat * center_ray_end_su;
}
}
}
const float4x4 curves_to_world_mat(curves_object.object_to_world);
const float4x4 world_to_curves_mat = math::invert(curves_to_world_mat);
const float4x4 curves_to_world_mat = curves_object.object_to_world;
const float4x4 world_to_curves_mat = curves_to_world_mat.inverted();
const float3 center_ray_start_cu = math::transform_point(world_to_curves_mat,
center_ray_start_wo);
const float3 center_ray_end_cu = math::transform_point(world_to_curves_mat, center_ray_end_wo);
const float3 center_ray_start_cu = world_to_curves_mat * center_ray_start_wo;
const float3 center_ray_end_cu = world_to_curves_mat * center_ray_end_wo;
const bke::crazyspace::GeometryDeformation deformation =
bke::crazyspace::get_evaluated_curves_deformation(depsgraph, curves_object);
@ -255,9 +253,8 @@ std::optional<CurvesBrush3D> sample_curves_3d_brush(const Depsgraph &depsgraph,
radius_ray_start_wo,
radius_ray_end_wo,
true);
const float3 radius_ray_start_cu = math::transform_point(world_to_curves_mat,
radius_ray_start_wo);
const float3 radius_ray_end_cu = math::transform_point(world_to_curves_mat, radius_ray_end_wo);
const float3 radius_ray_start_cu = world_to_curves_mat * radius_ray_start_wo;
const float3 radius_ray_end_cu = world_to_curves_mat * radius_ray_end_wo;
CurvesBrush3D brush_3d;
brush_3d.position_cu = brush_position_cu;
@ -277,10 +274,8 @@ std::optional<CurvesBrush3D> sample_curves_surface_3d_brush(
float3 brush_ray_start_wo, brush_ray_end_wo;
ED_view3d_win_to_segment_clipped(
&depsgraph, &region, &v3d, brush_pos_re, brush_ray_start_wo, brush_ray_end_wo, true);
const float3 brush_ray_start_su = math::transform_point(transforms.world_to_surface,
brush_ray_start_wo);
const float3 brush_ray_end_su = math::transform_point(transforms.world_to_surface,
brush_ray_end_wo);
const float3 brush_ray_start_su = transforms.world_to_surface * brush_ray_start_wo;
const float3 brush_ray_end_su = transforms.world_to_surface * brush_ray_end_wo;
const float3 brush_ray_direction_su = math::normalize(brush_ray_end_su - brush_ray_start_su);
@ -306,13 +301,11 @@ std::optional<CurvesBrush3D> sample_curves_surface_3d_brush(
brush_radius_ray_start_wo,
brush_radius_ray_end_wo,
true);
const float3 brush_radius_ray_start_cu = math::transform_point(transforms.world_to_curves,
brush_radius_ray_start_wo);
const float3 brush_radius_ray_end_cu = math::transform_point(transforms.world_to_curves,
brush_radius_ray_end_wo);
const float3 brush_radius_ray_start_cu = transforms.world_to_curves * brush_radius_ray_start_wo;
const float3 brush_radius_ray_end_cu = transforms.world_to_curves * brush_radius_ray_end_wo;
const float3 brush_pos_su = ray_hit.co;
const float3 brush_pos_cu = math::transform_point(transforms.surface_to_curves, brush_pos_su);
const float3 brush_pos_cu = transforms.surface_to_curves * brush_pos_su;
const float brush_radius_cu = dist_to_line_v3(
brush_pos_cu, brush_radius_ray_start_cu, brush_radius_ray_end_cu);
return CurvesBrush3D{brush_pos_cu, brush_radius_cu};
@ -335,9 +328,9 @@ Vector<float4x4> get_symmetry_brush_transforms(const eCurvesSymmetryType symmetr
for (const float y : symmetry_to_factors(CURVES_SYMMETRY_Y)) {
for (const float z : symmetry_to_factors(CURVES_SYMMETRY_Z)) {
float4x4 matrix = float4x4::identity();
matrix.ptr()[0][0] = x;
matrix.ptr()[1][1] = y;
matrix.ptr()[2][2] = z;
matrix.values[0][0] = x;
matrix.values[1][1] = y;
matrix.values[2][2] = z;
matrices.append(matrix);
}
}
@ -351,8 +344,8 @@ float transform_brush_radius(const float4x4 &transform,
const float old_radius)
{
const float3 offset_position = brush_position + float3(old_radius, 0.0f, 0.0f);
const float3 new_position = math::transform_point(transform, brush_position);
const float3 new_offset_position = math::transform_point(transform, offset_position);
const float3 new_position = transform * brush_position;
const float3 new_offset_position = transform * offset_position;
return math::distance(new_position, new_offset_position);
}

View File

@ -4,9 +4,9 @@
#include "curves_sculpt_intern.hh"
#include "BLI_float4x4.hh"
#include "BLI_index_mask_ops.hh"
#include "BLI_kdtree.h"
#include "BLI_math_matrix_types.hh"
#include "BLI_rand.hh"
#include "BLI_vector.hh"
@ -184,7 +184,7 @@ struct CombOperationExecutor {
void comb_projected(EnumerableThreadSpecific<Vector<int>> &r_changed_curves,
const float4x4 &brush_transform)
{
const float4x4 brush_transform_inv = math::invert(brush_transform);
const float4x4 brush_transform_inv = brush_transform.inverted();
MutableSpan<float3> positions_cu_orig = curves_orig_->positions_for_write();
const bke::crazyspace::GeometryDeformation deformation =
@ -192,7 +192,7 @@ struct CombOperationExecutor {
const OffsetIndices points_by_curve = curves_orig_->points_by_curve();
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, curves_ob_orig_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, curves_ob_orig_, projection.values);
const float brush_radius_re = brush_radius_base_re_ * brush_radius_factor_;
const float brush_radius_sq_re = pow2f(brush_radius_re);
@ -204,12 +204,12 @@ struct CombOperationExecutor {
const IndexRange points = points_by_curve[curve_i];
for (const int point_i : points.drop_front(1)) {
const float3 old_pos_cu = deformation.positions[point_i];
const float3 old_symm_pos_cu = math::transform_point(brush_transform_inv, old_pos_cu);
const float3 old_symm_pos_cu = brush_transform_inv * old_pos_cu;
/* Find the position of the point in screen space. */
float2 old_symm_pos_re;
ED_view3d_project_float_v2_m4(
ctx_.region, old_symm_pos_cu, old_symm_pos_re, projection.ptr());
ctx_.region, old_symm_pos_cu, old_symm_pos_re, projection.values);
const float distance_to_brush_sq_re = dist_squared_to_line_segment_v2(
old_symm_pos_re, brush_pos_prev_re_, brush_pos_re_);
@ -231,12 +231,11 @@ struct CombOperationExecutor {
float3 new_symm_pos_wo;
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
math::transform_point(transforms_.curves_to_world, old_symm_pos_cu),
transforms_.curves_to_world * old_symm_pos_cu,
new_symm_pos_re,
new_symm_pos_wo);
const float3 new_pos_cu = math::transform_point(
brush_transform,
math::transform_point(transforms_.world_to_curves, new_symm_pos_wo));
const float3 new_pos_cu = brush_transform *
(transforms_.world_to_curves * new_symm_pos_wo);
const float3 translation_eval = new_pos_cu - old_pos_cu;
const float3 translation_orig = deformation.translation_from_deformed_to_original(
@ -258,24 +257,21 @@ struct CombOperationExecutor {
void comb_spherical_with_symmetry(EnumerableThreadSpecific<Vector<int>> &r_changed_curves)
{
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, curves_ob_orig_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, curves_ob_orig_, projection.values);
float3 brush_start_wo, brush_end_wo;
ED_view3d_win_to_3d(
ctx_.v3d,
ctx_.region,
math::transform_point(transforms_.curves_to_world, self_->brush_3d_.position_cu),
brush_pos_prev_re_,
brush_start_wo);
ED_view3d_win_to_3d(
ctx_.v3d,
ctx_.region,
math::transform_point(transforms_.curves_to_world, self_->brush_3d_.position_cu),
brush_pos_re_,
brush_end_wo);
const float3 brush_start_cu = math::transform_point(transforms_.world_to_curves,
brush_start_wo);
const float3 brush_end_cu = math::transform_point(transforms_.world_to_curves, brush_end_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_prev_re_,
brush_start_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_re_,
brush_end_wo);
const float3 brush_start_cu = transforms_.world_to_curves * brush_start_wo;
const float3 brush_end_cu = transforms_.world_to_curves * brush_end_wo;
const float brush_radius_cu = self_->brush_3d_.radius_cu * brush_radius_factor_;
@ -283,8 +279,8 @@ struct CombOperationExecutor {
eCurvesSymmetryType(curves_id_orig_->symmetry));
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
this->comb_spherical(r_changed_curves,
math::transform_point(brush_transform, brush_start_cu),
math::transform_point(brush_transform, brush_end_cu),
brush_transform * brush_start_cu,
brush_transform * brush_end_cu,
brush_radius_cu);
}
}

View File

@ -4,9 +4,9 @@
#include "curves_sculpt_intern.hh"
#include "BLI_float4x4.hh"
#include "BLI_index_mask_ops.hh"
#include "BLI_kdtree.h"
#include "BLI_math_matrix_types.hh"
#include "BLI_rand.hh"
#include "BLI_vector.hh"
@ -166,10 +166,10 @@ struct DeleteOperationExecutor {
void delete_projected(const float4x4 &brush_transform, MutableSpan<bool> curves_to_delete)
{
const float4x4 brush_transform_inv = math::invert(brush_transform);
const float4x4 brush_transform_inv = brush_transform.inverted();
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values);
const float brush_radius_re = brush_radius_base_re_ * brush_radius_factor_;
const float brush_radius_sq_re = pow2f(brush_radius_re);
@ -179,10 +179,9 @@ struct DeleteOperationExecutor {
for (const int curve_i : curve_selection_.slice(range)) {
const IndexRange points = points_by_curve[curve_i];
if (points.size() == 1) {
const float3 pos_cu = math::transform_point(brush_transform_inv,
self_->deformed_positions_[points.first()]);
const float3 pos_cu = brush_transform_inv * self_->deformed_positions_[points.first()];
float2 pos_re;
ED_view3d_project_float_v2_m4(ctx_.region, pos_cu, pos_re, projection.ptr());
ED_view3d_project_float_v2_m4(ctx_.region, pos_cu, pos_re, projection.values);
if (math::distance_squared(brush_pos_re_, pos_re) <= brush_radius_sq_re) {
curves_to_delete[curve_i] = true;
@ -191,14 +190,12 @@ struct DeleteOperationExecutor {
}
for (const int segment_i : points.drop_back(1)) {
const float3 pos1_cu = math::transform_point(brush_transform_inv,
self_->deformed_positions_[segment_i]);
const float3 pos2_cu = math::transform_point(brush_transform_inv,
self_->deformed_positions_[segment_i + 1]);
const float3 pos1_cu = brush_transform_inv * self_->deformed_positions_[segment_i];
const float3 pos2_cu = brush_transform_inv * self_->deformed_positions_[segment_i + 1];
float2 pos1_re, pos2_re;
ED_view3d_project_float_v2_m4(ctx_.region, pos1_cu, pos1_re, projection.ptr());
ED_view3d_project_float_v2_m4(ctx_.region, pos2_cu, pos2_re, projection.ptr());
ED_view3d_project_float_v2_m4(ctx_.region, pos1_cu, pos1_re, projection.values);
ED_view3d_project_float_v2_m4(ctx_.region, pos2_cu, pos2_re, projection.values);
const float dist_sq_re = dist_squared_to_line_segment_v2(
brush_pos_re_, pos1_re, pos2_re);
@ -214,22 +211,21 @@ struct DeleteOperationExecutor {
void delete_spherical_with_symmetry(MutableSpan<bool> curves_to_delete)
{
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values);
float3 brush_wo;
ED_view3d_win_to_3d(
ctx_.v3d,
ctx_.region,
math::transform_point(transforms_.curves_to_world, self_->brush_3d_.position_cu),
brush_pos_re_,
brush_wo);
const float3 brush_cu = math::transform_point(transforms_.world_to_curves, brush_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_re_,
brush_wo);
const float3 brush_cu = transforms_.world_to_curves * brush_wo;
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
eCurvesSymmetryType(curves_id_->symmetry));
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
this->delete_spherical(math::transform_point(brush_transform, brush_cu), curves_to_delete);
this->delete_spherical(brush_transform * brush_cu, curves_to_delete);
}
}

View File

@ -178,7 +178,7 @@ struct DensityAddOperationExecutor {
BLI_assert_unreachable();
}
for (float3 &pos : new_positions_cu) {
pos = math::transform_point(transforms_.surface_to_curves, pos);
pos = transforms_.surface_to_curves * pos;
}
if (stroke_extension.is_first) {
@ -337,12 +337,12 @@ struct DensityAddOperationExecutor {
Vector<float3> &r_positions_su)
{
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, curves_ob_orig_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, curves_ob_orig_, projection.values);
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
eCurvesSymmetryType(curves_id_orig_->symmetry));
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
const float4x4 brush_transform_inv = math::invert(brush_transform);
const float4x4 brush_transform_inv = brush_transform.inverted();
const float4x4 transform = transforms_.curves_to_surface * brush_transform *
transforms_.world_to_curves;
Vector<float3> positions_su;
@ -358,8 +358,8 @@ struct DensityAddOperationExecutor {
float3 start_wo, end_wo;
ED_view3d_win_to_segment_clipped(
ctx_.depsgraph, ctx_.region, ctx_.v3d, pos_re, start_wo, end_wo, true);
r_start_su = math::transform_point(transform, start_wo);
r_end_su = math::transform_point(transform, end_wo);
r_start_su = transform * start_wo;
r_end_su = transform * end_wo;
},
true,
brush_settings_->density_add_attempts,
@ -371,10 +371,9 @@ struct DensityAddOperationExecutor {
/* Remove some sampled points randomly based on the brush falloff and strength. */
for (int i = new_points - 1; i >= 0; i--) {
const float3 pos_su = positions_su[i];
const float3 pos_cu = math::transform_point(
brush_transform_inv, math::transform_point(transforms_.surface_to_curves, pos_su));
const float3 pos_cu = brush_transform_inv * transforms_.surface_to_curves * pos_su;
float2 pos_re;
ED_view3d_project_float_v2_m4(ctx_.region, pos_cu, pos_re, projection.ptr());
ED_view3d_project_float_v2_m4(ctx_.region, pos_cu, pos_re, projection.values);
const float dist_to_brush_re = math::distance(brush_pos_re_, pos_re);
const float radius_falloff = BKE_brush_curve_strength(
brush_, dist_to_brush_re, brush_radius_re_);
@ -413,9 +412,8 @@ struct DensityAddOperationExecutor {
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
eCurvesSymmetryType(curves_id_orig_->symmetry));
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
const float3 brush_pos_cu = math::transform_point(brush_transform, brush_3d->position_cu);
const float3 brush_pos_su = math::transform_point(transforms_.curves_to_surface,
brush_pos_cu);
const float3 brush_pos_cu = brush_transform * brush_3d->position_cu;
const float3 brush_pos_su = transforms_.curves_to_surface * brush_pos_cu;
const float brush_radius_su = transform_brush_radius(
transforms_.curves_to_surface, brush_pos_cu, brush_3d->radius_cu);
const float brush_radius_sq_su = pow2f(brush_radius_su);
@ -450,7 +448,7 @@ struct DensityAddOperationExecutor {
/* Remove some sampled points randomly based on the brush falloff and strength. */
for (int i = new_points - 1; i >= 0; i--) {
const float3 pos_su = positions_su[i];
const float3 pos_cu = math::transform_point(transforms_.surface_to_curves, pos_su);
const float3 pos_cu = transforms_.surface_to_curves * pos_su;
const float dist_to_brush_cu = math::distance(pos_cu, brush_pos_cu);
const float radius_falloff = BKE_brush_curve_strength(
brush_, dist_to_brush_cu, brush_3d->radius_cu);
@ -646,7 +644,7 @@ struct DensitySubtractOperationExecutor {
const float brush_radius_sq_re = pow2f(brush_radius_re);
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values);
/* Randomly select the curves that are allowed to be removed, based on the brush radius and
* strength. */
@ -659,11 +657,10 @@ struct DensitySubtractOperationExecutor {
allow_remove_curve[curve_i] = true;
continue;
}
const float3 pos_cu = math::transform_point(brush_transform,
self_->deformed_root_positions_[curve_i]);
const float3 pos_cu = brush_transform * self_->deformed_root_positions_[curve_i];
float2 pos_re;
ED_view3d_project_float_v2_m4(ctx_.region, pos_cu, pos_re, projection.ptr());
ED_view3d_project_float_v2_m4(ctx_.region, pos_cu, pos_re, projection.values);
const float dist_to_brush_sq_re = math::distance_squared(brush_pos_re_, pos_re);
if (dist_to_brush_sq_re > brush_radius_sq_re) {
continue;
@ -687,9 +684,9 @@ struct DensitySubtractOperationExecutor {
continue;
}
const float3 orig_pos_cu = self_->deformed_root_positions_[curve_i];
const float3 pos_cu = math::transform_point(brush_transform, orig_pos_cu);
const float3 pos_cu = brush_transform * orig_pos_cu;
float2 pos_re;
ED_view3d_project_float_v2_m4(ctx_.region, pos_cu, pos_re, projection.ptr());
ED_view3d_project_float_v2_m4(ctx_.region, pos_cu, pos_re, projection.values);
const float dist_to_brush_sq_re = math::distance_squared(brush_pos_re_, pos_re);
if (dist_to_brush_sq_re > brush_radius_sq_re) {
continue;
@ -727,7 +724,7 @@ struct DensitySubtractOperationExecutor {
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
eCurvesSymmetryType(curves_id_->symmetry));
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
const float3 brush_pos_cu = math::transform_point(brush_transform, brush_3d->position_cu);
const float3 brush_pos_cu = brush_transform * brush_3d->position_cu;
this->reduce_density_spherical(brush_pos_cu, brush_3d->radius_cu, curves_to_delete);
}
}

View File

@ -3,8 +3,8 @@
#include <algorithm>
#include "BLI_enumerable_thread_specific.hh"
#include "BLI_float4x4.hh"
#include "BLI_length_parameterize.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_vector.hh"
#include "DEG_depsgraph.h"
@ -348,13 +348,13 @@ struct CurvesEffectOperationExecutor {
const OffsetIndices points_by_curve = curves_->points_by_curve();
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values);
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
eCurvesSymmetryType(curves_id_->symmetry));
Vector<float4x4> symmetry_brush_transforms_inv;
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
symmetry_brush_transforms_inv.append(math::invert(brush_transform));
symmetry_brush_transforms_inv.append(brush_transform.inverted());
}
const float brush_radius_re = brush_radius_base_re_ * brush_radius_factor_;
@ -371,14 +371,12 @@ struct CurvesEffectOperationExecutor {
float max_move_distance_cu = 0.0f;
for (const float4x4 &brush_transform_inv : symmetry_brush_transforms_inv) {
for (const int segment_i : points.drop_back(1)) {
const float3 p1_cu = math::transform_point(brush_transform_inv,
deformation.positions[segment_i]);
const float3 p2_cu = math::transform_point(brush_transform_inv,
deformation.positions[segment_i + 1]);
const float3 p1_cu = brush_transform_inv * deformation.positions[segment_i];
const float3 p2_cu = brush_transform_inv * deformation.positions[segment_i + 1];
float2 p1_re, p2_re;
ED_view3d_project_float_v2_m4(ctx_.region, p1_cu, p1_re, projection.ptr());
ED_view3d_project_float_v2_m4(ctx_.region, p2_cu, p2_re, projection.ptr());
ED_view3d_project_float_v2_m4(ctx_.region, p1_cu, p1_re, projection.values);
ED_view3d_project_float_v2_m4(ctx_.region, p2_cu, p2_re, projection.values);
float2 closest_on_brush_re;
float2 closest_on_segment_re;
@ -406,22 +404,18 @@ struct CurvesEffectOperationExecutor {
p1_cu, p2_cu, lambda_on_segment);
float3 brush_start_pos_wo, brush_end_pos_wo;
ED_view3d_win_to_3d(
ctx_.v3d,
ctx_.region,
math::transform_point(transforms_.curves_to_world, closest_on_segment_cu),
brush_pos_start_re_,
brush_start_pos_wo);
ED_view3d_win_to_3d(
ctx_.v3d,
ctx_.region,
math::transform_point(transforms_.curves_to_world, closest_on_segment_cu),
brush_pos_end_re_,
brush_end_pos_wo);
const float3 brush_start_pos_cu = math::transform_point(transforms_.world_to_curves,
brush_start_pos_wo);
const float3 brush_end_pos_cu = math::transform_point(transforms_.world_to_curves,
brush_end_pos_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
transforms_.curves_to_world * closest_on_segment_cu,
brush_pos_start_re_,
brush_start_pos_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
transforms_.curves_to_world * closest_on_segment_cu,
brush_pos_end_re_,
brush_end_pos_wo);
const float3 brush_start_pos_cu = transforms_.world_to_curves * brush_start_pos_wo;
const float3 brush_end_pos_cu = transforms_.world_to_curves * brush_end_pos_wo;
const float move_distance_cu = weight *
math::distance(brush_start_pos_cu, brush_end_pos_cu);
@ -442,17 +436,19 @@ struct CurvesEffectOperationExecutor {
const bke::crazyspace::GeometryDeformation deformation =
bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *object_);
float3 brush_pos_wo = math::transform_point(transforms_.curves_to_world,
self_->brush_3d_.position_cu);
float3 brush_pos_start_wo, brush_pos_end_wo;
ED_view3d_win_to_3d(
ctx_.v3d, ctx_.region, brush_pos_wo, brush_pos_start_re_, brush_pos_start_wo);
ED_view3d_win_to_3d(ctx_.v3d, ctx_.region, brush_pos_wo, brush_pos_end_re_, brush_pos_end_wo);
const float3 brush_pos_start_cu = math::transform_point(transforms_.world_to_curves,
brush_pos_start_wo);
const float3 brush_pos_end_cu = math::transform_point(transforms_.world_to_curves,
brush_pos_end_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_start_re_,
brush_pos_start_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_end_re_,
brush_pos_end_wo);
const float3 brush_pos_start_cu = transforms_.world_to_curves * brush_pos_start_wo;
const float3 brush_pos_end_cu = transforms_.world_to_curves * brush_pos_end_wo;
const float3 brush_pos_diff_cu = brush_pos_end_cu - brush_pos_start_cu;
const float brush_pos_diff_length_cu = math::length(brush_pos_diff_cu);
const float brush_radius_cu = self_->brush_3d_.radius_cu * brush_radius_factor_;
@ -473,10 +469,8 @@ struct CurvesEffectOperationExecutor {
const float curve_selection_factor = curve_selection_factors_[curve_i];
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
const float3 brush_pos_start_transformed_cu = math::transform_point(brush_transform,
brush_pos_start_cu);
const float3 brush_pos_end_transformed_cu = math::transform_point(brush_transform,
brush_pos_end_cu);
const float3 brush_pos_start_transformed_cu = brush_transform * brush_pos_start_cu;
const float3 brush_pos_end_transformed_cu = brush_transform * brush_pos_end_cu;
for (const int segment_i : points.drop_back(1)) {
const float3 &p1_cu = deformation.positions[segment_i];

View File

@ -693,11 +693,11 @@ static void select_grow_invoke_per_curve(const Curves &curves_id,
});
});
float4x4 curves_to_world_mat = float4x4(curves_ob.object_to_world);
float4x4 world_to_curves_mat = math::invert(curves_to_world_mat);
float4x4 curves_to_world_mat = curves_ob.object_to_world;
float4x4 world_to_curves_mat = curves_to_world_mat.inverted();
float4x4 projection;
ED_view3d_ob_project_mat_get(&rv3d, &curves_ob, projection.ptr());
ED_view3d_ob_project_mat_get(&rv3d, &curves_ob, projection.values);
/* Compute how mouse movements in screen space are converted into grow/shrink distances in
* object space. */
@ -711,7 +711,7 @@ static void select_grow_invoke_per_curve(const Curves &curves_id,
const float3 &pos_cu = positions[point_i];
float2 pos_re;
ED_view3d_project_float_v2_m4(&region, pos_cu, pos_re, projection.ptr());
ED_view3d_project_float_v2_m4(&region, pos_cu, pos_re, projection.values);
if (pos_re.x < 0 || pos_re.y < 0 || pos_re.x > region.winx || pos_re.y > region.winy) {
continue;
}
@ -719,12 +719,9 @@ static void select_grow_invoke_per_curve(const Curves &curves_id,
* space. */
const float2 pos_offset_re = pos_re + float2(1, 0);
float3 pos_offset_wo;
ED_view3d_win_to_3d(&v3d,
&region,
math::transform_point(curves_to_world_mat, pos_cu),
pos_offset_re,
pos_offset_wo);
const float3 pos_offset_cu = math::transform_point(world_to_curves_mat, pos_offset_wo);
ED_view3d_win_to_3d(
&v3d, &region, curves_to_world_mat * pos_cu, pos_offset_re, pos_offset_wo);
const float3 pos_offset_cu = world_to_curves_mat * pos_offset_wo;
const float dist_cu = math::distance(pos_cu, pos_offset_cu);
const float dist_re = math::distance(pos_re, pos_offset_re);
const float factor = dist_cu / dist_re;
@ -937,7 +934,7 @@ static void min_distance_edit_draw(bContext *C, int /*x*/, int /*y*/, void *cust
const float3 point_pos_cu = op_data.pos_cu + op_data.normal_cu * 0.0001f +
x_iter * tangent_x_cu + y_iter * tangent_y_cu;
const float3 point_pos_wo = math::transform_point(op_data.curves_to_world_mat, point_pos_cu);
const float3 point_pos_wo = op_data.curves_to_world_mat * point_pos_cu;
points_wo.append(point_pos_wo);
}
}
@ -970,7 +967,7 @@ static void min_distance_edit_draw(bContext *C, int /*x*/, int /*y*/, void *cust
GPU_point_size(3.0f);
immBegin(GPU_PRIM_POINTS, points_wo.size());
float3 brush_origin_wo = math::transform_point(op_data.curves_to_world_mat, op_data.pos_cu);
float3 brush_origin_wo = op_data.curves_to_world_mat * op_data.pos_cu;
float2 brush_origin_re;
ED_view3d_project_v2(region, brush_origin_wo, brush_origin_re);
@ -1048,8 +1045,8 @@ static int min_distance_edit_invoke(bContext *C, wmOperator *op, const wmEvent *
const CurvesSurfaceTransforms transforms{curves_ob_orig, &surface_ob_orig};
const float3 ray_start_su = math::transform_point(transforms.world_to_surface, ray_start_wo);
const float3 ray_end_su = math::transform_point(transforms.world_to_surface, ray_end_wo);
const float3 ray_start_su = transforms.world_to_surface * ray_start_wo;
const float3 ray_end_su = transforms.world_to_surface * ray_end_wo;
const float3 ray_direction_su = math::normalize(ray_end_su - ray_start_su);
BVHTreeRayHit ray_hit;
@ -1070,9 +1067,9 @@ static int min_distance_edit_invoke(bContext *C, wmOperator *op, const wmEvent *
const float3 hit_pos_su = ray_hit.co;
const float3 hit_normal_su = ray_hit.no;
const float3 hit_pos_cu = math::transform_point(transforms.surface_to_curves, hit_pos_su);
const float3 hit_normal_cu = math::normalize(
math::transform_direction(transforms.surface_to_curves_normal, hit_normal_su));
const float3 hit_pos_cu = transforms.surface_to_curves * hit_pos_su;
const float3 hit_normal_cu = math::normalize(transforms.surface_to_curves_normal *
hit_normal_su);
MinDistanceEditData *op_data = MEM_new<MinDistanceEditData>(__func__);
op_data->curves_to_world_mat = transforms.curves_to_world;

View File

@ -4,7 +4,7 @@
#include "curves_sculpt_intern.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_float4x4.hh"
#include "BLI_vector.hh"
#include "PIL_time.h"
@ -156,14 +156,14 @@ struct PinchOperationExecutor {
void pinch_projected(const float4x4 &brush_transform, MutableSpan<bool> r_changed_curves)
{
const float4x4 brush_transform_inv = math::invert(brush_transform);
const float4x4 brush_transform_inv = brush_transform.inverted();
const bke::crazyspace::GeometryDeformation deformation =
bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *object_);
const OffsetIndices points_by_curve = curves_->points_by_curve();
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values);
MutableSpan<float3> positions_cu = curves_->positions_for_write();
const float brush_radius_re = brush_radius_base_re_ * brush_radius_factor_;
const float brush_radius_sq_re = pow2f(brush_radius_re);
@ -173,10 +173,10 @@ struct PinchOperationExecutor {
const IndexRange points = points_by_curve[curve_i];
for (const int point_i : points.drop_front(1)) {
const float3 old_pos_cu = deformation.positions[point_i];
const float3 old_symm_pos_cu = math::transform_point(brush_transform_inv, old_pos_cu);
const float3 old_symm_pos_cu = brush_transform_inv * old_pos_cu;
float2 old_symm_pos_re;
ED_view3d_project_float_v2_m4(
ctx_.region, old_symm_pos_cu, old_symm_pos_re, projection.ptr());
ctx_.region, old_symm_pos_cu, old_symm_pos_re, projection.values);
const float dist_to_brush_sq_re = math::distance_squared(old_symm_pos_re, brush_pos_re_);
if (dist_to_brush_sq_re > brush_radius_sq_re) {
@ -194,12 +194,12 @@ struct PinchOperationExecutor {
float3 new_symm_pos_wo;
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
math::transform_point(transforms_.curves_to_world, old_symm_pos_cu),
transforms_.curves_to_world * old_symm_pos_cu,
new_symm_pos_re,
new_symm_pos_wo);
float3 new_pos_cu = math::transform_point(transforms_.world_to_curves, new_symm_pos_wo);
new_pos_cu = math::transform_point(brush_transform, new_pos_cu);
const float3 new_pos_cu = brush_transform * transforms_.world_to_curves *
new_symm_pos_wo;
const float3 translation_eval = new_pos_cu - old_pos_cu;
const float3 translation_orig = deformation.translation_from_deformed_to_original(
point_i, translation_eval);
@ -213,20 +213,18 @@ struct PinchOperationExecutor {
void pinch_spherical_with_symmetry(MutableSpan<bool> r_changed_curves)
{
float3 brush_pos_wo;
ED_view3d_win_to_3d(
ctx_.v3d,
ctx_.region,
math::transform_point(transforms_.curves_to_world, self_->brush_3d_.position_cu),
brush_pos_re_,
brush_pos_wo);
const float3 brush_pos_cu = math::transform_point(transforms_.world_to_curves, brush_pos_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_re_,
brush_pos_wo);
const float3 brush_pos_cu = transforms_.world_to_curves * brush_pos_wo;
const float brush_radius_cu = self_->brush_3d_.radius_cu * brush_radius_factor_;
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
eCurvesSymmetryType(curves_id_->symmetry));
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
this->pinch_spherical(
math::transform_point(brush_transform, brush_pos_cu), brush_radius_cu, r_changed_curves);
this->pinch_spherical(brush_transform * brush_pos_cu, brush_radius_cu, r_changed_curves);
}
}

View File

@ -20,7 +20,6 @@
#include "WM_api.h"
#include "BLI_length_parameterize.hh"
#include "BLI_math_matrix.hh"
#include "GEO_add_curves_on_mesh.hh"
@ -174,10 +173,10 @@ struct PuffOperationExecutor {
void find_curve_weights_projected(const float4x4 &brush_transform,
MutableSpan<float> r_curve_weights)
{
const float4x4 brush_transform_inv = math::invert(brush_transform);
const float4x4 brush_transform_inv = brush_transform.inverted();
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values);
const float brush_radius_re = brush_radius_base_re_ * brush_radius_factor_;
const float brush_radius_sq_re = pow2f(brush_radius_re);
@ -190,15 +189,13 @@ struct PuffOperationExecutor {
for (const int curve_selection_i : range) {
const int curve_i = curve_selection_[curve_selection_i];
const IndexRange points = points_by_curve[curve_i];
const float3 first_pos_cu = math::transform_point(brush_transform_inv,
deformation.positions[points[0]]);
const float3 first_pos_cu = brush_transform_inv * deformation.positions[points[0]];
float2 prev_pos_re;
ED_view3d_project_float_v2_m4(ctx_.region, first_pos_cu, prev_pos_re, projection.ptr());
ED_view3d_project_float_v2_m4(ctx_.region, first_pos_cu, prev_pos_re, projection.values);
for (const int point_i : points.drop_front(1)) {
const float3 pos_cu = math::transform_point(brush_transform_inv,
deformation.positions[point_i]);
const float3 pos_cu = brush_transform_inv * deformation.positions[point_i];
float2 pos_re;
ED_view3d_project_float_v2_m4(ctx_.region, pos_cu, pos_re, projection.ptr());
ED_view3d_project_float_v2_m4(ctx_.region, pos_cu, pos_re, projection.values);
BLI_SCOPED_DEFER([&]() { prev_pos_re = pos_re; });
const float dist_to_brush_sq_re = dist_squared_to_line_segment_v2(
@ -220,23 +217,22 @@ struct PuffOperationExecutor {
void find_curves_weights_spherical_with_symmetry(MutableSpan<float> r_curve_weights)
{
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values);
float3 brush_pos_wo;
ED_view3d_win_to_3d(
ctx_.v3d,
ctx_.region,
math::transform_point(transforms_.curves_to_world, self_->brush_3d_.position_cu),
brush_pos_re_,
brush_pos_wo);
const float3 brush_pos_cu = math::transform_point(transforms_.world_to_curves, brush_pos_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_re_,
brush_pos_wo);
const float3 brush_pos_cu = transforms_.world_to_curves * brush_pos_wo;
const float brush_radius_cu = self_->brush_3d_.radius_cu * brush_radius_factor_;
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
eCurvesSymmetryType(curves_id_->symmetry));
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
this->find_curves_weights_spherical(
math::transform_point(brush_transform, brush_pos_cu), brush_radius_cu, r_curve_weights);
brush_transform * brush_pos_cu, brush_radius_cu, r_curve_weights);
}
}
@ -286,8 +282,7 @@ struct PuffOperationExecutor {
const IndexRange points = points_by_curve[curve_i];
const int first_point_i = points[0];
const float3 first_pos_cu = positions_cu[first_point_i];
const float3 first_pos_su = math::transform_point(transforms_.curves_to_surface,
first_pos_cu);
const float3 first_pos_su = transforms_.curves_to_surface * first_pos_cu;
/* Find the nearest position on the surface. The curve will be aligned to the normal of
* that point. */
@ -308,8 +303,7 @@ struct PuffOperationExecutor {
interp_weights_tri_v3(bary_coords, v0_su, v1_su, v2_su, closest_pos_su);
const float3 normal_su = geometry::compute_surface_point_normal(
looptri, bary_coords, corner_normals_su_);
const float3 normal_cu = math::normalize(
math::transform_direction(transforms_.surface_to_curves_normal, normal_su));
const float3 normal_cu = math::normalize(transforms_.surface_to_curves_normal * normal_su);
accumulated_lengths_cu.reinitialize(points.size() - 1);
length_parameterize::accumulate_lengths<float3>(

View File

@ -3,7 +3,6 @@
#include <algorithm>
#include <numeric>
#include "BLI_math_matrix.hh"
#include "BLI_memory_utils.hh"
#include "BLI_task.hh"
@ -158,10 +157,10 @@ struct SelectionPaintOperationExecutor {
void paint_point_selection_projected(const float4x4 &brush_transform,
MutableSpan<float> selection)
{
const float4x4 brush_transform_inv = math::invert(brush_transform);
const float4x4 brush_transform_inv = brush_transform.inverted();
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values);
const bke::crazyspace::GeometryDeformation deformation =
bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *object_);
@ -171,12 +170,11 @@ struct SelectionPaintOperationExecutor {
threading::parallel_for(curves_->points_range(), 1024, [&](const IndexRange point_range) {
for (const int point_i : point_range) {
const float3 pos_cu = math::transform_point(brush_transform_inv,
deformation.positions[point_i]);
const float3 pos_cu = brush_transform_inv * deformation.positions[point_i];
/* Find the position of the point in screen space. */
float2 pos_re;
ED_view3d_project_float_v2_m4(ctx_.region, pos_cu, pos_re, projection.ptr());
ED_view3d_project_float_v2_m4(ctx_.region, pos_cu, pos_re, projection.values);
const float distance_to_brush_sq_re = math::distance_squared(pos_re, brush_pos_re_);
if (distance_to_brush_sq_re > brush_radius_sq_re) {
@ -199,23 +197,21 @@ struct SelectionPaintOperationExecutor {
void paint_point_selection_spherical_with_symmetry(MutableSpan<float> selection)
{
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values);
float3 brush_wo;
ED_view3d_win_to_3d(
ctx_.v3d,
ctx_.region,
math::transform_point(transforms_.curves_to_world, self_->brush_3d_.position_cu),
brush_pos_re_,
brush_wo);
const float3 brush_cu = math::transform_point(transforms_.world_to_curves, brush_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_re_,
brush_wo);
const float3 brush_cu = transforms_.world_to_curves * brush_wo;
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
eCurvesSymmetryType(curves_id_->symmetry));
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
this->paint_point_selection_spherical(selection,
math::transform_point(brush_transform, brush_cu));
this->paint_point_selection_spherical(selection, brush_transform * brush_cu);
}
}
@ -263,14 +259,14 @@ struct SelectionPaintOperationExecutor {
void paint_curve_selection_projected(const float4x4 &brush_transform,
MutableSpan<float> selection)
{
const float4x4 brush_transform_inv = math::invert(brush_transform);
const float4x4 brush_transform_inv = brush_transform.inverted();
const bke::crazyspace::GeometryDeformation deformation =
bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *object_);
const OffsetIndices points_by_curve = curves_->points_by_curve();
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values);
const float brush_radius_re = brush_radius_base_re_ * brush_radius_factor_;
const float brush_radius_sq_re = pow2f(brush_radius_re);
@ -284,15 +280,13 @@ struct SelectionPaintOperationExecutor {
[&](const IndexRange segment_range, const float init) {
float max_weight = init;
for (const int segment_i : segment_range) {
const float3 pos1_cu = math::transform_point(brush_transform_inv,
deformation.positions[segment_i]);
const float3 pos2_cu = math::transform_point(brush_transform_inv,
deformation.positions[segment_i + 1]);
const float3 pos1_cu = brush_transform_inv * deformation.positions[segment_i];
const float3 pos2_cu = brush_transform_inv * deformation.positions[segment_i + 1];
float2 pos1_re;
float2 pos2_re;
ED_view3d_project_float_v2_m4(ctx_.region, pos1_cu, pos1_re, projection.ptr());
ED_view3d_project_float_v2_m4(ctx_.region, pos2_cu, pos2_re, projection.ptr());
ED_view3d_project_float_v2_m4(ctx_.region, pos1_cu, pos1_re, projection.values);
ED_view3d_project_float_v2_m4(ctx_.region, pos2_cu, pos2_re, projection.values);
const float distance_sq_re = dist_squared_to_line_segment_v2(
brush_pos_re_, pos1_re, pos2_re);
@ -315,23 +309,21 @@ struct SelectionPaintOperationExecutor {
void paint_curve_selection_spherical_with_symmetry(MutableSpan<float> selection)
{
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values);
float3 brush_wo;
ED_view3d_win_to_3d(
ctx_.v3d,
ctx_.region,
math::transform_point(transforms_.curves_to_world, self_->brush_3d_.position_cu),
brush_pos_re_,
brush_wo);
const float3 brush_cu = math::transform_point(transforms_.world_to_curves, brush_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_re_,
brush_wo);
const float3 brush_cu = transforms_.world_to_curves * brush_wo;
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
eCurvesSymmetryType(curves_id_->symmetry));
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
this->paint_curve_selection_spherical(selection,
math::transform_point(brush_transform, brush_cu));
this->paint_curve_selection_spherical(selection, brush_transform * brush_cu);
}
}

View File

@ -4,7 +4,8 @@
#include "curves_sculpt_intern.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_float3x3.hh"
#include "BLI_float4x4.hh"
#include "BLI_vector.hh"
#include "DEG_depsgraph.h"
@ -254,7 +255,7 @@ struct SlideOperationExecutor {
self_->slide_info_.append_as();
SlideInfo &slide_info = self_->slide_info_.last();
slide_info.brush_transform = brush_transform;
this->find_curves_to_slide(math::transform_point(brush_transform, brush_3d->position_cu),
this->find_curves_to_slide(brush_transform * brush_3d->position_cu,
brush_3d->radius_cu,
reverse_uv_sampler_orig,
slide_info.curves_to_slide);
@ -290,12 +291,11 @@ struct SlideOperationExecutor {
continue;
}
/* Compute the normal at the initial surface position. */
const float3 point_no = geometry::compute_surface_point_normal(
surface_looptris_orig_[result.looptri_index],
result.bary_weights,
corner_normals_orig_su_);
const float3 normal_cu = math::normalize(
math::transform_point(transforms_.surface_to_curves_normal, point_no));
transforms_.surface_to_curves_normal *
geometry::compute_surface_point_normal(surface_looptris_orig_[result.looptri_index],
result.bary_weights,
corner_normals_orig_su_));
r_curves_to_slide.append({curve_i, radius_falloff, normal_cu});
}
@ -313,7 +313,7 @@ struct SlideOperationExecutor {
const ReverseUVSampler &reverse_uv_sampler_orig,
const float4x4 &brush_transform)
{
const float4x4 brush_transform_inv = math::invert(brush_transform);
const float4x4 brush_transform_inv = brush_transform.inverted();
const Span<float3> positions_orig_su = surface_orig_->vert_positions();
const Span<MLoop> loops_orig = surface_orig_->loops();
@ -323,7 +323,7 @@ struct SlideOperationExecutor {
MutableSpan<float2> surface_uv_coords = curves_orig_->surface_uv_coords_for_write();
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, curves_ob_orig_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, curves_ob_orig_, projection.values);
const float2 brush_pos_diff_re = brush_pos_re_ - self_->initial_brush_pos_re_;
@ -339,14 +339,14 @@ struct SlideOperationExecutor {
const int first_point_i = points[0];
const float3 old_first_pos_eval_cu = self_->initial_deformed_positions_cu_[first_point_i];
const float3 old_first_symm_pos_eval_cu = math::transform_point(brush_transform_inv,
old_first_pos_eval_cu);
const float3 old_first_pos_eval_su = math::transform_point(transforms_.curves_to_surface,
old_first_pos_eval_cu);
const float3 old_first_symm_pos_eval_cu = brush_transform_inv * old_first_pos_eval_cu;
const float3 old_first_pos_eval_su = transforms_.curves_to_surface * old_first_pos_eval_cu;
float2 old_first_symm_pos_eval_re;
ED_view3d_project_float_v2_m4(
ctx_.region, old_first_symm_pos_eval_cu, old_first_symm_pos_eval_re, projection.ptr());
ED_view3d_project_float_v2_m4(ctx_.region,
old_first_symm_pos_eval_cu,
old_first_symm_pos_eval_re,
projection.values);
const float radius_falloff = slide_curve_info.radius_falloff;
const float curve_weight = brush_strength_ * radius_falloff * curve_factors_[curve_i];
@ -362,10 +362,8 @@ struct SlideOperationExecutor {
ray_start_wo,
ray_end_wo,
true);
const float3 ray_start_su = math::transform_point(world_to_surface_with_symmetry_mat,
ray_start_wo);
const float3 ray_end_su = math::transform_point(world_to_surface_with_symmetry_mat,
ray_end_wo);
const float3 ray_start_su = world_to_surface_with_symmetry_mat * ray_start_wo;
const float3 ray_end_su = world_to_surface_with_symmetry_mat * ray_end_wo;
const float3 ray_direction_su = math::normalize(ray_end_su - ray_start_su);
/* Find the ray hit that is closest to the initial curve root position. */
@ -399,27 +397,25 @@ struct SlideOperationExecutor {
/* Gather old and new surface normal. */
const float3 &initial_normal_cu = slide_curve_info.initial_normal_cu;
const float3 new_normal_cu = math::normalize(math::transform_point(
transforms_.surface_to_curves_normal,
const float3 new_normal_cu = math::normalize(
transforms_.surface_to_curves_normal *
geometry::compute_surface_point_normal(
looptri_orig, result.bary_weights, corner_normals_orig_su_)));
looptri_orig, result.bary_weights, corner_normals_orig_su_));
/* Gather old and new surface position. */
const float3 new_first_pos_orig_su = attribute_math::mix3<float3>(
bary_weights_orig,
positions_orig_su[loops_orig[looptri_orig.tri[0]].v],
positions_orig_su[loops_orig[looptri_orig.tri[1]].v],
positions_orig_su[loops_orig[looptri_orig.tri[2]].v]);
const float3 old_first_pos_orig_cu = self_->initial_positions_cu_[first_point_i];
const float3 new_first_pos_orig_cu = math::transform_point(transforms_.surface_to_curves,
new_first_pos_orig_su);
const float3 new_first_pos_orig_cu =
transforms_.surface_to_curves *
attribute_math::mix3<float3>(bary_weights_orig,
positions_orig_su[loops_orig[looptri_orig.tri[0]].v],
positions_orig_su[loops_orig[looptri_orig.tri[1]].v],
positions_orig_su[loops_orig[looptri_orig.tri[2]].v]);
/* Actually transform curve points. */
const float4x4 slide_transform = this->get_slide_transform(
old_first_pos_orig_cu, new_first_pos_orig_cu, initial_normal_cu, new_normal_cu);
for (const int point_i : points) {
positions_orig_cu[point_i] = math::transform_point(
slide_transform, self_->initial_positions_cu_[point_i]);
positions_orig_cu[point_i] = slide_transform * self_->initial_positions_cu_[point_i];
}
surface_uv_coords[curve_i] = uv;
}
@ -469,12 +465,14 @@ struct SlideOperationExecutor {
const float3 &new_normal)
{
float3x3 rotation_3x3;
rotation_between_vecs_to_mat3(rotation_3x3.ptr(), old_normal, new_normal);
rotation_between_vecs_to_mat3(rotation_3x3.values, old_normal, new_normal);
float4x4 rotation_4x4;
copy_m4_m3(rotation_4x4.values, rotation_3x3.values);
float4x4 transform = float4x4::identity();
transform.location() -= old_root_pos;
transform = float4x4(rotation_3x3) * transform;
transform.location() += new_root_pos;
sub_v3_v3(transform.values[3], old_root_pos);
mul_m4_m4_pre(transform.values, rotation_4x4.values);
add_v3_v3(transform.values[3], new_root_pos);
return transform;
}
};

View File

@ -128,13 +128,13 @@ struct SmoothOperationExecutor {
void find_projected_smooth_factors(const float4x4 &brush_transform,
MutableSpan<float> r_point_smooth_factors)
{
const float4x4 brush_transform_inv = math::invert(brush_transform);
const float4x4 brush_transform_inv = brush_transform.inverted();
const float brush_radius_re = brush_radius_base_re_ * brush_radius_factor_;
const float brush_radius_sq_re = pow2f(brush_radius_re);
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values);
const bke::crazyspace::GeometryDeformation deformation =
bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *object_);
@ -144,10 +144,9 @@ struct SmoothOperationExecutor {
for (const int curve_i : curve_selection_.slice(range)) {
const IndexRange points = points_by_curve[curve_i];
for (const int point_i : points) {
const float3 &pos_cu = math::transform_point(brush_transform_inv,
deformation.positions[point_i]);
const float3 &pos_cu = brush_transform_inv * deformation.positions[point_i];
float2 pos_re;
ED_view3d_project_float_v2_m4(ctx_.region, pos_cu, pos_re, projection.ptr());
ED_view3d_project_float_v2_m4(ctx_.region, pos_cu, pos_re, projection.values);
const float dist_to_brush_sq_re = math::distance_squared(pos_re, brush_pos_re_);
if (dist_to_brush_sq_re > brush_radius_sq_re) {
continue;
@ -170,24 +169,22 @@ struct SmoothOperationExecutor {
void find_spherical_smooth_factors_with_symmetry(MutableSpan<float> r_point_smooth_factors)
{
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values);
float3 brush_pos_wo;
ED_view3d_win_to_3d(
ctx_.v3d,
ctx_.region,
math::transform_point(transforms_.curves_to_world, self_->brush_3d_.position_cu),
brush_pos_re_,
brush_pos_wo);
const float3 brush_pos_cu = math::transform_point(transforms_.world_to_curves, brush_pos_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_re_,
brush_pos_wo);
const float3 brush_pos_cu = transforms_.world_to_curves * brush_pos_wo;
const float brush_radius_cu = self_->brush_3d_.radius_cu * brush_radius_factor_;
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
eCurvesSymmetryType(curves_id_->symmetry));
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
this->find_spherical_smooth_factors(math::transform_point(brush_transform, brush_pos_cu),
brush_radius_cu,
r_point_smooth_factors);
this->find_spherical_smooth_factors(
brush_transform * brush_pos_cu, brush_radius_cu, r_point_smooth_factors);
}
}

View File

@ -4,10 +4,10 @@
#include "curves_sculpt_intern.hh"
#include "BLI_float4x4.hh"
#include "BLI_index_mask_ops.hh"
#include "BLI_kdtree.h"
#include "BLI_length_parameterize.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_rand.hh"
#include "BLI_vector.hh"
@ -176,7 +176,7 @@ struct SnakeHookOperatorExecutor {
void projected_snake_hook(const float4x4 &brush_transform)
{
const float4x4 brush_transform_inv = math::invert(brush_transform);
const float4x4 brush_transform_inv = brush_transform.inverted();
const bke::crazyspace::GeometryDeformation deformation =
bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *object_);
const OffsetIndices points_by_curve = curves_->points_by_curve();
@ -184,7 +184,7 @@ struct SnakeHookOperatorExecutor {
MutableSpan<float3> positions_cu = curves_->positions_for_write();
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values);
const float brush_radius_re = brush_radius_base_re_ * brush_radius_factor_;
const float brush_radius_sq_re = pow2f(brush_radius_re);
@ -195,11 +195,11 @@ struct SnakeHookOperatorExecutor {
const IndexRange points = points_by_curve[curve_i];
const int last_point_i = points.last();
const float3 old_pos_cu = deformation.positions[last_point_i];
const float3 old_symm_pos_cu = math::transform_point(brush_transform_inv, old_pos_cu);
const float3 old_symm_pos_cu = brush_transform_inv * old_pos_cu;
float2 old_symm_pos_re;
ED_view3d_project_float_v2_m4(
ctx_.region, old_symm_pos_cu, old_symm_pos_re, projection.ptr());
ctx_.region, old_symm_pos_cu, old_symm_pos_re, projection.values);
const float distance_to_brush_sq_re = math::distance_squared(old_symm_pos_re,
brush_pos_prev_re_);
@ -215,11 +215,11 @@ struct SnakeHookOperatorExecutor {
float3 new_symm_pos_wo;
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
math::transform_point(transforms_.curves_to_world, old_symm_pos_cu),
transforms_.curves_to_world * old_symm_pos_cu,
new_symm_pos_re,
new_symm_pos_wo);
const float3 new_pos_cu = math::transform_point(
brush_transform, math::transform_point(transforms_.world_to_curves, new_symm_pos_wo));
const float3 new_pos_cu = brush_transform *
(transforms_.world_to_curves * new_symm_pos_wo);
const float3 translation_eval = new_pos_cu - old_pos_cu;
const float3 translation_orig = deformation.translation_from_deformed_to_original(
last_point_i, translation_eval);
@ -233,33 +233,29 @@ struct SnakeHookOperatorExecutor {
void spherical_snake_hook_with_symmetry()
{
float4x4 projection;
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.ptr());
ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values);
float3 brush_start_wo, brush_end_wo;
ED_view3d_win_to_3d(
ctx_.v3d,
ctx_.region,
math::transform_point(transforms_.curves_to_world, self_->brush_3d_.position_cu),
brush_pos_prev_re_,
brush_start_wo);
ED_view3d_win_to_3d(
ctx_.v3d,
ctx_.region,
math::transform_point(transforms_.curves_to_world, self_->brush_3d_.position_cu),
brush_pos_re_,
brush_end_wo);
const float3 brush_start_cu = math::transform_point(transforms_.world_to_curves,
brush_start_wo);
const float3 brush_end_cu = math::transform_point(transforms_.world_to_curves, brush_end_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_prev_re_,
brush_start_wo);
ED_view3d_win_to_3d(ctx_.v3d,
ctx_.region,
transforms_.curves_to_world * self_->brush_3d_.position_cu,
brush_pos_re_,
brush_end_wo);
const float3 brush_start_cu = transforms_.world_to_curves * brush_start_wo;
const float3 brush_end_cu = transforms_.world_to_curves * brush_end_wo;
const float brush_radius_cu = self_->brush_3d_.radius_cu * brush_radius_factor_;
const Vector<float4x4> symmetry_brush_transforms = get_symmetry_brush_transforms(
eCurvesSymmetryType(curves_id_->symmetry));
for (const float4x4 &brush_transform : symmetry_brush_transforms) {
this->spherical_snake_hook(math::transform_point(brush_transform, brush_start_cu),
math::transform_point(brush_transform, brush_end_cu),
brush_radius_cu);
this->spherical_snake_hook(
brush_transform * brush_start_cu, brush_transform * brush_end_cu, brush_radius_cu);
}
}

View File

@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_index_mask_ops.hh"
#include "BLI_math_matrix.hh"
#include "BLI_virtual_array.hh"
#include "BKE_attribute.hh"
@ -160,13 +159,13 @@ std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values(
if (STREQ(column_id.name, "Rotation")) {
return std::make_unique<ColumnValues>(
column_id.name, VArray<float3>::ForFunc(domain_num, [transforms](int64_t index) {
return float3(math::to_euler(transforms[index]));
return transforms[index].to_euler();
}));
}
if (STREQ(column_id.name, "Scale")) {
return std::make_unique<ColumnValues>(
column_id.name, VArray<float3>::ForFunc(domain_num, [transforms](int64_t index) {
return math::to_scale(transforms[index]);
return transforms[index].scale();
}));
}
}

View File

@ -3,7 +3,6 @@
#include <cstring>
#include "BLI_listbase.h"
#include "BLI_math_matrix.hh"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
@ -212,7 +211,7 @@ static void apply_row_filter(const SpreadsheetRowFilter &row_filter,
apply_filter_operation(
column_data.typed<ColorGeometry4f>(),
[&](const ColorGeometry4f cell) {
return math::distance_squared(float4(cell), float4(value)) <= threshold_sq;
return len_squared_v4v4(cell, value) <= threshold_sq;
},
prev_mask,
new_indices);
@ -253,7 +252,7 @@ static void apply_row_filter(const SpreadsheetRowFilter &row_filter,
const ColorGeometry4f cell = cell_bytes.decode();
const float4 cell_floats = {
float(cell.r), float(cell.g), float(cell.b), float(cell.a)};
return math::distance_squared(value_floats, cell_floats) <= threshold_sq;
return len_squared_v4v4(value_floats, cell_floats) <= threshold_sq;
},
prev_mask,
new_indices);

View File

@ -9,11 +9,11 @@
#include "MEM_guardedalloc.h"
#include "BLI_bitmap.h"
#include "BLI_float4x4.hh"
#include "BLI_kdopbvh.h"
#include "BLI_listbase.h"
#include "BLI_map.hh"
#include "BLI_math.h"
#include "BLI_math_matrix_types.hh"
#include "BLI_math_vector.hh"
#include "BLI_utildefines.h"

View File

@ -3,7 +3,7 @@
#include "BLI_color.hh"
#include "BLI_cpp_type_make.hh"
#include "BLI_cpp_types_make.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_float4x4.hh"
#include "BLI_math_vector_types.hh"
#include "FN_field_cpp_type_make.hh"

View File

@ -2,8 +2,8 @@
#pragma once
#include "BLI_float4x4.hh"
#include "BLI_kdtree.h"
#include "BLI_math_matrix_types.hh"
#include "BLI_math_vector.hh"
#include "BLI_span.hh"

View File

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_float4x4.hh"
#include "BLI_function_ref.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_string_ref.hh"
#include "DNA_mesh_types.h"

View File

@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_length_parameterize.hh"
#include "BLI_math_matrix.hh"
#include "BLI_task.hh"
#include "BKE_attribute_math.hh"
@ -127,8 +126,7 @@ static void interpolate_position_without_interpolation(
const float3 &root_cu = root_positions_cu[i];
const float length = new_lengths_cu[i];
const float3 &normal_su = new_normals_su[i];
const float3 normal_cu = math::normalize(
math::transform_direction(surface_to_curves_normal_mat, normal_su));
const float3 normal_cu = math::normalize(surface_to_curves_normal_mat * normal_su);
const float3 tip_cu = root_cu + length * normal_cu;
initialize_straight_curve_positions(root_cu, tip_cu, positions_cu.slice(points));
@ -161,8 +159,7 @@ static void interpolate_position_with_interpolation(CurvesGeometry &curves,
const float length_cu = new_lengths_cu[added_curve_i];
const float3 &normal_su = new_normals_su[added_curve_i];
const float3 normal_cu = math::normalize(
math::transform_direction(transforms.surface_to_curves_normal, normal_su));
const float3 normal_cu = math::normalize(transforms.surface_to_curves_normal * normal_su);
const float3 &root_cu = root_positions_cu[added_curve_i];
@ -185,8 +182,8 @@ static void interpolate_position_with_interpolation(CurvesGeometry &curves,
const float3 neighbor_normal_su = compute_surface_point_normal(
looptris[result.looptri_index], result.bary_weights, corner_normals_su);
const float3 neighbor_normal_cu = math::normalize(
math::transform_direction(transforms.surface_to_curves_normal, neighbor_normal_su));
const float3 neighbor_normal_cu = math::normalize(transforms.surface_to_curves_normal *
neighbor_normal_su);
/* The rotation matrix used to transform relative coordinates of the neighbor curve
* to the new curve. */
@ -268,8 +265,7 @@ AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves,
surface_positions[surface_loops[looptri.tri[0]].v],
surface_positions[surface_loops[looptri.tri[1]].v],
surface_positions[surface_loops[looptri.tri[2]].v]);
root_positions_cu.append(
math::transform_point(inputs.transforms->surface_to_curves, root_position_su));
root_positions_cu.append(inputs.transforms->surface_to_curves * root_position_su);
used_uvs.append(uv);
}

View File

@ -1,7 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_math_matrix.hh"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
#include "BKE_volume.h"
@ -60,8 +58,7 @@ void OpenVDBMeshAdapter::getIndexSpacePoint(size_t polygon_index,
openvdb::Vec3d &pos) const
{
const MLoopTri &looptri = looptris_[polygon_index];
const float3 transformed_co = math::transform_point(
transform_, positions_[loops_[looptri.tri[vertex_index]].v]);
const float3 transformed_co = transform_ * positions_[loops_[looptri.tri[vertex_index]].v];
pos = &transformed_co.x;
}
@ -89,8 +86,7 @@ float volume_compute_voxel_size(const Depsgraph *depsgraph,
/* Compute the voxel size based on the desired number of voxels and the approximated bounding
* box of the volume. */
const float diagonal = math::distance(math::transform_point(transform, bb_max),
math::transform_point(transform, bb_min));
const float diagonal = math::distance(transform * bb_max, transform * bb_min);
const float approximate_volume_side_length = diagonal + exterior_band_width * 2.0f;
const float voxel_size = approximate_volume_side_length / res.settings.voxel_amount /
volume_simplify;
@ -109,10 +105,11 @@ static openvdb::FloatGrid::Ptr mesh_to_volume_grid(const Mesh *mesh,
return nullptr;
}
float4x4 mesh_to_index_space_transform = math::from_scale<float4x4>(float3(1.0f / voxel_size));
mesh_to_index_space_transform *= mesh_to_volume_space_transform;
float4x4 mesh_to_index_space_transform;
scale_m4_fl(mesh_to_index_space_transform.values, 1.0f / voxel_size);
mul_m4_m4_post(mesh_to_index_space_transform.values, mesh_to_volume_space_transform.values);
/* Better align generated grid with the source mesh. */
mesh_to_index_space_transform.location() -= 0.5f;
add_v3_fl(mesh_to_index_space_transform.values[3], -0.5f);
OpenVDBMeshAdapter mesh_adapter{*mesh, mesh_to_index_space_transform};

View File

@ -9,7 +9,6 @@
#include "DNA_object_types.h"
#include "DNA_pointcloud_types.h"
#include "BLI_math_matrix.hh"
#include "BLI_noise.hh"
#include "BLI_task.hh"
@ -277,7 +276,7 @@ static void copy_transformed_positions(const Span<float3> src,
{
threading::parallel_for(src.index_range(), 1024, [&](const IndexRange range) {
for (const int i : range) {
dst[i] = math::transform_point(transform, src[i]);
dst[i] = transform * src[i];
}
});
}
@ -431,12 +430,11 @@ static void foreach_geometry_in_reference(
case InstanceReference::Type::Collection: {
Collection &collection = reference.collection();
float4x4 offset_matrix = float4x4::identity();
offset_matrix.location() -= collection.instance_offset;
sub_v3_v3(offset_matrix.values[3], collection.instance_offset);
int index = 0;
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (&collection, object) {
const GeometrySet object_geometry_set = object_get_evaluated_geometry_set(*object);
const float4x4 matrix = base_transform * offset_matrix *
float4x4_view(object->object_to_world);
const float4x4 matrix = base_transform * offset_matrix * object->object_to_world;
const int sub_id = noise::hash(id, index);
fn(object_geometry_set, matrix, sub_id);
index++;
@ -965,7 +963,7 @@ static void execute_realize_mesh_task(const RealizeInstancesOptions &options,
threading::parallel_for(src_positions.index_range(), 1024, [&](const IndexRange vert_range) {
for (const int i : vert_range) {
dst_positions[i] = math::transform_point(task.transform, src_positions[i]);
dst_positions[i] = task.transform * src_positions[i];
}
});
threading::parallel_for(src_edges.index_range(), 1024, [&](const IndexRange edge_range) {

View File

@ -67,7 +67,9 @@
# include "BLI_assert.h"
# ifdef __cplusplus
# include "BLI_math_matrix_types.hh"
# ifndef __BLI_MATH_MATRIX_TYPES_HH__
# include "BLI_float4x4.hh"
# endif
# include "BLI_math_vector_types.hh"
using blender::float2;
using blender::float3;

View File

@ -8,9 +8,10 @@
#include <array>
#include <type_traits>
#include "BLI_float4x4.hh"
#include "BLI_math.h"
#include "BLI_math_color_blend.h"
#include "BLI_math_matrix.hh"
#include "BLI_math_vector.hh"
#include "BLI_rect.h"
#include "BLI_task.hh"
#include "BLI_vector.hh"
@ -60,7 +61,7 @@ struct TransformUserData {
/**
* \brief Initialize the start_uv, add_x and add_y fields based on the given transform matrix.
*/
void init(const float4x4 &transform_matrix,
void init(const float transform_matrix[4][4],
const int num_subsamples,
const bool do_crop_destination_region)
{
@ -72,23 +73,35 @@ struct TransformUserData {
}
private:
void init_start_uv(const float4x4 &transform_matrix)
void init_start_uv(const float transform_matrix[4][4])
{
start_uv = double2(transform_matrix.location().xy());
double3 start_uv_v3;
double3 orig(0.0);
double transform_matrix_double[4][4];
copy_m4d_m4(transform_matrix_double, transform_matrix);
mul_v3_m4v3_db(start_uv_v3, transform_matrix_double, orig);
start_uv = double2(start_uv_v3);
}
void init_add_x(const float4x4 &transform_matrix)
void init_add_x(const float transform_matrix[4][4])
{
double transform_matrix_double[4][4];
copy_m4d_m4(transform_matrix_double, transform_matrix);
const double width = src->x;
add_x = double2(transform_matrix.x_axis()) * width + double2(transform_matrix.location());
add_x = (add_x - start_uv) * (1.0 / width);
double3 add_x_v3;
mul_v3_m4v3_db(add_x_v3, transform_matrix_double, double3(width, 0.0, 0.0));
add_x = double2((add_x_v3 - double3(start_uv)) * (1.0 / width));
}
void init_add_y(const float4x4 &transform_matrix)
void init_add_y(const float transform_matrix[4][4])
{
double transform_matrix_double[4][4];
copy_m4d_m4(transform_matrix_double, transform_matrix);
const double height = src->y;
add_y = double2(transform_matrix.y_axis()) * height + double2(transform_matrix.location());
add_y = (add_y - start_uv) * (1.0 / height);
double3 add_y_v3;
double3 uv_max_y(0.0, height, 0.0);
mul_v3_m4v3_db(add_y_v3, transform_matrix_double, double3(0.0, height, 0.0));
add_y = double2((add_y_v3 - double3(start_uv)) * (1.0 / height));
}
void init_subsampling(const int num_subsamples)
@ -121,14 +134,14 @@ struct TransformUserData {
const int2 margin(2);
rcti rect;
BLI_rcti_init_minmax(&rect);
float4x4 inverse = math::invert(transform_matrix);
float4x4 inverse = transform_matrix.inverted();
for (const int2 &src_coords : {
int2(src_crop.xmin, src_crop.ymin),
int2(src_crop.xmax, src_crop.ymin),
int2(src_crop.xmin, src_crop.ymax),
int2(src_crop.xmax, src_crop.ymax),
}) {
float3 dst_co = math::transform_point(inverse, float3(src_coords.x, src_coords.y, 0.0f));
float3 dst_co = inverse * float3(src_coords.x, src_coords.y, 0.0f);
BLI_rcti_do_minmax_v(&rect, int2(dst_co) + margin);
BLI_rcti_do_minmax_v(&rect, int2(dst_co) - margin);
}
@ -733,9 +746,7 @@ void IMB_transform(const struct ImBuf *src,
if (mode == IMB_TRANSFORM_MODE_CROP_SRC) {
user_data.src_crop = *src_crop;
}
user_data.init(blender::float4x4(transform_matrix),
num_subsamples,
ELEM(mode, IMB_TRANSFORM_MODE_CROP_SRC));
user_data.init(transform_matrix, num_subsamples, ELEM(mode, IMB_TRANSFORM_MODE_CROP_SRC));
if (filter == IMB_FILTER_NEAREST) {
transform_threaded<IMB_FILTER_NEAREST>(&user_data, mode);

View File

@ -13,7 +13,6 @@
#include "BLI_fileops.h"
#include "BLI_index_range.hh"
#include "BLI_math_base.h"
#include "BLI_path_util.h"
#include "BLI_string.h"

View File

@ -10,9 +10,9 @@
#include "BLI_utildefines.h"
#include "BLI_array.hh"
#include "BLI_float4x4.hh"
#include "BLI_math_geom.h"
#include "BLI_math_matrix.h"
#include "BLI_math_matrix_types.hh"
#include "BLI_vector.hh"
#include "BLI_vector_set.hh"

View File

@ -37,8 +37,8 @@
#include "MOD_modifiertypes.h"
#include "MOD_ui_common.h"
#include "BLI_float4x4.hh"
#include "BLI_index_range.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_span.hh"
#include "RNA_access.h"

View File

@ -30,7 +30,7 @@
#include "RNA_access.h"
#include "RNA_prototypes.h"
#include "BLI_math_matrix_types.hh"
#include "BLI_float4x4.hh"
#include "BLI_math_vector.h"
#include "BLI_span.hh"
#include "BLI_timeit.hh"

View File

@ -5,8 +5,10 @@
* \ingroup cmpnodes
*/
#include "BLI_float3x3.hh"
#include "BLI_math_base.hh"
#include "BLI_math_matrix.hh"
#include "BLI_math_vector.hh"
#include "BLI_math_vector_types.hh"
#include "UI_interface.h"
#include "UI_resources.h"
@ -109,8 +111,7 @@ class DirectionalBlurOperation : public NodeOperation {
{
const float diagonal_length = math::length(float2(get_input("Image").domain().size));
const float translation_amount = diagonal_length * node_storage(bnode()).distance;
const float2x2 rotation = math::from_rotation<float2x2>(
math::AngleRadian(-node_storage(bnode()).angle));
const float3x3 rotation = float3x3::from_rotation(-node_storage(bnode()).angle);
return rotation * float2(-translation_amount / get_iterations(), 0.0f);
}
@ -136,13 +137,13 @@ class DirectionalBlurOperation : public NodeOperation {
float3x3 get_transformation()
{
/* Construct the transformation that will be applied on each iteration. */
const float3x3 transformation = math::from_loc_rot_scale<float3x3>(
get_translation(), math::AngleRadian(get_rotation()), get_scale());
const float3x3 transformation = float3x3::from_translation_rotation_scale(
get_translation(), get_rotation(), get_scale());
/* Change the origin of the transformation to the user-specified origin. */
const float3x3 origin_transformation = math::from_origin_transform<float3x3>(transformation,
get_origin());
const float3x3 origin_transformation = float3x3::from_origin_transformation(transformation,
get_origin());
/* The shader will transform the coordinates, not the image itself, so take the inverse. */
return math::invert(origin_transformation);
return origin_transformation.inverted();
}
/* The actual number of iterations is 2 to the power of the user supplied iterations. The power

View File

@ -5,7 +5,7 @@
* \ingroup cmpnodes
*/
#include "BLI_math_matrix_types.hh"
#include "BLI_float3x3.hh"
#include "UI_interface.h"
#include "UI_resources.h"

View File

@ -5,7 +5,8 @@
* \ingroup cmpnodes
*/
#include "BLI_math_matrix.hh"
#include "BLI_math_vector.hh"
#include "BLI_math_vector_types.hh"
#include "COM_node_operation.hh"
@ -49,14 +50,14 @@ class PixelateOperation : public NodeOperation {
/* Get the scaling component of the domain transformation, but make sure it doesn't exceed 1,
* because pixelation should only happen if the input is scaled down. */
const float2 scale = math::min(float2(1.0f), math::to_scale(float2x2(domain.transformation)));
const float2 scale = math::min(float2(1.0f), domain.transformation.scale_2d());
/* Multiply the size of the domain by its scale to match its apparent size, but make sure it is
* at least 1 pixel in both axis. */
domain.size = math::max(int2(float2(domain.size) * scale), int2(1));
/* Reset the scale of the transformation by transforming it with the inverse of the scale. */
domain.transformation *= math::from_scale<float3x3>(math::safe_divide(float2(1.0f), scale));
domain.transformation *= float3x3::from_scale(math::safe_divide(float2(1.0f), scale));
return domain;
}

View File

@ -6,7 +6,7 @@
*/
#include "BLI_assert.h"
#include "BLI_math_matrix.hh"
#include "BLI_float3x3.hh"
#include "UI_interface.h"
#include "UI_resources.h"
@ -55,9 +55,9 @@ class RotateOperation : public NodeOperation {
Result &result = get_result("Image");
input.pass_through(result);
const math::AngleRadian rotation = get_input("Degr").get_float_value_default(0.0f);
const float rotation = get_input("Degr").get_float_value_default(0.0f);
const float3x3 transformation = math::from_rotation<float3x3>(rotation);
const float3x3 transformation = float3x3::from_rotation(rotation);
result.transform(transformation);
result.get_realization_options().interpolation = get_interpolation();

View File

@ -6,8 +6,8 @@
*/
#include "BLI_assert.h"
#include "BLI_float3x3.hh"
#include "BLI_math_base.hh"
#include "BLI_math_matrix.hh"
#include "BLI_math_vector_types.hh"
#include "RNA_access.h"
@ -84,8 +84,8 @@ class ScaleOperation : public NodeOperation {
Result &result = get_result("Image");
input.pass_through(result);
const float3x3 transformation = math::from_loc_rot_scale<float3x3>(
get_translation(), math::AngleRadian(0.0f), get_scale());
const float3x3 transformation = float3x3::from_translation_rotation_scale(
get_translation(), 0.0f, get_scale());
result.transform(transformation);
}

View File

@ -6,7 +6,7 @@
*/
#include "BLI_assert.h"
#include "BLI_math_matrix.hh"
#include "BLI_float3x3.hh"
#include "BLI_math_vector.h"
#include "UI_interface.h"
@ -55,7 +55,6 @@ static void node_composit_buts_transform(uiLayout *layout, bContext * /*C*/, Poi
}
using namespace blender::realtime_compositor;
using namespace blender::math;
class TransformOperation : public NodeOperation {
public:
@ -69,10 +68,11 @@ class TransformOperation : public NodeOperation {
const float2 translation = float2(get_input("X").get_float_value_default(0.0f),
get_input("Y").get_float_value_default(0.0f));
const AngleRadian rotation = AngleRadian(get_input("Angle").get_float_value_default(0.0f));
const float rotation = get_input("Angle").get_float_value_default(0.0f);
const float2 scale = float2(get_input("Scale").get_float_value_default(1.0f));
const float3x3 transformation = from_loc_rot_scale<float3x3>(translation, rotation, scale);
const float3x3 transformation = float3x3::from_translation_rotation_scale(
translation, rotation, scale);
result.transform(transformation);
result.get_realization_options().interpolation = get_interpolation();

View File

@ -5,7 +5,8 @@
* \ingroup cmpnodes
*/
#include "BLI_math_matrix.hh"
#include "BLI_float3x3.hh"
#include "BLI_math_vector_types.hh"
#include "UI_interface.h"
#include "UI_resources.h"
@ -70,7 +71,7 @@ class TranslateOperation : public NodeOperation {
}
const float2 translation = float2(x, y);
const float3x3 transformation = math::from_location<float3x3>(translation);
const float3x3 transformation = float3x3::from_translation(translation);
result.transform(transformation);
result.get_realization_options().repeat_x = get_repeat_x();

View File

@ -4,7 +4,7 @@
#include <string.h>
#include "BLI_math_matrix_types.hh"
#include "BLI_float4x4.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_utildefines.h"

View File

@ -91,12 +91,12 @@ static void node_geo_exec(GeoNodeExecParams params)
for (Collection *child_collection : children_collections) {
float4x4 transform = float4x4::identity();
if (!reset_children) {
transform.location() += float3(child_collection->instance_offset);
add_v3_v3(transform.values[3], child_collection->instance_offset);
if (use_relative_transform) {
transform = float4x4(self_object->world_to_object) * transform;
mul_m4_m4_pre(transform.values, self_object->world_to_object);
}
else {
transform.location() -= float3(collection->instance_offset);
sub_v3_v3(transform.values[3], collection->instance_offset);
}
}
const int handle = instances->add_reference(*child_collection);
@ -107,12 +107,12 @@ static void node_geo_exec(GeoNodeExecParams params)
float4x4 transform = float4x4::identity();
if (!reset_children) {
if (use_relative_transform) {
transform = float4x4(self_object->world_to_object);
transform = self_object->world_to_object;
}
else {
transform.location() -= float3(collection->instance_offset);
sub_v3_v3(transform.values[3], collection->instance_offset);
}
transform *= float4x4(child_object->object_to_world);
mul_m4_m4_post(transform.values, child_object->object_to_world);
}
entries.append({handle, &(child_object->id.name[2]), transform});
}
@ -129,8 +129,8 @@ static void node_geo_exec(GeoNodeExecParams params)
else {
float4x4 transform = float4x4::identity();
if (use_relative_transform) {
transform.location() = collection->instance_offset;
transform = float4x4_view(self_object->world_to_object) * transform;
copy_v3_v3(transform.values[3], collection->instance_offset);
mul_m4_m4_pre(transform.values, self_object->world_to_object);
}
const int handle = instances->add_reference(*collection);

View File

@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_array.hh"
#include "BLI_math_matrix.hh"
#include "BLI_task.hh"
#include "BLI_timeit.hh"
@ -73,8 +72,8 @@ static void fill_rotation_attribute(const Span<float3> tangents,
{
threading::parallel_for(IndexRange(rotations.size()), 512, [&](IndexRange range) {
for (const int i : range) {
rotations[i] = float3(
math::to_euler(math::from_orthonormal_axes<float4x4>(normals[i], tangents[i])));
rotations[i] =
float4x4::from_normalized_axis_data({0, 0, 0}, normals[i], tangents[i]).to_euler();
}
});
}

View File

@ -10,7 +10,7 @@
#include "BKE_modifier.h"
#include "BKE_type_conversions.hh"
#include "BLI_math_matrix.hh"
#include "BLI_float3x3.hh"
#include "BLI_task.hh"
#include "UI_interface.h"
@ -64,7 +64,7 @@ static void deform_curves(const CurvesGeometry &curves,
[&]() { reverse_uv_sampler_old.sample_many(curve_attachment_uvs, surface_samples_old); },
[&]() { reverse_uv_sampler_new.sample_many(curve_attachment_uvs, surface_samples_new); });
const float4x4 curves_to_surface = math::invert(surface_to_curves);
const float4x4 curves_to_surface = surface_to_curves.inverted();
const Span<float3> surface_positions_old = surface_mesh_old.vert_positions();
const Span<MLoop> surface_loops_old = surface_mesh_old.loops();
@ -163,26 +163,36 @@ static void deform_curves(const CurvesGeometry &curves,
const float3 tangent_y_new = math::normalize(math::cross(normal_new, tangent_x_new));
/* Construct rotation matrix that encodes the orientation of the old surface position. */
float3x3 rotation_old(tangent_x_old, tangent_y_old, normal_old);
float3x3 rotation_old;
copy_v3_v3(rotation_old.values[0], tangent_x_old);
copy_v3_v3(rotation_old.values[1], tangent_y_old);
copy_v3_v3(rotation_old.values[2], normal_old);
/* Construct rotation matrix that encodes the orientation of the new surface position. */
float3x3 rotation_new(tangent_x_new, tangent_y_new, normal_new);
float3x3 rotation_new;
copy_v3_v3(rotation_new.values[0], tangent_x_new);
copy_v3_v3(rotation_new.values[1], tangent_y_new);
copy_v3_v3(rotation_new.values[2], normal_new);
/* Can use transpose instead of inverse because the matrix is orthonormal. In the case of
* zero-area triangles, the matrix would not be orthonormal, but in this case, none of this
* works anyway. */
const float3x3 rotation_old_inv = math::transpose(rotation_old);
const float3x3 rotation_old_inv = rotation_old.transposed();
/* Compute a rotation matrix that rotates points from the old to the new surface
* orientation. */
const float3x3 rotation = rotation_new * rotation_old_inv;
float4x4 rotation_4x4;
copy_m4_m3(rotation_4x4.values, rotation.values);
/* Construction transformation matrix for this surface position that includes rotation and
* translation. */
float4x4 surface_transform = float4x4::identity();
/* Subtract and add #pos_old, so that the rotation origin is the position on the surface. */
float4x4 surface_transform = math::from_origin_transform<float4x4>(float4x4(rotation),
pos_old);
surface_transform.location() += translation;
sub_v3_v3(surface_transform.values[3], pos_old);
mul_m4_m4_pre(surface_transform.values, rotation_4x4.values);
add_v3_v3(surface_transform.values[3], pos_old);
add_v3_v3(surface_transform.values[3], translation);
/* Change the basis of the transformation so to that it can be applied in the local space of
* the curves. */
@ -192,7 +202,7 @@ static void deform_curves(const CurvesGeometry &curves,
const IndexRange points = points_by_curve[curve_i];
for (const int point_i : points) {
const float3 old_point_pos = r_positions[point_i];
const float3 new_point_pos = math::transform_point(curve_transform, old_point_pos);
const float3 new_point_pos = curve_transform * old_point_pos;
r_positions[point_i] = new_point_pos;
}

View File

@ -2,8 +2,6 @@
#include "node_geometry_util.hh"
#include "BLI_math_matrix.hh"
#include "BKE_instances.hh"
namespace blender::nodes::node_geo_input_instance_rotation_cc {
@ -21,9 +19,7 @@ class InstanceRotationFieldInput final : public bke::InstancesFieldInput {
GVArray get_varray_for_context(const bke::Instances &instances, IndexMask /*mask*/) const final
{
auto rotation_fn = [&](const int i) -> float3 {
return float3(math::to_euler(instances.transforms()[i]));
};
auto rotation_fn = [&](const int i) -> float3 { return instances.transforms()[i].to_euler(); };
return VArray<float3>::ForFunc(instances.instances_num(), rotation_fn);
}

View File

@ -2,8 +2,6 @@
#include "node_geometry_util.hh"
#include "BLI_math_matrix.hh"
#include "BKE_instances.hh"
namespace blender::nodes::node_geo_input_instance_scale_cc {
@ -21,9 +19,7 @@ class InstanceScaleFieldInput final : public bke::InstancesFieldInput {
GVArray get_varray_for_context(const bke::Instances &instances, IndexMask /*mask*/) const final
{
auto scale_fn = [&](const int i) -> float3 {
return math::to_scale(instances.transforms()[i]);
};
auto scale_fn = [&](const int i) -> float3 { return instances.transforms()[i].scale(); };
return VArray<float3>::ForFunc(instances.instances_num(), scale_fn);
}

View File

@ -1,8 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_math_matrix.hh"
#include "BLI_math_vector.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"

View File

@ -1,7 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_math_vector.hh"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"

View File

@ -4,7 +4,6 @@
#include "BLI_array_utils.hh"
#include "BLI_hash.h"
#include "BLI_math_matrix.hh"
#include "BLI_task.hh"
#include "UI_interface.h"
@ -115,8 +114,7 @@ static void add_instances_from_component(
/* Compute base transform for every instances. */
float4x4 &dst_transform = dst_transforms[range_i];
dst_transform = math::from_loc_rot_scale<float4x4>(
positions[i], math::EulerXYZ(rotations[i]), scales[i]);
dst_transform = float4x4::from_loc_eul_scale(positions[i], rotations[i], scales[i]);
/* Reference that will be used by this new instance. */
int dst_handle = empty_reference_handle;
@ -135,7 +133,7 @@ static void add_instances_from_component(
dst_handle = handle_mapping[src_handle];
/* Take transforms of the source instance into account. */
mul_m4_m4_post(dst_transform.ptr(), src_instances->transforms()[index].ptr());
mul_m4_m4_post(dst_transform.values, src_instances->transforms()[index].values);
}
}
}

View File

@ -51,7 +51,7 @@ static Mesh *create_ico_sphere_mesh(const int subdivisions,
"create_icosphere subdivisions=%i radius=%f matrix=%m4 calc_uvs=%b",
subdivisions,
std::abs(radius),
transform.ptr(),
transform.values,
create_uv_map);
BMeshToMeshParams params{};

View File

@ -3,7 +3,6 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BLI_math_vector.hh"
#include "BLI_task.hh"
#include "BKE_material.h"

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_math_matrix.hh"
#include "BLI_math_matrix.h"
#include "BKE_geometry_set_instances.hh"
#include "BKE_instances.hh"
@ -45,20 +45,19 @@ static void node_geo_exec(GeoNodeExecParams params)
return;
}
const float4x4 object_matrix = float4x4(object->object_to_world);
const float4x4 &object_matrix = object->object_to_world;
const float4x4 transform = float4x4(self_object->world_to_object) * object_matrix;
float3 location, scale;
math::EulerXYZ rotation;
if (transform_space_relative) {
math::to_loc_rot_scale(transform, location, rotation, scale);
params.set_output("Location", transform.translation());
params.set_output("Rotation", transform.to_euler());
params.set_output("Scale", transform.scale());
}
else {
math::to_loc_rot_scale(object_matrix, location, rotation, scale);
params.set_output("Location", object_matrix.translation());
params.set_output("Rotation", object_matrix.to_euler());
params.set_output("Scale", object_matrix.scale());
}
params.set_output("Location", location);
params.set_output("Rotation", float3(rotation));
params.set_output("Scale", scale);
if (params.output_is_required("Geometry")) {
if (object == self_object) {

View File

@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_math_vector.h"
#include "BLI_task.hh"
#include "BLI_timeit.hh"

View File

@ -1,7 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "BLI_math_matrix.hh"
#include "BLI_math_rotation.hh"
#include "BLI_task.hh"
#include "BKE_instances.hh"
@ -22,8 +20,6 @@ static void node_declare(NodeDeclarationBuilder &b)
static void rotate_instances(GeoNodeExecParams &params, bke::Instances &instances)
{
using namespace blender::math;
const bke::InstancesFieldContext context{instances};
fn::FieldEvaluator evaluator{context, instances.instances_num()};
evaluator.set_selection(params.extract_input<Field<bool>>("Selection"));
@ -51,31 +47,35 @@ static void rotate_instances(GeoNodeExecParams &params, bke::Instances &instance
if (local_spaces[i]) {
/* Find rotation axis from the matrix. This should work even if the instance is skewed. */
const float3 rotation_axis_x = instance_transform.values[0];
const float3 rotation_axis_y = instance_transform.values[1];
const float3 rotation_axis_z = instance_transform.values[2];
/* Create rotations around the individual axis. This could be optimized to skip some axis
* when the angle is zero. */
const float3x3 rotation_x = from_rotation<float3x3>(
AxisAngle(instance_transform.x_axis(), euler.x));
const float3x3 rotation_y = from_rotation<float3x3>(
AxisAngle(instance_transform.y_axis(), euler.y));
const float3x3 rotation_z = from_rotation<float3x3>(
AxisAngle(instance_transform.z_axis(), euler.z));
float rotation_x[3][3], rotation_y[3][3], rotation_z[3][3];
axis_angle_to_mat3(rotation_x, rotation_axis_x, euler.x);
axis_angle_to_mat3(rotation_y, rotation_axis_y, euler.y);
axis_angle_to_mat3(rotation_z, rotation_axis_z, euler.z);
/* Combine the previously computed rotations into the final rotation matrix. */
rotation_matrix = float4x4(rotation_z * rotation_y * rotation_x);
float rotation[3][3];
mul_m3_series(rotation, rotation_z, rotation_y, rotation_x);
copy_m4_m3(rotation_matrix.values, rotation);
/* Transform the passed in pivot into the local space of the instance. */
used_pivot = transform_point(instance_transform, pivot);
used_pivot = instance_transform * pivot;
}
else {
used_pivot = pivot;
rotation_matrix = from_rotation<float4x4>(EulerXYZ(euler));
eul_to_mat4(rotation_matrix.values, euler);
}
/* Move the pivot to the origin so that we can rotate around it. */
instance_transform.location() -= used_pivot;
sub_v3_v3(instance_transform.values[3], used_pivot);
/* Perform the actual rotation. */
instance_transform = rotation_matrix * instance_transform;
mul_m4_m4_pre(instance_transform.values, rotation_matrix.values);
/* Undo the pivot shifting done before. */
instance_transform.location() += used_pivot;
add_v3_v3(instance_transform.values[3], used_pivot);
}
});
}

View File

@ -2,7 +2,6 @@
#include "BLI_array.hh"
#include "BLI_disjoint_set.hh"
#include "BLI_math_matrix.hh"
#include "BLI_task.hh"
#include "BLI_vector.hh"
#include "BLI_vector_set.hh"
@ -124,25 +123,25 @@ static float4x4 create_single_axis_transform(const float3 &center,
float4x4 transform = float4x4::identity();
/* Move scaling center to the origin. */
transform.location() -= center;
sub_v3_v3(transform.values[3], center);
/* `base_change` and `base_change_inv` are used to rotate space so that scaling along the
* provided axis is the same as scaling along the x axis. */
float4x4 base_change = float4x4::identity();
base_change.x_axis() = x_axis;
base_change.y_axis() = y_axis;
base_change.z_axis() = z_axis;
copy_v3_v3(base_change.values[0], x_axis);
copy_v3_v3(base_change.values[1], y_axis);
copy_v3_v3(base_change.values[2], z_axis);
/* Can invert by transposing, because the matrix is orthonormal. */
float4x4 base_change_inv = math::transpose(base_change);
float4x4 base_change_inv = base_change.transposed();
float4x4 scale_transform = float4x4::identity();
scale_transform[0][0] = scale;
scale_transform.values[0][0] = scale;
transform = base_change * scale_transform * base_change_inv * transform;
/* Move scaling center back to where it was. */
transform.location() += center;
add_v3_v3(transform.values[3], center);
return transform;
}
@ -229,7 +228,7 @@ static void scale_vertex_islands_on_axis(Mesh &mesh,
const float4x4 transform = create_single_axis_transform(center, axis, scale);
for (const int vert_index : vertex_indices) {
positions[vert_index] = math::transform_point(transform, positions[vert_index]);
positions[vert_index] = transform * positions[vert_index];
}
}
});

Some files were not shown because too many files have changed in this diff Show More