diff options
author | Joseph Gilbert <ascotan@gmail.com> | 2005-09-26 19:06:28 +0400 |
---|---|---|
committer | Joseph Gilbert <ascotan@gmail.com> | 2005-09-26 19:06:28 +0400 |
commit | 9656e8be02972740055f3614590645535840acc9 (patch) | |
tree | 68c2ef13b4a77769a801ecec60fb502a48da1d18 /source | |
parent | b6ecdb8c354233c33dcd1282ddf8bc7e68120c37 (diff) |
Theeth's mathutils patch
- adds intersections for lines
- triangle area
- tracking quaternion from vector
- some helpful normal calculators
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/python/api2_2x/Mathutils.c | 319 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Mathutils.h | 5 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Mathutils.py | 95 | ||||
-rw-r--r-- | source/blender/python/api2_2x/vector.c | 115 | ||||
-rw-r--r-- | source/blender/python/api2_2x/vector.h | 1 |
5 files changed, 535 insertions, 0 deletions
diff --git a/source/blender/python/api2_2x/Mathutils.c b/source/blender/python/api2_2x/Mathutils.c index 4250d23ab4e..63ab90ad0e3 100644 --- a/source/blender/python/api2_2x/Mathutils.c +++ b/source/blender/python/api2_2x/Mathutils.c @@ -35,6 +35,7 @@ #include "BLI_arithb.h" #include "PIL_time.h" #include "BLI_rand.h" +#include "BKE_utildefines.h" #include "gen_utils.h" //-------------------------DOC STRINGS --------------------------- @@ -65,6 +66,11 @@ static char M_Mathutils_DotQuats_doc[] = "() - return the dot product of two qua static char M_Mathutils_Slerp_doc[] = "() - returns the interpolation between two quaternions"; static char M_Mathutils_DifferenceQuats_doc[] = "() - return the angular displacment difference between two quats"; static char M_Mathutils_RotateEuler_doc[] = "() - rotate euler by an axis and angle"; +static char M_Mathutils_Intersect_doc[] = "(v1, v2, v3, ray, orig, clip=1) - returns the intersection between a ray and a triangle, if possible, returns None otherwise"; +static char M_Mathutils_TriangleArea_doc[] = "(v1, v2, v3) - returns the area size of the 2D or 3D triangle defined"; +static char M_Mathutils_TriangleNormal_doc[] = "(v1, v2, v3) - returns the normal of the 3D triangle defined"; +static char M_Mathutils_QuadNormal_doc[] = "(v1, v2, v3, v4) - returns the normal of the 3D quad defined"; +static char M_Mathutils_LineIntersect_doc[] = "(v1, v2, v3, v4) - returns a tuple with the points on each line respectively closest to the other"; //-----------------------METHOD DEFINITIONS ---------------------- struct PyMethodDef M_Mathutils_methods[] = { {"Rand", (PyCFunction) M_Mathutils_Rand, METH_VARARGS, M_Mathutils_Rand_doc}, @@ -93,6 +99,11 @@ struct PyMethodDef M_Mathutils_methods[] = { {"Euler", (PyCFunction) M_Mathutils_Euler, METH_VARARGS, M_Mathutils_Euler_doc}, {"CopyEuler", (PyCFunction) M_Mathutils_CopyEuler, METH_VARARGS, M_Mathutils_CopyEuler_doc}, {"RotateEuler", (PyCFunction) M_Mathutils_RotateEuler, METH_VARARGS, M_Mathutils_RotateEuler_doc}, + {"Intersect", ( PyCFunction ) M_Mathutils_Intersect, METH_VARARGS, M_Mathutils_Intersect_doc}, + {"TriangleArea", ( PyCFunction ) M_Mathutils_TriangleArea, METH_VARARGS, M_Mathutils_TriangleArea_doc}, + {"TriangleNormal", ( PyCFunction ) M_Mathutils_TriangleNormal, METH_VARARGS, M_Mathutils_TriangleNormal_doc}, + {"QuadNormal", ( PyCFunction ) M_Mathutils_QuadNormal, METH_VARARGS, M_Mathutils_QuadNormal_doc}, + {"LineIntersect", ( PyCFunction ) M_Mathutils_LineIntersect, METH_VARARGS, M_Mathutils_LineIntersect_doc}, {NULL, NULL, 0, NULL} }; //----------------------------MODULE INIT------------------------- @@ -1279,6 +1290,314 @@ PyObject *M_Mathutils_Euler(PyObject * self, PyObject * args) Py_DECREF(listObject); return (PyObject *) newEulerObject(eul, Py_NEW); } +//---------------------------------INTERSECTION FUNCTIONS-------------------- +//----------------------------------Mathutils.Intersect() ------------------- +PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args ) +{ + VectorObject *ray; + VectorObject *ray_off; + VectorObject *vec1; + VectorObject *vec2; + VectorObject *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", &vector_Type, &vec1, &vector_Type, &vec2 + , &vector_Type, &vec3, &vector_Type, &ray, &vector_Type, &ray_off , &clip) ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "expected 5 vector types\n" ) ); + if( vec1->size != 3 || vec2->size != 3 || vec3->size != 3 || + ray->size != 3 || ray_off->size != 3) + return ( EXPP_ReturnPyObjError( PyExc_TypeError, + "only 3D vectors for all parameters\n" ) ); + + VECCOPY(v1, vec1->vec); + VECCOPY(v2, vec2->vec); + VECCOPY(v3, vec3->vec); + + VECCOPY(dir, ray->vec); + Normalise(dir); + + VECCOPY(orig, ray_off->vec); + + /* find vectors for two edges sharing v1 */ + VecSubf(e1, v2, v1); + VecSubf(e2, v3, v1); + + /* begin calculating determinant - also used to calculated U parameter */ + Crossf(pvec, dir, e2); + + /* if determinant is near zero, ray lies in plane of triangle */ + det = Inpf(e1, pvec); + + if (det > -0.000001 && det < 0.000001) { + return EXPP_incr_ret( Py_None ); + } + + inv_det = 1.0f / det; + + /* calculate distance from v1 to ray origin */ + VecSubf(tvec, orig, v1); + + /* calculate U parameter and test bounds */ + u = Inpf(tvec, pvec) * inv_det; + if (clip && (u < 0.0f || u > 1.0f)) { + return EXPP_incr_ret( Py_None ); + } + + /* prepare to test the V parameter */ + Crossf(qvec, tvec, e1); + + /* calculate V parameter and test bounds */ + v = Inpf(dir, qvec) * inv_det; + + if (clip && (v < 0.0f || u + v > 1.0f)) { + return EXPP_incr_ret( Py_None ); + } + + /* calculate t, ray intersects triangle */ + t = Inpf(e2, qvec) * inv_det; + + VecMulf(dir, t); + VecAddf(pvec, orig, dir); + + return newVectorObject(pvec, 3, Py_NEW); +} +//----------------------------------Mathutils.LineIntersect() ------------------- +/* Line-Line intersection using algorithm from mathworld.wolfram.com */ +PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ) +{ + PyObject * tuple; + VectorObject *vec1; + VectorObject *vec2; + VectorObject *vec3; + VectorObject *vec4; + float v1[3], v2[3], v3[3], v4[3], i1[3], i2[3]; + + if( !PyArg_ParseTuple + ( args, "O!O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2 + , &vector_Type, &vec3, &vector_Type, &vec4 ) ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "expected 4 vector types\n" ) ); + if( vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec2->size) + return ( EXPP_ReturnPyObjError( PyExc_TypeError, + "vectors must be of the same size\n" ) ); + + if( vec1->size == 3 || vec1->size == 2) { + float a[3], b[3], c[3], ab[3], cb[3], dir1[3], dir2[3]; + float d; + 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; + } + + VecSubf(c, v3, v1); + VecSubf(a, v2, v1); + VecSubf(b, v4, v3); + + VECCOPY(dir1, a); + Normalise(dir1); + VECCOPY(dir2, b); + Normalise(dir2); + d = Inpf(dir1, dir2); + if (d == 1.0f || d == -1.0f) { + /* colinear */ + return EXPP_incr_ret( Py_None ); + } + + Crossf(ab, a, b); + d = Inpf(c, ab); + + /* test if the two lines are coplanar */ + if (d > -0.000001f && d < 0.000001f) { + Crossf(cb, c, b); + + VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab)); + VecAddf(i1, v1, a); + VECCOPY(i2, i1); + } + /* if not */ + else { + float n[3], t[3]; + VecSubf(t, v1, v3); + + /* offset between both plane where the lines lies */ + Crossf(n, a, b); + Projf(t, t, n); + + /* for the first line, offset the second line until it is coplanar */ + VecAddf(v3, v3, t); + VecAddf(v4, v4, t); + + VecSubf(c, v3, v1); + VecSubf(a, v2, v1); + VecSubf(b, v4, v3); + + Crossf(ab, a, b); + Crossf(cb, c, b); + + VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab)); + VecAddf(i1, v1, a); + + /* for the second line, just substract the offset from the first intersection point */ + VecSubf(i2, i1, t); + } + + tuple = PyTuple_New( 2 ); + PyTuple_SetItem( tuple, 0, newVectorObject(i1, vec1->size, Py_NEW) ); + PyTuple_SetItem( tuple, 1, newVectorObject(i2, vec1->size, Py_NEW) ); + return tuple; + } + else { + return ( EXPP_ReturnPyObjError( PyExc_TypeError, + "2D/3D vectors only\n" ) ); + } +} +//---------------------------------NORMALS FUNCTIONS-------------------- +//----------------------------------Mathutils.QuadNormal() ------------------- +PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args ) +{ + VectorObject *vec1; + VectorObject *vec2; + VectorObject *vec3; + VectorObject *vec4; + float v1[3], v2[3], v3[3], v4[3], e1[3], e2[3], n1[3], n2[3]; + + if( !PyArg_ParseTuple + ( args, "O!O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2 + , &vector_Type, &vec3, &vector_Type, &vec4 ) ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "expected 4 vector types\n" ) ); + if( vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec4->size) + return ( EXPP_ReturnPyObjError( PyExc_TypeError, + "vectors must be of the same size\n" ) ); + if( vec1->size != 3 ) + return ( EXPP_ReturnPyObjError( PyExc_TypeError, + "only 3D vectors\n" ) ); + + VECCOPY(v1, vec1->vec); + VECCOPY(v2, vec2->vec); + VECCOPY(v3, vec3->vec); + VECCOPY(v4, vec4->vec); + + /* find vectors for two edges sharing v2 */ + VecSubf(e1, v1, v2); + VecSubf(e2, v3, v2); + + Crossf(n1, e2, e1); + Normalise(n1); + + /* find vectors for two edges sharing v4 */ + VecSubf(e1, v3, v4); + VecSubf(e2, v1, v4); + + Crossf(n2, e2, e1); + Normalise(n2); + + /* adding and averaging the normals of both triangles */ + VecAddf(n1, n2, n1); + Normalise(n1); + + return newVectorObject(n1, 3, Py_NEW); +} + +//----------------------------Mathutils.TriangleNormal() ------------------- +PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args ) +{ + VectorObject *vec1; + VectorObject *vec2; + VectorObject *vec3; + float v1[3], v2[3], v3[3], e1[3], e2[3], n[3]; + + if( !PyArg_ParseTuple + ( args, "O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2 + , &vector_Type, &vec3 ) ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "expected 3 vector types\n" ) ); + if( vec1->size != vec2->size || vec1->size != vec3->size ) + return ( EXPP_ReturnPyObjError( PyExc_TypeError, + "vectors must be of the same size\n" ) ); + if( vec1->size != 3 ) + return ( EXPP_ReturnPyObjError( PyExc_TypeError, + "only 3D vectors\n" ) ); + + VECCOPY(v1, vec1->vec); + VECCOPY(v2, vec2->vec); + VECCOPY(v3, vec3->vec); + + /* find vectors for two edges sharing v2 */ + VecSubf(e1, v1, v2); + VecSubf(e2, v3, v2); + + Crossf(n, e2, e1); + Normalise(n); + + return newVectorObject(n, 3, Py_NEW); +} + +//--------------------------------- AREA FUNCTIONS-------------------- +//----------------------------------Mathutils.TriangleArea() ------------------- +PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args ) +{ + VectorObject *vec1; + VectorObject *vec2; + VectorObject *vec3; + float v1[3], v2[3], v3[3]; + + if( !PyArg_ParseTuple + ( args, "O!O!O!", &vector_Type, &vec1, &vector_Type, &vec2 + , &vector_Type, &vec3 ) ) + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, "expected 3 vector types\n" ) ); + if( vec1->size != vec2->size || vec1->size != vec3->size ) + return ( EXPP_ReturnPyObjError( PyExc_TypeError, + "vectors must be of the same size\n" ) ); + + if (vec1->size == 3) { + VECCOPY(v1, vec1->vec); + VECCOPY(v2, vec2->vec); + VECCOPY(v3, vec3->vec); + + return PyFloat_FromDouble( AreaT3Dfl(v1, v2, v3) ); + } + else if (vec1->size == 2) { + v1[0] = vec1->vec[0]; + v1[1] = vec1->vec[1]; + + v2[0] = vec2->vec[0]; + v2[1] = vec2->vec[1]; + + v3[0] = vec3->vec[0]; + v3[1] = vec3->vec[1]; + + return PyFloat_FromDouble( AreaF2Dfl(v1, v2, v3) ); + } + else { + return ( EXPP_ReturnPyObjError( PyExc_TypeError, + "only 2D,3D vectors are supported\n" ) ); + } +} //#############################DEPRECATED################################ //####################################################################### //----------------------------------Mathutils.CopyMat() ----------------- diff --git a/source/blender/python/api2_2x/Mathutils.h b/source/blender/python/api2_2x/Mathutils.h index 6649da67e5a..d2914c8e81c 100644 --- a/source/blender/python/api2_2x/Mathutils.h +++ b/source/blender/python/api2_2x/Mathutils.h @@ -68,6 +68,11 @@ PyObject *M_Mathutils_DotQuats(PyObject * self, PyObject * args); PyObject *M_Mathutils_DifferenceQuats(PyObject * self, PyObject * args); PyObject *M_Mathutils_Slerp(PyObject * self, PyObject * args); PyObject *M_Mathutils_Euler(PyObject * self, PyObject * args); +PyObject *M_Mathutils_Intersect( PyObject * self, PyObject * args ); +PyObject *M_Mathutils_TriangleArea( PyObject * self, PyObject * args ); +PyObject *M_Mathutils_TriangleNormal( PyObject * self, PyObject * args ); +PyObject *M_Mathutils_QuadNormal( PyObject * self, PyObject * args ); +PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args ); //DEPRECATED PyObject *M_Mathutils_CopyMat(PyObject * self, PyObject * args); PyObject *M_Mathutils_CopyVec(PyObject * self, PyObject * args); diff --git a/source/blender/python/api2_2x/doc/Mathutils.py b/source/blender/python/api2_2x/doc/Mathutils.py index 0319553c6e6..0255f031ccc 100644 --- a/source/blender/python/api2_2x/doc/Mathutils.py +++ b/source/blender/python/api2_2x/doc/Mathutils.py @@ -39,6 +39,81 @@ def Rand (high = 1, low = 0): @param low: The lower range. """ +def Intersect(vec1, vec2, vec3, ray, orig, clip=1): + """ + Return the intersection between a ray and a triangle, if possible, return None otherwise. + @type vec1: Vector object. + @param vec1: A 3d vector, one corner of the triangle. + @type vec2: Vector object. + @param vec2: A 3d vector, one corner of the triangle. + @type vec3: Vector object. + @param vec3: A 3d vector, one corner of the triangle. + @type ray: Vector object. + @param ray: A 3d vector, the orientation of the ray. + @type orig: Vector object. + @param orig: A 3d vector, the origin of the ray. + @type clip: integer + @param clip: if 0, don't restrict the intersection to the area of the triangle, use the infinite plane defined by the triangle. + @rtype: Vector object + @return: The intersection between a ray and a triangle, if possible, None otherwise. + """ + +def TriangleArea(vec1, vec2, vec3): + """ + Return the area size of the 2D or 3D triangle defined. + @type vec1: Vector object. + @param vec1: A 2d or 3d vector, one corner of the triangle. + @type vec2: Vector object. + @param vec2: A 2d or 3d vector, one corner of the triangle. + @type vec3: Vector object. + @param vec3: A 2d or 3d vector, one corner of the triangle. + @rtype: float + @return: The area size of the 2D or 3D triangle defined. + """ + +def TriangleNormal(vec1, vec2, vec3): + """ + Return the normal of the 3D triangle defined. + @type vec1: Vector object. + @param vec1: A 3d vector, one corner of the triangle. + @type vec2: Vector object. + @param vec2: A 3d vector, one corner of the triangle. + @type vec3: Vector object. + @param vec3: A 3d vector, one corner of the triangle. + @rtype: float + @return: The normal of the 3D triangle defined. + """ + +def QuadNormal(vec1, vec2, vec3, vec4): + """ + Return the normal of the 3D quad defined. + @type vec1: Vector object. + @param vec1: A 3d vector, the first vertex of the quad. + @type vec2: Vector object. + @param vec2: A 3d vector, the second vertex of the quad. + @type vec3: Vector object. + @param vec3: A 3d vector, the third vertex of the quad. + @type vec4: Vector object. + @param vec4: A 3d vector, the fourth vertex of the quad. + @rtype: float + @return: The normal of the 3D quad defined. + """ + +def LineIntersect(vec1, vec2, vec3, vec4): + """ + Return a tuple with the points on each line respectively closest to the other (when both lines intersect, both vector hold the same value). + @type vec1: Vector object. + @param vec1: A 3d vector, one point on the first line. + @type vec2: Vector object. + @param vec2: A 3d vector, another point on the first line. + @type vec3: Vector object. + @param vec3: A 3d vector, one point on the second line. + @type vec4: Vector object. + @param vec4: A 3d vector, another point on the second line. + @rtype: (Vector object, Vector object) + @return: A tuple with the points on each line respectively closest to the other. + """ + def CopyVec(vector): """ Create a copy of the Vector object. @@ -356,6 +431,26 @@ class Vector: Resize the vector to 4d. """ + def toTrackQuat(track, up): + """ + Return a quaternion rotation from the vector and the track and up axis. + @type track: String. + @param track: Possible values: + - "x - x-axis up" + - "y - y-axis up" + - "z - z-axis up" + - "-x - negative x-axis up" + - "-y - negative y-axis up" + - "-z - negative z-axis up" + @type up: String. + @param up: Possible values: + - "x - x-axis up" + - "y - y-axis up" + - "z - z-axis up" + @rtype: Quaternion + @return: Return a quaternion rotation from the vector and the track and up axis. + """ + class Euler: """ The Euler object diff --git a/source/blender/python/api2_2x/vector.c b/source/blender/python/api2_2x/vector.c index 469b858b609..60766644e39 100644 --- a/source/blender/python/api2_2x/vector.c +++ b/source/blender/python/api2_2x/vector.c @@ -32,6 +32,7 @@ #include "BLI_blenlib.h" #include "BKE_utildefines.h" +#include "BLI_arithb.h" #include "gen_utils.h" @@ -43,6 +44,7 @@ char Vector_Resize2D_doc[] = "() - resize a vector to [x,y]"; char Vector_Resize3D_doc[] = "() - resize a vector to [x,y,z]"; char Vector_Resize4D_doc[] = "() - resize a vector to [x,y,z,w]"; char Vector_toPoint_doc[] = "() - create a new Point Object from this vector"; +char Vector_ToTrackQuat_doc[] = "(track, up) - extract a quaternion from the vector and the track and up axis"; //-----------------------METHOD DEFINITIONS ---------------------- struct PyMethodDef Vector_methods[] = { {"zero", (PyCFunction) Vector_Zero, METH_NOARGS, Vector_Zero_doc}, @@ -52,6 +54,7 @@ struct PyMethodDef Vector_methods[] = { {"resize3D", (PyCFunction) Vector_Resize3D, METH_NOARGS, Vector_Resize2D_doc}, {"resize4D", (PyCFunction) Vector_Resize4D, METH_NOARGS, Vector_Resize2D_doc}, {"toPoint", (PyCFunction) Vector_toPoint, METH_NOARGS, Vector_toPoint_doc}, + {"toTrackQuat", ( PyCFunction ) Vector_ToTrackQuat, METH_VARARGS, Vector_ToTrackQuat_doc}, {NULL, NULL, 0, NULL} }; //-----------------------------METHODS---------------------------- @@ -164,6 +167,118 @@ PyObject *Vector_Resize4D(VectorObject * self) self->size = 4; return EXPP_incr_ret((PyObject*)self); } +//----------------------------Vector.toTrackQuat(track, up) ---------------------- +//extract a quaternion from the vector and the track and up axis +PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ) +{ + float vec[3]; + char *strack, *sup; + short track = 2, up = 1; + + if( !PyArg_ParseTuple ( args, "|ss", &strack, &sup ) ) { + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, + "expected optional two strings\n" ) ); + } + if (self->size != 3) { + return ( EXPP_ReturnPyObjError + ( PyExc_TypeError, + "only for 3D vectors\n" ) ); + } + + if (strack) { + if (strlen(strack) == 2) { + if (strack[0] == '-') { + switch(strack[1]) { + case 'X': + case 'x': + track = 3; + break; + case 'Y': + case 'y': + track = 4; + break; + case 'z': + case 'Z': + track = 5; + break; + default: + return EXPP_ReturnPyObjError( PyExc_ValueError, + "only X, -X, Y, -Y, Z or -Z for track axis\n" ); + } + } + else { + return EXPP_ReturnPyObjError( PyExc_ValueError, + "only X, -X, Y, -Y, Z or -Z for track axis\n" ); + } + } + else if (strlen(strack) == 1) { + switch(strack[0]) { + case '-': + case 'X': + case 'x': + track = 0; + break; + case 'Y': + case 'y': + track = 1; + break; + case 'z': + case 'Z': + track = 2; + break; + default: + return EXPP_ReturnPyObjError( PyExc_ValueError, + "only X, -X, Y, -Y, Z or -Z for track axis\n" ); + } + } + else { + return EXPP_ReturnPyObjError( PyExc_ValueError, + "only X, -X, Y, -Y, Z or -Z for track axis\n" ); + } + } + + if (sup) { + if (strlen(sup) == 1) { + switch(*sup) { + case 'X': + case 'x': + up = 0; + break; + case 'Y': + case 'y': + up = 1; + break; + case 'z': + case 'Z': + up = 2; + break; + default: + return EXPP_ReturnPyObjError( PyExc_ValueError, + "only X, Y or Z for up axis\n" ); + } + } + else { + return EXPP_ReturnPyObjError( PyExc_ValueError, + "only X, Y or Z for up axis\n" ); + } + } + + if (track == up) { + return EXPP_ReturnPyObjError( PyExc_ValueError, + "Can't have the same axis for track and up\n" ); + } + + /* + flip vector around, since vectoquat expect a vector from target to tracking object + and the python function expects the inverse (a vector to the target). + */ + vec[0] = -self->vec[0]; + vec[1] = -self->vec[1]; + vec[2] = -self->vec[2]; + + return newQuaternionObject(vectoquat(vec, track, up), Py_NEW); +} //----------------------------dealloc()(internal) ---------------- //free the py_object static void Vector_dealloc(VectorObject * self) diff --git a/source/blender/python/api2_2x/vector.h b/source/blender/python/api2_2x/vector.h index 05f9a373f96..5a99b5298a0 100644 --- a/source/blender/python/api2_2x/vector.h +++ b/source/blender/python/api2_2x/vector.h @@ -65,6 +65,7 @@ PyObject *Vector_Resize2D( VectorObject * self ); PyObject *Vector_Resize3D( VectorObject * self ); PyObject *Vector_Resize4D( VectorObject * self ); PyObject *Vector_toPoint( VectorObject * self ); +PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args ); PyObject *newVectorObject(float *vec, int size, int type); #endif /* EXPP_vector_h */ |