Merge from trunk 16031:16122
authorIan Thompson <quornian@googlemail.com>
Fri, 15 Aug 2008 00:00:27 +0000 (00:00 +0000)
committerIan Thompson <quornian@googlemail.com>
Fri, 15 Aug 2008 00:00:27 +0000 (00:00 +0000)
1  2 
intern/bmfont/intern/BDF2BMF.py
source/blender/blenkernel/intern/bvhutils.c
source/blender/include/BIF_editarmature.h
source/blender/src/buttons_logic.c
source/blender/src/editarmature.c
source/gameengine/Converter/BL_ShapeActionActuator.cpp
source/gameengine/GameLogic/SCA_ActuatorSensor.cpp

index 0000000,0000000..15b9e5b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,177 @@@
++#!/usr/bin/python
++
++# ***** BEGIN GPL LICENSE BLOCK *****
++#
++# This program is free software; you can redistribute it and/or
++# modify it under the terms of the GNU General Public License
++# as published by the Free Software Foundation; either version 2
++# of the License, or (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.        See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software Foundation,
++# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++#
++# ***** END GPL LICENCE BLOCK *****
++# --------------------------------------------------------------------------
++
++HELP_TXT = \
++'''
++Convert BDF pixmap fonts into C++ files Blender can read.
++Use to replace bitmap fonts or add new ones.
++
++Usage
++      python bdf2bmf.py -name=SomeName myfile.bdf
++
++Blender currently supports fonts with a maximum width of 8 pixels.
++'''
++
++# -------- Simple BDF parser
++import sys
++def parse_bdf(f, MAX_CHARS=256):
++      lines = [l.strip().upper().split() for l in f.readlines()]
++
++      is_bitmap = False
++      dummy = {'BITMAP':[]}
++      char_data = [dummy.copy() for i in xrange(MAX_CHARS)]
++      context_bitmap = []
++
++      for l in lines:
++              if l[0]=='ENCODING':            enc = int(l[1])
++              elif l[0]=='BBX':                       bbx = [int(c) for c in l[1:]]
++              elif l[0]=='DWIDTH':            dwidth = int(l[1])
++              elif l[0]=='BITMAP':            is_bitmap = True
++              elif l[0]=='ENDCHAR':
++                      if enc < MAX_CHARS:
++                              char_data[enc]['BBX'] = bbx
++                              char_data[enc]['DWIDTH'] = dwidth
++                              char_data[enc]['BITMAP'] = context_bitmap
++                              
++                      context_bitmap = []
++                      enc = bbx = None
++                      is_bitmap = False
++              else:
++                      # None of the above, Ok, were reading a bitmap
++                      if is_bitmap and enc < MAX_CHARS:
++                              context_bitmap.append( int(l[0], 16) )
++      
++      return char_data
++# -------- end simple BDF parser
++
++def bdf2cpp_name(path):
++      return path.split('.')[0] + '.cpp'
++
++def convert_to_blender(bdf_dict, font_name, origfilename, MAX_CHARS=256):
++      
++      # first get a global width/height, also set the offsets
++      xmin = ymin =  10000000
++      xmax = ymax = -10000000
++      
++      bitmap_offsets = [-1] * MAX_CHARS
++      bitmap_tot = 0
++      for i, c in enumerate(bdf_dict):
++              if c.has_key('BBX'):
++                      bbx = c['BBX']
++                      xmax = max(bbx[0], xmax)
++                      ymax = max(bbx[1], ymax)
++                      xmin = min(bbx[2], xmin)
++                      ymin = min(bbx[3], ymin)
++                      
++                      bitmap_offsets[i] = bitmap_tot
++                      bitmap_tot += len(c['BITMAP'])
++              
++              c['BITMAP'].reverse()
++      
++      # Now we can write. Ok if we have no .'s in the path.
++      f = open(bdf2cpp_name(origfilename), 'w')
++      
++      f.write('''
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include "BMF_FontData.h"
++
++#include "BMF_Settings.h"
++''')
++      
++      f.write('#if BMF_INCLUDE_%s\n\n' % font_name.upper())
++      f.write('static unsigned char bitmap_data[]= {')
++      newline = 8
++      
++      for i, c in enumerate(bdf_dict):
++      
++              for cdata in c['BITMAP']:
++                      # Just formatting
++                      newline+=1
++                      if newline >= 8:
++                              newline = 0
++                              f.write('\n\t')
++                      # End formatting
++                      
++                      f.write('0x%.2hx,' % cdata) # 0x80 <- format
++                      
++      f.write("\n};\n")
++      
++      f.write("BMF_FontData BMF_font_%s = {\n" % font_name)
++      f.write('\t%d, %d,\n' % (xmin, ymin))
++      f.write('\t%d, %d,\n' % (xmax, ymax))
++      
++      f.write('\t{\n')
++      
++
++      for i, c in enumerate(bdf_dict):
++              if bitmap_offsets[i] == -1 or c.has_key('BBX') == False:
++                      f.write('\t\t{0,0,0,0,0, -1},\n')
++              else:
++                      bbx = c['BBX']
++                      f.write('\t\t{%d,%d,%d,%d,%d, %d},\n' % (bbx[0], bbx[1], -bbx[2], -bbx[3], c['DWIDTH'], bitmap_offsets[i]))
++      
++      f.write('''
++      },
++      bitmap_data
++};
++
++#endif
++''')
++
++def main():
++      # replace "[-name=foo]" with  "[-name] [foo]"
++      args = []
++      for arg in sys.argv:
++              for a in arg.replace('=', ' ').split():
++                      args.append(a)
++      
++      name = 'untitled'
++      done_anything = False
++      for i, arg in enumerate(args):
++              if arg == '-name':
++                      if i==len(args)-1:
++                              print 'no arg given for -name, aborting'
++                              return
++                      else:
++                              name = args[i+1]
++              
++              elif arg.lower().endswith('.bdf'):
++                      try:
++                              f = open(arg)
++                              print '...Writing to:', bdf2cpp_name(arg)
++                      except:
++                              print 'could not open "%s", aborting' % arg
++                      
++                      
++                      bdf_dict = parse_bdf(f)
++                      convert_to_blender(bdf_dict, name, arg)
++                      done_anything = True
++      
++      if not done_anything:
++              print HELP_TXT
++              print '...nothing to do'
++
++if __name__ == '__main__':
++      main()
++      
index 10e92b8,0000000..042e2af
mode 100644,000000..100644
--- /dev/null
@@@ -1,433 -1,0 +1,577 @@@
- static float nearest_point_in_tri_surface(const float *point, const float *v0, const float *v1, const float *v2, float *nearest);
- #define ISECT_EPSILON 1e-6
 +/**
 + *
 + * $Id$
 + *
 + * ***** BEGIN GPL LICENSE BLOCK *****
 + *
 + * This program is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU General Public License
 + * as published by the Free Software Foundation; either version 2
 + * of the License, or (at your option) any later version.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software Foundation,
 + * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 + *
 + * The Original Code is Copyright (C) Blender Foundation.
 + * All rights reserved.
 + *
 + * The Original Code is: all of this file.
 + *
 + * Contributor(s): AndrĂ© Pinto.
 + *
 + * ***** END GPL LICENSE BLOCK *****
 + */
 +#include <stdio.h>
 +#include <string.h>
 +#include <math.h>
 +
 +#include "BKE_bvhutils.h"
 +
 +#include "DNA_object_types.h"
 +#include "DNA_modifier_types.h"
 +#include "DNA_meshdata_types.h"
 +
 +#include "BKE_DerivedMesh.h"
 +#include "BKE_utildefines.h"
 +#include "BKE_deform.h"
 +#include "BKE_cdderivedmesh.h"
 +#include "BKE_displist.h"
 +#include "BKE_global.h"
 +
 +#include "BLI_arithb.h"
 +
 +/* Math stuff for ray casting on mesh faces and for nearest surface */
 +
