Пример #1
0
static PyObject *Quaternion_to_euler(QuaternionObject *self, PyObject *args)
{
	float tquat[4];
	float eul[3];
	const char *order_str = NULL;
	short order = EULER_ORDER_XYZ;
	EulerObject *eul_compat = NULL;

	if (!PyArg_ParseTuple(args, "|sO!:to_euler", &order_str, &euler_Type, &eul_compat))
		return NULL;

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

	if (order_str) {
		order = euler_order_from_string(order_str, "Matrix.to_euler()");

		if (order == -1)
			return NULL;
	}

	normalize_qt_qt(tquat, self->quat);

	if (eul_compat) {
		float mat[3][3];

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

		quat_to_mat3(mat, tquat);

		if (order == EULER_ORDER_XYZ)  mat3_to_compatible_eul(eul, eul_compat->eul, mat);
		else                           mat3_to_compatible_eulO(eul, eul_compat->eul, order, mat);
	}
	else {
		if (order == EULER_ORDER_XYZ)  quat_to_eul(eul, tquat);
		else                           quat_to_eulO(eul, order, tquat);
	}

	return Euler_CreatePyObject(eul, order, Py_NEW, NULL);
}
Пример #2
0
int BL_ArmatureChannel::py_attr_set_joint_rotation(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{
	BL_ArmatureChannel* self= static_cast<BL_ArmatureChannel*>(self_v);
	bPoseChannel* pchan = self->m_posechannel;
	PyObject *item;
	float joints[3];
	float quat[4];

	if (!PySequence_Check(value) || PySequence_Size(value) != 3) {
		PyErr_SetString(PyExc_AttributeError, "expected a sequence of [3] floats");
		return PY_SET_ATTR_FAIL;
	}
	for (int i=0; i<3; i++) {
		item = PySequence_GetItem(value, i); /* new ref */
		joints[i] = PyFloat_AsDouble(item);
		Py_DECREF(item);
		if (joints[i] == -1.0f && PyErr_Occurred()) {
			PyErr_SetString(PyExc_AttributeError, "expected a sequence of [3] floats");
			return PY_SET_ATTR_FAIL;
		}
	}

	int flag = 0;
	if (!(pchan->ikflag & BONE_IK_NO_XDOF))
		flag |= 1;
	if (!(pchan->ikflag & BONE_IK_NO_YDOF))
		flag |= 2;
	if (!(pchan->ikflag & BONE_IK_NO_ZDOF))
		flag |= 4;
	unit_qt(quat);
	switch (flag) {
	case 0:	// fixed joint
		break;
	case 1:	// X only
		joints[1] = joints[2] = 0.f;
		eulO_to_quat( quat,joints, EULER_ORDER_XYZ);
		break;
	case 2:	// Y only
		joints[0] = joints[2] = 0.f;
		eulO_to_quat( quat,joints, EULER_ORDER_XYZ);
		break;
	case 3:	// X+Y
		joints[2] = 0.f;
		eulO_to_quat( quat,joints, EULER_ORDER_ZYX);
		break;
	case 4:	// Z only
		joints[0] = joints[1] = 0.f;
		eulO_to_quat( quat,joints, EULER_ORDER_XYZ);
		break;
	case 5:	// X+Z
		// X and Z are components of an equivalent rotation axis
		joints[1] = 0;
		axis_angle_to_quat( quat,joints, len_v3(joints));
		break;
	case 6:	// Y+Z
		joints[0] = 0.f;
		eulO_to_quat( quat,joints, EULER_ORDER_XYZ);
		break;
	case 7: // X+Y+Z
		// equivalent axis
		axis_angle_to_quat( quat,joints, len_v3(joints));
		break;
	}
	if (pchan->rotmode > 0) {
		quat_to_eulO( joints, pchan->rotmode,quat);
		copy_v3_v3(pchan->eul, joints);
	} else
		copy_qt_qt(pchan->quat, quat);
	return PY_SET_ATTR_SUCCESS;
}