Merge branch 'master' into cmake_targets_determine_lib_path
commit
51438bff87
|
@ -7,8 +7,7 @@ on:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-ubuntu:
|
linux:
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
@ -20,3 +19,28 @@ jobs:
|
||||||
- name: test
|
- name: test
|
||||||
run: cd bin && ./unit
|
run: cd bin && ./unit
|
||||||
|
|
||||||
|
mac:
|
||||||
|
runs-on: macos-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: configure
|
||||||
|
run: cmake CMakeLists.txt
|
||||||
|
- name: build
|
||||||
|
run: cmake --build .
|
||||||
|
- name: test
|
||||||
|
run: cd bin && ./unit
|
||||||
|
|
||||||
|
windows:
|
||||||
|
runs-on: windows-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: configure
|
||||||
|
run: cmake CMakeLists.txt
|
||||||
|
- name: build
|
||||||
|
run: cmake --build . --config Release
|
||||||
|
- name: test
|
||||||
|
run: |
|
||||||
|
cd bin\Release
|
||||||
|
.\unit
|
||||||
|
|
|
@ -693,3 +693,598 @@ ASSIMP_API C_STRUCT const aiImporterDesc* aiGetImporterDesc( const char *extensi
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API int aiVector2AreEqual(
|
||||||
|
const C_STRUCT aiVector2D* a,
|
||||||
|
const C_STRUCT aiVector2D* b) {
|
||||||
|
ai_assert(NULL != a);
|
||||||
|
ai_assert(NULL != b);
|
||||||
|
return *a == *b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API int aiVector2AreEqualEpsilon(
|
||||||
|
const C_STRUCT aiVector2D* a,
|
||||||
|
const C_STRUCT aiVector2D* b,
|
||||||
|
const float epsilon) {
|
||||||
|
ai_assert(NULL != a);
|
||||||
|
ai_assert(NULL != b);
|
||||||
|
return a->Equal(*b, epsilon);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector2Add(
|
||||||
|
C_STRUCT aiVector2D* dst,
|
||||||
|
const C_STRUCT aiVector2D* src) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
ai_assert(NULL != src);
|
||||||
|
*dst = *dst + *src;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector2Subtract(
|
||||||
|
C_STRUCT aiVector2D* dst,
|
||||||
|
const C_STRUCT aiVector2D* src) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
ai_assert(NULL != src);
|
||||||
|
*dst = *dst - *src;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector2Scale(
|
||||||
|
C_STRUCT aiVector2D* dst,
|
||||||
|
const float s) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
*dst *= s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector2SymMul(
|
||||||
|
C_STRUCT aiVector2D* dst,
|
||||||
|
const C_STRUCT aiVector2D* other) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
ai_assert(NULL != other);
|
||||||
|
*dst = dst->SymMul(*other);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector2DivideByScalar(
|
||||||
|
C_STRUCT aiVector2D* dst,
|
||||||
|
const float s) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
*dst /= s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector2DivideByVector(
|
||||||
|
C_STRUCT aiVector2D* dst,
|
||||||
|
C_STRUCT aiVector2D* v) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
ai_assert(NULL != v);
|
||||||
|
*dst = *dst / *v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API float aiVector2Length(
|
||||||
|
const C_STRUCT aiVector2D* v) {
|
||||||
|
ai_assert(NULL != v);
|
||||||
|
return v->Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API float aiVector2SquareLength(
|
||||||
|
const C_STRUCT aiVector2D* v) {
|
||||||
|
ai_assert(NULL != v);
|
||||||
|
return v->SquareLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector2Negate(
|
||||||
|
C_STRUCT aiVector2D* dst) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
*dst = -(*dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API float aiVector2DotProduct(
|
||||||
|
const C_STRUCT aiVector2D* a,
|
||||||
|
const C_STRUCT aiVector2D* b) {
|
||||||
|
ai_assert(NULL != a);
|
||||||
|
ai_assert(NULL != b);
|
||||||
|
return (*a) * (*b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector2Normalize(
|
||||||
|
C_STRUCT aiVector2D* v) {
|
||||||
|
ai_assert(NULL != v);
|
||||||
|
v->Normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API int aiVector3AreEqual(
|
||||||
|
const C_STRUCT aiVector3D* a,
|
||||||
|
const C_STRUCT aiVector3D* b) {
|
||||||
|
ai_assert(NULL != a);
|
||||||
|
ai_assert(NULL != b);
|
||||||
|
return *a == *b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API int aiVector3AreEqualEpsilon(
|
||||||
|
const C_STRUCT aiVector3D* a,
|
||||||
|
const C_STRUCT aiVector3D* b,
|
||||||
|
const float epsilon) {
|
||||||
|
ai_assert(NULL != a);
|
||||||
|
ai_assert(NULL != b);
|
||||||
|
return a->Equal(*b, epsilon);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API int aiVector3LessThan(
|
||||||
|
const C_STRUCT aiVector3D* a,
|
||||||
|
const C_STRUCT aiVector3D* b) {
|
||||||
|
ai_assert(NULL != a);
|
||||||
|
ai_assert(NULL != b);
|
||||||
|
return *a < *b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector3Add(
|
||||||
|
C_STRUCT aiVector3D* dst,
|
||||||
|
const C_STRUCT aiVector3D* src) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
ai_assert(NULL != src);
|
||||||
|
*dst = *dst + *src;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector3Subtract(
|
||||||
|
C_STRUCT aiVector3D* dst,
|
||||||
|
const C_STRUCT aiVector3D* src) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
ai_assert(NULL != src);
|
||||||
|
*dst = *dst - *src;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector3Scale(
|
||||||
|
C_STRUCT aiVector3D* dst,
|
||||||
|
const float s) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
*dst *= s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector3SymMul(
|
||||||
|
C_STRUCT aiVector3D* dst,
|
||||||
|
const C_STRUCT aiVector3D* other) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
ai_assert(NULL != other);
|
||||||
|
*dst = dst->SymMul(*other);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector3DivideByScalar(
|
||||||
|
C_STRUCT aiVector3D* dst, const float s) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
*dst /= s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector3DivideByVector(
|
||||||
|
C_STRUCT aiVector3D* dst,
|
||||||
|
C_STRUCT aiVector3D* v) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
ai_assert(NULL != v);
|
||||||
|
*dst = *dst / *v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API float aiVector3Length(
|
||||||
|
const C_STRUCT aiVector3D* v) {
|
||||||
|
ai_assert(NULL != v);
|
||||||
|
return v->Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API float aiVector3SquareLength(
|
||||||
|
const C_STRUCT aiVector3D* v) {
|
||||||
|
ai_assert(NULL != v);
|
||||||
|
return v->SquareLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector3Negate(
|
||||||
|
C_STRUCT aiVector3D* dst) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
*dst = -(*dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API float aiVector3DotProduct(
|
||||||
|
const C_STRUCT aiVector3D* a,
|
||||||
|
const C_STRUCT aiVector3D* b) {
|
||||||
|
ai_assert(NULL != a);
|
||||||
|
ai_assert(NULL != b);
|
||||||
|
return (*a) * (*b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector3CrossProduct(
|
||||||
|
C_STRUCT aiVector3D* dst,
|
||||||
|
const C_STRUCT aiVector3D* a,
|
||||||
|
const C_STRUCT aiVector3D* b) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
ai_assert(NULL != a);
|
||||||
|
ai_assert(NULL != b);
|
||||||
|
*dst = *a ^ *b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector3Normalize(
|
||||||
|
C_STRUCT aiVector3D* v) {
|
||||||
|
ai_assert(NULL != v);
|
||||||
|
v->Normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector3NormalizeSafe(
|
||||||
|
C_STRUCT aiVector3D* v) {
|
||||||
|
ai_assert(NULL != v);
|
||||||
|
v->NormalizeSafe();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiVector3RotateByQuaternion(
|
||||||
|
C_STRUCT aiVector3D* v,
|
||||||
|
const C_STRUCT aiQuaternion* q) {
|
||||||
|
ai_assert(NULL != v);
|
||||||
|
ai_assert(NULL != q);
|
||||||
|
*v = q->Rotate(*v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix3FromMatrix4(
|
||||||
|
C_STRUCT aiMatrix3x3* dst,
|
||||||
|
const C_STRUCT aiMatrix4x4* mat) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
*dst = aiMatrix3x3(*mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix3FromQuaternion(
|
||||||
|
C_STRUCT aiMatrix3x3* mat,
|
||||||
|
const C_STRUCT aiQuaternion* q) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
ai_assert(NULL != q);
|
||||||
|
*mat = q->GetMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API int aiMatrix3AreEqual(
|
||||||
|
const C_STRUCT aiMatrix3x3* a,
|
||||||
|
const C_STRUCT aiMatrix3x3* b) {
|
||||||
|
ai_assert(NULL != a);
|
||||||
|
ai_assert(NULL != b);
|
||||||
|
return *a == *b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API int aiMatrix3AreEqualEpsilon(
|
||||||
|
const C_STRUCT aiMatrix3x3* a,
|
||||||
|
const C_STRUCT aiMatrix3x3* b,
|
||||||
|
const float epsilon) {
|
||||||
|
ai_assert(NULL != a);
|
||||||
|
ai_assert(NULL != b);
|
||||||
|
return a->Equal(*b, epsilon);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix3Inverse(C_STRUCT aiMatrix3x3* mat) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
mat->Inverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API float aiMatrix3Determinant(const C_STRUCT aiMatrix3x3* mat) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
return mat->Determinant();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix3RotationZ(
|
||||||
|
C_STRUCT aiMatrix3x3* mat,
|
||||||
|
const float angle) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
aiMatrix3x3::RotationZ(angle, *mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix3FromRotationAroundAxis(
|
||||||
|
C_STRUCT aiMatrix3x3* mat,
|
||||||
|
const C_STRUCT aiVector3D* axis,
|
||||||
|
const float angle) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
ai_assert(NULL != axis);
|
||||||
|
aiMatrix3x3::Rotation(angle, *axis, *mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix3Translation(
|
||||||
|
C_STRUCT aiMatrix3x3* mat,
|
||||||
|
const C_STRUCT aiVector2D* translation) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
ai_assert(NULL != translation);
|
||||||
|
aiMatrix3x3::Translation(*translation, *mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix3FromTo(
|
||||||
|
C_STRUCT aiMatrix3x3* mat,
|
||||||
|
const C_STRUCT aiVector3D* from,
|
||||||
|
const C_STRUCT aiVector3D* to) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
ai_assert(NULL != from);
|
||||||
|
ai_assert(NULL != to);
|
||||||
|
aiMatrix3x3::FromToMatrix(*from, *to, *mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix4FromMatrix3(
|
||||||
|
C_STRUCT aiMatrix4x4* dst,
|
||||||
|
const C_STRUCT aiMatrix3x3* mat) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
*dst = aiMatrix4x4(*mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix4FromScalingQuaternionPosition(
|
||||||
|
C_STRUCT aiMatrix4x4* mat,
|
||||||
|
const C_STRUCT aiVector3D* scaling,
|
||||||
|
const C_STRUCT aiQuaternion* rotation,
|
||||||
|
const C_STRUCT aiVector3D* position) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
ai_assert(NULL != scaling);
|
||||||
|
ai_assert(NULL != rotation);
|
||||||
|
ai_assert(NULL != position);
|
||||||
|
*mat = aiMatrix4x4(*scaling, *rotation, *position);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix4Add(
|
||||||
|
C_STRUCT aiMatrix4x4* dst,
|
||||||
|
const C_STRUCT aiMatrix4x4* src) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
ai_assert(NULL != src);
|
||||||
|
*dst = *dst + *src;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API int aiMatrix4AreEqual(
|
||||||
|
const C_STRUCT aiMatrix4x4* a,
|
||||||
|
const C_STRUCT aiMatrix4x4* b) {
|
||||||
|
ai_assert(NULL != a);
|
||||||
|
ai_assert(NULL != b);
|
||||||
|
return *a == *b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API int aiMatrix4AreEqualEpsilon(
|
||||||
|
const C_STRUCT aiMatrix4x4* a,
|
||||||
|
const C_STRUCT aiMatrix4x4* b,
|
||||||
|
const float epsilon) {
|
||||||
|
ai_assert(NULL != a);
|
||||||
|
ai_assert(NULL != b);
|
||||||
|
return a->Equal(*b, epsilon);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix4Inverse(C_STRUCT aiMatrix4x4* mat) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
mat->Inverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API float aiMatrix4Determinant(const C_STRUCT aiMatrix4x4* mat) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
return mat->Determinant();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API int aiMatrix4IsIdentity(const C_STRUCT aiMatrix4x4* mat) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
return mat->IsIdentity();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix4DecomposeIntoScalingEulerAnglesPosition(
|
||||||
|
const C_STRUCT aiMatrix4x4* mat,
|
||||||
|
C_STRUCT aiVector3D* scaling,
|
||||||
|
C_STRUCT aiVector3D* rotation,
|
||||||
|
C_STRUCT aiVector3D* position) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
ai_assert(NULL != scaling);
|
||||||
|
ai_assert(NULL != rotation);
|
||||||
|
ai_assert(NULL != position);
|
||||||
|
mat->Decompose(*scaling, *rotation, *position);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix4DecomposeIntoScalingAxisAnglePosition(
|
||||||
|
const C_STRUCT aiMatrix4x4* mat,
|
||||||
|
C_STRUCT aiVector3D* scaling,
|
||||||
|
C_STRUCT aiVector3D* axis,
|
||||||
|
float* angle,
|
||||||
|
C_STRUCT aiVector3D* position) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
ai_assert(NULL != scaling);
|
||||||
|
ai_assert(NULL != axis);
|
||||||
|
ai_assert(NULL != angle);
|
||||||
|
ai_assert(NULL != position);
|
||||||
|
mat->Decompose(*scaling, *axis, *angle, *position);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix4DecomposeNoScaling(
|
||||||
|
const C_STRUCT aiMatrix4x4* mat,
|
||||||
|
C_STRUCT aiQuaternion* rotation,
|
||||||
|
C_STRUCT aiVector3D* position) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
ai_assert(NULL != rotation);
|
||||||
|
ai_assert(NULL != position);
|
||||||
|
mat->DecomposeNoScaling(*rotation, *position);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix4FromEulerAngles(
|
||||||
|
C_STRUCT aiMatrix4x4* mat,
|
||||||
|
float x, float y, float z) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
mat->FromEulerAnglesXYZ(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix4RotationX(
|
||||||
|
C_STRUCT aiMatrix4x4* mat,
|
||||||
|
const float angle) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
aiMatrix4x4::RotationX(angle, *mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix4RotationY(
|
||||||
|
C_STRUCT aiMatrix4x4* mat,
|
||||||
|
const float angle) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
aiMatrix4x4::RotationY(angle, *mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix4RotationZ(
|
||||||
|
C_STRUCT aiMatrix4x4* mat,
|
||||||
|
const float angle) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
aiMatrix4x4::RotationZ(angle, *mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix4FromRotationAroundAxis(
|
||||||
|
C_STRUCT aiMatrix4x4* mat,
|
||||||
|
const C_STRUCT aiVector3D* axis,
|
||||||
|
const float angle) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
ai_assert(NULL != axis);
|
||||||
|
aiMatrix4x4::Rotation(angle, *axis, *mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix4Translation(
|
||||||
|
C_STRUCT aiMatrix4x4* mat,
|
||||||
|
const C_STRUCT aiVector3D* translation) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
ai_assert(NULL != translation);
|
||||||
|
aiMatrix4x4::Translation(*translation, *mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix4Scaling(
|
||||||
|
C_STRUCT aiMatrix4x4* mat,
|
||||||
|
const C_STRUCT aiVector3D* scaling) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
ai_assert(NULL != scaling);
|
||||||
|
aiMatrix4x4::Scaling(*scaling, *mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiMatrix4FromTo(
|
||||||
|
C_STRUCT aiMatrix4x4* mat,
|
||||||
|
const C_STRUCT aiVector3D* from,
|
||||||
|
const C_STRUCT aiVector3D* to) {
|
||||||
|
ai_assert(NULL != mat);
|
||||||
|
ai_assert(NULL != from);
|
||||||
|
ai_assert(NULL != to);
|
||||||
|
aiMatrix4x4::FromToMatrix(*from, *to, *mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiQuaternionFromEulerAngles(
|
||||||
|
C_STRUCT aiQuaternion* q,
|
||||||
|
float x, float y, float z) {
|
||||||
|
ai_assert(NULL != q);
|
||||||
|
*q = aiQuaternion(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiQuaternionFromAxisAngle(
|
||||||
|
C_STRUCT aiQuaternion* q,
|
||||||
|
const C_STRUCT aiVector3D* axis,
|
||||||
|
const float angle) {
|
||||||
|
ai_assert(NULL != q);
|
||||||
|
ai_assert(NULL != axis);
|
||||||
|
*q = aiQuaternion(*axis, angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiQuaternionFromNormalizedQuaternion(
|
||||||
|
C_STRUCT aiQuaternion* q,
|
||||||
|
const C_STRUCT aiVector3D* normalized) {
|
||||||
|
ai_assert(NULL != q);
|
||||||
|
ai_assert(NULL != normalized);
|
||||||
|
*q = aiQuaternion(*normalized);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API int aiQuaternionAreEqual(
|
||||||
|
const C_STRUCT aiQuaternion* a,
|
||||||
|
const C_STRUCT aiQuaternion* b) {
|
||||||
|
ai_assert(NULL != a);
|
||||||
|
ai_assert(NULL != b);
|
||||||
|
return *a == *b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API int aiQuaternionAreEqualEpsilon(
|
||||||
|
const C_STRUCT aiQuaternion* a,
|
||||||
|
const C_STRUCT aiQuaternion* b,
|
||||||
|
const float epsilon) {
|
||||||
|
ai_assert(NULL != a);
|
||||||
|
ai_assert(NULL != b);
|
||||||
|
return a->Equal(*b, epsilon);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiQuaternionNormalize(
|
||||||
|
C_STRUCT aiQuaternion* q) {
|
||||||
|
ai_assert(NULL != q);
|
||||||
|
q->Normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiQuaternionConjugate(
|
||||||
|
C_STRUCT aiQuaternion* q) {
|
||||||
|
ai_assert(NULL != q);
|
||||||
|
q->Conjugate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiQuaternionMultiply(
|
||||||
|
C_STRUCT aiQuaternion* dst,
|
||||||
|
const C_STRUCT aiQuaternion* q) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
ai_assert(NULL != q);
|
||||||
|
*dst = (*dst) * (*q);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiQuaternionInterpolate(
|
||||||
|
C_STRUCT aiQuaternion* dst,
|
||||||
|
const C_STRUCT aiQuaternion* start,
|
||||||
|
const C_STRUCT aiQuaternion* end,
|
||||||
|
const float factor) {
|
||||||
|
ai_assert(NULL != dst);
|
||||||
|
ai_assert(NULL != start);
|
||||||
|
ai_assert(NULL != end);
|
||||||
|
aiQuaternion::Interpolate(*dst, *start, *end, factor);
|
||||||
|
}
|
||||||
|
|
|
@ -655,7 +655,8 @@ bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
|
||||||
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
||||||
const TransformationComp comp = static_cast<TransformationComp>(i);
|
const TransformationComp comp = static_cast<TransformationComp>(i);
|
||||||
|
|
||||||
if (comp == TransformationComp_Rotation || comp == TransformationComp_Scaling || comp == TransformationComp_Translation) {
|
if (comp == TransformationComp_Rotation || comp == TransformationComp_Scaling || comp == TransformationComp_Translation ||
|
||||||
|
comp == TransformationComp_PreRotation || comp == TransformationComp_PostRotation) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2739,15 +2740,12 @@ void FBXConverter::GenerateNodeAnimations(std::vector<aiNodeAnim *> &node_anims,
|
||||||
// be invoked _later_ (animations come first). If this node has only rotation,
|
// be invoked _later_ (animations come first). If this node has only rotation,
|
||||||
// scaling and translation _and_ there are no animated other components either,
|
// scaling and translation _and_ there are no animated other components either,
|
||||||
// we can use a single node and also a single node animation channel.
|
// we can use a single node and also a single node animation channel.
|
||||||
if (!has_complex && !NeedsComplexTransformationChain(target)) {
|
if( !has_complex && !NeedsComplexTransformationChain(target)) {
|
||||||
|
aiNodeAnim* const nd = GenerateSimpleNodeAnim(fixed_name, target, chain,
|
||||||
aiNodeAnim *const nd = GenerateSimpleNodeAnim(fixed_name, target, chain,
|
|
||||||
node_property_map.end(),
|
node_property_map.end(),
|
||||||
layer_map,
|
|
||||||
start, stop,
|
start, stop,
|
||||||
max_time,
|
max_time,
|
||||||
min_time,
|
min_time
|
||||||
true // input is TRS order, assimp is SRT
|
|
||||||
);
|
);
|
||||||
|
|
||||||
ai_assert(nd);
|
ai_assert(nd);
|
||||||
|
@ -3021,133 +3019,121 @@ aiNodeAnim *FBXConverter::GenerateTranslationNodeAnim(const std::string &name,
|
||||||
return na.release();
|
return na.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
aiNodeAnim *FBXConverter::GenerateSimpleNodeAnim(const std::string &name,
|
aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
|
||||||
const Model &target,
|
const Model& target,
|
||||||
NodeMap::const_iterator chain[TransformationComp_MAXIMUM],
|
NodeMap::const_iterator chain[TransformationComp_MAXIMUM],
|
||||||
NodeMap::const_iterator iter_end,
|
NodeMap::const_iterator iterEnd,
|
||||||
const LayerMap &layer_map,
|
|
||||||
int64_t start, int64_t stop,
|
int64_t start, int64_t stop,
|
||||||
double &max_time,
|
double& maxTime,
|
||||||
double &min_time,
|
double& minTime)
|
||||||
bool reverse_order)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
std::unique_ptr<aiNodeAnim> na(new aiNodeAnim());
|
std::unique_ptr<aiNodeAnim> na(new aiNodeAnim());
|
||||||
na->mNodeName.Set(name);
|
na->mNodeName.Set(name);
|
||||||
|
|
||||||
const PropertyTable &props = target.Props();
|
const PropertyTable &props = target.Props();
|
||||||
|
|
||||||
// need to convert from TRS order to SRT?
|
// collect unique times and keyframe lists
|
||||||
if (reverse_order) {
|
KeyFrameListList keyframeLists[TransformationComp_MAXIMUM];
|
||||||
|
KeyTimeList keytimes;
|
||||||
|
|
||||||
aiVector3D def_scale = PropertyGet(props, "Lcl Scaling", aiVector3D(1.f, 1.f, 1.f));
|
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
||||||
aiVector3D def_translate = PropertyGet(props, "Lcl Translation", aiVector3D(0.f, 0.f, 0.f));
|
if (chain[i] == iterEnd)
|
||||||
aiVector3D def_rot = PropertyGet(props, "Lcl Rotation", aiVector3D(0.f, 0.f, 0.f));
|
continue;
|
||||||
|
|
||||||
KeyFrameListList scaling;
|
keyframeLists[i] = GetKeyframeList((*chain[i]).second, start, stop);
|
||||||
KeyFrameListList translation;
|
|
||||||
KeyFrameListList rotation;
|
|
||||||
|
|
||||||
if (chain[TransformationComp_Scaling] != iter_end) {
|
for (KeyFrameListList::const_iterator it = keyframeLists[i].begin(); it != keyframeLists[i].end(); ++it) {
|
||||||
scaling = GetKeyframeList((*chain[TransformationComp_Scaling]).second, start, stop);
|
const KeyTimeList& times = *std::get<0>(*it);
|
||||||
|
keytimes.insert(keytimes.end(), times.begin(), times.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chain[TransformationComp_Translation] != iter_end) {
|
// remove duplicates
|
||||||
translation = GetKeyframeList((*chain[TransformationComp_Translation]).second, start, stop);
|
std::sort(keytimes.begin(), keytimes.end());
|
||||||
|
|
||||||
|
auto last = std::unique(keytimes.begin(), keytimes.end());
|
||||||
|
keytimes.erase(last, keytimes.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chain[TransformationComp_Rotation] != iter_end) {
|
const Model::RotOrder rotOrder = target.RotationOrder();
|
||||||
rotation = GetKeyframeList((*chain[TransformationComp_Rotation]).second, start, stop);
|
const size_t keyCount = keytimes.size();
|
||||||
|
|
||||||
|
aiVector3D defTranslate = PropertyGet(props, "Lcl Translation", aiVector3D(0.f, 0.f, 0.f));
|
||||||
|
aiVector3D defRotation = PropertyGet(props, "Lcl Rotation", aiVector3D(0.f, 0.f, 0.f));
|
||||||
|
aiVector3D defScale = PropertyGet(props, "Lcl Scaling", aiVector3D(1.f, 1.f, 1.f));
|
||||||
|
aiQuaternion defQuat = EulerToQuaternion(defRotation, rotOrder);
|
||||||
|
|
||||||
|
aiVectorKey* outTranslations = new aiVectorKey[keyCount];
|
||||||
|
aiQuatKey* outRotations = new aiQuatKey[keyCount];
|
||||||
|
aiVectorKey* outScales = new aiVectorKey[keyCount];
|
||||||
|
|
||||||
|
if (keyframeLists[TransformationComp_Translation].size() > 0) {
|
||||||
|
InterpolateKeys(outTranslations, keytimes, keyframeLists[TransformationComp_Translation], defTranslate, maxTime, minTime);
|
||||||
|
} else {
|
||||||
|
for (size_t i = 0; i < keyCount; ++i) {
|
||||||
|
outTranslations[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps;
|
||||||
|
outTranslations[i].mValue = defTranslate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyFrameListList joined;
|
if (keyframeLists[TransformationComp_Rotation].size() > 0) {
|
||||||
joined.insert(joined.end(), scaling.begin(), scaling.end());
|
InterpolateKeys(outRotations, keytimes, keyframeLists[TransformationComp_Rotation], defRotation, maxTime, minTime, rotOrder);
|
||||||
joined.insert(joined.end(), translation.begin(), translation.end());
|
} else {
|
||||||
joined.insert(joined.end(), rotation.begin(), rotation.end());
|
for (size_t i = 0; i < keyCount; ++i) {
|
||||||
|
outRotations[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps;
|
||||||
const KeyTimeList × = GetKeyTimeList(joined);
|
outRotations[i].mValue = defQuat;
|
||||||
|
}
|
||||||
aiQuatKey *out_quat = new aiQuatKey[times.size()];
|
|
||||||
aiVectorKey *out_scale = new aiVectorKey[times.size()];
|
|
||||||
aiVectorKey *out_translation = new aiVectorKey[times.size()];
|
|
||||||
|
|
||||||
if (times.size()) {
|
|
||||||
ConvertTransformOrder_TRStoSRT(out_quat, out_scale, out_translation,
|
|
||||||
scaling,
|
|
||||||
translation,
|
|
||||||
rotation,
|
|
||||||
times,
|
|
||||||
max_time,
|
|
||||||
min_time,
|
|
||||||
target.RotationOrder(),
|
|
||||||
def_scale,
|
|
||||||
def_translate,
|
|
||||||
def_rot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX remove duplicates / redundant keys which this operation did
|
if (keyframeLists[TransformationComp_Scaling].size() > 0) {
|
||||||
// likely produce if not all three channels were equally dense.
|
InterpolateKeys(outScales, keytimes, keyframeLists[TransformationComp_Scaling], defScale, maxTime, minTime);
|
||||||
|
} else {
|
||||||
|
for (size_t i = 0; i < keyCount; ++i) {
|
||||||
|
outScales[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps;
|
||||||
|
outScales[i].mValue = defScale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
na->mNumScalingKeys = static_cast<unsigned int>(times.size());
|
bool ok = false;
|
||||||
|
const float zero_epsilon = 1e-6f;
|
||||||
|
|
||||||
|
const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
|
||||||
|
if (ok && preRotation.SquareLength() > zero_epsilon) {
|
||||||
|
const aiQuaternion preQuat = EulerToQuaternion(preRotation, Model::RotOrder_EulerXYZ);
|
||||||
|
for (size_t i = 0; i < keyCount; ++i) {
|
||||||
|
outRotations[i].mValue = preQuat * outRotations[i].mValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const aiVector3D& postRotation = PropertyGet<aiVector3D>(props, "PostRotation", ok);
|
||||||
|
if (ok && postRotation.SquareLength() > zero_epsilon) {
|
||||||
|
const aiQuaternion postQuat = EulerToQuaternion(postRotation, Model::RotOrder_EulerXYZ);
|
||||||
|
for (size_t i = 0; i < keyCount; ++i) {
|
||||||
|
outRotations[i].mValue = outRotations[i].mValue * postQuat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert TRS to SRT
|
||||||
|
for (size_t i = 0; i < keyCount; ++i) {
|
||||||
|
aiQuaternion& r = outRotations[i].mValue;
|
||||||
|
aiVector3D& s = outScales[i].mValue;
|
||||||
|
aiVector3D& t = outTranslations[i].mValue;
|
||||||
|
|
||||||
|
aiMatrix4x4 mat, temp;
|
||||||
|
aiMatrix4x4::Translation(t, mat);
|
||||||
|
mat *= aiMatrix4x4(r.GetMatrix());
|
||||||
|
mat *= aiMatrix4x4::Scaling(s, temp);
|
||||||
|
|
||||||
|
mat.Decompose(s, r, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
na->mNumScalingKeys = static_cast<unsigned int>(keyCount);
|
||||||
na->mNumRotationKeys = na->mNumScalingKeys;
|
na->mNumRotationKeys = na->mNumScalingKeys;
|
||||||
na->mNumPositionKeys = na->mNumScalingKeys;
|
na->mNumPositionKeys = na->mNumScalingKeys;
|
||||||
|
|
||||||
na->mScalingKeys = out_scale;
|
na->mScalingKeys = outScales;
|
||||||
na->mRotationKeys = out_quat;
|
na->mRotationKeys = outRotations;
|
||||||
na->mPositionKeys = out_translation;
|
na->mPositionKeys = outTranslations;
|
||||||
} else {
|
|
||||||
|
|
||||||
// if a particular transformation is not given, grab it from
|
|
||||||
// the corresponding node to meet the semantics of aiNodeAnim,
|
|
||||||
// which requires all of rotation, scaling and translation
|
|
||||||
// to be set.
|
|
||||||
if (chain[TransformationComp_Scaling] != iter_end) {
|
|
||||||
ConvertScaleKeys(na.get(), (*chain[TransformationComp_Scaling]).second,
|
|
||||||
layer_map,
|
|
||||||
start, stop,
|
|
||||||
max_time,
|
|
||||||
min_time);
|
|
||||||
} else {
|
|
||||||
na->mScalingKeys = new aiVectorKey[1];
|
|
||||||
na->mNumScalingKeys = 1;
|
|
||||||
|
|
||||||
na->mScalingKeys[0].mTime = 0.;
|
|
||||||
na->mScalingKeys[0].mValue = PropertyGet(props, "Lcl Scaling",
|
|
||||||
aiVector3D(1.f, 1.f, 1.f));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chain[TransformationComp_Rotation] != iter_end) {
|
|
||||||
ConvertRotationKeys(na.get(), (*chain[TransformationComp_Rotation]).second,
|
|
||||||
layer_map,
|
|
||||||
start, stop,
|
|
||||||
max_time,
|
|
||||||
min_time,
|
|
||||||
target.RotationOrder());
|
|
||||||
} else {
|
|
||||||
na->mRotationKeys = new aiQuatKey[1];
|
|
||||||
na->mNumRotationKeys = 1;
|
|
||||||
|
|
||||||
na->mRotationKeys[0].mTime = 0.;
|
|
||||||
na->mRotationKeys[0].mValue = EulerToQuaternion(
|
|
||||||
PropertyGet(props, "Lcl Rotation", aiVector3D(0.f, 0.f, 0.f)),
|
|
||||||
target.RotationOrder());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chain[TransformationComp_Translation] != iter_end) {
|
|
||||||
ConvertTranslationKeys(na.get(), (*chain[TransformationComp_Translation]).second,
|
|
||||||
layer_map,
|
|
||||||
start, stop,
|
|
||||||
max_time,
|
|
||||||
min_time);
|
|
||||||
} else {
|
|
||||||
na->mPositionKeys = new aiVectorKey[1];
|
|
||||||
na->mNumPositionKeys = 1;
|
|
||||||
|
|
||||||
na->mPositionKeys[0].mTime = 0.;
|
|
||||||
na->mPositionKeys[0].mValue = PropertyGet(props, "Lcl Translation",
|
|
||||||
aiVector3D(0.f, 0.f, 0.f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return na.release();
|
return na.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3328,10 +3314,7 @@ void FBXConverter::InterpolateKeys(aiQuatKey *valOut, const KeyTimeList &keys, c
|
||||||
// take shortest path by checking the inner product
|
// take shortest path by checking the inner product
|
||||||
// http://www.3dkingdoms.com/weekly/weekly.php?a=36
|
// http://www.3dkingdoms.com/weekly/weekly.php?a=36
|
||||||
if (quat.x * lastq.x + quat.y * lastq.y + quat.z * lastq.z + quat.w * lastq.w < 0) {
|
if (quat.x * lastq.x + quat.y * lastq.y + quat.z * lastq.z + quat.w * lastq.w < 0) {
|
||||||
quat.x = -quat.x;
|
quat.Conjugate();
|
||||||
quat.y = -quat.y;
|
|
||||||
quat.z = -quat.z;
|
|
||||||
quat.w = -quat.w;
|
|
||||||
}
|
}
|
||||||
lastq = quat;
|
lastq = quat;
|
||||||
|
|
||||||
|
@ -3339,60 +3322,6 @@ void FBXConverter::InterpolateKeys(aiQuatKey *valOut, const KeyTimeList &keys, c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FBXConverter::ConvertTransformOrder_TRStoSRT(aiQuatKey *out_quat, aiVectorKey *out_scale,
|
|
||||||
aiVectorKey *out_translation,
|
|
||||||
const KeyFrameListList &scaling,
|
|
||||||
const KeyFrameListList &translation,
|
|
||||||
const KeyFrameListList &rotation,
|
|
||||||
const KeyTimeList ×,
|
|
||||||
double &maxTime,
|
|
||||||
double &minTime,
|
|
||||||
Model::RotOrder order,
|
|
||||||
const aiVector3D &def_scale,
|
|
||||||
const aiVector3D &def_translate,
|
|
||||||
const aiVector3D &def_rotation) {
|
|
||||||
if (rotation.size()) {
|
|
||||||
InterpolateKeys(out_quat, times, rotation, def_rotation, maxTime, minTime, order);
|
|
||||||
} else {
|
|
||||||
for (size_t i = 0; i < times.size(); ++i) {
|
|
||||||
out_quat[i].mTime = CONVERT_FBX_TIME(times[i]) * anim_fps;
|
|
||||||
out_quat[i].mValue = EulerToQuaternion(def_rotation, order);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scaling.size()) {
|
|
||||||
InterpolateKeys(out_scale, times, scaling, def_scale, maxTime, minTime);
|
|
||||||
} else {
|
|
||||||
for (size_t i = 0; i < times.size(); ++i) {
|
|
||||||
out_scale[i].mTime = CONVERT_FBX_TIME(times[i]) * anim_fps;
|
|
||||||
out_scale[i].mValue = def_scale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (translation.size()) {
|
|
||||||
InterpolateKeys(out_translation, times, translation, def_translate, maxTime, minTime);
|
|
||||||
} else {
|
|
||||||
for (size_t i = 0; i < times.size(); ++i) {
|
|
||||||
out_translation[i].mTime = CONVERT_FBX_TIME(times[i]) * anim_fps;
|
|
||||||
out_translation[i].mValue = def_translate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t count = times.size();
|
|
||||||
for (size_t i = 0; i < count; ++i) {
|
|
||||||
aiQuaternion &r = out_quat[i].mValue;
|
|
||||||
aiVector3D &s = out_scale[i].mValue;
|
|
||||||
aiVector3D &t = out_translation[i].mValue;
|
|
||||||
|
|
||||||
aiMatrix4x4 mat, temp;
|
|
||||||
aiMatrix4x4::Translation(t, mat);
|
|
||||||
mat *= aiMatrix4x4(r.GetMatrix());
|
|
||||||
mat *= aiMatrix4x4::Scaling(s, temp);
|
|
||||||
|
|
||||||
mat.Decompose(s, r, t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
aiQuaternion FBXConverter::EulerToQuaternion(const aiVector3D &rot, Model::RotOrder order) {
|
aiQuaternion FBXConverter::EulerToQuaternion(const aiVector3D &rot, Model::RotOrder order) {
|
||||||
aiMatrix4x4 m;
|
aiMatrix4x4 m;
|
||||||
GetRotationMatrix(order, rot, m);
|
GetRotationMatrix(order, rot, m);
|
||||||
|
|
|
@ -349,12 +349,10 @@ private:
|
||||||
aiNodeAnim* GenerateSimpleNodeAnim(const std::string& name,
|
aiNodeAnim* GenerateSimpleNodeAnim(const std::string& name,
|
||||||
const Model& target,
|
const Model& target,
|
||||||
NodeMap::const_iterator chain[TransformationComp_MAXIMUM],
|
NodeMap::const_iterator chain[TransformationComp_MAXIMUM],
|
||||||
NodeMap::const_iterator iter_end,
|
NodeMap::const_iterator iterEnd,
|
||||||
const LayerMap& layer_map,
|
|
||||||
int64_t start, int64_t stop,
|
int64_t start, int64_t stop,
|
||||||
double& max_time,
|
double& maxTime,
|
||||||
double& min_time,
|
double& minTime);
|
||||||
bool reverse_order = false);
|
|
||||||
|
|
||||||
// key (time), value, mapto (component index)
|
// key (time), value, mapto (component index)
|
||||||
typedef std::tuple<std::shared_ptr<KeyTimeList>, std::shared_ptr<KeyValueList>, unsigned int > KeyFrameList;
|
typedef std::tuple<std::shared_ptr<KeyTimeList>, std::shared_ptr<KeyValueList>, unsigned int > KeyFrameList;
|
||||||
|
@ -379,20 +377,6 @@ private:
|
||||||
double& minTime,
|
double& minTime,
|
||||||
Model::RotOrder order);
|
Model::RotOrder order);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void ConvertTransformOrder_TRStoSRT(aiQuatKey* out_quat, aiVectorKey* out_scale,
|
|
||||||
aiVectorKey* out_translation,
|
|
||||||
const KeyFrameListList& scaling,
|
|
||||||
const KeyFrameListList& translation,
|
|
||||||
const KeyFrameListList& rotation,
|
|
||||||
const KeyTimeList& times,
|
|
||||||
double& maxTime,
|
|
||||||
double& minTime,
|
|
||||||
Model::RotOrder order,
|
|
||||||
const aiVector3D& def_scale,
|
|
||||||
const aiVector3D& def_translate,
|
|
||||||
const aiVector3D& def_rotation);
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// euler xyz -> quat
|
// euler xyz -> quat
|
||||||
aiQuaternion EulerToQuaternion(const aiVector3D& rot, Model::RotOrder order);
|
aiQuaternion EulerToQuaternion(const aiVector3D& rot, Model::RotOrder order);
|
||||||
|
|
|
@ -952,7 +952,7 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector<unsigned int> &
|
||||||
|
|
||||||
void glTF2Importer::ImportNodes(glTF2::Asset &r) {
|
void glTF2Importer::ImportNodes(glTF2::Asset &r) {
|
||||||
if (!r.scene) {
|
if (!r.scene) {
|
||||||
return;
|
throw DeadlyImportError("GLTF: No scene");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Ref<Node>> rootNodes = r.scene->nodes;
|
std::vector<Ref<Node>> rootNodes = r.scene->nodes;
|
||||||
|
@ -970,6 +970,8 @@ void glTF2Importer::ImportNodes(glTF2::Asset &r) {
|
||||||
root->mChildren[root->mNumChildren++] = node;
|
root->mChildren[root->mNumChildren++] = node;
|
||||||
}
|
}
|
||||||
mScene->mRootNode = root;
|
mScene->mRootNode = root;
|
||||||
|
} else {
|
||||||
|
mScene->mRootNode = new aiNode("ROOT");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -562,6 +562,675 @@ ASSIMP_API size_t aiGetImportFormatCount(void);
|
||||||
* @return A description of that specific import format. NULL if pIndex is out of range.
|
* @return A description of that specific import format. NULL if pIndex is out of range.
|
||||||
*/
|
*/
|
||||||
ASSIMP_API const C_STRUCT aiImporterDesc* aiGetImportFormatDescription( size_t pIndex);
|
ASSIMP_API const C_STRUCT aiImporterDesc* aiGetImportFormatDescription( size_t pIndex);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Check if 2D vectors are equal.
|
||||||
|
* @param a First vector to compare
|
||||||
|
* @param b Second vector to compare
|
||||||
|
* @return 1 if the vectors are equal
|
||||||
|
* @return 0 if the vectors are not equal
|
||||||
|
*/
|
||||||
|
ASSIMP_API int aiVector2AreEqual(
|
||||||
|
const C_STRUCT aiVector2D* a,
|
||||||
|
const C_STRUCT aiVector2D* b);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Check if 2D vectors are equal using epsilon.
|
||||||
|
* @param a First vector to compare
|
||||||
|
* @param b Second vector to compare
|
||||||
|
* @param epsilon Epsilon
|
||||||
|
* @return 1 if the vectors are equal
|
||||||
|
* @return 0 if the vectors are not equal
|
||||||
|
*/
|
||||||
|
ASSIMP_API int aiVector2AreEqualEpsilon(
|
||||||
|
const C_STRUCT aiVector2D* a,
|
||||||
|
const C_STRUCT aiVector2D* b,
|
||||||
|
const float epsilon);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Add 2D vectors.
|
||||||
|
* @param dst First addend, receives result.
|
||||||
|
* @param src Vector to be added to 'dst'.
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector2Add(
|
||||||
|
C_STRUCT aiVector2D* dst,
|
||||||
|
const C_STRUCT aiVector2D* src);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Subtract 2D vectors.
|
||||||
|
* @param dst Minuend, receives result.
|
||||||
|
* @param src Vector to be subtracted from 'dst'.
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector2Subtract(
|
||||||
|
C_STRUCT aiVector2D* dst,
|
||||||
|
const C_STRUCT aiVector2D* src);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Multiply a 2D vector by a scalar.
|
||||||
|
* @param dst Vector to be scaled by \p s
|
||||||
|
* @param s Scale factor
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector2Scale(
|
||||||
|
C_STRUCT aiVector2D* dst,
|
||||||
|
const float s);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Multiply each component of a 2D vector with
|
||||||
|
* the components of another vector.
|
||||||
|
* @param dst First vector, receives result
|
||||||
|
* @param other Second vector
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector2SymMul(
|
||||||
|
C_STRUCT aiVector2D* dst,
|
||||||
|
const C_STRUCT aiVector2D* other);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Divide a 2D vector by a scalar.
|
||||||
|
* @param dst Vector to be divided by \p s
|
||||||
|
* @param s Scalar divisor
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector2DivideByScalar(
|
||||||
|
C_STRUCT aiVector2D* dst,
|
||||||
|
const float s);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Divide each component of a 2D vector by
|
||||||
|
* the components of another vector.
|
||||||
|
* @param dst Vector as the dividend
|
||||||
|
* @param v Vector as the divisor
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector2DivideByVector(
|
||||||
|
C_STRUCT aiVector2D* dst,
|
||||||
|
C_STRUCT aiVector2D* v);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Get the length of a 2D vector.
|
||||||
|
* @return v Vector to evaluate
|
||||||
|
*/
|
||||||
|
ASSIMP_API float aiVector2Length(
|
||||||
|
const C_STRUCT aiVector2D* v);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Get the squared length of a 2D vector.
|
||||||
|
* @return v Vector to evaluate
|
||||||
|
*/
|
||||||
|
ASSIMP_API float aiVector2SquareLength(
|
||||||
|
const C_STRUCT aiVector2D* v);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Negate a 2D vector.
|
||||||
|
* @param dst Vector to be negated
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector2Negate(
|
||||||
|
C_STRUCT aiVector2D* dst);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Get the dot product of 2D vectors.
|
||||||
|
* @param a First vector
|
||||||
|
* @param b Second vector
|
||||||
|
* @return The dot product of vectors
|
||||||
|
*/
|
||||||
|
ASSIMP_API float aiVector2DotProduct(
|
||||||
|
const C_STRUCT aiVector2D* a,
|
||||||
|
const C_STRUCT aiVector2D* b);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Normalize a 2D vector.
|
||||||
|
* @param v Vector to normalize
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector2Normalize(
|
||||||
|
C_STRUCT aiVector2D* v);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Check if 3D vectors are equal.
|
||||||
|
* @param a First vector to compare
|
||||||
|
* @param b Second vector to compare
|
||||||
|
* @return 1 if the vectors are equal
|
||||||
|
* @return 0 if the vectors are not equal
|
||||||
|
*/
|
||||||
|
ASSIMP_API int aiVector3AreEqual(
|
||||||
|
const C_STRUCT aiVector3D* a,
|
||||||
|
const C_STRUCT aiVector3D* b);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Check if 3D vectors are equal using epsilon.
|
||||||
|
* @param a First vector to compare
|
||||||
|
* @param b Second vector to compare
|
||||||
|
* @param epsilon Epsilon
|
||||||
|
* @return 1 if the vectors are equal
|
||||||
|
* @return 0 if the vectors are not equal
|
||||||
|
*/
|
||||||
|
ASSIMP_API int aiVector3AreEqualEpsilon(
|
||||||
|
const C_STRUCT aiVector3D* a,
|
||||||
|
const C_STRUCT aiVector3D* b,
|
||||||
|
const float epsilon);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Check if vector \p a is less than vector \p b.
|
||||||
|
* @param a First vector to compare
|
||||||
|
* @param b Second vector to compare
|
||||||
|
* @param epsilon Epsilon
|
||||||
|
* @return 1 if \p a is less than \p b
|
||||||
|
* @return 0 if \p a is equal or greater than \p b
|
||||||
|
*/
|
||||||
|
ASSIMP_API int aiVector3LessThan(
|
||||||
|
const C_STRUCT aiVector3D* a,
|
||||||
|
const C_STRUCT aiVector3D* b);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Add 3D vectors.
|
||||||
|
* @param dst First addend, receives result.
|
||||||
|
* @param src Vector to be added to 'dst'.
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector3Add(
|
||||||
|
C_STRUCT aiVector3D* dst,
|
||||||
|
const C_STRUCT aiVector3D* src);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Subtract 3D vectors.
|
||||||
|
* @param dst Minuend, receives result.
|
||||||
|
* @param src Vector to be subtracted from 'dst'.
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector3Subtract(
|
||||||
|
C_STRUCT aiVector3D* dst,
|
||||||
|
const C_STRUCT aiVector3D* src);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Multiply a 3D vector by a scalar.
|
||||||
|
* @param dst Vector to be scaled by \p s
|
||||||
|
* @param s Scale factor
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector3Scale(
|
||||||
|
C_STRUCT aiVector3D* dst,
|
||||||
|
const float s);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Multiply each component of a 3D vector with
|
||||||
|
* the components of another vector.
|
||||||
|
* @param dst First vector, receives result
|
||||||
|
* @param other Second vector
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector3SymMul(
|
||||||
|
C_STRUCT aiVector3D* dst,
|
||||||
|
const C_STRUCT aiVector3D* other);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Divide a 3D vector by a scalar.
|
||||||
|
* @param dst Vector to be divided by \p s
|
||||||
|
* @param s Scalar divisor
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector3DivideByScalar(
|
||||||
|
C_STRUCT aiVector3D* dst,
|
||||||
|
const float s);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Divide each component of a 3D vector by
|
||||||
|
* the components of another vector.
|
||||||
|
* @param dst Vector as the dividend
|
||||||
|
* @param v Vector as the divisor
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector3DivideByVector(
|
||||||
|
C_STRUCT aiVector3D* dst,
|
||||||
|
C_STRUCT aiVector3D* v);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Get the length of a 3D vector.
|
||||||
|
* @return v Vector to evaluate
|
||||||
|
*/
|
||||||
|
ASSIMP_API float aiVector3Length(
|
||||||
|
const C_STRUCT aiVector3D* v);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Get the squared length of a 3D vector.
|
||||||
|
* @return v Vector to evaluate
|
||||||
|
*/
|
||||||
|
ASSIMP_API float aiVector3SquareLength(
|
||||||
|
const C_STRUCT aiVector3D* v);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Negate a 3D vector.
|
||||||
|
* @param dst Vector to be negated
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector3Negate(
|
||||||
|
C_STRUCT aiVector3D* dst);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Get the dot product of 3D vectors.
|
||||||
|
* @param a First vector
|
||||||
|
* @param b Second vector
|
||||||
|
* @return The dot product of vectors
|
||||||
|
*/
|
||||||
|
ASSIMP_API float aiVector3DotProduct(
|
||||||
|
const C_STRUCT aiVector3D* a,
|
||||||
|
const C_STRUCT aiVector3D* b);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Get cross product of 3D vectors.
|
||||||
|
* @param dst Vector to receive the result.
|
||||||
|
* @param a First vector
|
||||||
|
* @param b Second vector
|
||||||
|
* @return The dot product of vectors
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector3CrossProduct(
|
||||||
|
C_STRUCT aiVector3D* dst,
|
||||||
|
const C_STRUCT aiVector3D* a,
|
||||||
|
const C_STRUCT aiVector3D* b);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Normalize a 3D vector.
|
||||||
|
* @param v Vector to normalize
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector3Normalize(
|
||||||
|
C_STRUCT aiVector3D* v);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Check for division by zero and normalize a 3D vector.
|
||||||
|
* @param v Vector to normalize
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector3NormalizeSafe(
|
||||||
|
C_STRUCT aiVector3D* v);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Rotate a 3D vector by a quaternion.
|
||||||
|
* @param v The vector to rotate by \p q
|
||||||
|
* @param q Quaternion to use to rotate \p v
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiVector3RotateByQuaternion(
|
||||||
|
C_STRUCT aiVector3D* v,
|
||||||
|
const C_STRUCT aiQuaternion* q);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Construct a 3x3 matrix from a 4x4 matrix.
|
||||||
|
* @param dst Receives the output matrix
|
||||||
|
* @param mat The 4x4 matrix to use
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix3FromMatrix4(
|
||||||
|
C_STRUCT aiMatrix3x3* dst,
|
||||||
|
const C_STRUCT aiMatrix4x4* mat);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Construct a 3x3 matrix from a quaternion.
|
||||||
|
* @param mat Receives the output matrix
|
||||||
|
* @param q The quaternion matrix to use
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix3FromQuaternion(
|
||||||
|
C_STRUCT aiMatrix3x3* mat,
|
||||||
|
const C_STRUCT aiQuaternion* q);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Check if 3x3 matrices are equal.
|
||||||
|
* @param a First matrix to compare
|
||||||
|
* @param b Second matrix to compare
|
||||||
|
* @return 1 if the matrices are equal
|
||||||
|
* @return 0 if the matrices are not equal
|
||||||
|
*/
|
||||||
|
ASSIMP_API int aiMatrix3AreEqual(
|
||||||
|
const C_STRUCT aiMatrix3x3* a,
|
||||||
|
const C_STRUCT aiMatrix3x3* b);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Check if 3x3 matrices are equal.
|
||||||
|
* @param a First matrix to compare
|
||||||
|
* @param b Second matrix to compare
|
||||||
|
* @param epsilon Epsilon
|
||||||
|
* @return 1 if the matrices are equal
|
||||||
|
* @return 0 if the matrices are not equal
|
||||||
|
*/
|
||||||
|
ASSIMP_API int aiMatrix3AreEqualEpsilon(
|
||||||
|
const C_STRUCT aiMatrix3x3* a,
|
||||||
|
const C_STRUCT aiMatrix3x3* b,
|
||||||
|
const float epsilon);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Invert a 3x3 matrix.
|
||||||
|
* @param mat Matrix to invert
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix3Inverse(
|
||||||
|
C_STRUCT aiMatrix3x3* mat);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Get the determinant of a 3x3 matrix.
|
||||||
|
* @param mat Matrix to get the determinant from
|
||||||
|
*/
|
||||||
|
ASSIMP_API float aiMatrix3Determinant(
|
||||||
|
const C_STRUCT aiMatrix3x3* mat);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Get a 3x3 rotation matrix around the Z axis.
|
||||||
|
* @param mat Receives the output matrix
|
||||||
|
* @param angle Rotation angle, in radians
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix3RotationZ(
|
||||||
|
C_STRUCT aiMatrix3x3* mat,
|
||||||
|
const float angle);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Returns a 3x3 rotation matrix for a rotation around an arbitrary axis.
|
||||||
|
* @param mat Receives the output matrix
|
||||||
|
* @param axis Rotation axis, should be a normalized vector
|
||||||
|
* @param angle Rotation angle, in radians
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix3FromRotationAroundAxis(
|
||||||
|
C_STRUCT aiMatrix3x3* mat,
|
||||||
|
const C_STRUCT aiVector3D* axis,
|
||||||
|
const float angle);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Get a 3x3 translation matrix.
|
||||||
|
* @param mat Receives the output matrix
|
||||||
|
* @param translation The translation vector
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix3Translation(
|
||||||
|
C_STRUCT aiMatrix3x3* mat,
|
||||||
|
const C_STRUCT aiVector2D* translation);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Create a 3x3 matrix that rotates one vector to another vector.
|
||||||
|
* @param mat Receives the output matrix
|
||||||
|
* @param from Vector to rotate from
|
||||||
|
* @param to Vector to rotate to
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix3FromTo(
|
||||||
|
C_STRUCT aiMatrix3x3* mat,
|
||||||
|
const C_STRUCT aiVector3D* from,
|
||||||
|
const C_STRUCT aiVector3D* to);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Construct a 4x4 matrix from a 3x3 matrix.
|
||||||
|
* @param dst Receives the output matrix
|
||||||
|
* @param mat The 3x3 matrix to use
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix4FromMatrix3(
|
||||||
|
C_STRUCT aiMatrix4x4* dst,
|
||||||
|
const C_STRUCT aiMatrix3x3* mat);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Construct a 4x4 matrix from scaling, rotation and position.
|
||||||
|
* @param mat Receives the output matrix.
|
||||||
|
* @param scaling The scaling for the x,y,z axes
|
||||||
|
* @param rotation The rotation as a hamilton quaternion
|
||||||
|
* @param position The position for the x,y,z axes
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix4FromScalingQuaternionPosition(
|
||||||
|
C_STRUCT aiMatrix4x4* mat,
|
||||||
|
const C_STRUCT aiVector3D* scaling,
|
||||||
|
const C_STRUCT aiQuaternion* rotation,
|
||||||
|
const C_STRUCT aiVector3D* position);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Add 4x4 matrices.
|
||||||
|
* @param dst First addend, receives result.
|
||||||
|
* @param src Matrix to be added to 'dst'.
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix4Add(
|
||||||
|
C_STRUCT aiMatrix4x4* dst,
|
||||||
|
const C_STRUCT aiMatrix4x4* src);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Check if 4x4 matrices are equal.
|
||||||
|
* @param a First matrix to compare
|
||||||
|
* @param b Second matrix to compare
|
||||||
|
* @return 1 if the matrices are equal
|
||||||
|
* @return 0 if the matrices are not equal
|
||||||
|
*/
|
||||||
|
ASSIMP_API int aiMatrix4AreEqual(
|
||||||
|
const C_STRUCT aiMatrix4x4* a,
|
||||||
|
const C_STRUCT aiMatrix4x4* b);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Check if 4x4 matrices are equal.
|
||||||
|
* @param a First matrix to compare
|
||||||
|
* @param b Second matrix to compare
|
||||||
|
* @param epsilon Epsilon
|
||||||
|
* @return 1 if the matrices are equal
|
||||||
|
* @return 0 if the matrices are not equal
|
||||||
|
*/
|
||||||
|
ASSIMP_API int aiMatrix4AreEqualEpsilon(
|
||||||
|
const C_STRUCT aiMatrix4x4* a,
|
||||||
|
const C_STRUCT aiMatrix4x4* b,
|
||||||
|
const float epsilon);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Invert a 4x4 matrix.
|
||||||
|
* @param result Matrix to invert
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix4Inverse(
|
||||||
|
C_STRUCT aiMatrix4x4* mat);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Get the determinant of a 4x4 matrix.
|
||||||
|
* @param mat Matrix to get the determinant from
|
||||||
|
* @return The determinant of the matrix
|
||||||
|
*/
|
||||||
|
ASSIMP_API float aiMatrix4Determinant(
|
||||||
|
const C_STRUCT aiMatrix4x4* mat);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Returns true of the matrix is the identity matrix.
|
||||||
|
* @param mat Matrix to get the determinant from
|
||||||
|
* @return 1 if \p mat is an identity matrix.
|
||||||
|
* @return 0 if \p mat is not an identity matrix.
|
||||||
|
*/
|
||||||
|
ASSIMP_API int aiMatrix4IsIdentity(
|
||||||
|
const C_STRUCT aiMatrix4x4* mat);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Decompose a transformation matrix into its scaling,
|
||||||
|
* rotational as euler angles, and translational components.
|
||||||
|
*
|
||||||
|
* @param mat Matrix to decompose
|
||||||
|
* @param scaling Receives the output scaling for the x,y,z axes
|
||||||
|
* @param rotation Receives the output rotation as a Euler angles
|
||||||
|
* @param position Receives the output position for the x,y,z axes
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix4DecomposeIntoScalingEulerAnglesPosition(
|
||||||
|
const C_STRUCT aiMatrix4x4* mat,
|
||||||
|
C_STRUCT aiVector3D* scaling,
|
||||||
|
C_STRUCT aiVector3D* rotation,
|
||||||
|
C_STRUCT aiVector3D* position);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Decompose a transformation matrix into its scaling,
|
||||||
|
* rotational split into an axis and rotational angle,
|
||||||
|
* and it's translational components.
|
||||||
|
*
|
||||||
|
* @param mat Matrix to decompose
|
||||||
|
* @param rotation Receives the rotational component
|
||||||
|
* @param axis Receives the output rotation axis
|
||||||
|
* @param angle Receives the output rotation angle
|
||||||
|
* @param position Receives the output position for the x,y,z axes.
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix4DecomposeIntoScalingAxisAnglePosition(
|
||||||
|
const C_STRUCT aiMatrix4x4* mat,
|
||||||
|
C_STRUCT aiVector3D* scaling,
|
||||||
|
C_STRUCT aiVector3D* axis,
|
||||||
|
float* angle,
|
||||||
|
C_STRUCT aiVector3D* position);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Decompose a transformation matrix into its rotational and
|
||||||
|
* translational components.
|
||||||
|
*
|
||||||
|
* @param mat Matrix to decompose
|
||||||
|
* @param rotation Receives the rotational component
|
||||||
|
* @param position Receives the translational component.
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix4DecomposeNoScaling(
|
||||||
|
const C_STRUCT aiMatrix4x4* mat,
|
||||||
|
C_STRUCT aiQuaternion* rotation,
|
||||||
|
C_STRUCT aiVector3D* position);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Creates a 4x4 matrix from a set of euler angles.
|
||||||
|
* @param mat Receives the output matrix
|
||||||
|
* @param x Rotation angle for the x-axis, in radians
|
||||||
|
* @param y Rotation angle for the y-axis, in radians
|
||||||
|
* @param z Rotation angle for the z-axis, in radians
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix4FromEulerAngles(
|
||||||
|
C_STRUCT aiMatrix4x4* mat,
|
||||||
|
float x, float y, float z);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Get a 4x4 rotation matrix around the X axis.
|
||||||
|
* @param mat Receives the output matrix
|
||||||
|
* @param angle Rotation angle, in radians
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix4RotationX(
|
||||||
|
C_STRUCT aiMatrix4x4* mat,
|
||||||
|
const float angle);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Get a 4x4 rotation matrix around the Y axis.
|
||||||
|
* @param mat Receives the output matrix
|
||||||
|
* @param angle Rotation angle, in radians
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix4RotationY(
|
||||||
|
C_STRUCT aiMatrix4x4* mat,
|
||||||
|
const float angle);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Get a 4x4 rotation matrix around the Z axis.
|
||||||
|
* @param mat Receives the output matrix
|
||||||
|
* @param angle Rotation angle, in radians
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix4RotationZ(
|
||||||
|
C_STRUCT aiMatrix4x4* mat,
|
||||||
|
const float angle);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Returns a 4x4 rotation matrix for a rotation around an arbitrary axis.
|
||||||
|
* @param mat Receives the output matrix
|
||||||
|
* @param axis Rotation axis, should be a normalized vector
|
||||||
|
* @param angle Rotation angle, in radians
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix4FromRotationAroundAxis(
|
||||||
|
C_STRUCT aiMatrix4x4* mat,
|
||||||
|
const C_STRUCT aiVector3D* axis,
|
||||||
|
const float angle);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Get a 4x4 translation matrix.
|
||||||
|
* @param mat Receives the output matrix
|
||||||
|
* @param translation The translation vector
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix4Translation(
|
||||||
|
C_STRUCT aiMatrix4x4* mat,
|
||||||
|
const C_STRUCT aiVector3D* translation);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Get a 4x4 scaling matrix.
|
||||||
|
* @param mat Receives the output matrix
|
||||||
|
* @param scaling The scaling vector
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix4Scaling(
|
||||||
|
C_STRUCT aiMatrix4x4* mat,
|
||||||
|
const C_STRUCT aiVector3D* scaling);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Create a 4x4 matrix that rotates one vector to another vector.
|
||||||
|
* @param mat Receives the output matrix
|
||||||
|
* @param from Vector to rotate from
|
||||||
|
* @param to Vector to rotate to
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiMatrix4FromTo(
|
||||||
|
C_STRUCT aiMatrix4x4* mat,
|
||||||
|
const C_STRUCT aiVector3D* from,
|
||||||
|
const C_STRUCT aiVector3D* to);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Create a Quaternion from euler angles.
|
||||||
|
* @param q Receives the output quaternion
|
||||||
|
* @param x Rotation angle for the x-axis, in radians
|
||||||
|
* @param y Rotation angle for the y-axis, in radians
|
||||||
|
* @param z Rotation angle for the z-axis, in radians
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiQuaternionFromEulerAngles(
|
||||||
|
C_STRUCT aiQuaternion* q,
|
||||||
|
float x, float y, float z);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Create a Quaternion from an axis angle pair.
|
||||||
|
* @param q Receives the output quaternion
|
||||||
|
* @param axis The orientation axis
|
||||||
|
* @param angle The rotation angle, in radians
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiQuaternionFromAxisAngle(
|
||||||
|
C_STRUCT aiQuaternion* q,
|
||||||
|
const C_STRUCT aiVector3D* axis,
|
||||||
|
const float angle);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Create a Quaternion from a normalized quaternion stored
|
||||||
|
* in a 3D vector.
|
||||||
|
* @param q Receives the output quaternion
|
||||||
|
* @param normalized The vector that stores the quaternion
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiQuaternionFromNormalizedQuaternion(
|
||||||
|
C_STRUCT aiQuaternion* q,
|
||||||
|
const C_STRUCT aiVector3D* normalized);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Check if quaternions are equal.
|
||||||
|
* @param a First quaternion to compare
|
||||||
|
* @param b Second quaternion to compare
|
||||||
|
* @return 1 if the quaternions are equal
|
||||||
|
* @return 0 if the quaternions are not equal
|
||||||
|
*/
|
||||||
|
ASSIMP_API int aiQuaternionAreEqual(
|
||||||
|
const C_STRUCT aiQuaternion* a,
|
||||||
|
const C_STRUCT aiQuaternion* b);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Check if quaternions are equal using epsilon.
|
||||||
|
* @param a First quaternion to compare
|
||||||
|
* @param b Second quaternion to compare
|
||||||
|
* @param epsilon Epsilon
|
||||||
|
* @return 1 if the quaternions are equal
|
||||||
|
* @return 0 if the quaternions are not equal
|
||||||
|
*/
|
||||||
|
ASSIMP_API int aiQuaternionAreEqualEpsilon(
|
||||||
|
const C_STRUCT aiQuaternion* a,
|
||||||
|
const C_STRUCT aiQuaternion* b,
|
||||||
|
const float epsilon);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Normalize a quaternion.
|
||||||
|
* @param q Quaternion to normalize
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiQuaternionNormalize(
|
||||||
|
C_STRUCT aiQuaternion* q);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Compute quaternion conjugate.
|
||||||
|
* @param q Quaternion to compute conjugate,
|
||||||
|
* receives the output quaternion
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiQuaternionConjugate(
|
||||||
|
C_STRUCT aiQuaternion* q);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Multiply quaternions.
|
||||||
|
* @param dst First quaternion, receives the output quaternion
|
||||||
|
* @param q Second quaternion
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiQuaternionMultiply(
|
||||||
|
C_STRUCT aiQuaternion* dst,
|
||||||
|
const C_STRUCT aiQuaternion* q);
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
/** Performs a spherical interpolation between two quaternions.
|
||||||
|
* @param dst Receives the quaternion resulting from the interpolation.
|
||||||
|
* @param start Quaternion when factor == 0
|
||||||
|
* @param end Quaternion when factor == 1
|
||||||
|
* @param factor Interpolation factor between 0 and 1
|
||||||
|
*/
|
||||||
|
ASSIMP_API void aiQuaternionInterpolate(
|
||||||
|
C_STRUCT aiQuaternion* dst,
|
||||||
|
const C_STRUCT aiQuaternion* start,
|
||||||
|
const C_STRUCT aiQuaternion* end,
|
||||||
|
const float factor);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -99,7 +99,7 @@ public:
|
||||||
aiQuaterniont& Conjugate ();
|
aiQuaterniont& Conjugate ();
|
||||||
|
|
||||||
/** Rotate a point by this quaternion */
|
/** Rotate a point by this quaternion */
|
||||||
aiVector3t<TReal> Rotate (const aiVector3t<TReal>& in);
|
aiVector3t<TReal> Rotate (const aiVector3t<TReal>& in) const;
|
||||||
|
|
||||||
/** Multiply two quaternions */
|
/** Multiply two quaternions */
|
||||||
aiQuaterniont operator* (const aiQuaterniont& two) const;
|
aiQuaterniont operator* (const aiQuaterniont& two) const;
|
||||||
|
|
|
@ -277,7 +277,7 @@ inline aiQuaterniont<TReal>& aiQuaterniont<TReal>::Conjugate ()
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template<typename TReal>
|
template<typename TReal>
|
||||||
inline aiVector3t<TReal> aiQuaterniont<TReal>::Rotate (const aiVector3t<TReal>& v)
|
inline aiVector3t<TReal> aiQuaterniont<TReal>::Rotate (const aiVector3t<TReal>& v) const
|
||||||
{
|
{
|
||||||
aiQuaterniont q2(0.f,v.x,v.y,v.z), q = *this, qinv = q;
|
aiQuaterniont q2(0.f,v.x,v.y,v.z), q = *this, qinv = q;
|
||||||
qinv.Conjugate();
|
qinv.Conjugate();
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"asset": {
|
||||||
|
"version": "2.0"
|
||||||
|
},
|
||||||
|
"scene": 0
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"asset": {
|
||||||
|
"version": "2.0"
|
||||||
|
},
|
||||||
|
"scene": 0,
|
||||||
|
"scenes": [
|
||||||
|
{
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -490,3 +490,16 @@ TEST_F(utglTF2ImportExport, texcoords) {
|
||||||
EXPECT_EQ(aiGetMaterialInteger(material, AI_MATKEY_GLTF_TEXTURE_TEXCOORD(aiTextureType_UNKNOWN, 0), &uvIndex), aiReturn_SUCCESS);
|
EXPECT_EQ(aiGetMaterialInteger(material, AI_MATKEY_GLTF_TEXTURE_TEXCOORD(aiTextureType_UNKNOWN, 0), &uvIndex), aiReturn_SUCCESS);
|
||||||
EXPECT_EQ(uvIndex, 1);
|
EXPECT_EQ(uvIndex, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(utglTF2ImportExport, norootnode_noscene) {
|
||||||
|
Assimp::Importer importer;
|
||||||
|
const aiScene* scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/TestNoRootNode/NoScene.gltf", aiProcess_ValidateDataStructure);
|
||||||
|
ASSERT_EQ(scene, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(utglTF2ImportExport, norootnode_scenewithoutnodes) {
|
||||||
|
Assimp::Importer importer;
|
||||||
|
const aiScene* scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/TestNoRootNode/SceneWithoutNodes.gltf", aiProcess_ValidateDataStructure);
|
||||||
|
ASSERT_NE(scene, nullptr);
|
||||||
|
ASSERT_NE(scene->mRootNode, nullptr);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue