Ejemplo n.º 1
0
static PyObject *M_Geometry_intersect_line_sphere_2d(PyObject *UNUSED(self), PyObject* args)
{
	VectorObject *line_a, *line_b, *sphere_co;
	float sphere_radius;
	int clip= TRUE;

	float isect_a[3];
	float isect_b[3];

	if(!PyArg_ParseTuple(args, "O!O!O!f|i:intersect_line_sphere_2d",
	  &vector_Type, &line_a,
	  &vector_Type, &line_b,
	  &vector_Type, &sphere_co,
	  &sphere_radius, &clip)
	) {
		return NULL;
	}

	if(		BaseMath_ReadCallback(line_a) == -1 ||
	        BaseMath_ReadCallback(line_b) == -1 ||
	        BaseMath_ReadCallback(sphere_co) == -1
	) {
		return NULL;
	}
	else {
		short use_a= TRUE;
		short use_b= TRUE;
		float lambda;

		PyObject *ret= PyTuple_New(2);

		switch(isect_line_sphere_v2(line_a->vec, line_b->vec, sphere_co->vec, sphere_radius, isect_a, isect_b)) {
		case 1:
			if(!(!clip || (((lambda= line_point_factor_v2(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a= FALSE;
			use_b= FALSE;
			break;
		case 2:
			if(!(!clip || (((lambda= line_point_factor_v2(isect_a, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_a= FALSE;
			if(!(!clip || (((lambda= line_point_factor_v2(isect_b, line_a->vec, line_b->vec)) >= 0.0f) && (lambda <= 1.0f)))) use_b= FALSE;
			break;
		default:
			use_a= FALSE;
			use_b= FALSE;
		}

		if(use_a) { PyTuple_SET_ITEM(ret, 0,  newVectorObject(isect_a, 2, Py_NEW, NULL)); }
		else      { PyTuple_SET_ITEM(ret, 0,  Py_None); Py_INCREF(Py_None); }

		if(use_b) { PyTuple_SET_ITEM(ret, 1,  newVectorObject(isect_b, 2, Py_NEW, NULL)); }
		else      { PyTuple_SET_ITEM(ret, 1,  Py_None); Py_INCREF(Py_None); }

		return ret;
	}
}
Ejemplo n.º 2
0
PyObject* PyObjectFrom(const MT_Tuple2 &vec)
{
#ifdef USE_MATHUTILS
	float fvec[2]= {vec[0], vec[1]};
	return newVectorObject(fvec, 2, Py_NEW, NULL);
#else
	PyObject *list = PyList_New(2);
	PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0]));
	PyList_SET_ITEM(list, 1, PyFloat_FromDouble(vec[1]));
	return list;
#endif
}
Ejemplo n.º 3
0
static PyObject *M_Geometry_interpolate_bezier(PyObject *UNUSED(self), PyObject* args)
{
	VectorObject *vec_k1, *vec_h1, *vec_k2, *vec_h2;
	int resolu;
	int dims;
	int i;
	float *coord_array, *fp;
	PyObject *list;

	float k1[4]= {0.0, 0.0, 0.0, 0.0};
	float h1[4]= {0.0, 0.0, 0.0, 0.0};
	float k2[4]= {0.0, 0.0, 0.0, 0.0};
	float h2[4]= {0.0, 0.0, 0.0, 0.0};


	if(!PyArg_ParseTuple(args, "O!O!O!O!i:interpolate_bezier",
	  &vector_Type, &vec_k1,
	  &vector_Type, &vec_h1,
	  &vector_Type, &vec_h2,
	  &vector_Type, &vec_k2, &resolu)
	) {
		return NULL;
	}

	if(resolu <= 1) {
		PyErr_SetString(PyExc_ValueError,
		                "resolution must be 2 or over");
		return NULL;
	}

	if(BaseMath_ReadCallback(vec_k1) == -1 || BaseMath_ReadCallback(vec_h1) == -1 || BaseMath_ReadCallback(vec_k2) == -1 || BaseMath_ReadCallback(vec_h2) == -1)
		return NULL;

	dims= MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size);

	for(i=0; i < vec_k1->size; i++) k1[i]= vec_k1->vec[i];
	for(i=0; i < vec_h1->size; i++) h1[i]= vec_h1->vec[i];
	for(i=0; i < vec_k2->size; i++) k2[i]= vec_k2->vec[i];
	for(i=0; i < vec_h2->size; i++) h2[i]= vec_h2->vec[i];

	coord_array= MEM_callocN(dims * (resolu) * sizeof(float), "interpolate_bezier");
	for(i=0; i<dims; i++) {
		forward_diff_bezier(k1[i], h1[i], h2[i], k2[i], coord_array+i, resolu-1, sizeof(float)*dims);
	}

	list= PyList_New(resolu);
	fp= coord_array;
	for(i=0; i<resolu; i++, fp= fp+dims) {
		PyList_SET_ITEM(list, i, newVectorObject(fp, dims, Py_NEW, NULL));
	}
	MEM_freeN(coord_array);
	return list;
}
Ejemplo n.º 4
0
static PyObject *M_Geometry_BezierInterp( PyObject * self, PyObject * args )
{
	VectorObject *vec_k1, *vec_h1, *vec_k2, *vec_h2;
	int resolu;
	int dims;
	int i;
	float *coord_array, *fp;
	PyObject *list;
	
	float k1[4] = {0.0, 0.0, 0.0, 0.0};
	float h1[4] = {0.0, 0.0, 0.0, 0.0};
	float k2[4] = {0.0, 0.0, 0.0, 0.0};
	float h2[4] = {0.0, 0.0, 0.0, 0.0};
	
	
	if( !PyArg_ParseTuple ( args, "O!O!O!O!i",
	  &vector_Type, &vec_k1,
	  &vector_Type, &vec_h1,
	  &vector_Type, &vec_h2,
	  &vector_Type, &vec_k2, &resolu) || (resolu<=1)
	) {
		PyErr_SetString( PyExc_TypeError, "expected 4 vector types and an int greater then 1\n" );
		return NULL;
	}
	
	if(!BaseMath_ReadCallback(vec_k1) || !BaseMath_ReadCallback(vec_h1) || !BaseMath_ReadCallback(vec_k2) || !BaseMath_ReadCallback(vec_h2))
		return NULL;
	
	dims= MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size);
	
	for(i=0; i < vec_k1->size; i++) k1[i]= vec_k1->vec[i];
	for(i=0; i < vec_h1->size; i++) h1[i]= vec_h1->vec[i];
	for(i=0; i < vec_k2->size; i++) k2[i]= vec_k2->vec[i];
	for(i=0; i < vec_h2->size; i++) h2[i]= vec_h2->vec[i];
	
	coord_array = MEM_callocN(dims * (resolu) * sizeof(float), "BezierInterp");
	for(i=0; i<dims; i++) {
		forward_diff_bezier(k1[i], h1[i], h2[i], k2[i], coord_array+i, resolu-1, sizeof(float)*dims);
	}
	
	list= PyList_New(resolu);
	fp= coord_array;
	for(i=0; i<resolu; i++, fp= fp+dims) {
		PyList_SET_ITEM(list, i, newVectorObject(fp, dims, Py_NEW, NULL));
	}
	MEM_freeN(coord_array);
	return list;
}
Ejemplo n.º 5
0
static PyObject *M_Geometry_normal(PyObject *UNUSED(self), PyObject* args)
{
	VectorObject *vec1, *vec2, *vec3, *vec4;
	float n[3];

	if(PyTuple_GET_SIZE(args) == 3) {
		if(!PyArg_ParseTuple(args, "O!O!O!:normal", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3)) {
			return NULL;
		}
		if(vec1->size != vec2->size || vec1->size != vec3->size) {
			PyErr_SetString(PyExc_ValueError,
			                "vectors must be of the same size");
			return NULL;
		}
		if(vec1->size < 3) {
			PyErr_SetString(PyExc_ValueError,
			                "2D vectors unsupported");
			return NULL;
		}

		if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1 || BaseMath_ReadCallback(vec3) == -1)
			return NULL;

		normal_tri_v3(n, vec1->vec, vec2->vec, vec3->vec);
	}
	else {
		if(!PyArg_ParseTuple(args, "O!O!O!O!:normal", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &vec4)) {
			return NULL;
		}
		if(vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec4->size) {
			PyErr_SetString(PyExc_ValueError,
			                "vectors must be of the same size");
			return NULL;
		}
		if(vec1->size < 3) {
			PyErr_SetString(PyExc_ValueError,
			                "2D vectors unsupported");
			return NULL;
		}

		if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1 || BaseMath_ReadCallback(vec3) == -1 || BaseMath_ReadCallback(vec4) == -1)
			return NULL;

		normal_quad_v3(n, vec1->vec, vec2->vec, vec3->vec, vec4->vec);
	}

	return newVectorObject(n, 3, Py_NEW, NULL);
}
Ejemplo n.º 6
0
static PyObject *M_Geometry_barycentric_transform(PyObject *UNUSED(self), PyObject *args)
{
	VectorObject *vec_pt;
	VectorObject *vec_t1_tar, *vec_t2_tar, *vec_t3_tar;
	VectorObject *vec_t1_src, *vec_t2_src, *vec_t3_src;
	float vec[3];

	if(!PyArg_ParseTuple(args, "O!O!O!O!O!O!O!:barycentric_transform",
		  &vector_Type, &vec_pt,
		  &vector_Type, &vec_t1_src,
		  &vector_Type, &vec_t2_src,
		  &vector_Type, &vec_t3_src,
		  &vector_Type, &vec_t1_tar,
		  &vector_Type, &vec_t2_tar,
		  &vector_Type, &vec_t3_tar)
	) {
		return NULL;
	}

	if(	vec_pt->size != 3 ||
		vec_t1_src->size != 3 ||
		vec_t2_src->size != 3 ||
		vec_t3_src->size != 3 ||
		vec_t1_tar->size != 3 ||
		vec_t2_tar->size != 3 ||
		vec_t3_tar->size != 3)
	{
		PyErr_SetString(PyExc_ValueError,
		                "One of more of the vector arguments wasn't a 3D vector");
		return NULL;
	}

	barycentric_transform(vec, vec_pt->vec,
			vec_t1_tar->vec, vec_t2_tar->vec, vec_t3_tar->vec,
			vec_t1_src->vec, vec_t2_src->vec, vec_t3_src->vec);

	return newVectorObject(vec, 3, Py_NEW, NULL);
}
Ejemplo n.º 7
0
static PyObject *M_Geometry_intersect_line_line_2d(PyObject *UNUSED(self), PyObject* args)
{
	VectorObject *line_a1, *line_a2, *line_b1, *line_b2;
	float vi[2];
	if(!PyArg_ParseTuple(args, "O!O!O!O!:intersect_line_line_2d",
	  &vector_Type, &line_a1,
	  &vector_Type, &line_a2,
	  &vector_Type, &line_b1,
	  &vector_Type, &line_b2)
	) {
		return NULL;
	}
	
	if(BaseMath_ReadCallback(line_a1) == -1 || BaseMath_ReadCallback(line_a2) == -1 || BaseMath_ReadCallback(line_b1) == -1 || BaseMath_ReadCallback(line_b2) == -1)
		return NULL;

	if(isect_seg_seg_v2_point(line_a1->vec, line_a2->vec, line_b1->vec, line_b2->vec, vi) == 1) {
		return newVectorObject(vi, 2, Py_NEW, NULL);
	}
	else {
		Py_RETURN_NONE;
	}
}
Ejemplo n.º 8
0
static PyObject *M_Geometry_ClosestPointOnLine( PyObject * self, PyObject * args )
{
	VectorObject *pt, *line_1, *line_2;
	float pt_in[3], pt_out[3], l1[3], l2[3];
	float lambda;
	PyObject *ret;
	
	if( !PyArg_ParseTuple ( args, "O!O!O!",
	&vector_Type, &pt,
	&vector_Type, &line_1,
	&vector_Type, &line_2)
	  ) {
		PyErr_SetString( PyExc_TypeError, "expected 3 vector types\n" );
		return NULL;
	}
	
	if(!BaseMath_ReadCallback(pt) || !BaseMath_ReadCallback(line_1) || !BaseMath_ReadCallback(line_2))
		return NULL;
	
	/* accept 2d verts */
	if (pt->size==3) { VECCOPY(pt_in, pt->vec);}
	else { pt_in[2]=0.0;	VECCOPY2D(pt_in, pt->vec) }
	
	if (line_1->size==3) { VECCOPY(l1, line_1->vec);}
	else { l1[2]=0.0;	VECCOPY2D(l1, line_1->vec) }
	
	if (line_2->size==3) { VECCOPY(l2, line_2->vec);}
	else { l2[2]=0.0;	VECCOPY2D(l2, line_2->vec) }
	
	/* do the calculation */
	lambda = lambda_cp_line_ex(pt_in, l1, l2, pt_out);
	
	ret = PyTuple_New(2);
	PyTuple_SET_ITEM( ret, 0, newVectorObject(pt_out, 3, Py_NEW, NULL) );
	PyTuple_SET_ITEM( ret, 1, PyFloat_FromDouble(lambda) );
	return ret;
}
Ejemplo n.º 9
0
static PyObject *M_Geometry_intersect_line_plane(PyObject *UNUSED(self), PyObject* args)
{
	VectorObject *line_a, *line_b, *plane_co, *plane_no;
	int no_flip= 0;
	float isect[3];
	if(!PyArg_ParseTuple(args, "O!O!O!O!|i:intersect_line_plane",
	  &vector_Type, &line_a,
	  &vector_Type, &line_b,
	  &vector_Type, &plane_co,
	  &vector_Type, &plane_no,
	  &no_flip)
	) {
		return NULL;
	}

	if(		BaseMath_ReadCallback(line_a) == -1 ||
	        BaseMath_ReadCallback(line_b) == -1 ||
	        BaseMath_ReadCallback(plane_co) == -1 ||
	        BaseMath_ReadCallback(plane_no) == -1
	) {
		return NULL;
	}

	if(ELEM4(2, line_a->size, line_b->size, plane_co->size, plane_no->size)) {
		PyErr_SetString(PyExc_ValueError,
		                "geometry.intersect_line_plane(...): "
		                " can't use 2D Vectors");
		return NULL;
	}

	if(isect_line_plane_v3(isect, line_a->vec, line_b->vec, plane_co->vec, plane_no->vec, no_flip) == 1) {
		return newVectorObject(isect, 3, Py_NEW, NULL);
	}
	else {
		Py_RETURN_NONE;
	}
}
Ejemplo n.º 10
0
static PyObject *M_Geometry_intersect_point_line(PyObject *UNUSED(self), PyObject* args)
{
	VectorObject *pt, *line_1, *line_2;
	float pt_in[3], pt_out[3], l1[3], l2[3];
	float lambda;
	PyObject *ret;
	
	if(!PyArg_ParseTuple(args, "O!O!O!:intersect_point_line",
		&vector_Type, &pt,
		&vector_Type, &line_1,
		&vector_Type, &line_2)
	) {
		return NULL;
	}
	
	if(BaseMath_ReadCallback(pt) == -1 || BaseMath_ReadCallback(line_1) == -1 || BaseMath_ReadCallback(line_2) == -1)
		return NULL;
	
	/* accept 2d verts */
	if (pt->size==3) { VECCOPY(pt_in, pt->vec);}
	else { pt_in[2]=0.0;	VECCOPY2D(pt_in, pt->vec) }
	
	if (line_1->size==3) { VECCOPY(l1, line_1->vec);}
	else { l1[2]=0.0;	VECCOPY2D(l1, line_1->vec) }
	
	if (line_2->size==3) { VECCOPY(l2, line_2->vec);}
	else { l2[2]=0.0;	VECCOPY2D(l2, line_2->vec) }
	
	/* do the calculation */
	lambda= closest_to_line_v3(pt_out, pt_in, l1, l2);
	
	ret= PyTuple_New(2);
	PyTuple_SET_ITEM(ret, 0, newVectorObject(pt_out, 3, Py_NEW, NULL));
	PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(lambda));
	return ret;
}
Ejemplo n.º 11
0
PyObject* BL_ArmatureChannel::py_attr_get_joint_rotation(void *self_v, const struct KX_PYATTRIBUTE_DEF *attrdef)
{
	bPoseChannel* pchan = static_cast<bPoseChannel*>(self_v);
	// decompose the pose matrix in euler rotation
	float rest_mat[3][3];
	float pose_mat[3][3];
	float joint_mat[3][3];
	float joints[3];
	float norm;
	double sa, ca;
	// get rotation in armature space
	copy_m3_m4(pose_mat, pchan->pose_mat);
	normalize_m3(pose_mat);
	if (pchan->parent) {
		// bone has a parent, compute the rest pose of the bone taking actual pose of parent
		mul_m3_m3m4(rest_mat, pchan->bone->bone_mat, pchan->parent->pose_mat);
		normalize_m3(rest_mat);
	} else {
		// otherwise, the bone matrix in armature space is the rest pose
		copy_m3_m4(rest_mat, pchan->bone->arm_mat);
	}
	// remove the rest pose to get the joint movement
	transpose_m3(rest_mat);
	mul_m3_m3m3(joint_mat, rest_mat, pose_mat);		
	joints[0] = joints[1] = joints[2] = 0.f;
	// returns a 3 element list that gives corresponding joint
	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;
	switch (flag) {
	case 0:	// fixed joint
		break;
	case 1:	// X only
		mat3_to_eulO( joints, EULER_ORDER_XYZ,joint_mat);
		joints[1] = joints[2] = 0.f;
		break;
	case 2:	// Y only
		mat3_to_eulO( joints, EULER_ORDER_XYZ,joint_mat);
		joints[0] = joints[2] = 0.f;
		break;
	case 3:	// X+Y
		mat3_to_eulO( joints, EULER_ORDER_ZYX,joint_mat);
		joints[2] = 0.f;
		break;
	case 4:	// Z only
		mat3_to_eulO( joints, EULER_ORDER_XYZ,joint_mat);
		joints[0] = joints[1] = 0.f;
		break;
	case 5:	// X+Z
		// decompose this as an equivalent rotation vector in X/Z plane
		joints[0] = joint_mat[1][2];
		joints[2] = -joint_mat[1][0];
		norm = normalize_v3(joints);
		if (norm < FLT_EPSILON) {
			norm = (joint_mat[1][1] < 0.f) ? M_PI : 0.f;
		} else {
			norm = acos(joint_mat[1][1]);
		}
		mul_v3_fl(joints, norm);
		break;
	case 6:	// Y+Z
		mat3_to_eulO( joints, EULER_ORDER_XYZ,joint_mat);
		joints[0] = 0.f;
		break;
	case 7: // X+Y+Z
		// equivalent axis
		joints[0] = (joint_mat[1][2]-joint_mat[2][1])*0.5f;
		joints[1] = (joint_mat[2][0]-joint_mat[0][2])*0.5f;
		joints[2] = (joint_mat[0][1]-joint_mat[1][0])*0.5f;
		sa = len_v3(joints);
		ca = (joint_mat[0][0]+joint_mat[1][1]+joint_mat[1][1]-1.0f)*0.5f;
		if (sa > FLT_EPSILON) {
			norm = atan2(sa,ca)/sa;
		} else {
		   if (ca < 0.0) {
			   norm = M_PI;
			   mul_v3_fl(joints,0.f);
			   if (joint_mat[0][0] > 0.f) {
				   joints[0] = 1.0f;
			   } else if (joint_mat[1][1] > 0.f) {
				   joints[1] = 1.0f;
			   } else {
				   joints[2] = 1.0f;
			   }
		   } else {
			   norm = 0.0;
		   }
		}
		mul_v3_fl(joints,norm);
		break;
	}
	return newVectorObject(joints, 3, Py_NEW, NULL);
}
Ejemplo n.º 12
0
/* note, this is called as a python 'getset, where the PyAttributeDef is the closure */
PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef *attrdef)
{
	PyObjectPlus *ref= (BGE_PROXY_REF(self_py));
	char* ptr = (attrdef->m_usePtr) ? (char*)BGE_PROXY_PTR(self_py) : (char*)ref;
	if(ptr == NULL || (BGE_PROXY_PYREF(self_py) && (ref==NULL || !ref->py_is_valid()))) {
		if(attrdef == attr_invalid)
			Py_RETURN_TRUE; // dont bother running the function

		PyErr_SetString(PyExc_SystemError, BGE_PROXY_ERROR_MSG);
		return NULL;
	}

	if (attrdef->m_type == KX_PYATTRIBUTE_TYPE_DUMMY)
	{
		// fake attribute, ignore
		return NULL;
	}
	if (attrdef->m_type == KX_PYATTRIBUTE_TYPE_FUNCTION)
	{
		// the attribute has no field correspondance, handover processing to function.
		if (attrdef->m_getFunction == NULL)
			return NULL;
		return (*attrdef->m_getFunction)(ref, attrdef);
	}
	ptr += attrdef->m_offset;
	if (attrdef->m_length > 1)
	{
		PyObject* resultlist = PyList_New(attrdef->m_length);
		for (unsigned int i=0; i<attrdef->m_length; i++)
		{
			switch (attrdef->m_type) {
			case KX_PYATTRIBUTE_TYPE_BOOL:
				{
					bool *val = reinterpret_cast<bool*>(ptr);
					ptr += sizeof(bool);
					PyList_SET_ITEM(resultlist,i,PyLong_FromSsize_t(*val));
					break;
				}
			case KX_PYATTRIBUTE_TYPE_SHORT:
				{
					short int *val = reinterpret_cast<short int*>(ptr);
					ptr += sizeof(short int);
					PyList_SET_ITEM(resultlist,i,PyLong_FromSsize_t(*val));
					break;
				}
			case KX_PYATTRIBUTE_TYPE_ENUM:
				// enum are like int, just make sure the field size is the same
				if (sizeof(int) != attrdef->m_size)
				{
					Py_DECREF(resultlist);
					return NULL;
				}
				// walkthrough
			case KX_PYATTRIBUTE_TYPE_INT:
				{
					int *val = reinterpret_cast<int*>(ptr);
					ptr += sizeof(int);
					PyList_SET_ITEM(resultlist,i,PyLong_FromSsize_t(*val));
					break;
				}
			case KX_PYATTRIBUTE_TYPE_FLOAT:
				{
					float *val = reinterpret_cast<float*>(ptr);
					ptr += sizeof(float);
					PyList_SET_ITEM(resultlist,i,PyFloat_FromDouble(*val));
					break;
				}
			default:
				// no support for array of complex data
				Py_DECREF(resultlist);
				return NULL;
			}
		}
		return resultlist;
	}
	else
	{
		switch (attrdef->m_type) {
		case KX_PYATTRIBUTE_TYPE_FLAG:
			{
				bool bval;
				switch (attrdef->m_size) {
				case 1:
					{
						unsigned char *val = reinterpret_cast<unsigned char*>(ptr);
						bval = (*val & attrdef->m_imin);
						break;
					}
				case 2:
					{
						unsigned short *val = reinterpret_cast<unsigned short*>(ptr);
						bval = (*val & attrdef->m_imin);
						break;
					}
				case 4:
					{
						unsigned int *val = reinterpret_cast<unsigned int*>(ptr);
						bval = (*val & attrdef->m_imin);
						break;
					}
				default:
					return NULL;
				}
				if (attrdef->m_imax)
					bval = !bval;
				return PyLong_FromSsize_t(bval);
			}
		case KX_PYATTRIBUTE_TYPE_BOOL:
			{
				bool *val = reinterpret_cast<bool*>(ptr);
				return PyLong_FromSsize_t(*val);
			}
		case KX_PYATTRIBUTE_TYPE_SHORT:
			{
				short int *val = reinterpret_cast<short int*>(ptr);
				return PyLong_FromSsize_t(*val);
			}
		case KX_PYATTRIBUTE_TYPE_ENUM:
			// enum are like int, just make sure the field size is the same
			if (sizeof(int) != attrdef->m_size)
			{
				return NULL;
			}
			// walkthrough
		case KX_PYATTRIBUTE_TYPE_INT:
			{
				int *val = reinterpret_cast<int*>(ptr);
				return PyLong_FromSsize_t(*val);
			}
		case KX_PYATTRIBUTE_TYPE_FLOAT:
			{
				float *val = reinterpret_cast<float*>(ptr);
				if (attrdef->m_imin == 0) {
					if (attrdef->m_imax == 0) {
						return PyFloat_FromDouble(*val);
					} else {
						// vector, verify size
						if (attrdef->m_size != attrdef->m_imax*sizeof(float)) 
						{
							return NULL;
						}
#ifdef USE_MATHUTILS
						return newVectorObject(val, attrdef->m_imax, Py_NEW, NULL);
#else
						PyObject* resultlist = PyList_New(attrdef->m_imax);
						for (unsigned int i=0; i<attrdef->m_imax; i++)
						{
							PyList_SET_ITEM(resultlist,i,PyFloat_FromDouble(val[i]));
						}
						return resultlist;
#endif
					}
				} else {
					// matrix case
					if (attrdef->m_size != attrdef->m_imax*attrdef->m_imin*sizeof(float)) 
					{
						return NULL;
					}
#ifdef USE_MATHUTILS
					return newMatrixObject(val, attrdef->m_imin, attrdef->m_imax, Py_WRAP, NULL);
#else
					PyObject* rowlist = PyList_New(attrdef->m_imin);
					for (unsigned int i=0; i<attrdef->m_imin; i++)
					{
						PyObject* collist = PyList_New(attrdef->m_imax);
						for (unsigned int j=0; j<attrdef->m_imax; j++)
						{
							PyList_SET_ITEM(collist,j,PyFloat_FromDouble(val[j]));
						}
						PyList_SET_ITEM(rowlist,i,collist);
						val += attrdef->m_imax;
					}
					return rowlist;
#endif
				}
			}
		case KX_PYATTRIBUTE_TYPE_VECTOR:
			{
				MT_Vector3 *val = reinterpret_cast<MT_Vector3*>(ptr);
#ifdef USE_MATHUTILS
				float fval[3]= {(*val)[0], (*val)[1], (*val)[2]};
				return newVectorObject(fval, 3, Py_NEW, NULL);
#else
				PyObject* resultlist = PyList_New(3);
				for (unsigned int i=0; i<3; i++)
				{
					PyList_SET_ITEM(resultlist,i,PyFloat_FromDouble((*val)[i]));
				}
				return resultlist;
#endif
			}
		case KX_PYATTRIBUTE_TYPE_STRING:
			{
				STR_String *val = reinterpret_cast<STR_String*>(ptr);
				return PyUnicode_FromString(*val);
			}
		case KX_PYATTRIBUTE_TYPE_CHAR:
			{
				return PyUnicode_FromString(ptr);
			}
		default:
			return NULL;
		}
	}
}
Ejemplo n.º 13
0
static PyObject *M_Geometry_LineIntersect2D( PyObject * self, PyObject * args )
{
	VectorObject *line_a1, *line_a2, *line_b1, *line_b2;
	float a1x, a1y, a2x, a2y,  b1x, b1y, b2x, b2y, xi, yi, a1,a2,b1,b2, newvec[2];
	if( !PyArg_ParseTuple ( args, "O!O!O!O!",
	  &vector_Type, &line_a1,
	  &vector_Type, &line_a2,
	  &vector_Type, &line_b1,
	  &vector_Type, &line_b2)
	) {
		PyErr_SetString( PyExc_TypeError, "expected 4 vector types\n" );
		return NULL;
	}
	
	if(!BaseMath_ReadCallback(line_a1) || !BaseMath_ReadCallback(line_a2) || !BaseMath_ReadCallback(line_b1) || !BaseMath_ReadCallback(line_b2))
		return NULL;
	
	a1x= line_a1->vec[0];
	a1y= line_a1->vec[1];
	a2x= line_a2->vec[0];
	a2y= line_a2->vec[1];

	b1x= line_b1->vec[0];
	b1y= line_b1->vec[1];
	b2x= line_b2->vec[0];
	b2y= line_b2->vec[1];
	
	if((MIN2(a1x, a2x) > MAX2(b1x, b2x)) ||
	   (MAX2(a1x, a2x) < MIN2(b1x, b2x)) ||
	   (MIN2(a1y, a2y) > MAX2(b1y, b2y)) ||
	   (MAX2(a1y, a2y) < MIN2(b1y, b2y))  ) {
		Py_RETURN_NONE;
	}
	/* Make sure the hoz/vert line comes first. */
	if (fabs(b1x - b2x) < eul || fabs(b1y - b2y) < eul) {
		SWAP_FLOAT(a1x, b1x, xi); /*abuse xi*/
		SWAP_FLOAT(a1y, b1y, xi);
		SWAP_FLOAT(a2x, b2x, xi);
		SWAP_FLOAT(a2y, b2y, xi);
	}
	
	if (fabs(a1x-a2x) < eul) { /* verticle line */
		if (fabs(b1x-b2x) < eul){ /*verticle second line */
			Py_RETURN_NONE; /* 2 verticle lines dont intersect. */
		}
		else if (fabs(b1y-b2y) < eul) {
			/*X of vert, Y of hoz. no calculation needed */
			newvec[0]= a1x;
			newvec[1]= b1y;
			return newVectorObject(newvec, 2, Py_NEW, NULL);
		}
		
		yi = (float)(((b1y / fabs(b1x - b2x)) * fabs(b2x - a1x)) + ((b2y / fabs(b1x - b2x)) * fabs(b1x - a1x)));
		
		if (yi > MAX2(a1y, a2y)) {/* New point above seg1's vert line */
			Py_RETURN_NONE;
		} else if (yi < MIN2(a1y, a2y)) { /* New point below seg1's vert line */
			Py_RETURN_NONE;
		}
		newvec[0]= a1x;
		newvec[1]= yi;
		return newVectorObject(newvec, 2, Py_NEW, NULL);
	} else if (fabs(a2y-a1y) < eul) {  /* hoz line1 */
		if (fabs(b2y-b1y) < eul) { /*hoz line2*/
			Py_RETURN_NONE; /*2 hoz lines dont intersect*/
		}
		
		/* Can skip vert line check for seg 2 since its covered above. */
		xi = (float)(((b1x / fabs(b1y - b2y)) * fabs(b2y - a1y)) + ((b2x / fabs(b1y - b2y)) * fabs(b1y - a1y)));
		if (xi > MAX2(a1x, a2x)) { /* New point right of hoz line1's */
			Py_RETURN_NONE;
		} else if (xi < MIN2(a1x, a2x)) { /*New point left of seg1's hoz line */
			Py_RETURN_NONE;
		}
		newvec[0]= xi;
		newvec[1]= a1y;
		return newVectorObject(newvec, 2, Py_NEW, NULL);
	}
	
	b1 = (a2y-a1y)/(a2x-a1x);
	b2 = (b2y-b1y)/(b2x-b1x);
	a1 = a1y-b1*a1x;
	a2 = b1y-b2*b1x;
	
	if (b1 - b2 == 0.0) {
		Py_RETURN_NONE;
	}
	
	xi = - (a1-a2)/(b1-b2);
	yi = a1+b1*xi;
	if ((a1x-xi)*(xi-a2x) >= 0 && (b1x-xi)*(xi-b2x) >= 0 && (a1y-yi)*(yi-a2y) >= 0 && (b1y-yi)*(yi-b2y)>=0) {
		newvec[0]= xi;
		newvec[1]= yi;
		return newVectorObject(newvec, 2, Py_NEW, NULL);
	}
	Py_RETURN_NONE;
}
Ejemplo n.º 14
0
static PyObject *M_Geometry_intersect_ray_tri(PyObject *UNUSED(self), PyObject* args)
{
	VectorObject *ray, *ray_off, *vec1, *vec2, *vec3;
	float dir[3], orig[3], v1[3], v2[3], v3[3], e1[3], e2[3], pvec[3], tvec[3], qvec[3];
	float det, inv_det, u, v, t;
	int clip= 1;

	if(!PyArg_ParseTuple(args, "O!O!O!O!O!|i:intersect_ray_tri", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &ray, &vector_Type, &ray_off , &clip)) {
		return NULL;
	}
	if(vec1->size != 3 || vec2->size != 3 || vec3->size != 3 || ray->size != 3 || ray_off->size != 3) {
		PyErr_SetString(PyExc_ValueError,
		                "only 3D vectors for all parameters");
		return NULL;
	}

	if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1 || BaseMath_ReadCallback(vec3) == -1 || BaseMath_ReadCallback(ray) == -1 || BaseMath_ReadCallback(ray_off) == -1)
		return NULL;

	VECCOPY(v1, vec1->vec);
	VECCOPY(v2, vec2->vec);
	VECCOPY(v3, vec3->vec);

	VECCOPY(dir, ray->vec);
	normalize_v3(dir);

	VECCOPY(orig, ray_off->vec);

	/* find vectors for two edges sharing v1 */
	sub_v3_v3v3(e1, v2, v1);
	sub_v3_v3v3(e2, v3, v1);

	/* begin calculating determinant - also used to calculated U parameter */
	cross_v3_v3v3(pvec, dir, e2);

	/* if determinant is near zero, ray lies in plane of triangle */
	det= dot_v3v3(e1, pvec);

	if (det > -0.000001f && det < 0.000001f) {
		Py_RETURN_NONE;
	}

	inv_det= 1.0f / det;

	/* calculate distance from v1 to ray origin */
	sub_v3_v3v3(tvec, orig, v1);

	/* calculate U parameter and test bounds */
	u= dot_v3v3(tvec, pvec) * inv_det;
	if (clip && (u < 0.0f || u > 1.0f)) {
		Py_RETURN_NONE;
	}

	/* prepare to test the V parameter */
	cross_v3_v3v3(qvec, tvec, e1);

	/* calculate V parameter and test bounds */
	v= dot_v3v3(dir, qvec) * inv_det;

	if (clip && (v < 0.0f || u + v > 1.0f)) {
		Py_RETURN_NONE;
	}

	/* calculate t, ray intersects triangle */
	t= dot_v3v3(e2, qvec) * inv_det;

	mul_v3_fl(dir, t);
	add_v3_v3v3(pvec, orig, dir);

	return newVectorObject(pvec, 3, Py_NEW, NULL);
}
Ejemplo n.º 15
0
static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject *args)
{
	PyObject *tuple;
	VectorObject *vec1, *vec2, *vec3, *vec4;
	float v1[3], v2[3], v3[3], v4[3], i1[3], i2[3];

	if(!PyArg_ParseTuple(args, "O!O!O!O!:intersect_line_line", &vector_Type, &vec1, &vector_Type, &vec2, &vector_Type, &vec3, &vector_Type, &vec4)) {
		return NULL;
	}
	if(vec1->size != vec2->size || vec1->size != vec3->size || vec3->size != vec2->size) {
		PyErr_SetString(PyExc_ValueError,
		                "vectors must be of the same size");
		return NULL;
	}

	if(BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1 || BaseMath_ReadCallback(vec3) == -1 || BaseMath_ReadCallback(vec4) == -1)
		return NULL;

	if(vec1->size == 3 || vec1->size == 2) {
		int result;

		if (vec1->size == 3) {
			VECCOPY(v1, vec1->vec);
			VECCOPY(v2, vec2->vec);
			VECCOPY(v3, vec3->vec);
			VECCOPY(v4, vec4->vec);
		}
		else {
			v1[0]= vec1->vec[0];
			v1[1]= vec1->vec[1];
			v1[2]= 0.0f;

			v2[0]= vec2->vec[0];
			v2[1]= vec2->vec[1];
			v2[2]= 0.0f;

			v3[0]= vec3->vec[0];
			v3[1]= vec3->vec[1];
			v3[2]= 0.0f;

			v4[0]= vec4->vec[0];
			v4[1]= vec4->vec[1];
			v4[2]= 0.0f;
		}

		result= isect_line_line_v3(v1, v2, v3, v4, i1, i2);

		if (result == 0) {
			/* colinear */
			Py_RETURN_NONE;
		}
		else {
			tuple= PyTuple_New(2);
			PyTuple_SET_ITEM(tuple, 0, newVectorObject(i1, vec1->size, Py_NEW, NULL));
			PyTuple_SET_ITEM(tuple, 1, newVectorObject(i2, vec1->size, Py_NEW, NULL));
			return tuple;
		}
	}
	else {
		PyErr_SetString(PyExc_ValueError,
		                "2D/3D vectors only");
		return NULL;
	}
}