This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/blenlib/BLI_float3x3.hh
Omar Emara ac66a819c1 Realtime Compositor: Implement pixelate node
This patch implements the pixelate node for the realtime compositor.

Differential Revision: https://developer.blender.org/D15662

Reviewed By: Clement Foucault
2022-09-09 13:15:01 +02:00

216 lines
5.0 KiB
C++

/* 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_vec_types.hh"
#include "BLI_math_vector.h"
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