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/io/collada/BCMath.cpp
Sybren A. Stüvel d329a6a937 Fix bug in cleanup commit
Fix a copy-paste error in rB11c4066159e
2020-12-07 12:54:46 +01:00

251 lines
5.8 KiB
C++

/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2008 Blender Foundation.
* All rights reserved.
*/
#include "BLI_utildefines.h"
#include "BCMath.h"
#include "BlenderContext.h"
void BCQuat::rotate_to(Matrix &mat_to)
{
Quat qd;
Matrix matd;
Matrix mati;
Matrix mat_from;
quat_to_mat4(mat_from, q);
/* Calculate the difference matrix matd between mat_from and mat_to */
invert_m4_m4(mati, mat_from);
mul_m4_m4m4(matd, mati, mat_to);
mat4_to_quat(qd, matd);
mul_qt_qtqt(q, qd, q); /* rotate to the final rotation to mat_to */
}
BCMatrix::BCMatrix(const BCMatrix &mat)
{
set_transform(mat.matrix);
}
BCMatrix::BCMatrix(Matrix &mat)
{
set_transform(mat);
}
BCMatrix::BCMatrix(Object *ob)
{
set_transform(ob);
}
BCMatrix::BCMatrix()
{
unit();
}
BCMatrix::BCMatrix(BC_global_forward_axis global_forward_axis, BC_global_up_axis global_up_axis)
{
float mrot[3][3];
float mat[4][4];
mat3_from_axis_conversion(
BC_DEFAULT_FORWARD, BC_DEFAULT_UP, global_forward_axis, global_up_axis, mrot);
transpose_m3(
mrot); /* TODO: Verify that mat3_from_axis_conversion() returns a transposed matrix */
copy_m4_m3(mat, mrot);
set_transform(mat);
}
void BCMatrix::add_transform(const Matrix &mat, bool inverted)
{
add_transform(this->matrix, mat, this->matrix, inverted);
}
void BCMatrix::add_transform(const BCMatrix &mat, bool inverted)
{
add_transform(this->matrix, mat.matrix, this->matrix, inverted);
}
void BCMatrix::apply_transform(const BCMatrix &mat, bool inverted)
{
apply_transform(this->matrix, mat.matrix, this->matrix, inverted);
}
void BCMatrix::add_transform(Matrix &to,
const Matrix &transform,
const Matrix &from,
bool inverted)
{
if (inverted) {
Matrix globinv;
invert_m4_m4(globinv, transform);
add_transform(to, globinv, from, /*inverted=*/false);
}
else {
mul_m4_m4m4(to, transform, from);
}
}
void BCMatrix::apply_transform(Matrix &to,
const Matrix &transform,
const Matrix &from,
bool inverse)
{
Matrix globinv;
invert_m4_m4(globinv, transform);
if (inverse) {
add_transform(to, globinv, from, /*inverted=*/false);
}
else {
mul_m4_m4m4(to, transform, from);
mul_m4_m4m4(to, to, globinv);
}
}
void BCMatrix::add_inverted_transform(Matrix &to, const Matrix &transform, const Matrix &from)
{
Matrix workmat;
invert_m4_m4(workmat, transform);
mul_m4_m4m4(to, workmat, from);
}
void BCMatrix::set_transform(Object *ob)
{
Matrix lmat;
BKE_object_matrix_local_get(ob, lmat);
copy_m4_m4(matrix, lmat);
mat4_decompose(this->loc, this->q, this->size, lmat);
quat_to_compatible_eul(this->rot, ob->rot, this->q);
}
void BCMatrix::set_transform(Matrix &mat)
{
copy_m4_m4(matrix, mat);
mat4_decompose(this->loc, this->q, this->size, mat);
quat_to_eul(this->rot, this->q);
}
void BCMatrix::copy(Matrix &r, Matrix &a)
{
/* destination comes first: */
memcpy(r, a, sizeof(Matrix));
}
void BCMatrix::transpose(Matrix &mat)
{
transpose_m4(mat);
}
void BCMatrix::sanitize(Matrix &mat, int precision)
{
for (auto &row : mat) {
for (float &cell : row) {
double val = (double)cell;
val = double_round(val, precision);
cell = (float)val;
}
}
}
void BCMatrix::sanitize(DMatrix &mat, int precision)
{
for (auto &row : mat) {
for (double &cell : row) {
cell = double_round(cell, precision);
}
}
}
void BCMatrix::unit()
{
unit_m4(this->matrix);
mat4_decompose(this->loc, this->q, this->size, this->matrix);
quat_to_eul(this->rot, this->q);
}
/* We need double here because the OpenCollada API needs it.
* precision = -1 indicates to not limit the precision. */
void BCMatrix::get_matrix(DMatrix &mat, const bool transposed, const int precision) const
{
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
float val = (transposed) ? matrix[j][i] : matrix[i][j];
if (precision >= 0) {
val = floor((val * pow(10, precision) + 0.5)) / pow(10, precision);
}
mat[i][j] = val;
}
}
}
void BCMatrix::get_matrix(Matrix &mat,
const bool transposed,
const int precision,
const bool inverted) const
{
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
float val = (transposed) ? matrix[j][i] : matrix[i][j];
if (precision >= 0) {
val = floor((val * pow(10, precision) + 0.5)) / pow(10, precision);
}
mat[i][j] = val;
}
}
if (inverted) {
invert_m4(mat);
}
}
bool BCMatrix::in_range(const BCMatrix &other, float distance) const
{
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (fabs(other.matrix[i][j] - matrix[i][j]) > distance) {
return false;
}
}
}
return true;
}
float (&BCMatrix::location() const)[3]
{
return loc;
}
float (&BCMatrix::rotation() const)[3]
{
return rot;
}
float (&BCMatrix::scale() const)[3]
{
return size;
}
float (&BCMatrix::quat() const)[4]
{
return q;
}