-  * This calculates the distance from point to the plane
-  * Distance is negative if point is on the back side of plane
 +static float ray_tri_intersection(const BVHTreeRay *ray, const float m_dist, const float *v0, const float *v1, const float *v2)
 +{
 +      float dist;
 +
 +      if(RayIntersectsTriangle((float*)ray->origin, (float*)ray->direction, (float*)v0, (float*)v1, (float*)v2, &dist, NULL))
 +              return dist;
 +
 +      return FLT_MAX;
 +}
 +
 +static float sphereray_tri_intersection(const BVHTreeRay *ray, float radius, const float m_dist, const float *v0, const float *v1, const float *v2)
 +{
 +      
 +      float idist;
 +      float p1[3];
 +      float plane_normal[3], hit_point[3];
 +
 +      CalcNormFloat((float*)v0, (float*)v1, (float*)v2, plane_normal);
 +
 +      VECADDFAC( p1, ray->origin, ray->direction, m_dist);
 +      if(SweepingSphereIntersectsTriangleUV((float*)ray->origin, p1, radius, (float*)v0, (float*)v1, (float*)v2, &idist, hit_point))
 +      {
 +              return idist * m_dist;
 +      }
 +
 +      return FLT_MAX;
 +}
 +
++
 +/*
- static float point_plane_distance(const float *point, const float *plane_point, const float *plane_normal)
++ * Function adapted from David Eberly's distance tools (LGPL)
++ * http://www.geometrictools.com/LibFoundation/Distance/Distance.html
 + */
