PyObject* PyObjectFrom(const MT_Quaternion &qrot)
{
	/* NOTE, were re-ordering here for Mathutils compat */
	float fvec[4];
	qrot.getValue(fvec);
	return Quaternion_CreatePyObject(fvec, Py_NEW, NULL);
}
static PyObject *quat_mul_float(QuaternionObject *quat, const float scalar)
{
	float tquat[4];
	copy_qt_qt(tquat, quat->quat);
	mul_qt_fl(tquat, scalar);
	return Quaternion_CreatePyObject(tquat, Py_NEW, Py_TYPE(quat));
}
/* subtraction */
static PyObject *Quaternion_sub(PyObject *q1, PyObject *q2)
{
	int x;
	float quat[QUAT_SIZE];
	QuaternionObject *quat1 = NULL, *quat2 = NULL;

	if (!QuaternionObject_Check(q1) || !QuaternionObject_Check(q2)) {
		PyErr_Format(PyExc_TypeError,
		             "Quaternion subtraction: (%s - %s) "
		             "invalid type for this operation",
		             Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name);
		return NULL;
	}

	quat1 = (QuaternionObject *)q1;
	quat2 = (QuaternionObject *)q2;

	if (BaseMath_ReadCallback(quat1) == -1 || BaseMath_ReadCallback(quat2) == -1)
		return NULL;

	for (x = 0; x < QUAT_SIZE; x++) {
		quat[x] = quat1->quat[x] - quat2->quat[x];
	}

	return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(q1));
}
static PyObject *Quaternion_copy(QuaternionObject *self)
{
	if (BaseMath_ReadCallback(self) == -1)
		return NULL;

	return Quaternion_CreatePyObject(self->quat, Py_NEW, Py_TYPE(self));
}
static PyObject *Quaternion_slerp(QuaternionObject *self, PyObject *args)
{
	PyObject *value;
	float tquat[QUAT_SIZE], quat[QUAT_SIZE], fac;

	if (!PyArg_ParseTuple(args, "Of:slerp", &value, &fac)) {
		PyErr_SetString(PyExc_TypeError,
		                "quat.slerp(): "
		                "expected Quaternion types and float");
		return NULL;
	}

	if (BaseMath_ReadCallback(self) == -1)
		return NULL;

	if (mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value,
	                          "Quaternion.slerp(other), invalid 'other' arg") == -1)
	{
		return NULL;
	}

	if (fac > 1.0f || fac < 0.0f) {
		PyErr_SetString(PyExc_ValueError,
		                "quat.slerp(): "
		                "interpolation factor must be between 0.0 and 1.0");
		return NULL;
	}

	interp_qt_qtqt(quat, self->quat, tquat, fac);

	return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(self));
}
Exemple #6
0
/* -obj
 * returns the negative of this object*/
