Bug fix: on scene append of curve deformer displist causes crash...
[blender.git] / source / blender / blenkernel / intern / lattice.c
1 /**
2  * lattice.c
3  *
4  *
5  * $Id$
6  *
7  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version. The Blender
13  * Foundation also sells licenses for use in proprietary software under
14  * the Blender License.  See http://www.blender.org/BL/ for information
15  * about this.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software Foundation,
24  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  *
26  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
27  * All rights reserved.
28  *
29  * The Original Code is: all of this file.
30  *
31  * Contributor(s): none yet.
32  *
33  * ***** END GPL/BL DUAL LICENSE BLOCK *****
34  */
35
36 #include <stdio.h>
37 #include <string.h>
38 #include <math.h>
39 #include <stdlib.h>
40
41 #include "MEM_guardedalloc.h"
42
43 #include "BLI_blenlib.h"
44 #include "BLI_arithb.h"
45
46 #include "DNA_armature_types.h"
47 #include "DNA_mesh_types.h"
48 #include "DNA_meshdata_types.h"
49 #include "DNA_object_types.h"
50 #include "DNA_scene_types.h"
51 #include "DNA_lattice_types.h"
52 #include "DNA_curve_types.h"
53 #include "DNA_key_types.h"
54 #include "DNA_ika_types.h"
55
56 #include "BKE_anim.h"
57 #include "BKE_armature.h"
58 #include "BKE_curve.h"
59 #include "BKE_deform.h"
60 #include "BKE_displist.h"
61 #include "BKE_global.h"
62 #include "BKE_ika.h"
63 #include "BKE_key.h"
64 #include "BKE_lattice.h"
65 #include "BKE_library.h"
66 #include "BKE_main.h"
67 #include "BKE_object.h"
68 #include "BKE_screen.h"
69 #include "BKE_utildefines.h"
70
71 #ifdef HAVE_CONFIG_H
72 #include <config.h>
73 #endif
74
75 #include "blendef.h"
76
77 Lattice *editLatt=0, *deformLatt=0;
78
79 float *latticedata=0, latmat[4][4];
80
81 void resizelattice(Lattice *lt)
82 {
83         BPoint *bp;
84         int u, v, w;
85         float vec[3], fu, fv, fw, du=0.0, dv=0.0, dw=0.0;
86         
87
88         MEM_freeN(lt->def);
89         lt->def= MEM_callocN(lt->pntsu*lt->pntsv*lt->pntsw*sizeof(BPoint), "lattice bp");
90         
91         bp= lt->def;
92         
93         while(lt->pntsu*lt->pntsv*lt->pntsw > 32000) {
94                 if( lt->pntsu>=lt->pntsv && lt->pntsu>=lt->pntsw) lt->pntsu--;
95                 else if( lt->pntsv>=lt->pntsu && lt->pntsv>=lt->pntsw) lt->pntsv--;
96                 else lt->pntsw--;
97         }
98         
99         calc_lat_fudu(lt->flag, lt->pntsu, &fu, &du);
100         calc_lat_fudu(lt->flag, lt->pntsv, &fv, &dv);
101         calc_lat_fudu(lt->flag, lt->pntsw, &fw, &dw);
102         
103         vec[2]= fw;
104         for(w=0; w<lt->pntsw; w++) {
105                 vec[1]= fv;
106                 for(v=0; v<lt->pntsv; v++) {
107                         vec[0]= fu;
108                         for(u=0; u<lt->pntsu; u++, bp++) {
109                                 VECCOPY(bp->vec, vec);
110                                 vec[0]+= du;
111                         }
112                         vec[1]+= dv;
113                 }
114                 vec[2]+= dw;
115         }
116 }
117
118 Lattice *add_lattice()
119 {
120         Lattice *lt;
121         
122         lt= alloc_libblock(&G.main->latt, ID_LT, "Lattice");
123         
124         lt->pntsu=lt->pntsv=lt->pntsw= 2;
125         lt->flag= LT_GRID;
126         
127         lt->typeu= lt->typev= lt->typew= KEY_BSPLINE;
128         
129         /* temporally */
130         lt->def= MEM_callocN(sizeof(BPoint), "lattvert");
131         
132         resizelattice(lt);      /* creates a uniform lattice */
133                 
134         return lt;
135 }
136
137 Lattice *copy_lattice(Lattice *lt)
138 {
139         Lattice *ltn;
140
141         ltn= copy_libblock(lt);
142         ltn->def= MEM_dupallocN(lt->def);
143                 
144         id_us_plus((ID *)ltn->ipo);
145
146         ltn->key= copy_key(ltn->key);
147         if(ltn->key) ltn->key->from= (ID *)ltn;
148         
149         return ltn;
150 }
151
152 void free_lattice(Lattice *lt)
153 {
154         if(lt->def) MEM_freeN(lt->def);
155 }
156
157
158 void make_local_lattice(Lattice *lt)
159 {
160         Object *ob;
161         Lattice *ltn;
162         int local=0, lib=0;
163
164         /* - only lib users: do nothing
165          * - only local users: set flag
166          * - mixed: make copy
167          */
168         
169         if(lt->id.lib==0) return;
170         if(lt->id.us==1) {
171                 lt->id.lib= 0;
172                 lt->id.flag= LIB_LOCAL;
173                 new_id(0, (ID *)lt, 0);
174                 return;
175         }
176         
177         ob= G.main->object.first;
178         while(ob) {
179                 if(ob->data==lt) {
180                         if(ob->id.lib) lib= 1;
181                         else local= 1;
182                 }
183                 ob= ob->id.next;
184         }
185         
186         if(local && lib==0) {
187                 lt->id.lib= 0;
188                 lt->id.flag= LIB_LOCAL;
189                 new_id(0, (ID *)lt, 0);
190         }
191         else if(local && lib) {
192                 ltn= copy_lattice(lt);
193                 ltn->id.us= 0;
194                 
195                 ob= G.main->object.first;
196                 while(ob) {
197                         if(ob->data==lt) {
198                                 
199                                 if(ob->id.lib==0) {
200                                         ob->data= ltn;
201                                         ltn->id.us++;
202                                         lt->id.us--;
203                                 }
204                         }
205                         ob= ob->id.next;
206                 }
207         }
208 }
209
210
211
212 void calc_lat_fudu(int flag, int res, float *fu, float *du)
213 {
214         
215         if(res==1) {
216                 *fu= 0.0;
217                 *du= 0.0;
218         }
219         else if(flag & LT_GRID) {
220                 *fu= -0.5f*(res-1);
221                 *du= 1.0f;
222         }
223         else {
224                 *fu= -1.0f;
225                 *du= 2.0f/(res-1);
226         }
227         
228 }
229
230 void init_latt_deform(Object *oblatt, Object *ob)
231 {
232         /* we make an array with all differences */
233         BPoint *bp;
234         float *fp, imat[4][4];
235         float vec[3], fu, fv, fw, du=0.0, dv=0.0, dw=0.0;
236         int u, v, w;
237         
238         if(oblatt==G.obedit) deformLatt= editLatt;
239         else deformLatt= oblatt->data;
240         
241         fp= latticedata= MEM_mallocN(sizeof(float)*3*deformLatt->pntsu*deformLatt->pntsv*deformLatt->pntsw, "latticedata");
242         
243         lattice_modifier(oblatt, 's');
244         bp= deformLatt->def;
245
246         if(ob) where_is_object(ob);
247
248         /* for example with a particle system: ob==0 */
249         if(ob==0) {
250                 /* in deformspace, calc matrix  */
251                 Mat4Invert(latmat, oblatt->obmat);
252         
253                 /* back: put in deform array */
254                 Mat4Invert(imat, latmat);
255         }
256         else {
257                 /* in deformspace, calc matrix */
258                 Mat4Invert(imat, oblatt->obmat);
259                 Mat4MulMat4(latmat, ob->obmat, imat);
260         
261                 /* back: put in deform array */
262                 Mat4Invert(imat, latmat);
263         }
264         calc_lat_fudu(deformLatt->flag, deformLatt->pntsu, &fu, &du);
265         calc_lat_fudu(deformLatt->flag, deformLatt->pntsv, &fv, &dv);
266         calc_lat_fudu(deformLatt->flag, deformLatt->pntsw, &fw, &dw);
267         
268         /* we keep calculating the u v w lattice coordinates, not enough reason to store that */
269         
270         vec[2]= fw;
271         for(w=0; w<deformLatt->pntsw; w++) {
272                 vec[1]= fv;
273                 for(v=0; v<deformLatt->pntsv; v++) {
274                         vec[0]= fu;
275                         for(u=0; u<deformLatt->pntsu; u++, bp++) {
276                                 
277                                 VecSubf(fp, bp->vec, vec);
278                                 Mat4Mul3Vecfl(imat, fp);
279                 
280                                 vec[0]+= du;
281                                 fp+= 3;
282                         }
283                         vec[1]+= dv;
284                 }
285                 vec[2]+= dw;
286         }
287
288         lattice_modifier(oblatt, 'e');
289
290 }
291
292 void calc_latt_deform(float *co)
293 {
294         Lattice *lt;
295         float fu, du, u, v, w, tu[4], tv[4], tw[4];
296         float *fpw, *fpv, *fpu, vec[3];
297         int ui, vi, wi, uu, vv, ww;
298         
299         if(latticedata==0) return;
300         
301         lt= deformLatt; /* just for shorter notation! */
302         
303         /* co is in local coords, treat with latmat */
304         
305         VECCOPY(vec, co);
306         Mat4MulVecfl(latmat, vec);
307         
308         /* u v w coords */
309         
310         if(lt->pntsu>1) {
311                 calc_lat_fudu(lt->flag, lt->pntsu, &fu, &du);
312                 u= (vec[0]-fu)/du;
313                 ui= (int)floor(u);
314                 u -= ui;
315                 set_four_ipo(u, tu, lt->typeu);
316         }
317         else {
318                 tu[0]= tu[2]= tu[3]= 0.0; tu[1]= 1.0;
319                 ui= 0;
320         }
321         
322         if(lt->pntsv>1) {
323                 calc_lat_fudu(lt->flag, lt->pntsv, &fu, &du);
324                 v= (vec[1]-fu)/du;
325                 vi= (int)floor(v);
326                 v -= vi;
327                 set_four_ipo(v, tv, lt->typev);
328         }
329         else {
330                 tv[0]= tv[2]= tv[3]= 0.0; tv[1]= 1.0;
331                 vi= 0;
332         }
333         
334         if(lt->pntsw>1) {
335                 calc_lat_fudu(lt->flag, lt->pntsw, &fu, &du);
336                 w= (vec[2]-fu)/du;
337                 wi= (int)floor(w);
338                 w -= wi;
339                 set_four_ipo(w, tw, lt->typew);
340         }
341         else {
342                 tw[0]= tw[2]= tw[3]= 0.0; tw[1]= 1.0;
343                 wi= 0;
344         }
345         
346         for(ww= wi-1; ww<=wi+2; ww++) {
347                 w= tw[ww-wi+1];
348                 
349                 if(w!=0.0) {
350                         if(ww>0) {
351                                 if(ww<lt->pntsw) fpw= latticedata + 3*ww*lt->pntsu*lt->pntsv;
352                                 else fpw= latticedata + 3*(lt->pntsw-1)*lt->pntsu*lt->pntsv;
353                         }
354                         else fpw= latticedata;
355                         
356                         for(vv= vi-1; vv<=vi+2; vv++) {
357                                 v= w*tv[vv-vi+1];
358                                 
359                                 if(v!=0.0) {
360                                         if(vv>0) {
361                                                 if(vv<lt->pntsv) fpv= fpw + 3*vv*lt->pntsu;
362                                                 else fpv= fpw + 3*(lt->pntsv-1)*lt->pntsu;
363                                         }
364                                         else fpv= fpw;
365                                         
366                                         for(uu= ui-1; uu<=ui+2; uu++) {
367                                                 u= v*tu[uu-ui+1];
368                                                 
369                                                 if(u!=0.0) {
370                                                         if(uu>0) {
371                                                                 if(uu<lt->pntsu) fpu= fpv + 3*uu;
372                                                                 else fpu= fpv + 3*(lt->pntsu-1);
373                                                         }
374                                                         else fpu= fpv;
375                                                         
376                                                         co[0]+= u*fpu[0];
377                                                         co[1]+= u*fpu[1];
378                                                         co[2]+= u*fpu[2];
379                                                 }
380                                         }
381                                 }
382                         }
383                 }
384         }
385 }
386
387 void end_latt_deform()
388 {
389
390         MEM_freeN(latticedata);
391         latticedata= 0;
392 }
393
394         /* calculations is in local space of deformed object
395            so we store in latmat transform from path coord inside object 
396          */
397 typedef struct {
398         float dmin[3], dmax[3], dsize, dloc[3];
399         float curvespace[4][4], objectspace[4][4];
400 } CurveDeform;
401
402 static void init_curve_deform(Object *par, Object *ob, CurveDeform *cd)
403 {
404         Mat4Invert(ob->imat, ob->obmat);
405         Mat4MulMat4(cd->objectspace, par->obmat, ob->imat);
406         Mat4Invert(cd->curvespace, cd->objectspace);
407
408         // offset vector for 'no smear'
409         Mat4Invert(par->imat, par->obmat);
410         VecMat4MulVecfl(cd->dloc, par->imat, ob->obmat[3]);
411
412 }
413
414 /* this makes sure we can extend for non-cyclic */
415 static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir)        /* returns OK */
416 {
417         Curve *cu= ob->data;
418         BevList *bl;
419         float ctime1;
420         int cycl=0;
421         
422         /* test for cyclic */
423         bl= cu->bev.first;
424         if(bl && bl->poly> -1) cycl= 1;
425
426         if(cycl==0) {
427                 ctime1= CLAMPIS(ctime, 0.0, 1.0);
428         }
429         else ctime1= ctime;
430
431         if(where_on_path(ob, ctime1, vec, dir)) {
432                 
433                 if(cycl==0) {
434                         Path *path= cu->path;
435                         float dvec[3];
436                         
437                         if(ctime < 0.0) {
438                                 VecSubf(dvec, path->data+4, path->data);
439                                 VecMulf(dvec, ctime*(float)path->len);
440                                 VECADD(vec, vec, dvec);
441                         }
442                         else if(ctime > 1.0) {
443                                 VecSubf(dvec, path->data+4*path->len-4, path->data+4*path->len-8);
444                                 VecMulf(dvec, (ctime-1.0)*(float)path->len);
445                                 VECADD(vec, vec, dvec);
446                         }
447                 }
448                 return 1;
449         }
450         return 0;
451 }
452
453         /* for each point, rotate & translate to curve */
454         /* use path, since it has constant distances */
455         /* co: local coord, result local too */
456 static void calc_curve_deform(Object *par, float *co, short axis, CurveDeform *cd)
457 {
458         Curve *cu= par->data;
459         float fac, loc[3], dir[3], *quat, mat[3][3], cent[3];
460         short upflag, index;
461         
462         if(axis==OB_POSX || axis==OB_NEGX) {
463                 upflag= OB_POSZ;
464                 cent[0]= 0.0;
465                 cent[1]= co[1];
466                 cent[2]= co[2];
467                 index= 0;
468         }
469         else if(axis==OB_POSY || axis==OB_NEGY) {
470                 upflag= OB_POSZ;
471                 cent[0]= co[0];
472                 cent[1]= 0.0;
473                 cent[2]= co[2];
474                 index= 1;
475         }
476         else {
477                 upflag= OB_POSY;
478                 cent[0]= co[0];
479                 cent[1]= co[1];
480                 cent[2]= 0.0;
481                 index= 2;
482         }
483         /* to be sure */
484         if(cu->path==NULL) {
485                 calc_curvepath(par);
486                 if(cu->path==NULL) return;      // happens on append...
487         }
488         /* options */
489         if(cu->flag & CU_STRETCH)
490                 fac= (co[index]-cd->dmin[index])/(cd->dmax[index] - cd->dmin[index]);
491         else
492                 fac= (cd->dloc[index])/(cu->path->totdist) + (co[index]-cd->dmin[index])/(cu->path->totdist);
493         
494         if( where_on_path_deform(par, fac, loc, dir)) { /* returns OK */
495
496                 quat= vectoquat(dir, axis, upflag);
497                 QuatToMat3(quat, mat);
498         
499                 /* local rotation */
500                 Mat3MulVecfl(mat, cent);
501                 
502                 /* translation */
503                 VECADD(co, cent, loc);
504                 
505         }
506
507 }
508
509
510 static int _object_deform(Object *ob, int applyflag)
511 {
512         Mesh *me;
513         Curve *cu;
514         DispList *dl;
515         MVert *mvert;
516         float *fp;
517         int a, tot, flag;
518
519         if(ob->parent==NULL) return 0;
520         
521         /* always try to do the entire deform in this function: apply! */
522
523         if(ob->parent->type==OB_CURVE) {
524                 CurveDeform cd;
525                 
526                 if (ob->partype != PARSKEL){
527                         return 0;
528                 }
529                 cu= ob->parent->data;
530                 flag= cu->flag;
531                 cu->flag |= (CU_PATH|CU_FOLLOW); // needed for path & bevlist
532                 
533                 if(ob->type==OB_MESH) {
534                         
535                         me= ob->data;
536                         if(me->totvert==0) return 0;
537                         
538                         /* init deform */
539                         init_curve_deform(ob->parent, ob, &cd);
540                         
541                         /* transformation to curve space, and min max*/
542                         INIT_MINMAX(cd.dmin, cd.dmax);
543                         
544                         for(a=0, mvert=me->mvert; a<me->totvert; a++, mvert++) {
545                                 Mat4MulVecfl(cd.curvespace, mvert->co);
546                                 DO_MINMAX(mvert->co, cd.dmin, cd.dmax);
547                         }
548
549                         mvert= me->mvert;
550                         for(a=0; a<me->totvert; a++, mvert++) {
551                                 calc_curve_deform(ob->parent, mvert->co, ob->trackflag, &cd);
552                                 /* move coord back to objectspace */
553                                 Mat4MulVecfl(cd.objectspace, mvert->co);
554                         }
555                 }
556                 /* restore */
557                 cu->flag = flag;
558                 return 1;
559         }
560         else if(ob->parent->type==OB_LATTICE) {
561                 
562                 init_latt_deform(ob->parent, ob);
563                 
564                 if(ob->type==OB_MESH) {
565                         me= ob->data;
566                         
567                         mvert= me->mvert;
568                         for(a=0; a<me->totvert; a++, mvert++) {
569                                 calc_latt_deform(mvert->co);
570                         }
571                 }
572                 else if(ob->type==OB_MBALL) {
573                         dl=ob->disp.first;
574                         while(dl) {
575                                 fp = dl->verts;
576                                 for(a=0;a<dl->nr;a++,fp+=3)
577                                         calc_latt_deform(fp);
578                                 dl=dl->next;
579                         }
580                 }
581                 else if ELEM(ob->type, OB_CURVE, OB_SURF) {
582                 
583                         cu= ob->data;
584                         if(applyflag) {
585                                 Nurb *nu;
586                                 BPoint *bp;
587                                 BezTriple *bezt;
588                                 
589                                 nu= cu->nurb.first;
590                                 while(nu) {
591                                         if(nu->bp) {
592                                                 a= nu->pntsu*nu->pntsv;
593                                                 bp= nu->bp;
594                                                 while(a--) {
595                                                         calc_latt_deform(bp->vec);
596                                                         bp++;
597                                                 }
598                                         }
599                                         else if(nu->bezt) {
600                                                 a= nu->pntsu;
601                                                 bezt= nu->bezt;
602                                                 while(a--) {
603                                                         calc_latt_deform(bezt->vec[0]);
604                                                         calc_latt_deform(bezt->vec[1]);
605                                                         calc_latt_deform(bezt->vec[2]);
606                                                         bezt++;
607                                                 }
608                                                 test2DNurb(nu);
609                                         }
610                                         nu= nu->next;
611                                 }
612                         }
613                         else {
614                                 /* apply deform on displist */
615                                 dl= cu->disp.first;
616                                 while(dl) {
617                                         
618                                         fp= dl->verts;
619                                         
620                                         if(dl->type==DL_INDEX3) tot=dl->parts;
621                                         else tot= dl->nr*dl->parts;
622                                         
623                                         for(a=0; a<tot; a++, fp+=3) {
624                                                 calc_latt_deform(fp);
625                                         }
626                                         
627                                         dl= dl->next;
628                                 }
629                         }
630                 }
631                 end_latt_deform();
632                 return 1;
633         }
634         else if(ob->parent->type==OB_ARMATURE) {
635                 if (ob->partype != PARSKEL){
636                         return 0;
637                 }
638                 
639                 init_armature_deform (ob->parent, ob);
640
641                 switch (ob->type){
642                 case OB_MESH:
643                         me= ob->data;
644                         
645                         mvert= me->mvert;
646                         for(a=0; a<me->totvert; a++, mvert++) {
647                                 calc_armature_deform(ob->parent, mvert->co, a);
648                         }
649                         break;
650                 case OB_CURVE:
651                 case OB_SURF:
652                         break;
653                 }
654                 
655                 return 1;
656         }
657         
658         return 0;
659
660 }
661
662 int object_deform(Object *ob)
663 {
664         return _object_deform(ob, 0);
665 }
666 int object_apply_deform(Object *ob)
667 {
668         return _object_deform(ob, 1);
669 }
670
671
672 BPoint *latt_bp(Lattice *lt, int u, int v, int w)
673 {
674         return lt->def+ u + v*lt->pntsu + w*lt->pntsu*lt->pntsv;
675 }
676
677 void outside_lattice(Lattice *lt)
678 {
679         BPoint *bp, *bp1, *bp2;
680         int u, v, w;
681         float fac1, du=0.0, dv=0.0, dw=0.0;
682
683         bp= lt->def;
684
685         if(lt->pntsu>1) du= 1.0f/((float)lt->pntsu-1);
686         if(lt->pntsv>1) dv= 1.0f/((float)lt->pntsv-1);
687         if(lt->pntsw>1) dw= 1.0f/((float)lt->pntsw-1);
688                 
689         for(w=0; w<lt->pntsw; w++) {
690                 
691                 for(v=0; v<lt->pntsv; v++) {
692                 
693                         for(u=0; u<lt->pntsu; u++, bp++) {
694                                 if(u==0 || v==0 || w==0 || u==lt->pntsu-1 || v==lt->pntsv-1 || w==lt->pntsw-1);
695                                 else {
696                                 
697                                         bp->hide= 1;
698                                         bp->f1 &= ~SELECT;
699                                         
700                                         /* u extrema */
701                                         bp1= latt_bp(lt, 0, v, w);
702                                         bp2= latt_bp(lt, lt->pntsu-1, v, w);
703                                         
704                                         fac1= du*u;
705                                         bp->vec[0]= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
706                                         bp->vec[1]= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
707                                         bp->vec[2]= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
708                                         
709                                         /* v extrema */
710                                         bp1= latt_bp(lt, u, 0, w);
711                                         bp2= latt_bp(lt, u, lt->pntsv-1, w);
712                                         
713                                         fac1= dv*v;
714                                         bp->vec[0]+= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
715                                         bp->vec[1]+= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
716                                         bp->vec[2]+= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
717                                         
718                                         /* w extrema */
719                                         bp1= latt_bp(lt, u, v, 0);
720                                         bp2= latt_bp(lt, u, v, lt->pntsw-1);
721                                         
722                                         fac1= dw*w;
723                                         bp->vec[0]+= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
724                                         bp->vec[1]+= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
725                                         bp->vec[2]+= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
726                                         
727                                         VecMulf(bp->vec, 0.3333333f);
728                                         
729                                 }
730                         }
731                         
732                 }
733                 
734         }
735         
736 }