Move files around. Centralize sparsity and pattern structures. Add a view for b3SparseMat33.
This commit is contained in:
@ -87,7 +87,9 @@ private:
|
||||
void ApplyConstraints();
|
||||
|
||||
// Solve Ax = b.
|
||||
void Solve(b3DenseVec3& x, u32& iterations, const b3SparseSymMat33View& A, const b3DenseVec3& b, const b3DiagMat33& S, const b3DenseVec3& z, const b3DenseVec3& y) const;
|
||||
void SolveMPCG(b3DenseVec3& x,
|
||||
const b3SparseSymMat33View& A, const b3DenseVec3& b,
|
||||
const b3DiagMat33& S, const b3DenseVec3& z, const b3DenseVec3& y, u32 maxIterations = 30) const;
|
||||
|
||||
b3StackAllocator* m_allocator;
|
||||
|
||||
|
@ -22,7 +22,36 @@
|
||||
#include <bounce/common/math/mat33.h>
|
||||
#include <bounce/cloth/diag_mat33.h>
|
||||
#include <bounce/cloth/dense_vec3.h>
|
||||
#include <bounce/cloth/sparse_sym_mat33.h>
|
||||
|
||||
// An element in a sparse matrix.
|
||||
struct b3RowValue
|
||||
{
|
||||
u32 column;
|
||||
b3Mat33 value;
|
||||
b3RowValue* next;
|
||||
};
|
||||
|
||||
// Singly linked list of row elements.
|
||||
struct b3RowValueList
|
||||
{
|
||||
b3RowValueList()
|
||||
{
|
||||
head = nullptr;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
~b3RowValueList() { }
|
||||
|
||||
void PushFront(b3RowValue* link)
|
||||
{
|
||||
link->next = head;
|
||||
head = link;
|
||||
++count;
|
||||
}
|
||||
|
||||
b3RowValue* head;
|
||||
u32 count;
|
||||
};
|
||||
|
||||
// A sparse matrix.
|
||||
// Each row is a list of non-zero elements in the row.
|
137
include/bounce/cloth/sparse_mat33_view.h
Normal file
137
include/bounce/cloth/sparse_mat33_view.h
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2019 Irlan Robson https://irlanrobson.github.io
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef B3_SPARSE_MAT_33_VIEW_H
|
||||
#define B3_SPARSE_MAT_33_VIEW_H
|
||||
|
||||
#include <bounce/cloth/sparse_mat33.h>
|
||||
|
||||
struct b3ArrayRowValue
|
||||
{
|
||||
u32 column;
|
||||
b3Mat33 value;
|
||||
};
|
||||
|
||||
struct b3RowValueArray
|
||||
{
|
||||
u32 count;
|
||||
b3ArrayRowValue* values;
|
||||
};
|
||||
|
||||
// A read-only sparse matrix.
|
||||
struct b3SparseMat33View
|
||||
{
|
||||
//
|
||||
b3SparseMat33View(const b3SparseMat33& _m);
|
||||
|
||||
//
|
||||
~b3SparseMat33View();
|
||||
|
||||
//
|
||||
const b3Mat33& operator()(u32 i, u32 j) const;
|
||||
|
||||
u32 rowCount;
|
||||
b3RowValueArray* rows;
|
||||
};
|
||||
|
||||
inline b3SparseMat33View::b3SparseMat33View(const b3SparseMat33& _m)
|
||||
{
|
||||
rowCount = _m.rowCount;
|
||||
rows = (b3RowValueArray*)b3Alloc(rowCount * sizeof(b3RowValueArray));
|
||||
for (u32 i = 0; i < _m.rowCount; ++i)
|
||||
{
|
||||
b3RowValueList* rowList = _m.rows + i;
|
||||
b3RowValueArray* rowArray = rows + i;
|
||||
|
||||
rowArray->count = rowList->count;
|
||||
rowArray->values = (b3ArrayRowValue*)b3Alloc(rowArray->count * sizeof(b3ArrayRowValue));
|
||||
|
||||
u32 valueIndex = 0;
|
||||
for (b3RowValue* v = rowList->head; v; v = v->next)
|
||||
{
|
||||
rowArray->values[valueIndex].column = v->column;
|
||||
rowArray->values[valueIndex].value = v->value;
|
||||
++valueIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline b3SparseMat33View::~b3SparseMat33View()
|
||||
{
|
||||
for (u32 i = 0; i < rowCount; ++i)
|
||||
{
|
||||
b3RowValueArray* rowArray = rows + i;
|
||||
b3Free(rowArray->values);
|
||||
}
|
||||
b3Free(rows);
|
||||
}
|
||||
|
||||
inline const b3Mat33& b3SparseMat33View::operator()(u32 i, u32 j) const
|
||||
{
|
||||
B3_ASSERT(i < rowCount);
|
||||
B3_ASSERT(j < rowCount);
|
||||
|
||||
if (i > j)
|
||||
{
|
||||
b3Swap(i, j);
|
||||
}
|
||||
|
||||
b3RowValueArray* vs = rows + i;
|
||||
|
||||
for (u32 c = 0; c < vs->count; ++c)
|
||||
{
|
||||
b3ArrayRowValue* rv = vs->values + c;
|
||||
if (rv->column == j)
|
||||
{
|
||||
return rv->value;
|
||||
}
|
||||
}
|
||||
|
||||
return b3Mat33_zero;
|
||||
}
|
||||
|
||||
inline void b3Mul(b3DenseVec3& out, const b3SparseMat33View& A, const b3DenseVec3& v)
|
||||
{
|
||||
B3_ASSERT(A.rowCount == out.n);
|
||||
|
||||
out.SetZero();
|
||||
|
||||
for (u32 i = 0; i < A.rowCount; ++i)
|
||||
{
|
||||
b3RowValueArray* rowArray = A.rows + i;
|
||||
|
||||
for (u32 c = 0; c < rowArray->count; ++c)
|
||||
{
|
||||
b3ArrayRowValue* rv = rowArray->values + c;
|
||||
|
||||
u32 j = rv->column;
|
||||
b3Mat33 a = rv->value;
|
||||
|
||||
out[i] += a * v[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline b3DenseVec3 operator*(const b3SparseMat33View& A, const b3DenseVec3& v)
|
||||
{
|
||||
b3DenseVec3 result(v.n);
|
||||
b3Mul(result, A, v);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
@ -19,44 +19,14 @@
|
||||
#ifndef B3_SPARSE_SYM_MAT_33_H
|
||||
#define B3_SPARSE_SYM_MAT_33_H
|
||||
|
||||
#include <bounce/common/math/mat33.h>
|
||||
#include <bounce/cloth/diag_mat33.h>
|
||||
#include <bounce/cloth/dense_vec3.h>
|
||||
|
||||
// An element in a sparse symmetric matrix.
|
||||
struct b3RowValue
|
||||
{
|
||||
u32 column;
|
||||
b3Mat33 value;
|
||||
b3RowValue* next;
|
||||
};
|
||||
|
||||
// Doubly linked list of row elements.
|
||||
struct b3RowValueList
|
||||
{
|
||||
b3RowValueList()
|
||||
{
|
||||
head = nullptr;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
~b3RowValueList() { }
|
||||
|
||||
void PushFront(b3RowValue* link)
|
||||
{
|
||||
link->next = head;
|
||||
head = link;
|
||||
++count;
|
||||
}
|
||||
|
||||
b3RowValue* head;
|
||||
u32 count;
|
||||
};
|
||||
#include <bounce/cloth/sparse_mat33.h>
|
||||
|
||||
// A sparse symmetric matrix.
|
||||
// Each row is a list of non-zero elements in the row.
|
||||
// The total matrix capacity is bounded by
|
||||
// M * (M + 1) / 2
|
||||
// You must write only the upper triangle elements of the original
|
||||
// matrix to this matrix because a_ji = a_ij.
|
||||
struct b3SparseSymMat33
|
||||
{
|
||||
//
|
||||
|
@ -19,20 +19,9 @@
|
||||
#ifndef B3_SPARSE_SYM_MAT_33_VIEW_H
|
||||
#define B3_SPARSE_SYM_MAT_33_VIEW_H
|
||||
|
||||
#include <bounce/cloth/sparse_mat33_view.h>
|
||||
#include <bounce/cloth/sparse_sym_mat33.h>
|
||||
|
||||
struct b3ArrayRowValue
|
||||
{
|
||||
u32 column;
|
||||
b3Mat33 value;
|
||||
};
|
||||
|
||||
struct b3RowValueArray
|
||||
{
|
||||
u32 count;
|
||||
b3ArrayRowValue* values;
|
||||
};
|
||||
|
||||
// A read-only sparse symmetric matrix.
|
||||
struct b3SparseSymMat33View
|
||||
{
|
||||
@ -45,9 +34,6 @@ struct b3SparseSymMat33View
|
||||
//
|
||||
const b3Mat33& operator()(u32 i, u32 j) const;
|
||||
|
||||
//
|
||||
void Diagonal(b3DiagMat33& out) const;
|
||||
|
||||
u32 rowCount;
|
||||
b3RowValueArray* rows;
|
||||
};
|
||||
@ -99,6 +85,7 @@ inline const b3Mat33& b3SparseSymMat33View::operator()(u32 i, u32 j) const
|
||||
for (u32 c = 0; c < vs->count; ++c)
|
||||
{
|
||||
b3ArrayRowValue* rv = vs->values + c;
|
||||
|
||||
if (rv->column == j)
|
||||
{
|
||||
return rv->value;
|
||||
@ -108,16 +95,6 @@ inline const b3Mat33& b3SparseSymMat33View::operator()(u32 i, u32 j) const
|
||||
return b3Mat33_zero;
|
||||
}
|
||||
|
||||
inline void b3SparseSymMat33View::Diagonal(b3DiagMat33& out) const
|
||||
{
|
||||
B3_ASSERT(rowCount == out.n);
|
||||
|
||||
for (u32 i = 0; i < rowCount; ++i)
|
||||
{
|
||||
out[i] = (*this)(i, i);
|
||||
}
|
||||
}
|
||||
|
||||
inline void b3Mul(b3DenseVec3& out, const b3SparseSymMat33View& A, const b3DenseVec3& v)
|
||||
{
|
||||
B3_ASSERT(A.rowCount == out.n);
|
||||
@ -152,4 +129,4 @@ inline b3DenseVec3 operator*(const b3SparseSymMat33View& A, const b3DenseVec3& v
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
Reference in New Issue
Block a user