Mathutils fix: Vector.reflect
authorDalai Felinto <dfelinto@gmail.com>
Sun, 6 Sep 2009 19:51:57 +0000 (19:51 +0000)
committerDalai Felinto <dfelinto@gmail.com>
Sun, 6 Sep 2009 19:51:57 +0000 (19:51 +0000)
* correct function for reflection and moving it to arithb.c
* note: 2.5 has an already more elegant solution for it (still wrong, but the code is cleaner).
Therefore the merge may need to be manual in that case.

Specifically in 2.5 we are doing:
if(!BaseMath_ReadCallback(self) || !BaseMath_ReadCallback(value)) return NULL;
And there we don't need to create a VectorObject *mirrvec; only to get the values.

Code used to test it:
http://www.pasteall.org/7654/python

* YoFrankie script probably needs to be fixed too.

source/blender/blenlib/BLI_arithb.h
source/blender/blenlib/intern/arithb.c
source/blender/python/api2_2x/vector.c

index 86b626dabdffb69aad8b00135866af9ef5740c3d..0c3ec40f16d714d1cf372329fe43ed48acee6c62 100644 (file)
@@ -270,6 +270,7 @@ void AxisAngleToQuat(float *q, float *axis, float angle);
 void RotationBetweenVectorsToQuat(float *q, float v1[3], float v2[3]);
 void vectoquat(float *vec, short axis, short upflag, float *q);
 
+void VecReflect(float *out, float *v1, float *v2);
 void VecBisect3(float *v, float *v1, float *v2, float *v3);
 float VecAngle2(float *v1, float *v2);
 float VecAngle3(float *v1, float *v2, float *v3);
index c20794953b9ca44ca510f1e2ce2eee97b42b50d1..e7a31e37581c58dee6acdb76366e63ddae7f4b46 100644 (file)
@@ -2981,6 +2981,29 @@ void VecBisect3(float *out, float *v1, float *v2, float *v3)
        Normalize(out);
 }
 
+/* Returns a reflection vector from a vector and a normal vector
+reflect = vec - ((2 * DotVecs(vec, mirror)) * mirror)
+*/
+void VecReflect(float *out, float *v1, float *v2)
+{
+       float vec[3], normal[3];
+       float reflect[3] = {0.0f, 0.0f, 0.0f};
+       float dot2;
+
+       VecCopyf(vec, v1);
+       VecCopyf(normal, v2);
+
+       Normalize(normal);
+
+       dot2 = 2 * Inpf(vec, normal);
+
+       reflect[0] = vec[0] - (dot2 * normal[0]);
+       reflect[1] = vec[1] - (dot2 * normal[1]);
+       reflect[2] = vec[2] - (dot2 * normal[2]);
+
+       VecCopyf(out, reflect);
+}
+
 /* Return the angle in degrees between vecs 1-2 and 2-3 in degrees
    If v1 is a shoulder, v2 is the elbow and v3 is the hand,
    this would return the angle at the elbow */
index a7e00e2878a9ee8810062aec12da33f4b52f9159..6a0107142c104663a811110c8b182201ec9fd5a9 100644 (file)
@@ -277,19 +277,14 @@ PyObject *Vector_ToTrackQuat( VectorObject * self, PyObject * args )
 
 /*----------------------------Vector.reflect(mirror) ----------------------
   return a reflected vector on the mirror normal
-  ((2 * DotVecs(vec, mirror)) * mirror) - vec
-  using arithb.c would be nice here */
+   vec - ((2 * DotVecs(vec, mirror)) * mirror)
+*/
 PyObject *Vector_Reflect( VectorObject * self, PyObject * value )
 {
        VectorObject *mirrvec;
        float mirror[3];
        float vec[3];
-       float reflect[4] = {0.0f, 0.0f, 0.0f, 0.0f};
-       float dot2;
-       
-       /* for normalizing */
-       int i;
-       float norm = 0.0f;
+       float reflect[3] = {0.0f, 0.0f, 0.0f};
        
        if (!VectorObject_Check(value)) {
                PyErr_SetString( PyExc_TypeError, "vec.reflect(value): expected a vector argument" );
@@ -302,27 +297,13 @@ PyObject *Vector_Reflect( VectorObject * self, PyObject * value )
        if (mirrvec->size > 2)  mirror[2] = mirrvec->vec[2];
        else                                    mirror[2] = 0.0;
        
-       /* normalize, whos idea was it not to use arithb.c? :-/ */
-       for(i = 0; i < 3; i++) {
-               norm += mirror[i] * mirror[i];
-       }
-       norm = (float) sqrt(norm);
-       for(i = 0; i < 3; i++) {
-               mirror[i] /= norm;
-       }
-       /* done */
-       
        vec[0] = self->vec[0];
        vec[1] = self->vec[1];
        if (self->size > 2)             vec[2] = self->vec[2];
        else                                    vec[2] = 0.0;
-       
-       dot2 = 2 * vec[0]*mirror[0]+vec[1]*mirror[1]+vec[2]*mirror[2];
-       
-       reflect[0] = (dot2 * mirror[0]) - vec[0];
-       reflect[1] = (dot2 * mirror[1]) - vec[1];
-       reflect[2] = (dot2 * mirror[2]) - vec[2];
-       
+
+       VecReflect(reflect, vec, mirror);
+
        return newVectorObject(reflect, self->size, Py_NEW);
 }