static PyObject *Quaternion_neg(QuaternionObject *self)
{
	float tquat[QUAT_SIZE];

	if (BaseMath_ReadCallback(self) == -1)
		return NULL;

	negate_v4_v4(tquat, self->quat);
	return Quaternion_CreatePyObject(tquat, Py_NEW, Py_TYPE(self));
}
static PyObject *Euler_to_quaternion(EulerObject *self)
{
	float quat[4];

	if (BaseMath_ReadCallback(self) == -1)
		return NULL;

	eulO_to_quat(quat, self->eul, self->order);

	return Quaternion_CreatePyObject(quat, Py_NEW, NULL);
}
Exemple #8
0
PyObject *Quaternion_CreatePyObject_cb(PyObject *cb_user,
                                       unsigned char cb_type, unsigned char cb_subtype)
{
	QuaternionObject *self = (QuaternionObject *)Quaternion_CreatePyObject(NULL, Py_NEW, NULL);
	if (self) {
		Py_INCREF(cb_user);
		self->cb_user         = cb_user;
		self->cb_type         = cb_type;
		self->cb_subtype      = cb_subtype;
		PyObject_GC_Track(self);
	}

	return (PyObject *)self;
}
Exemple #9
0
static PyObject *Quaternion_cross(QuaternionObject *self, PyObject *value)
{
	float quat[QUAT_SIZE], tquat[QUAT_SIZE];

	if (BaseMath_ReadCallback(self) == -1)
		return NULL;

	if (mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value,
	                          "Quaternion.cross(other), invalid 'other' arg") == -1) {
		return NULL;
	}

	mul_qt_qtqt(quat, self->quat, tquat);
	return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(self));
}
Exemple #10
0
static PyObject *Quaternion_rotation_difference(QuaternionObject *self, PyObject *value)
{
	float tquat[QUAT_SIZE], quat[QUAT_SIZE];

	if (BaseMath_ReadCallback(self) == -1)
		return NULL;

	if (mathutils_array_parse(tquat, QUAT_SIZE, QUAT_SIZE, value,
	                          "Quaternion.difference(other), invalid 'other' arg") == -1)
	{
		return NULL;
	}

	rotation_between_quats_to_quat(quat, self->quat, tquat);

	return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(self));
}
Exemple #11
0
//------------------------NUMERIC PROTOCOLS----------------------
//------------------------obj + obj------------------------------
//addition
static PyObject *Quaternion_add(PyObject *q1, PyObject *q2)
{
	float quat[QUAT_SIZE];
	QuaternionObject *quat1 = NULL, *quat2 = NULL;

	if (!QuaternionObject_Check(q1) || !QuaternionObject_Check(q2)) {
		PyErr_Format(PyExc_TypeError,
		             "Quaternion addition: (%s + %s) "
		             "invalid type for this operation",
		             Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name);
		return NULL;
	}
	quat1 = (QuaternionObject *)q1;
	quat2 = (QuaternionObject *)q2;

	if (BaseMath_ReadCallback(quat1) == -1 || BaseMath_ReadCallback(quat2) == -1)
		return NULL;

	add_qt_qtqt(quat, quat1->quat, quat2->quat, 1.0f);
	return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(q1));
}
/* ----------------------------------mathutils.Quaternion() -------------- */
static PyObject *Quaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
	PyObject *seq = NULL;
	double angle = 0.0f;
	float quat[QUAT_SIZE] = {0.0f, 0.0f, 0.0f, 0.0f};

	if (kwds && PyDict_Size(kwds)) {
		PyErr_SetString(PyExc_TypeError,
		                "mathutils.Quaternion(): "
		                "takes no keyword args");
		return NULL;
	}

	if (!PyArg_ParseTuple(args, "|Od:mathutils.Quaternion", &seq, &angle))
		return NULL;

	switch (PyTuple_GET_SIZE(args)) {
		case 0:
			break;
		case 1:
			if (mathutils_array_parse(quat, QUAT_SIZE, QUAT_SIZE, seq, "mathutils.Quaternion()") == -1)
				return NULL;
			break;
		case 2:
		{
			float axis[3];
			if (mathutils_array_parse(axis, 3, 3, seq, "mathutils.Quaternion()") == -1)
				return NULL;
			angle = angle_wrap_rad(angle); /* clamp because of precision issues */
			axis_angle_to_quat(quat, axis, angle);
			break;
			/* PyArg_ParseTuple assures no more than 2 */
		}
	}
	return Quaternion_CreatePyObject(quat, Py_NEW, type);
}
Exemple #13
0
//------------------------obj * obj------------------------------
//mulplication
static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2)
{
	float quat[QUAT_SIZE], scalar;
	QuaternionObject *quat1 = NULL, *quat2 = NULL;

	if (QuaternionObject_Check(q1)) {
		quat1 = (QuaternionObject *)q1;
		if (BaseMath_ReadCallback(quat1) == -1)
			return NULL;
	}
	if (QuaternionObject_Check(q2)) {
		quat2 = (QuaternionObject *)q2;
		if (BaseMath_ReadCallback(quat2) == -1)
			return NULL;
	}

	if (quat1 && quat2) { /* QUAT * QUAT (cross product) */
		mul_qt_qtqt(quat, quat1->quat, quat2->quat);
		return Quaternion_CreatePyObject(quat, Py_NEW, Py_TYPE(q1));
	}
	/* the only case this can happen (for a supported type is "FLOAT * QUAT") */
	else if (quat2) { /* FLOAT * QUAT */
		if (((scalar = PyFloat_AsDouble(q1)) == -1.0f && PyErr_Occurred()) == 0) {
			return quat_mul_float(quat2, scalar);
		}
	}
	else if (quat1) {
		/* QUAT * VEC */
		if (VectorObject_Check(q2)) {
			VectorObject *vec2 = (VectorObject *)q2;
			float tvec[3];

			if (vec2->size != 3) {
				PyErr_SetString(PyExc_ValueError,
				                "Vector multiplication: "
				                "only 3D vector rotations (with quats) "
				                "currently supported");
				return NULL;
			}
			if (BaseMath_ReadCallback(vec2) == -1) {
				return NULL;
			}

			copy_v3_v3(tvec, vec2->vec);
			mul_qt_v3(quat1->quat, tvec);

			return Vector_CreatePyObject(tvec, 3, Py_NEW, Py_TYPE(vec2));
		}
		/* QUAT * FLOAT */
		else if ((((scalar = PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred()) == 0)) {
			return quat_mul_float(quat1, scalar);
		}
	}
	else {
		BLI_assert(!"internal error");
	}

	PyErr_Format(PyExc_TypeError,
	             "Quaternion multiplication: "
	             "not supported between '%.200s' and '%.200s' types",
	             Py_TYPE(q1)->tp_name, Py_TYPE(q2)->tp_name);
	return NULL;
}