-       float pp[3];
-       VECSUB(pp, point, plane_point);
-       return INPR(pp, plane_normal);
- }
- static float choose_nearest(const float v0[2], const float v1[2], const float point[2], float closest[2])
- {
-       float d[2][2], sdist[2];
-       VECSUB2D(d[0], v0, point);
-       VECSUB2D(d[1], v1, point);
-       sdist[0] = d[0][0]*d[0][0] + d[0][1]*d[0][1];
-       sdist[1] = d[1][0]*d[1][0] + d[1][1]*d[1][1];
-       if(sdist[0] < sdist[1])
++static float nearest_point_in_tri_surface(const float *v0,const float *v1,const float *v2,const float *p, int *v, int *e, float *d, float *nearest )
 +{
-               if(closest)
-                       VECCOPY2D(closest, v0);
-               return sdist[0];
++      float diff[3];
++      float e0[3];
++      float e1[3];
++      float A00;
++      float A01;
++      float A11;
++      float B0;
++      float B1;
++      float C;
++      float Det;
++      float S;
++      float T;
++      float sqrDist;
++      int lv = -1, le = -1;
++      
++      VECSUB(diff, v0, p);
++      VECSUB(e0, v1, v0);
++      VECSUB(e1, v2, v0);
++      
++      A00 = INPR ( e0, e0 );
++      A01 = INPR( e0, e1 );
++      A11 = INPR ( e1, e1 );
++      B0 = INPR( diff, e0 );
++      B1 = INPR( diff, e1 );
++      C = INPR( diff, diff );
++      Det = fabs( A00 * A11 - A01 * A01 );
++      S = A01 * B1 - A11 * B0;
++      T = A01 * B0 - A00 * B1;
++
++      if ( S + T <= Det )
 +      {
-               if(closest)
-                       VECCOPY2D(closest, v1);
-               return sdist[1];
-       }
- }
- /*
-  * calculates the closest point between point-tri (2D)
-  * returns that tri must be right-handed
-  * Returns square distance
-  */
- static float closest_point_in_tri2D(const float point[2], /*const*/ float tri[3][2], float closest[2])
- {
-       float edge_di[2];
-       float v_point[2];
-       float proj[2];                                  //point projected over edge-dir, edge-normal (witouth normalized edge)
-       const float *v0 = tri[2], *v1;
-       float edge_slen, d;                             //edge squared length
-       int i;
-       const float *nearest_vertex = NULL;
-       //for each edge
-       for(i=0, v0=tri[2], v1=tri[0]; i < 3; v0=tri[i++], v1=tri[i])
-       {
-               VECSUB2D(edge_di,    v1, v0);
-               VECSUB2D(v_point, point, v0);
++              if ( S < 0.0f )
++              {
++                      if ( T < 0.0f )  // Region 4
++                      {
++                              if ( B0 < 0.0f )
++                              {
++                                      T = 0.0f;
++                                      if ( -B0 >= A00 )
++                                      {
++                                              S = (float)1.0;
++                                              sqrDist = A00 + 2.0f * B0 + C;
++                                              lv = 1;
++                                      }
++                                      else
++                                      {
++                                              if(fabs(A00) > FLT_EPSILON)
++                                                      S = -B0/A00;
++                                              else
++                                                      S = 0.0f;
++                                              sqrDist = B0 * S + C;
++                                              le = 0;
++                                      }
++                              }
++                              else
++                              {
++                                      S = 0.0f;
++                                      if ( B1 >= 0.0f )
++                                      {
++                                              T = 0.0f;
++                                              sqrDist = C;
++                                              lv = 0;
++                                      }
++                                      else if ( -B1 >= A11 )
++                                      {
++                                              T = 1.0f;
++                                              sqrDist = A11 + 2.0f * B1 + C;
++                                              lv = 2;
++                                      }
++                                      else
++                                      {
++                                              if(fabs(A11) > FLT_EPSILON)
++                                                      T = -B1 / A11;
++                                              else
++                                                      T = 0.0f;
++                                              sqrDist = B1 * T + C;
++                                              le = 1;
++                                      }
++                              }
++                      }
++                      else  // Region 3
++                      {
++                              S = 0.0f;
++                              if ( B1 >= 0.0f )
++                              {
++                                      T = 0.0f;
++                                      sqrDist = C;
++                                      lv = 0;
++                              }
++                              else if ( -B1 >= A11 )
++                              {
++                                      T = 1.0f;
++                                      sqrDist = A11 + 2.0f * B1 + C;
++                                      lv = 2;
++                              }
++                              else
++                              {
++                                      if(fabs(A11) > FLT_EPSILON)
++                                              T = -B1 / A11;
++                                      else
++                                              T = 0.0;
++                                      sqrDist = B1 * T + C;
++                                      le = 1;
++                              }
++                      }
++              }
++              else if ( T < 0.0f )  // Region 5
++              {
++                      T = 0.0f;
++                      if ( B0 >= 0.0f )
++                      {
++                              S = 0.0f;
++                              sqrDist = C;
++                              lv = 0;
++                      }
++                      else if ( -B0 >= A00 )
++                      {
++                              S = 1.0f;
++                              sqrDist = A00 + 2.0f * B0 + C;
++                              lv = 1;
++                      }
++                      else
++                      {
++                              if(fabs(A00) > FLT_EPSILON)
++                                      S = -B0 / A00;
++                              else
++                                      S = 0.0f;
++                              sqrDist = B0 * S + C;
++                              le = 0;
++                      }
++              }
++              else  // Region 0
++              {
++            // Minimum at interior lv
++                      float invDet;
++                      if(fabs(Det) > FLT_EPSILON)
++                              invDet = 1.0f / Det;
++                      else
++                              invDet = 0.0f;
++                      S *= invDet;
++                      T *= invDet;
++                      sqrDist = S * ( A00 * S + A01 * T + 2.0f * B0) +
++                                      T * ( A01 * S + A11 * T + 2.0f * B1 ) + C;
++              }
 +      }
 +      else
 +      {
-               proj[1] =  v_point[0]*edge_di[1] - v_point[1]*edge_di[0];       //dot product with edge normal
-               //point inside this edge
-               if(proj[1] < 0)
-                       continue;
-               proj[0] = v_point[0]*edge_di[0] + v_point[1]*edge_di[1];
-               //closest to this edge is v0
-               if(proj[0] < 0)
++              float tmp0, tmp1, numer, denom;
 +
-                       if(nearest_vertex == NULL || nearest_vertex == v0)
-                               nearest_vertex = v0;
++              if ( S < 0.0f )  // Region 2
 +              {
-                               //choose nearest
-                               return choose_nearest(nearest_vertex, v0, point, closest);
++                      tmp0 = A01 + B0;
++                      tmp1 = A11 + B1;
++                      if ( tmp1 > tmp0 )
++                      {
++                              numer = tmp1 - tmp0;
++                              denom = A00 - 2.0f * A01 + A11;
++                              if ( numer >= denom )
++                              {
++                                      S = 1.0f;
++                                      T = 0.0f;
++                                      sqrDist = A00 + 2.0f * B0 + C;
++                                      lv = 1;
++                              }
++                              else
++                              {
++                                      if(fabs(denom) > FLT_EPSILON)
++                                              S = numer / denom;
++                                      else
++                                              S = 0.0f;
++                                      T = 1.0f - S;
++                                      sqrDist = S * ( A00 * S + A01 * T + 2.0f * B0 ) +
++                                                      T * ( A01 * S + A11 * T + 2.0f * B1 ) + C;
++                                      le = 2;
++                              }
++                      }
 +                      else
 +                      {
-                       i++;    //We can skip next edge
-                       continue;
++                              S = 0.0f;
++                              if ( tmp1 <= 0.0f )
++                              {
++                                      T = 1.0f;
++                                      sqrDist = A11 + 2.0f * B1 + C;
++                                      lv = 2;
++                              }
++                              else if ( B1 >= 0.0f )
++                              {
++                                      T = 0.0f;
++                                      sqrDist = C;
++                                      lv = 0;
++                              }
++                              else
++                              {
++                                      if(fabs(A11) > FLT_EPSILON)
++                                              T = -B1 / A11;
++                                      else
++                                              T = 0.0f;
++                                      sqrDist = B1 * T + C;
++                                      le = 1;
++                              }
 +                      }
-               edge_slen = edge_di[0]*edge_di[0] + edge_di[1]*edge_di[1];      //squared edge len
-               //closest to this edge is v1
-               if(proj[0] > edge_slen)
 +              }
-                       if(nearest_vertex == NULL || nearest_vertex == v1)
-                               nearest_vertex = v1;
++              else if ( T < 0.0f )  // Region 6
 +              {
-                               return choose_nearest(nearest_vertex, v1, point, closest);
++                      tmp0 = A01 + B1;
++                      tmp1 = A00 + B0;
++                      if ( tmp1 > tmp0 )
++                      {
++                              numer = tmp1 - tmp0;
++                              denom = A00 - 2.0f * A01 + A11;
++                              if ( numer >= denom )
++                              {
++                                      T = 1.0f;
++                                      S = 0.0f;
++                                      sqrDist = A11 + 2.0f * B1 + C;
++                                      lv = 2;
++                              }
++                              else
++                              {
++                                      if(fabs(denom) > FLT_EPSILON)
++                                              T = numer / denom;
++                                      else
++                                              T = 0.0f;
++                                      S = 1.0f - T;
++                                      sqrDist = S * ( A00 * S + A01 * T + 2.0f * B0 ) +
++                                                      T * ( A01 * S + A11 * T + 2.0f * B1 ) + C;
++                                      le = 2;
++                              }
++                      }
 +                      else
 +                      {
-                       continue;
++                              T = 0.0f;
++                              if ( tmp1 <= 0.0f )
++                              {
++                                      S = 1.0f;
++                                      sqrDist = A00 + 2.0f * B0 + C;
++                                      lv = 1;
++                              }
++                              else if ( B0 >= 0.0f )
++                              {
++                                      S = 0.0f;
++                                      sqrDist = C;
++                                      lv = 0;
++                              }
++                              else
++                              {
++                                      if(fabs(A00) > FLT_EPSILON)
++                                              S = -B0 / A00;
++                                      else
++                                              S = 0.0f;
++                                      sqrDist = B0 * S + C;
++                                      le = 0;
++                              }
++                      }
++              }
++              else  // Region 1
++              {
++                      numer = A11 + B1 - A01 - B0;
++                      if ( numer <= 0.0f )
++                      {
++                              S = 0.0f;
++                              T = 1.0f;
++                              sqrDist = A11 + 2.0f * B1 + C;
++                              lv = 2;
++                      }
++                      else
++                      {
++                              denom = A00 - 2.0f * A01 + A11;
++                              if ( numer >= denom )
++                              {
++                                      S = 1.0f;
++                                      T = 0.0f;
++                                      sqrDist = A00 + 2.0f * B0 + C;
++                                      lv = 1;
++                              }
++                              else
++                              {
++                                      if(fabs(denom) > FLT_EPSILON)
++                                              S = numer / denom;
++                                      else
++                                              S = 0.0f;
++                                      T = 1.0f - S;
++                                      sqrDist = S * ( A00 * S + A01 * T + 2.0f * B0 ) +
++                                                      T * ( A01 * S + A11 * T + 2.0f * B1 ) + C;
++                                      le = 2;
++                              }
 +                      }
-               //nearest is on this edge
-               d= proj[1] / edge_slen;
-               closest[0] = point[0] - edge_di[1] * d;
-               closest[1] = point[1] + edge_di[0] * d;
-               return proj[1]*proj[1]/edge_slen;
 +              }
-       if(nearest_vertex)
-       {
-               VECSUB2D(v_point, nearest_vertex, point);
-               VECCOPY2D(closest, nearest_vertex);
-               return v_point[0]*v_point[0] + v_point[1]*v_point[1];
-       }
-       else
-       {
-               VECCOPY(closest, point);        //point is already inside
-               return 0.0f;
-       }
- }
- /*
-  * Returns the square of the minimum distance between the point and a triangle surface
-  * If nearest is not NULL the nearest surface point is written on it
-  */
- static float nearest_point_in_tri_surface(const float *point, const float *v0, const float *v1, const float *v2, float *nearest)
- {
-       //Lets solve the 2D problem (closest point-tri)
-       float normal_dist, plane_sdist, plane_offset;
-       float du[3], dv[3], dw[3];      //orthogonal axis (du=(v0->v1), dw=plane normal)
-       float p_2d[2], tri_2d[3][2], nearest_2d[2];
-       CalcNormFloat((float*)v0, (float*)v1, (float*)v2, dw);
-       //point-plane distance and calculate axis
-       normal_dist = point_plane_distance(point, v0, dw);
-       // OPTIMIZATION
-       //      if we are only interested in nearest distance if its closer than some distance already found
-       //  we can:
-       //              if(normal_dist*normal_dist >= best_dist_so_far) return FLOAT_MAX;
-       //
-       VECSUB(du, v1, v0);
-       Normalize(du);
-       Crossf(dv, dw, du);
-       plane_offset = INPR(v0, dw);
-       //project stuff to 2d
-       tri_2d[0][0] = INPR(du, v0);
-       tri_2d[0][1] = INPR(dv, v0);
-       tri_2d[1][0] = INPR(du, v1);
-       tri_2d[1][1] = INPR(dv, v1);
-       tri_2d[2][0] = INPR(du, v2);
-       tri_2d[2][1] = INPR(dv, v2);
-       p_2d[0] = INPR(du, point);
-       p_2d[1] = INPR(dv, point);
-       //we always have a right-handed tri
-       //this should always happen because of the way normal is calculated
-       plane_sdist = closest_point_in_tri2D(p_2d, tri_2d, nearest_2d);
-       //project back to 3d
-       if(nearest)
 +      }
 +
-               nearest[0] = du[0]*nearest_2d[0] + dv[0] * nearest_2d[1] + dw[0] * plane_offset;
-               nearest[1] = du[1]*nearest_2d[0] + dv[1] * nearest_2d[1] + dw[1] * plane_offset;
-               nearest[2] = du[2]*nearest_2d[0] + dv[2] * nearest_2d[1] + dw[2] * plane_offset;
++      // Account for numerical round-off error
++      if ( sqrDist < FLT_EPSILON )
++              sqrDist = 0.0f;
++      
 +      {
-       return plane_sdist + normal_dist*normal_dist;
++              float w[3], x[3], y[3], z[3];
++              VECCOPY(w, v0);
++              VECCOPY(x, e0);
++              VecMulf(x, S);
++              VECCOPY(y, e1);
++              VecMulf(y, T);
++              VECADD(z, w, x);
++              VECADD(z, z, y);
++              VECSUB(d, p, z);
++              VECCOPY(nearest, z);
++              // d = p - ( v0 + S * e0 + T * e1 );
 +      }
++      *v = lv;
++      *e = le;
 +
-               float nearest_tmp[3], dist;
-               float vec[3][3];
++      return sqrDist;
 +}
 +
 +
 +/*
 + * BVH from meshs callbacks
 + */
 +
 +// Callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_faces.
 +// userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree.
 +static void mesh_faces_nearest_point(void *userdata, int index, const float *co, BVHTreeNearest *nearest)
 +{
 +      const BVHTreeFromMesh *data = (BVHTreeFromMesh*) userdata;
 +      MVert *vert     = data->vert;
 +      MFace *face = data->face + index;
 +
 +      float *t0, *t1, *t2, *t3;
 +      t0 = vert[ face->v1 ].co;
 +      t1 = vert[ face->v2 ].co;
 +      t2 = vert[ face->v3 ].co;
 +      t3 = face->v4 ? vert[ face->v4].co : NULL;
 +
 +      
 +      do
 +      {       
-               // only insert valid triangles / quads with area > 0
-               VECSUB(vec[0], t2, t1);
-               VECSUB(vec[1], t0, t1);
-               Crossf(vec[2], vec[0], vec[1]);
-               if(INPR(vec[2], vec[2]) >= FLT_EPSILON)
++              float nearest_tmp[3], col_normal[3], dist;
++              int vertex, edge;
 +              
-                       dist = nearest_point_in_tri_surface(co,t0, t1, t2, nearest_tmp);
-                       if(dist < nearest->dist)
-                       {
-                               nearest->index = index;
-                               nearest->dist = dist;
-                               VECCOPY(nearest->co, nearest_tmp);
-                               CalcNormFloat((float*)t0, (float*)t1, (float*)t2, nearest->no); //TODO.. (interpolate normals from the vertexs coordinates?
-                       }
++              dist = nearest_point_in_tri_surface(t0, t1, t2, co, &vertex, &edge, col_normal, nearest_tmp);
++              if(dist < nearest->dist)
 +              {
++                      nearest->index = index;
++                      nearest->dist = dist;
++                      VECCOPY(nearest->co, nearest_tmp);
++                      VECCOPY(nearest->no, col_normal);
 +              }
 +
 +              t1 = t2;
 +              t2 = t3;
 +              t3 = NULL;
 +
 +      } while(t2);
 +}
 +
 +// Callback to bvh tree raycast. The tree must bust have been built using bvhtree_from_mesh_faces.
 +// userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree.
 +static void mesh_faces_spherecast(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
 +{
 +      const BVHTreeFromMesh *data = (BVHTreeFromMesh*) userdata;
 +      MVert *vert     = data->vert;
 +      MFace *face = data->face + index;
 +
 +      float *t0, *t1, *t2, *t3;
 +      t0 = vert[ face->v1 ].co;
 +      t1 = vert[ face->v2 ].co;
 +      t2 = vert[ face->v3 ].co;
 +      t3 = face->v4 ? vert[ face->v4].co : NULL;
 +
 +      
 +      do
 +      {       
 +              float dist;
 +              if(data->sphere_radius == 0.0f)
 +                      dist = ray_tri_intersection(ray, hit->dist, t0, t1, t2);
 +              else
 +                      dist = sphereray_tri_intersection(ray, data->sphere_radius, hit->dist, t0, t1, t2);
 +
 +              if(dist >= 0 && dist < hit->dist)
 +              {
 +                      hit->index = index;
 +                      hit->dist = dist;
 +                      VECADDFAC(hit->co, ray->origin, ray->direction, dist);
 +
 +                      CalcNormFloat(t0, t1, t2, hit->no);
 +              }
 +
 +              t1 = t2;
 +              t2 = t3;
 +              t3 = NULL;
 +
 +      } while(t2);
 +}
 +
 +/*
 + * BVH builders
 + */
 +// Builds a bvh tree.. where nodes are the vertexs of the given mesh
 +void bvhtree_from_mesh_verts(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis)
 +{
 +      int i;
 +      int numVerts= mesh->getNumVerts(mesh);
 +      MVert *vert     = mesh->getVertDataArray(mesh, CD_MVERT);
 +      BVHTree *tree = NULL;
 +
 +      memset(data, 0, sizeof(*data));
 +
 +      if(vert == NULL)
 +      {
 +              printf("bvhtree cant be build: cant get a vertex array");
 +              return;
 +      }
 +
 +      tree = BLI_bvhtree_new(numVerts, epsilon, tree_type, axis);
 +      if(tree != NULL)
 +      {
 +              for(i = 0; i < numVerts; i++)
 +                      BLI_bvhtree_insert(tree, i, vert[i].co, 1);
 +
 +              BLI_bvhtree_balance(tree);
 +
 +              data->tree = tree;
 +
 +              //a NULL nearest callback works fine
 +              //remeber the min distance to point is the same as the min distance to BV of point
 +              data->nearest_callback = NULL;
 +              data->raycast_callback = NULL;
 +
 +              data->mesh = mesh;
 +              data->vert = mesh->getVertDataArray(mesh, CD_MVERT);
 +              data->face = mesh->getFaceDataArray(mesh, CD_MFACE);
 +
 +              data->sphere_radius = epsilon;
 +      }
 +}
 +
 +// Builds a bvh tree.. where nodes are the faces of the given mesh.
 +void bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float epsilon, int tree_type, int axis)
 +{
 +      int i;
 +      int numFaces= mesh->getNumFaces(mesh);
 +      MVert *vert     = mesh->getVertDataArray(mesh, CD_MVERT);
 +      MFace *face = mesh->getFaceDataArray(mesh, CD_MFACE);
 +      BVHTree *tree = NULL;
 +
 +      memset(data, 0, sizeof(*data));
 +
 +      if(vert == NULL && face == NULL)
 +      {
 +              printf("bvhtree cant be build: cant get a vertex/face array");
 +              return;
 +      }
 +
 +      /* Create a bvh-tree of the given target */
 +      tree = BLI_bvhtree_new(numFaces, epsilon, tree_type, axis);
 +      if(tree != NULL)
 +      {
 +              for(i = 0; i < numFaces; i++)
 +              {
 +                      float co[4][3];
 +                      VECCOPY(co[0], vert[ face[i].v1 ].co);
 +                      VECCOPY(co[1], vert[ face[i].v2 ].co);
 +                      VECCOPY(co[2], vert[ face[i].v3 ].co);
 +                      if(face[i].v4)
 +                              VECCOPY(co[3], vert[ face[i].v4 ].co);
 +                      
 +                      BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3);
 +              }
 +              BLI_bvhtree_balance(tree);
 +
 +              data->tree = tree;
 +              data->nearest_callback = mesh_faces_nearest_point;
 +              data->raycast_callback = mesh_faces_spherecast;
 +
 +              data->mesh = mesh;
 +              data->vert = mesh->getVertDataArray(mesh, CD_MVERT);
 +              data->face = mesh->getFaceDataArray(mesh, CD_MFACE);
 +
 +              data->sphere_radius = epsilon;
 +      }
 +}
 +
 +// Frees data allocated by a call to bvhtree_from_mesh_*.
 +void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data)
 +{
 +      if(data->tree)
 +      {
 +              BLI_bvhtree_free(data->tree);
 +              memset( data, 0, sizeof(data) );
 +      }
 +}
 +
 +
