python mathutils change
quat * quat was returning the dot product (a float), rather then the cross product. Use BLI_math's mul_qt_qtqt() function.
This commit is contained in:
@@ -44,9 +44,9 @@ void copy_qt_qt(float q[4], const float a[4]);
|
|||||||
|
|
||||||
/* arithmetic */
|
/* arithmetic */
|
||||||
void mul_qt_qtqt(float q[4], const float a[4], const float b[4]);
|
void mul_qt_qtqt(float q[4], const float a[4], const float b[4]);
|
||||||
void mul_qt_v3(float q[4], float r[3]);
|
void mul_qt_v3(const float q[4], float r[3]);
|
||||||
void mul_qt_fl(float q[4], float f);
|
void mul_qt_fl(float q[4], const float f);
|
||||||
void mul_fac_qt_fl(float q[4], float f);
|
void mul_fac_qt_fl(float q[4], const float f);
|
||||||
|
|
||||||
void sub_qt_qtqt(float q[4], float a[4], float b[4]);
|
void sub_qt_qtqt(float q[4], float a[4], float b[4]);
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ void mul_qt_qtqt(float *q, const float *q1, const float *q2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Assumes a unit quaternion */
|
/* Assumes a unit quaternion */
|
||||||
void mul_qt_v3(float *q, float *v)
|
void mul_qt_v3(const float *q, float *v)
|
||||||
{
|
{
|
||||||
float t0, t1, t2;
|
float t0, t1, t2;
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ void invert_qt_qt(float *q1, const float *q2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* simple mult */
|
/* simple mult */
|
||||||
void mul_qt_fl(float *q, float f)
|
void mul_qt_fl(float *q, const float f)
|
||||||
{
|
{
|
||||||
q[0] *= f;
|
q[0] *= f;
|
||||||
q[1] *= f;
|
q[1] *= f;
|
||||||
@@ -127,7 +127,7 @@ void sub_qt_qtqt(float *q, float *q1, float *q2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* angular mult factor */
|
/* angular mult factor */
|
||||||
void mul_fac_qt_fl(float *q, float fac)
|
void mul_fac_qt_fl(float *q, const float fac)
|
||||||
{
|
{
|
||||||
float angle= fac*saacos(q[0]); /* quat[0]= cos(0.5*angle), but now the 0.5 and 2.0 rule out */
|
float angle= fac*saacos(q[0]); /* quat[0]= cos(0.5*angle), but now the 0.5 and 2.0 rule out */
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
* - toEuler --> to_euler
|
* - toEuler --> to_euler
|
||||||
* - toQuat --> to_quat
|
* - toQuat --> to_quat
|
||||||
* - Vector.toTrackQuat --> Vector.to_track_quat
|
* - Vector.toTrackQuat --> Vector.to_track_quat
|
||||||
|
* - Quaternion * Quaternion --> cross product (not dot product)
|
||||||
*
|
*
|
||||||
* Moved to Geometry module: Intersect, TriangleArea, TriangleNormal, QuadNormal, LineIntersect
|
* Moved to Geometry module: Intersect, TriangleArea, TriangleNormal, QuadNormal, LineIntersect
|
||||||
*/
|
*/
|
||||||
@@ -92,74 +93,6 @@ int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------METHODS----------------------------
|
|
||||||
//-----------------quat_rotation (internal)-----------
|
|
||||||
//This function multiplies a vector/point * quat or vice versa
|
|
||||||
//to rotate the point/vector by the quaternion
|
|
||||||
//arguments should all be 3D
|
|
||||||
PyObject *quat_rotation(PyObject *arg1, PyObject *arg2)
|
|
||||||
{
|
|
||||||
float rot[3];
|
|
||||||
QuaternionObject *quat = NULL;
|
|
||||||
VectorObject *vec = NULL;
|
|
||||||
|
|
||||||
if(QuaternionObject_Check(arg1)){
|
|
||||||
quat = (QuaternionObject*)arg1;
|
|
||||||
if(!BaseMath_ReadCallback(quat))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if(VectorObject_Check(arg2)){
|
|
||||||
vec = (VectorObject*)arg2;
|
|
||||||
|
|
||||||
if(!BaseMath_ReadCallback(vec))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
rot[0] = quat->quat[0]*quat->quat[0]*vec->vec[0] + 2*quat->quat[2]*quat->quat[0]*vec->vec[2] -
|
|
||||||
2*quat->quat[3]*quat->quat[0]*vec->vec[1] + quat->quat[1]*quat->quat[1]*vec->vec[0] +
|
|
||||||
2*quat->quat[2]*quat->quat[1]*vec->vec[1] + 2*quat->quat[3]*quat->quat[1]*vec->vec[2] -
|
|
||||||
quat->quat[3]*quat->quat[3]*vec->vec[0] - quat->quat[2]*quat->quat[2]*vec->vec[0];
|
|
||||||
rot[1] = 2*quat->quat[1]*quat->quat[2]*vec->vec[0] + quat->quat[2]*quat->quat[2]*vec->vec[1] +
|
|
||||||
2*quat->quat[3]*quat->quat[2]*vec->vec[2] + 2*quat->quat[0]*quat->quat[3]*vec->vec[0] -
|
|
||||||
quat->quat[3]*quat->quat[3]*vec->vec[1] + quat->quat[0]*quat->quat[0]*vec->vec[1] -
|
|
||||||
2*quat->quat[1]*quat->quat[0]*vec->vec[2] - quat->quat[1]*quat->quat[1]*vec->vec[1];
|
|
||||||
rot[2] = 2*quat->quat[1]*quat->quat[3]*vec->vec[0] + 2*quat->quat[2]*quat->quat[3]*vec->vec[1] +
|
|
||||||
quat->quat[3]*quat->quat[3]*vec->vec[2] - 2*quat->quat[0]*quat->quat[2]*vec->vec[0] -
|
|
||||||
quat->quat[2]*quat->quat[2]*vec->vec[2] + 2*quat->quat[0]*quat->quat[1]*vec->vec[1] -
|
|
||||||
quat->quat[1]*quat->quat[1]*vec->vec[2] + quat->quat[0]*quat->quat[0]*vec->vec[2];
|
|
||||||
return newVectorObject(rot, 3, Py_NEW, NULL);
|
|
||||||
}
|
|
||||||
}else if(VectorObject_Check(arg1)){
|
|
||||||
vec = (VectorObject*)arg1;
|
|
||||||
|
|
||||||
if(!BaseMath_ReadCallback(vec))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if(QuaternionObject_Check(arg2)){
|
|
||||||
quat = (QuaternionObject*)arg2;
|
|
||||||
if(!BaseMath_ReadCallback(quat))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
rot[0] = quat->quat[0]*quat->quat[0]*vec->vec[0] + 2*quat->quat[2]*quat->quat[0]*vec->vec[2] -
|
|
||||||
2*quat->quat[3]*quat->quat[0]*vec->vec[1] + quat->quat[1]*quat->quat[1]*vec->vec[0] +
|
|
||||||
2*quat->quat[2]*quat->quat[1]*vec->vec[1] + 2*quat->quat[3]*quat->quat[1]*vec->vec[2] -
|
|
||||||
quat->quat[3]*quat->quat[3]*vec->vec[0] - quat->quat[2]*quat->quat[2]*vec->vec[0];
|
|
||||||
rot[1] = 2*quat->quat[1]*quat->quat[2]*vec->vec[0] + quat->quat[2]*quat->quat[2]*vec->vec[1] +
|
|
||||||
2*quat->quat[3]*quat->quat[2]*vec->vec[2] + 2*quat->quat[0]*quat->quat[3]*vec->vec[0] -
|
|
||||||
quat->quat[3]*quat->quat[3]*vec->vec[1] + quat->quat[0]*quat->quat[0]*vec->vec[1] -
|
|
||||||
2*quat->quat[1]*quat->quat[0]*vec->vec[2] - quat->quat[1]*quat->quat[1]*vec->vec[1];
|
|
||||||
rot[2] = 2*quat->quat[1]*quat->quat[3]*vec->vec[0] + 2*quat->quat[2]*quat->quat[3]*vec->vec[1] +
|
|
||||||
quat->quat[3]*quat->quat[3]*vec->vec[2] - 2*quat->quat[0]*quat->quat[2]*vec->vec[0] -
|
|
||||||
quat->quat[2]*quat->quat[2]*vec->vec[2] + 2*quat->quat[0]*quat->quat[1]*vec->vec[1] -
|
|
||||||
quat->quat[1]*quat->quat[1]*vec->vec[2] + quat->quat[0]*quat->quat[0]*vec->vec[2];
|
|
||||||
return newVectorObject(rot, 3, Py_NEW, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PyErr_SetString(PyExc_RuntimeError, "quat_rotation(internal): internal problem rotating vector/point\n");
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------MATRIX FUNCTIONS--------------------
|
//----------------------------------MATRIX FUNCTIONS--------------------
|
||||||
//----------------------------------mathutils.RotationMatrix() ----------
|
//----------------------------------mathutils.RotationMatrix() ----------
|
||||||
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
|
//mat is a 1D array of floats - row[0][0],row[0][1], row[1][0], etc.
|
||||||
|
|||||||
@@ -63,8 +63,6 @@ void BaseMathObject_dealloc(BaseMathObject * self);
|
|||||||
PyObject *Mathutils_Init(void);
|
PyObject *Mathutils_Init(void);
|
||||||
PyObject *Noise_Init(void); /* lazy, saves having own header */
|
PyObject *Noise_Init(void); /* lazy, saves having own header */
|
||||||
|
|
||||||
PyObject *quat_rotation(PyObject *arg1, PyObject *arg2);
|
|
||||||
|
|
||||||
int EXPP_FloatsAreEqual(float A, float B, int floatSteps);
|
int EXPP_FloatsAreEqual(float A, float B, int floatSteps);
|
||||||
int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps);
|
int EXPP_VectorsAreEqual(float *vecA, float *vecB, int size, int floatSteps);
|
||||||
|
|
||||||
|
|||||||
@@ -660,8 +660,9 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(quat1 && quat2) { /* QUAT*QUAT (dot product) */
|
if(quat1 && quat2) { /* QUAT*QUAT (cross product) */
|
||||||
return PyFloat_FromDouble(dot_qtqt(quat1->quat, quat2->quat));
|
mul_qt_qtqt(quat, quat1->quat, quat2->quat);
|
||||||
|
return newQuaternionObject(quat, Py_NEW, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the only case this can happen (for a supported type is "FLOAT*QUAT" ) */
|
/* the only case this can happen (for a supported type is "FLOAT*QUAT" ) */
|
||||||
@@ -677,12 +678,19 @@ static PyObject *Quaternion_mul(PyObject * q1, PyObject * q2)
|
|||||||
}
|
}
|
||||||
else { /* QUAT*SOMETHING */
|
else { /* QUAT*SOMETHING */
|
||||||
if(VectorObject_Check(q2)){ /* QUAT*VEC */
|
if(VectorObject_Check(q2)){ /* QUAT*VEC */
|
||||||
|
float tvec[3];
|
||||||
vec = (VectorObject*)q2;
|
vec = (VectorObject*)q2;
|
||||||
if(vec->size != 3){
|
if(vec->size != 3){
|
||||||
PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: only 3D vector rotations currently supported\n");
|
PyErr_SetString(PyExc_TypeError, "Quaternion multiplication: only 3D vector rotations currently supported\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return quat_rotation((PyObject*)quat1, (PyObject*)vec); /* vector updating done inside the func */
|
if(!BaseMath_ReadCallback(vec)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_v3_v3(tvec, vec->vec);
|
||||||
|
mul_qt_v3(quat1->quat, tvec);
|
||||||
|
return newVectorObject(tvec, 3, Py_NEW, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
scalar= PyFloat_AsDouble(q2);
|
scalar= PyFloat_AsDouble(q2);
|
||||||
|
|||||||
@@ -1010,13 +1010,20 @@ static PyObject *Vector_mul(PyObject * v1, PyObject * v2)
|
|||||||
/* VEC * MATRIX */
|
/* VEC * MATRIX */
|
||||||
return row_vector_multiplication(vec1, (MatrixObject*)v2);
|
return row_vector_multiplication(vec1, (MatrixObject*)v2);
|
||||||
} else if (QuaternionObject_Check(v2)) {
|
} else if (QuaternionObject_Check(v2)) {
|
||||||
QuaternionObject *quat = (QuaternionObject*)v2; /* quat_rotation validates */
|
/* VEC * QUAT */
|
||||||
|
QuaternionObject *quat2 = (QuaternionObject*)v2;
|
||||||
|
float tvec[4];
|
||||||
|
|
||||||
if(vec1->size != 3) {
|
if(vec1->size != 3) {
|
||||||
PyErr_SetString(PyExc_TypeError, "Vector multiplication: only 3D vector rotations (with quats) currently supported\n");
|
PyErr_SetString(PyExc_TypeError, "Vector multiplication: only 3D vector rotations (with quats) currently supported\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return quat_rotation((PyObject*)vec1, (PyObject*)quat);
|
if(!BaseMath_ReadCallback(quat2)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
copy_v3_v3(tvec, vec1->vec);
|
||||||
|
mul_qt_v3(quat2->quat, tvec);
|
||||||
|
return newVectorObject(tvec, 3, Py_NEW, NULL);
|
||||||
}
|
}
|
||||||
else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*FLOAT */
|
else if (((scalar= PyFloat_AsDouble(v2)) == -1.0 && PyErr_Occurred())==0) { /* VEC*FLOAT */
|
||||||
int i;
|
int i;
|
||||||
|
|||||||
Reference in New Issue
Block a user