@@@ -144,6 -146,13 +144,10 @@@ void     show_all_armature_bones(void)
  
  #define BONESEL_NOSEL 0x80000000      /* Indicates a negative number */
  
 -/* from autoarmature */
 -void BIF_retargetArmature();
 -
+ /* useful macros */
+ #define EBONE_VISIBLE(arm, ebone) ((arm->layer & ebone->layer) && !(ebone->flag & BONE_HIDDEN_A))
+ #define EBONE_EDITABLE(ebone) ((ebone->flag & BONE_SELECTED) && !(ebone->flag & BONE_EDITMODE_LOCKED)) 
  /* used in bone_select_hierachy() */
  #define BONE_SELECT_PARENT    0
  #define BONE_SELECT_CHILD     1
@@@ -1689,7 -1689,7 +1689,7 @@@ static short draw_actuatorbuttons(Objec
                                        uiDefBut(block, LABEL, 0, "Torque", xco, yco-106, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque");
                                        uiDefButF(block, NUM, 0, "",            xco+45, yco-106, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, "");
                                        uiDefButF(block, NUM, 0, "",            xco+45+wval, yco-106, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, "");
--                                      uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-6106, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, "");                               
++                                      uiDefButF(block, NUM, 0, "",            xco+45+2*wval, yco-106, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, "");                                
                                }
                                
                                if ( ob->gameflag & OB_DYNAMIC )
Simple merge