- removed makeDispList, set_displist_onlyzero
[blender.git] / source / blender / blenkernel / intern / object.c
1 /* object.c
2  *
3  * 
4  * $Id$
5  *
6  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version. The Blender
12  * Foundation also sells licenses for use in proprietary software under
13  * the Blender License.  See http://www.blender.org/BL/ for information
14  * about this.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  *
25  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
26  * All rights reserved.
27  *
28  * The Original Code is: all of this file.
29  *
30  * Contributor(s): none yet.
31  *
32  * ***** END GPL/BL DUAL LICENSE BLOCK *****
33  */
34
35 #include <string.h>
36 #include <math.h>
37 #include <stdio.h>                      
38
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 #endif
42
43 #include "MEM_guardedalloc.h"
44
45 #include "DNA_action_types.h"
46 #include "DNA_armature_types.h"
47 #include "DNA_camera_types.h"
48 #include "DNA_constraint_types.h"
49 #include "DNA_curve_types.h"
50 #include "DNA_group_types.h"
51 #include "DNA_ipo_types.h"
52 #include "DNA_lamp_types.h"
53 #include "DNA_lattice_types.h"
54 #include "DNA_material_types.h"
55 #include "DNA_mesh_types.h"
56 #include "DNA_meshdata_types.h"
57 #include "DNA_object_types.h"
58 #include "DNA_object_force.h"
59 #include "DNA_oops_types.h"
60 #include "DNA_scene_types.h"
61 #include "DNA_screen_types.h"
62 #include "DNA_space_types.h"
63 #include "DNA_texture_types.h"
64 #include "DNA_userdef_types.h"
65 #include "DNA_view3d_types.h"
66 #include "DNA_world_types.h"
67
68 #include "BKE_armature.h"
69 #include "BKE_action.h"
70 #include "BKE_deform.h"
71 #include "BKE_nla.h"
72
73 #include "BLI_blenlib.h"
74 #include "BLI_arithb.h"
75 #include "BLI_editVert.h"
76
77 #include "BKE_utildefines.h"
78 #include "BKE_bad_level_calls.h"
79
80 #include "BKE_main.h"
81 #include "BKE_global.h"
82
83 #include "BKE_anim.h"
84 #include "BKE_blender.h"
85 #include "BKE_constraint.h"
86 #include "BKE_curve.h"
87 #include "BKE_displist.h"
88 #include "BKE_effect.h"
89 #include "BKE_group.h"
90 #include "BKE_ipo.h"
91 #include "BKE_key.h"
92 #include "BKE_lattice.h"
93 #include "BKE_library.h"
94 #include "BKE_mesh.h"
95 #include "BKE_mball.h"
96 #include "BKE_object.h"
97 #include "BKE_property.h"
98 #include "BKE_sca.h"
99 #include "BKE_scene.h"
100 #include "BKE_screen.h"
101 #include "BKE_softbody.h"
102
103 #include "BPY_extern.h"
104
105 /* Local function protos */
106 static void solve_parenting (Object *ob, Object *par, float slowmat[][4], int simul);
107
108 float originmat[3][3];  /* after where_is_object(), can be used in other functions (bad!) */
109 Object workob;
110
111 void clear_workob(void)
112 {
113         memset(&workob, 0, sizeof(Object));
114         
115         workob.size[0]= workob.size[1]= workob.size[2]= 1.0;
116         
117 }
118
119 void copy_baseflags()
120 {
121         Base *base= G.scene->base.first;
122         
123         while(base) {
124                 base->object->flag= base->flag;
125                 base= base->next;
126         }
127 }
128
129 void copy_objectflags()
130 {
131         Base *base= G.scene->base.first;
132         
133         while(base) {
134                 base->flag= base->object->flag;
135                 base= base->next;
136         }
137 }
138
139 void update_base_layer(Object *ob)
140 {
141         Base *base= G.scene->base.first;
142
143         while (base) {
144                 if (base->object == ob) base->lay= ob->lay;
145                 base= base->next;
146         }
147 }
148
149 static void free_hooks(ListBase *lb)
150 {
151         while(lb->first) {
152                 ObHook *hook= lb->first;
153                 if(hook->indexar) MEM_freeN(hook->indexar);
154                 BLI_remlink(lb, hook);
155                 MEM_freeN(hook);
156         }
157 }
158
159 static void copy_hooks(ListBase *new, ListBase *old)
160 {
161         ObHook *hook, *hookn;
162         new->first= new->last= NULL;
163         
164         for(hook= old->first; hook; hook= hook->next) {
165                 hookn= MEM_dupallocN(hook);
166                 hookn->indexar= MEM_dupallocN(hookn->indexar);
167                 BLI_addtail(new, hookn);
168         }
169
170 }
171
172 /* do not free object itself */
173 void free_object(Object *ob)
174 {
175         int a;
176         
177         /* disconnect specific data */
178         if(ob->data) {
179                 ID *id= ob->data;
180                 id->us--;
181                 if(id->us==0) {
182                         if(ob->type==OB_MESH) unlink_mesh(ob->data);
183                         else if(ob->type==OB_CURVE) unlink_curve(ob->data);
184                         else if(ob->type==OB_MBALL) unlink_mball(ob->data);
185                 }
186                 ob->data= 0;
187         }
188         
189         for(a=0; a<ob->totcol; a++) {
190                 if(ob->mat[a]) ob->mat[a]->id.us--;
191         }
192         if(ob->mat) MEM_freeN(ob->mat);
193         ob->mat= 0;
194         if(ob->bb) MEM_freeN(ob->bb); 
195         ob->bb= 0;
196         if(ob->path) free_path(ob->path); 
197         ob->path= 0;
198         if(ob->ipo) ob->ipo->id.us--;
199         if(ob->action) ob->action->id.us--;
200         if(ob->defbase.first)
201                 BLI_freelistN(&ob->defbase);
202         if(ob->pose) {
203                 free_pose_channels(ob->pose);
204                 MEM_freeN(ob->pose);
205         }
206         free_effects(&ob->effect);
207         BLI_freelistN(&ob->network);
208         free_properties(&ob->prop);
209         
210         free_sensors(&ob->sensors);
211         free_controllers(&ob->controllers);
212         free_actuators(&ob->actuators);
213         
214         free_constraints(&ob->constraints);
215         free_constraint_channels(&ob->constraintChannels);
216         free_nlastrips(&ob->nlastrips);
217         
218         free_hooks(&ob->hooks);
219         
220         freedisplist(&ob->disp);
221         
222         BPY_free_scriptlink(&ob->scriptlink);
223         
224         if(ob->pd) MEM_freeN(ob->pd);
225         if(ob->soft) sbFree(ob->soft);
226 }
227
228 void unlink_object(Object *ob)
229 {
230         Object *obt;
231         Material *mat;
232         World *wrld;
233         bScreen *sc;
234         Scene *sce;
235         Curve *cu;
236         Tex *tex;
237         ObHook *hook;
238         Group *group;
239         bConstraint *con;
240         int a;
241         char *str;
242         
243         unlink_controllers(&ob->controllers);
244         unlink_actuators(&ob->actuators);
245         
246         /* check all objects: parents en bevels */
247         obt= G.main->object.first;
248         while(obt) {
249                 if(obt->id.lib==NULL) {
250                         
251                         if(obt->parent==ob) {
252                                 obt->parent= NULL;
253                                 obt->recalc |= OB_RECALC;
254                         }
255                         
256                         if(obt->track==ob) {
257                                 obt->track= NULL;
258                                 obt->recalc |= OB_RECALC_OB;
259                         }
260                         
261                         for(hook=obt->hooks.first; hook; hook= hook->next) {
262                                 if(hook->parent==ob) {
263                                         hook->parent= NULL;
264                                         obt->recalc |= OB_RECALC;
265                                 }
266                         }
267                         
268                         if ELEM(obt->type, OB_CURVE, OB_FONT) {
269                                 cu= obt->data;
270                                 if(cu->bevobj==ob) {
271                                         cu->bevobj= NULL;
272                                         obt->recalc |= OB_RECALC;
273                                 }
274                                 if(cu->taperobj==ob) {
275                                         cu->taperobj= NULL;
276                                         obt->recalc |= OB_RECALC;
277                                 }
278                                 if(cu->textoncurve==ob) {
279                                         cu->textoncurve= NULL;
280                                         obt->recalc |= OB_RECALC;
281                                 }
282                         }
283                         else if(obt->type==OB_ARMATURE && obt->pose) {
284                                 bPoseChannel *pchan;
285                                 for(pchan= obt->pose->chanbase.first; pchan; pchan= pchan->next) {
286                                         for (con = pchan->constraints.first; con; con=con->next) {
287                                                 if(ob==get_constraint_target(con, &str)) {
288                                                         set_constraint_target(con, NULL);
289                                                         obt->recalc |= OB_RECALC_DATA;
290                                                 }
291                                         }
292                                 }
293                         }
294                         
295                         sca_remove_ob_poin(obt, ob);
296                         
297                         for (con = obt->constraints.first; con; con=con->next) {
298                                 if(ob==get_constraint_target(con, &str)) {
299                                         set_constraint_target(con, NULL);
300                                         obt->recalc |= OB_RECALC_OB;
301                                 }
302                         }
303                 }
304                 obt= obt->id.next;
305         }
306         
307         /* materials */
308         mat= G.main->mat.first;
309         while(mat) {
310         
311                 for(a=0; a<MAX_MTEX; a++) {
312                         if(mat->mtex[a] && ob==mat->mtex[a]->object) {
313                                 /* actually, test for lib here... to do */
314                                 mat->mtex[a]->object= 0;
315                         }
316                 }
317
318                 mat= mat->id.next;
319         }
320         
321         /* textures */
322         tex= G.main->tex.first;
323         while(tex) {
324                 if(tex->env) {
325                         if(tex->env->object == ob) tex->env->object= 0;
326                 }
327                 tex= tex->id.next;
328         }
329         
330         /* mballs */
331         if(ob->type==OB_MBALL) {
332                 obt= find_basis_mball(ob);
333                 if(obt) freedisplist(&obt->disp);
334         }
335         
336         /* worlds */
337         wrld= G.main->world.first;
338         while(wrld) {
339                 if(wrld->id.lib==0) {
340                         for(a=0; a<MAX_MTEX; a++) {
341                                 if(wrld->mtex[a] && ob==wrld->mtex[a]->object)
342                                         wrld->mtex[a]->object =0;
343                         }
344                 }
345                 
346                 wrld= wrld->id.next;
347         }
348                 
349         /* scenes */
350         sce= G.main->scene.first;
351         while(sce) {
352                 if(sce->id.lib==0) {
353                         if(sce->camera==ob) sce->camera= 0;
354                 }
355                 sce= sce->id.next;
356         }
357         /* keys */
358         
359         /* screens */
360         sc= G.main->screen.first;
361         while(sc) {
362                 ScrArea *sa= sc->areabase.first;
363                 while(sa) {
364                         SpaceLink *sl;
365
366                         for (sl= sa->spacedata.first; sl; sl= sl->next) {
367                                 if(sl->spacetype==SPACE_VIEW3D) {
368                                         View3D *v3d= (View3D*) sl;
369
370                                         if(v3d->camera==ob) {
371                                                 v3d->camera= 0;
372                                                 if(v3d->persp>1) v3d->persp= 1;
373                                         }
374                                         if(v3d->localvd && v3d->localvd->camera==ob ) {
375                                                 v3d->localvd->camera= 0;
376                                                 if(v3d->localvd->persp>1) v3d->localvd->persp= 1;
377                                         }
378                                 }
379                                 else if(sl->spacetype==SPACE_IPO) {
380                                         SpaceIpo *sipo= (SpaceIpo *)sl;
381                                         if(sipo->from == (ID *)ob) sipo->from= NULL;
382                                 }
383                                 else if(sl->spacetype==SPACE_OOPS) {
384                                         SpaceOops *so= (SpaceOops *)sl;
385                                         Oops *oops;
386
387                                         oops= so->oops.first;
388                                         while(oops) {
389                                                 if(oops->id==(ID *)ob) oops->id= NULL;
390                                                 oops= oops->next;
391                                         }
392                                         if(so->treestore) {
393                                                 TreeStoreElem *tselem= so->treestore->data;
394                                                 int a;
395                                                 for(a=0; a<so->treestore->usedelem; a++, tselem++) {
396                                                         if(tselem->id==(ID *)ob) tselem->id= NULL;
397                                                 }
398                                         }
399                                         so->lockpoin= NULL;
400                                 }
401                         }
402
403                         sa= sa->next;
404                 }
405                 sc= sc->id.next;
406         }
407
408         /* groups */
409         group= G.main->group.first;
410         while(group) {
411                 rem_from_group(group, ob);
412                 group= group->id.next;
413         }
414 }
415
416 int exist_object(Object *obtest)
417 {
418         Object *ob;
419         
420         ob= G.main->object.first;
421         while(ob) {
422                 if(ob==obtest) return 1;
423                 ob= ob->id.next;
424         }
425         return 0;
426 }
427
428 void *add_camera()
429 {
430         Camera *cam;
431         
432         cam=  alloc_libblock(&G.main->camera, ID_CA, "Camera");
433
434         cam->lens= 35.0f;
435         cam->clipsta= 0.1f;
436         cam->clipend= 100.0f;
437         cam->drawsize= 0.5f;
438         cam->ortho_scale= 6.0;
439         
440         return cam;
441 }
442
443 Camera *copy_camera(Camera *cam)
444 {
445         Camera *camn;
446         
447         camn= copy_libblock(cam);
448         id_us_plus((ID *)camn->ipo);
449
450         BPY_copy_scriptlink(&camn->scriptlink);
451         
452         return camn;
453 }
454
455
456
457 void make_local_camera(Camera *cam)
458 {
459         Object *ob;
460         Camera *camn;
461         int local=0, lib=0;
462
463         /* - only lib users: do nothing
464             * - only local users: set flag
465             * - mixed: make copy
466             */
467         
468         if(cam->id.lib==0) return;
469         if(cam->id.us==1) {
470                 cam->id.lib= 0;
471                 cam->id.flag= LIB_LOCAL;
472                 new_id(0, (ID *)cam, 0);
473                 return;
474         }
475         
476         ob= G.main->object.first;
477         while(ob) {
478                 if(ob->data==cam) {
479                         if(ob->id.lib) lib= 1;
480                         else local= 1;
481                 }
482                 ob= ob->id.next;
483         }
484         
485         if(local && lib==0) {
486                 cam->id.lib= 0;
487                 cam->id.flag= LIB_LOCAL;
488                 new_id(0, (ID *)cam, 0);
489         }
490         else if(local && lib) {
491                 camn= copy_camera(cam);
492                 camn->id.us= 0;
493                 
494                 ob= G.main->object.first;
495                 while(ob) {
496                         if(ob->data==cam) {
497                                 
498                                 if(ob->id.lib==0) {
499                                         ob->data= camn;
500                                         camn->id.us++;
501                                         cam->id.us--;
502                                 }
503                         }
504                         ob= ob->id.next;
505                 }
506         }
507 }
508
509
510
511 void *add_lamp(void)
512 {
513         Lamp *la;
514         
515         la=  alloc_libblock(&G.main->lamp, ID_LA, "Lamp");
516         
517         la->r= la->g= la->b= la->k= 1.0;
518         la->haint= la->energy= 1.0;
519         la->dist= 20.0;
520         la->spotsize= 45.0;
521         la->spotblend= 0.15;
522         la->att2= 1.0;
523         la->mode= LA_SHAD;
524         la->bufsize= 512;
525         la->clipsta= 0.5;
526         la->clipend= 40.0;
527         la->shadspotsize= 45.0;
528         la->samp= 3;
529         la->bias= 1.0;
530         la->soft= 3.0;
531         la->ray_samp= la->ray_sampy= la->ray_sampz= 1; 
532         la->area_size=la->area_sizey=la->area_sizez= 1.0; 
533         
534         return la;
535 }
536
537 Lamp *copy_lamp(Lamp *la)
538 {
539         Lamp *lan;
540         int a;
541         
542         lan= copy_libblock(la);
543
544         for(a=0; a<MAX_MTEX; a++) {
545                 if(lan->mtex[a]) {
546                         lan->mtex[a]= MEM_mallocN(sizeof(MTex), "copylamptex");
547                         memcpy(lan->mtex[a], la->mtex[a], sizeof(MTex));
548                         id_us_plus((ID *)lan->mtex[a]->tex);
549                 }
550         }
551         
552         id_us_plus((ID *)lan->ipo);
553
554         BPY_copy_scriptlink(&la->scriptlink);
555         
556         return lan;
557 }
558
559 void make_local_lamp(Lamp *la)
560 {
561         Object *ob;
562         Lamp *lan;
563         int local=0, lib=0;
564
565         /* - only lib users: do nothing
566             * - only local users: set flag
567             * - mixed: make copy
568             */
569         
570         if(la->id.lib==0) return;
571         if(la->id.us==1) {
572                 la->id.lib= 0;
573                 la->id.flag= LIB_LOCAL;
574                 new_id(0, (ID *)la, 0);
575                 return;
576         }
577         
578         ob= G.main->object.first;
579         while(ob) {
580                 if(ob->data==la) {
581                         if(ob->id.lib) lib= 1;
582                         else local= 1;
583                 }
584                 ob= ob->id.next;
585         }
586         
587         if(local && lib==0) {
588                 la->id.lib= 0;
589                 la->id.flag= LIB_LOCAL;
590                 new_id(0, (ID *)la, 0);
591         }
592         else if(local && lib) {
593                 lan= copy_lamp(la);
594                 lan->id.us= 0;
595                 
596                 ob= G.main->object.first;
597                 while(ob) {
598                         if(ob->data==la) {
599                                 
600                                 if(ob->id.lib==0) {
601                                         ob->data= lan;
602                                         lan->id.us++;
603                                         la->id.us--;
604                                 }
605                         }
606                         ob= ob->id.next;
607                 }
608         }
609 }
610
611 void free_camera(Camera *ca)
612 {
613         BPY_free_scriptlink(&ca->scriptlink);
614 }
615
616 void free_lamp(Lamp *la)
617 {
618         MTex *mtex;
619         int a;
620
621         /* scriptlinks */
622                 
623         BPY_free_scriptlink(&la->scriptlink);
624         
625         for(a=0; a<MAX_MTEX; a++) {
626                 mtex= la->mtex[a];
627                 if(mtex && mtex->tex) mtex->tex->id.us--;
628                 if(mtex) MEM_freeN(mtex);
629         }
630         la->ipo= 0;
631 }
632
633 void *add_wave()
634 {
635         return 0;
636 }
637
638
639 /* *************************************************** */
640
641 static void *add_obdata_from_type(int type)
642 {
643         switch (type) {
644         case OB_MESH: G.totmesh++; return add_mesh();
645         case OB_CURVE: G.totcurve++; return add_curve(OB_CURVE);
646         case OB_SURF: G.totcurve++; return add_curve(OB_SURF);
647         case OB_FONT: return add_curve(OB_FONT);
648         case OB_MBALL: return add_mball();
649         case OB_CAMERA: return add_camera();
650         case OB_LAMP: G.totlamp++; return add_lamp();
651         case OB_LATTICE: return add_lattice();
652         case OB_WAVE: return add_wave();
653         case OB_ARMATURE: return add_armature();
654         case OB_EMPTY: return NULL;
655         default:
656                 printf("add_obdata_from_type: Internal error, bad type: %d\n", type);
657                 return NULL;
658         }
659 }
660
661 static char *get_obdata_defname(int type)
662 {
663         switch (type) {
664         case OB_MESH: return "Mesh";
665         case OB_CURVE: return "Curve";
666         case OB_SURF: return "Surf";
667         case OB_FONT: return "Font";
668         case OB_MBALL: return "Mball";
669         case OB_CAMERA: return "Camera";
670         case OB_LAMP: return "Lamp";
671         case OB_LATTICE: return "Lattice";
672         case OB_WAVE: return "Wave";
673         case OB_ARMATURE: return "Armature";
674         case OB_EMPTY: return "Empty";
675         default:
676                 printf("get_obdata_defname: Internal error, bad type: %d\n", type);
677                 return "Empty";
678         }
679 }
680
681 /* general add: to G.scene, with layer from area and default name */
682 /* creates minimum required data, but without vertices etc. */
683 Object *add_object(int type)
684 {
685         Object *ob;
686         Base *base;
687         char name[32];
688
689         if (G.obpose)
690                 exit_posemode(1);
691         
692         strcpy(name, get_obdata_defname(type));
693         
694         ob= alloc_libblock(&G.main->object, ID_OB, name);
695         G.totobj++;
696         
697         /* default object vars */
698         ob->type= type;
699         /* ob->transflag= OB_QUAT; */
700         
701         QuatOne(ob->quat);
702         QuatOne(ob->dquat);
703
704         ob->col[0]= ob->col[1]= ob->col[2]= 0.0;
705         ob->col[3]= 1.0;
706         
707         ob->loc[0]= ob->loc[1]= ob->loc[2]= 0.0;
708         ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0;
709         ob->size[0]= ob->size[1]= ob->size[2]= 1.0;
710
711         Mat4One(ob->parentinv);
712         Mat4One(ob->obmat);
713         ob->dt= OB_SHADED;
714         if(U.flag & USER_MAT_ON_OB) ob->colbits= -1;
715         
716         if(type==OB_CAMERA || type==OB_LAMP) {
717                 ob->trackflag= OB_NEGZ;
718                 ob->upflag= OB_POSY;
719         }
720         else {
721                 ob->trackflag= OB_POSY;
722                 ob->upflag= OB_POSZ;
723         }
724         ob->ipoflag = OB_OFFS_OB+OB_OFFS_PARENT;
725         ob->ipowin= ID_OB;      /* the ipowin shown */
726         ob->dupon= 1; ob->dupoff= 0;
727         ob->dupsta= 1; ob->dupend= 100;
728
729         /* Game engine defaults*/
730         ob->mass= ob->inertia= 1.0f;
731         ob->formfactor= 0.4f;
732         ob->damping= 0.04f;
733         ob->rdamping= 0.1f;
734         ob->anisotropicFriction[0] = 1.0f;
735         ob->anisotropicFriction[1] = 1.0f;
736         ob->anisotropicFriction[2] = 1.0f;
737         ob->gameflag= OB_PROP;
738         
739         ob->data= add_obdata_from_type(type);
740         
741         ob->lay= G.scene->lay;
742
743         base= scene_add_base(G.scene, ob);
744         scene_select_base(G.scene, base);
745         ob->recalc |= OB_RECALC;
746         
747         return ob;
748 }
749
750 void base_init_from_view3d(Base *base, View3D *v3d)
751 {
752         Object *ob= base->object;
753
754         if (v3d->localview) {
755                 base->lay= ob->lay= v3d->layact + v3d->lay;
756                 VECCOPY(ob->loc, v3d->cursor);
757         } else {
758                 base->lay= ob->lay= v3d->layact;
759                 VECCOPY(ob->loc, G.scene->cursor);
760         }
761
762         v3d->viewquat[0]= -v3d->viewquat[0];
763         if (ob->transflag & OB_QUAT) {
764                 QUATCOPY(ob->quat, v3d->viewquat);
765         } else {
766                 QuatToEul(v3d->viewquat, ob->rot);
767         }
768         v3d->viewquat[0]= -v3d->viewquat[0];
769 }
770
771 SoftBody *copy_softbody(SoftBody *sb)
772 {
773         SoftBody *sbn;
774         
775         if (sb==NULL) return(NULL);
776         
777         sbn= MEM_dupallocN(sb);
778         sbn->totspring= sbn->totpoint= 0;
779         sbn->bpoint= NULL;
780         sbn->bspring= NULL;
781         sbn->ctime= 0.0f;
782         
783         sbn->keys= NULL;
784         sbn->totkey= sbn->totpointkey= 0;
785         
786         return sbn;
787 }
788
789 Object *copy_object(Object *ob)
790 {
791         Object *obn;
792         int a;
793         bConstraintChannel *actcon;
794
795         obn= copy_libblock(ob);
796         
797         if(ob->totcol) {
798                 obn->mat= MEM_dupallocN(ob->mat);
799         }
800         
801         if(ob->bb) obn->bb= MEM_dupallocN(ob->bb);
802         obn->path= 0;
803         obn->flag &= ~OB_FROMGROUP;
804         
805         copy_effects(&obn->effect, &ob->effect);
806         
807         obn->network.first= obn->network.last= 0;
808         
809         BPY_copy_scriptlink(&ob->scriptlink);
810         
811         copy_properties(&obn->prop, &ob->prop);
812         copy_sensors(&obn->sensors, &ob->sensors);
813         copy_controllers(&obn->controllers, &ob->controllers);
814         copy_actuators(&obn->actuators, &ob->actuators);
815         
816         copy_pose(&obn->pose, ob->pose, 1);
817         copy_defgroups(&obn->defbase, &ob->defbase);
818         copy_nlastrips(&obn->nlastrips, &ob->nlastrips);
819         copy_constraints (&obn->constraints, &ob->constraints);
820
821         copy_hooks( &obn->hooks, &ob->hooks);
822         
823         actcon = clone_constraint_channels (&obn->constraintChannels, &ob->constraintChannels, ob->activecon);
824         /* If the active constraint channel was in this list, update it */
825         if (actcon)
826                 obn->activecon = actcon;
827
828
829         /* increase user numbers */
830         id_us_plus((ID *)obn->data);
831         id_us_plus((ID *)obn->ipo);
832         id_us_plus((ID *)obn->action);
833         for(a=0; a<obn->totcol; a++) id_us_plus((ID *)obn->mat[a]);
834         
835         obn->disp.first= obn->disp.last= NULL;
836         
837         if(ob->pd) obn->pd= MEM_dupallocN(ob->pd);
838         obn->soft= copy_softbody(ob->soft);
839         
840         return obn;
841 }
842
843 void expand_local_object(Object *ob)
844 {
845         int a;
846         
847         id_lib_extern((ID *)ob->action);
848         id_lib_extern((ID *)ob->ipo);
849         id_lib_extern((ID *)ob->data);
850         
851         for(a=0; a<ob->totcol; a++) {
852                 id_lib_extern((ID *)ob->mat[a]);
853         }
854 }
855
856 void make_local_object(Object *ob)
857 {
858         Object *obn;
859         Scene *sce;
860         Base *base;
861         int local=0, lib=0;
862
863         /* - only lib users: do nothing
864             * - only local users: set flag
865             * - mixed: make copy
866             */
867         
868         if(ob->id.lib==0) return;
869         if(ob->id.us==1) {
870                 ob->id.lib= 0;
871                 ob->id.flag= LIB_LOCAL;
872                 new_id(0, (ID *)ob, 0);
873
874         }
875         else {
876                 sce= G.main->scene.first;
877                 while(sce) {
878                         base= sce->base.first;
879                         while(base) {
880                                 if(base->object==ob) {
881                                         if(sce->id.lib) lib++;
882                                         else local++;
883                                         break;
884                                 }
885                                 base= base->next;
886                         }
887                         sce= sce->id.next;
888                 }
889                 
890                 if(local && lib==0) {
891                         ob->id.lib= 0;
892                         ob->id.flag= LIB_LOCAL;
893                         new_id(0, (ID *)ob, 0);
894                 }
895                 else if(local && lib) {
896                         obn= copy_object(ob);
897                         obn->id.us= 0;
898                         
899                         sce= G.main->scene.first;
900                         while(sce) {
901                                 if(sce->id.lib==0) {
902                                         base= sce->base.first;
903                                         while(base) {
904                                                 if(base->object==ob) {
905                                                         base->object= obn;
906                                                         obn->id.us++;
907                                                         ob->id.us--;
908                                                 }
909                                                 base= base->next;
910                                         }
911                                 }
912                                 sce= sce->id.next;
913                         }
914                 }
915         }
916         
917         expand_local_object(ob);
918 }
919
920 /* *************** CALC ****************** */
921
922 /* there is also a timing calculation in drawobject() */
923
924 float bluroffs= 0.0;
925 int no_speed_curve= 0;
926
927 void set_mblur_offs(int blur)
928 {
929         bluroffs= R.r.blurfac*((float)blur);
930         bluroffs/= (float)R.r.osa;
931 }
932         
933 void disable_speed_curve(int val)
934 {
935         no_speed_curve= val;
936 }
937
938 /* ob can be NULL */
939 float bsystem_time(Object *ob, Object *par, float cfra, float ofs)
940 {
941         /* returns float ( see frame_to_float in ipo.c) */
942
943         /* 2nd field */
944         if(R.flag & R_SEC_FIELD) {
945                 if(R.r.mode & R_FIELDSTILL); else cfra+= .5;
946         }
947
948
949         if(ob && (ob->flag & OB_FROMDUPLI));
950         else {
951                         /* motion blur */
952                 cfra+= bluroffs;
953         
954                 /* global time */
955                 cfra*= G.scene->r.framelen;     
956         }
957         
958         if(no_speed_curve==0) if(ob && ob->ipo) cfra= calc_ipo_time(ob->ipo, cfra);
959         
960         /* ofset frames */
961         if(ob && (ob->ipoflag & OB_OFFS_PARENT)) {
962                 if((ob->partype & PARSLOW)==0) cfra-= ob->sf;
963         }
964         
965         cfra-= ofs;
966
967         return cfra;
968 }
969
970 void object_to_mat3(Object *ob, float mat[][3]) /* no parent */
971 {
972         float smat[3][3], vec[3];
973         float rmat[3][3];
974         float q1[4];
975         
976         /* size */
977         if(ob->ipo) {
978                 vec[0]= ob->size[0]+ob->dsize[0];
979                 vec[1]= ob->size[1]+ob->dsize[1];
980                 vec[2]= ob->size[2]+ob->dsize[2];
981                 SizeToMat3(vec, smat);
982         }
983         else {
984                 SizeToMat3(ob->size, smat);
985         }
986
987         /* rot */
988         if(ob->transflag & OB_QUAT) {
989                 if(ob->ipo) {
990                         QuatMul(q1, ob->quat, ob->dquat);
991                         QuatToMat3(q1, rmat);
992                 }
993                 else {
994                         QuatToMat3(ob->quat, rmat);
995                 }
996         }
997         else {
998                 if(ob->ipo) {
999                         vec[0]= ob->rot[0]+ob->drot[0];
1000                         vec[1]= ob->rot[1]+ob->drot[1];
1001                         vec[2]= ob->rot[2]+ob->drot[2];
1002                         EulToMat3(vec, rmat);
1003                 }
1004                 else {
1005                         EulToMat3(ob->rot, rmat);
1006                 }
1007         }
1008         Mat3MulMat3(mat, rmat, smat);
1009 }
1010
1011 void object_to_mat4(Object *ob, float mat[][4])
1012 {
1013         float tmat[3][3];
1014         
1015         object_to_mat3(ob, tmat);
1016         
1017         Mat4CpyMat3(mat, tmat);
1018         
1019         VECCOPY(mat[3], ob->loc);
1020         if(ob->ipo) {
1021                 mat[3][0]+= ob->dloc[0];
1022                 mat[3][1]+= ob->dloc[1];
1023                 mat[3][2]+= ob->dloc[2];
1024         }
1025 }
1026
1027 int enable_cu_speed= 1;
1028
1029 void ob_parcurve(Object *ob, Object *par, float mat[][4])
1030 {
1031         Curve *cu;
1032         float q[4], vec[4], dir[3], *quat, x1, ctime;
1033         float timeoffs= 0.0;
1034         
1035         Mat4One(mat);
1036         
1037         cu= par->data;
1038         if(cu->path==NULL || cu->path->data==NULL) calc_curvepath(par);
1039         if(cu->path==NULL) return;
1040         
1041         /* exception, timeoffset is regarded as distance offset */
1042         if(cu->flag & CU_OFFS_PATHDIST) {
1043                 SWAP(float, timeoffs, ob->sf);
1044         }
1045         
1046         /* catch exceptions: curve paths used as a duplicator */
1047         if(enable_cu_speed) {
1048                 ctime= bsystem_time(ob, par, (float)G.scene->r.cfra, 0.0);
1049                 
1050                 if(calc_ipo_spec(cu->ipo, CU_SPEED, &ctime)==0) {
1051                         ctime /= cu->pathlen;
1052                         CLAMP(ctime, 0.0, 1.0);
1053                 }
1054         }
1055         else {
1056                 ctime= G.scene->r.cfra - ob->sf;
1057                 ctime /= cu->pathlen;
1058                 
1059                 CLAMP(ctime, 0.0, 1.0);
1060         }
1061         
1062         /* time calculus is correct, now apply distance offset */
1063         if(cu->flag & CU_OFFS_PATHDIST) {
1064                 ctime += timeoffs/cu->path->totdist;
1065
1066                 /* restore */
1067                 SWAP(float, timeoffs, ob->sf);
1068         }
1069         
1070         
1071         /* vec: 4 items! */
1072         if( where_on_path(par, ctime, vec, dir) ) {
1073
1074                 if(cu->flag & CU_FOLLOW) {
1075                         quat= vectoquat(dir, ob->trackflag, ob->upflag);
1076                         
1077                         /* the tilt */
1078                         Normalise(dir);
1079                         q[0]= (float)cos(0.5*vec[3]);
1080                         x1= (float)sin(0.5*vec[3]);
1081                         q[1]= -x1*dir[0];
1082                         q[2]= -x1*dir[1];
1083                         q[3]= -x1*dir[2];
1084                         QuatMul(quat, q, quat);
1085                         
1086                         QuatToMat4(quat, mat);
1087                 }
1088                 
1089                 VECCOPY(mat[3], vec);
1090                 
1091         }
1092 }
1093
1094 void ob_parbone(Object *ob, Object *par, float mat[][4])
1095 {       
1096         bPoseChannel *pchan;
1097         bArmature *arm;
1098         float vec[3];
1099         
1100         arm=get_armature(par);
1101         if (!arm) {
1102                 Mat4One(mat);
1103                 return;
1104         }
1105         
1106         /* Make sure the bone is still valid */
1107         pchan= get_pose_channel(par->pose, ob->parsubstr);
1108         if (!pchan){
1109                 printf ("Bone parent: no bone %s\n", ob->parsubstr);
1110                 Mat4One(mat);
1111                 return;
1112         }
1113
1114         /* get bone transform */
1115         Mat4CpyMat4(mat, pchan->pose_mat);
1116
1117         /* but for backwards compatibility, the child has to move to the tail */
1118         VECCOPY(vec, mat[1]);
1119         VecMulf(vec, pchan->bone->length);
1120         VecAddf(mat[3], mat[3], vec);
1121 }
1122
1123 void give_parvert(Object *par, int nr, float *vec)
1124 {
1125         EditMesh *em = G.editMesh;
1126         Mesh *me;
1127         EditVert *eve;
1128 /*      extern ListBase editNurb; already in bad lev calls */
1129         Nurb *nu;
1130         Curve *cu;
1131         BPoint *bp;
1132         DispList *dl;
1133         BezTriple *bezt;
1134         float *fp;
1135         int a, count;
1136         
1137         vec[0]=vec[1]=vec[2]= 0.0;
1138         
1139         if(par->type==OB_MESH) {
1140                 if(G.obedit && (par->data==G.obedit->data)) {
1141                         if(nr >= G.totvert) nr= 0;
1142
1143                         count= 0;
1144                         eve= em->verts.first;
1145                         while(eve) {
1146                                 if(count==nr) {
1147                                         memcpy(vec, eve->co, 12);
1148                                         break;
1149                                 }
1150                                 eve= eve->next;
1151                                 count++;
1152                         }
1153                 }
1154                 else {
1155                         me= par->data;
1156                         if(me->totvert) {
1157                                 if(nr >= me->totvert) nr= 0;
1158                                 
1159                                 /* is there a deform */
1160                                 dl= find_displist(&par->disp, DL_VERTS);
1161                                 if(dl) {
1162                                         fp= dl->verts+3*nr;
1163                                         VECCOPY(vec, fp);
1164                                 }
1165                                 else {
1166                                         MVert *mvert= me->mvert + nr;
1167                                         VECCOPY(vec, mvert->co);
1168                                 }
1169                         }
1170                 }
1171         }
1172         else if ELEM(par->type, OB_CURVE, OB_SURF) {
1173
1174                 cu= par->data;
1175                 nu= cu->nurb.first;
1176                 if(par==G.obedit) nu= editNurb.first;
1177                 
1178                 count= 0;
1179                 while(nu) {
1180                         if((nu->type & 7)==CU_BEZIER) {
1181                                 bezt= nu->bezt;
1182                                 a= nu->pntsu;
1183                                 while(a--) {
1184                                         if(count==nr) {
1185                                                 VECCOPY(vec, bezt->vec[1]);
1186                                                 break;
1187                                         }
1188                                         count++;
1189                                         bezt++;
1190                                 }
1191                         }
1192                         else {
1193                                 bp= nu->bp;
1194                                 a= nu->pntsu*nu->pntsv;
1195                                 while(a--) {
1196                                         if(count==nr) {
1197                                                 memcpy(vec, bp->vec, 12);
1198                                                 break;
1199                                         }
1200                                         count++;
1201                                         bp++;
1202                                 }
1203                         }
1204                         nu= nu->next;
1205                 }
1206
1207         }
1208         else return;
1209 }
1210
1211 void ob_parvert3(Object *ob, Object *par, float mat[][4])
1212 {
1213         float cmat[3][3], v1[3], v2[3], v3[3], q[4];
1214
1215         /* in local ob space */
1216         Mat4One(mat);
1217         
1218         if ELEM3(par->type, OB_MESH, OB_SURF, OB_CURVE) {
1219                 
1220                 give_parvert(par, ob->par1, v1);
1221                 give_parvert(par, ob->par2, v2);
1222                 give_parvert(par, ob->par3, v3);
1223                                 
1224                 triatoquat(v1, v2, v3, q);
1225                 QuatToMat3(q, cmat);
1226                 Mat4CpyMat3(mat, cmat);
1227                 
1228                 if(ob->type==OB_CURVE) {
1229                         VECCOPY(mat[3], v1);
1230                 }
1231                 else {
1232                         VecAddf(mat[3], v1, v2);
1233                         VecAddf(mat[3], mat[3], v3);
1234                         VecMulf(mat[3], 0.3333333f);
1235                 }
1236         }
1237 }
1238
1239 static int no_parent_ipo=0;
1240 void set_no_parent_ipo(int val)
1241 {
1242         no_parent_ipo= val;
1243 }
1244
1245 static float timefac= 1.0;              /* 50 Hz, dtime:2 */
1246 void set_dtime(int dtime)
1247 {
1248         timefac= ((float)(dtime-1))/2.0f;
1249 }
1250
1251 static int during_script_flag=0;
1252 void disable_where_script(short on)
1253 {
1254         during_script_flag= on;
1255 }
1256
1257 int during_script(void) {
1258         return during_script_flag;
1259 }
1260
1261 static int during_scriptlink_flag=0;
1262 void disable_where_scriptlink(short on)
1263 {
1264         during_scriptlink_flag= on;
1265 }
1266
1267 int during_scriptlink(void) {
1268         return during_scriptlink_flag;
1269 }
1270
1271 void where_is_object_time(Object *ob, float ctime)
1272 {
1273         Object *par;
1274         float *fp1, *fp2, slowmat[4][4] = MAT4_UNITY;
1275         float stime, fac1, fac2, vec[3];
1276         int a;
1277         int pop; 
1278         
1279         /* new version: correct parent+vertexparent and track+parent */
1280         /* this one only calculates direct attached parent and track */
1281         /* is faster, but should keep track of timeoffs */
1282         
1283         if(ob==NULL) return;
1284
1285         if( ctime != ob->ctime) {
1286                 ob->ctime= ctime;
1287                 
1288                 if(ob->ipo) {
1289                         
1290                         stime= bsystem_time(ob, 0, ctime, 0.0);
1291
1292                         calc_ipo(ob->ipo, stime);
1293                         execute_ipo((ID *)ob, ob->ipo);
1294                 }
1295                 /* do constraint ipos ... */
1296                 do_constraint_channels(&ob->constraints, &ob->constraintChannels, ctime);
1297         }
1298
1299         if(ob->parent) {
1300                 par= ob->parent;
1301
1302                 if(ob->ipoflag & OB_OFFS_PARENT) ctime-= ob->sf;
1303                 
1304                 /* hurms, code below conflicts with depgraph... (ton) */
1305                 pop= 0;
1306                 if(no_parent_ipo==0 && ctime != par->ctime) {
1307                 
1308                         // only for ipo systems? 
1309                         pushdata(par, sizeof(Object));
1310                         pop= 1;
1311                         
1312                         where_is_object_time(par, ctime);
1313                 }
1314                 
1315                 solve_parenting(ob, par, slowmat, 0);
1316
1317                 if(pop) {
1318                         poplast(par);
1319                 }
1320                 
1321                 if(ob->partype & PARSLOW) {
1322                         // include framerate
1323
1324                         fac1= (float)(timefac/(1.0+ fabs(ob->sf)));
1325                         if(fac1>=1.0) return;
1326                         fac2= 1.0f-fac1;
1327                         
1328                         fp1= ob->obmat[0];
1329                         fp2= slowmat[0];
1330                         for(a=0; a<16; a++, fp1++, fp2++) {
1331                                 fp1[0]= fac1*fp1[0] + fac2*fp2[0];
1332                         }
1333                 }
1334         
1335         }
1336         else {
1337                 object_to_mat4(ob, ob->obmat);
1338         }
1339
1340         /* Handle tracking */
1341         if(ob->track) {
1342                 if( ctime != ob->track->ctime) where_is_object_time(ob->track, ctime);
1343                 solve_tracking (ob, ob->track->obmat);
1344                 
1345         }
1346
1347         solve_constraints (ob, TARGET_OBJECT, NULL, ctime);
1348
1349         if(ob->scriptlink.totscript && !during_script()) {
1350                 if (G.f & G_DOSCRIPTLINKS) BPY_do_pyscript((ID *)ob, SCRIPT_REDRAW);
1351         }
1352         
1353         /* set negative scale flag in object */
1354         Crossf(vec, ob->obmat[0], ob->obmat[1]);
1355         if( Inpf(vec, ob->obmat[2]) < 0.0 ) ob->transflag |= OB_NEG_SCALE;
1356         else ob->transflag &= ~OB_NEG_SCALE;
1357 }
1358
1359 static void solve_parenting (Object *ob, Object *par, float slowmat[][4], int simul)
1360 {
1361         float totmat[4][4];
1362         float tmat[4][4];
1363         float obmat[4][4];
1364         float vec[3];
1365         int ok;
1366
1367         object_to_mat4(ob, obmat);
1368         
1369         if(ob->partype & PARSLOW) Mat4CpyMat4(slowmat, ob->obmat);
1370         
1371
1372         switch(ob->partype & PARTYPE) {
1373         case PAROBJECT:
1374                 ok= 0;
1375                 if(par->type==OB_CURVE) {
1376                         if( ((Curve *)par->data)->flag & CU_PATH ) {
1377                                 ob_parcurve(ob, par, tmat);
1378                                 ok= 1;
1379                         }
1380                 }
1381                 
1382                 if(ok) Mat4MulSerie(totmat, par->obmat, tmat, 
1383                         NULL, NULL, NULL, NULL, NULL, NULL);
1384                 else Mat4CpyMat4(totmat, par->obmat);
1385                 
1386                 break;
1387         case PARBONE:
1388                 ob_parbone(ob, par, tmat);
1389                 Mat4MulSerie(totmat, par->obmat, tmat,         
1390                         NULL, NULL, NULL, NULL, NULL, NULL);
1391                 break;
1392                 
1393         case PARVERT1:
1394                 Mat4One(totmat);
1395                 if (simul){
1396                         VECCOPY(totmat[3], par->obmat[3]);
1397                 }
1398                 else{
1399                         give_parvert(par, ob->par1, vec);
1400                         VecMat4MulVecfl(totmat[3], par->obmat, vec);
1401                 }
1402                 break;
1403         case PARVERT3:
1404                 ob_parvert3(ob, par, tmat);
1405                 
1406                 Mat4MulSerie(totmat, par->obmat, tmat,         
1407                         NULL, NULL, NULL, NULL, NULL, NULL);
1408                 break;
1409                 
1410         case PARSKEL:
1411 #if 0
1412                 if (ob!=G.obedit)
1413                         Mat4One(totmat);
1414                 else
1415                         Mat4CpyMat4(totmat, par->obmat);
1416                 break;
1417 #else
1418                         Mat4CpyMat4(totmat, par->obmat);
1419 #endif
1420         }
1421         
1422         // total 
1423         Mat4MulSerie(tmat, totmat, ob->parentinv,         
1424                 NULL, NULL, NULL, NULL, NULL, NULL);
1425         Mat4MulSerie(ob->obmat, tmat, obmat,         
1426                 NULL, NULL, NULL, NULL, NULL, NULL);
1427         
1428         if (simul){
1429
1430         }
1431         else{
1432                 // external usable originmat 
1433                 Mat3CpyMat4(originmat, tmat);
1434                 
1435                 // origin, voor help line
1436                 if( (ob->partype & 15)==PARSKEL ) {
1437                         VECCOPY(ob->orig, par->obmat[3]);
1438                 }
1439                 else {
1440                         VECCOPY(ob->orig, totmat[3]);
1441                 }
1442         }
1443
1444 }
1445 void solve_tracking (Object *ob, float targetmat[][4])
1446 {
1447         float *quat;
1448         float vec[3];
1449         float totmat[3][3];
1450         float tmat[4][4];
1451         
1452         VecSubf(vec, ob->obmat[3], targetmat[3]);
1453         quat= vectoquat(vec, ob->trackflag, ob->upflag);
1454         QuatToMat3(quat, totmat);
1455         
1456         if(ob->parent && (ob->transflag & OB_POWERTRACK)) {
1457                 /* 'temporal' : clear parent info */
1458                 object_to_mat4(ob, tmat);
1459                 tmat[0][3]= ob->obmat[0][3];
1460                 tmat[1][3]= ob->obmat[1][3];
1461                 tmat[2][3]= ob->obmat[2][3];
1462                 tmat[3][0]= ob->obmat[3][0];
1463                 tmat[3][1]= ob->obmat[3][1];
1464                 tmat[3][2]= ob->obmat[3][2];
1465                 tmat[3][3]= ob->obmat[3][3];
1466         }
1467         else Mat4CpyMat4(tmat, ob->obmat);
1468         
1469         Mat4MulMat34(ob->obmat, totmat, tmat);
1470
1471 }
1472
1473 void where_is_object(Object *ob)
1474 {
1475         
1476         /* these have been mem copied */
1477         if(ob->flag & OB_FROMDUPLI) return;
1478         
1479         where_is_object_time(ob, (float)G.scene->r.cfra);
1480 }
1481
1482
1483 void where_is_object_simul(Object *ob)
1484 /* was written for the old game engine (until 2.04) */
1485 /* It seems that this function is only called
1486 for a lamp that is the child of another object */
1487 {
1488         Object *par;
1489         Ipo *ipo;
1490         float *fp1, *fp2;
1491         float slowmat[4][4];
1492         float fac1, fac2;
1493         int a;
1494         
1495         /* NO TIMEOFFS */
1496         
1497         /* no ipo! (because of dloc and realtime-ipos) */
1498         ipo= ob->ipo;
1499         ob->ipo= NULL;
1500
1501         if(ob->parent) {
1502                 par= ob->parent;
1503                 
1504                 solve_parenting(ob, par, slowmat, 1);
1505
1506                 if(ob->partype & PARSLOW) {
1507
1508                         fac1= (float)(1.0/(1.0+ fabs(ob->sf)));
1509                         fac2= 1.0f-fac1;
1510                         fp1= ob->obmat[0];
1511                         fp2= slowmat[0];
1512                         for(a=0; a<16; a++, fp1++, fp2++) {
1513                                 fp1[0]= fac1*fp1[0] + fac2*fp2[0];
1514                         }
1515                 }
1516                 
1517         }
1518         else {
1519                 object_to_mat4(ob, ob->obmat);
1520         }
1521         
1522         if(ob->track) 
1523                 solve_tracking(ob, ob->track->obmat);
1524
1525         solve_constraints(ob, TARGET_OBJECT, NULL, G.scene->r.cfra);
1526         
1527         /*  WATCH IT!!! */
1528         ob->ipo= ipo;
1529         
1530 }
1531 extern void Mat4BlendMat4(float out[][4], float dst[][4], float src[][4], float srcweight);
1532
1533 void solve_constraints (Object *ob, short obtype, void *obdata, float ctime)
1534 {
1535         bConstraint *con;
1536         float tmat[4][4], focusmat[4][4], lastmat[4][4];
1537         int i, clear=1, tot=0;
1538         float   a=0;
1539         float   aquat[4], quat[4];
1540         float   aloc[3], loc[3];
1541         float   asize[3], size[3];
1542         float   oldmat[4][4];
1543         float   smat[3][3], rmat[3][3], mat[3][3];
1544         float enf;
1545
1546         for (con = ob->constraints.first; con; con=con->next) {
1547                 // inverse kinematics is solved seperate 
1548                 if (con->type==CONSTRAINT_TYPE_KINEMATIC) continue;
1549                 
1550                 /* Clear accumulators if necessary*/
1551                 if (clear) {
1552                         clear= 0;
1553                         a= 0;
1554                         tot= 0;
1555                         memset(aquat, 0, sizeof(float)*4);
1556                         memset(aloc, 0, sizeof(float)*3);
1557                         memset(asize, 0, sizeof(float)*3);
1558                 }
1559                 
1560                 /* Check this constraint only if it has some enforcement */
1561                 if (!(con->flag & CONSTRAINT_DISABLE)) {
1562                         enf = con->enforce;     // value from ipos (from action channels)
1563
1564                         /* Get the targetmat */
1565                         get_constraint_target_matrix(con, obtype, obdata, tmat, size, ctime);
1566                         
1567                         Mat4CpyMat4(focusmat, tmat);
1568                         
1569                         /* Extract the components & accumulate */
1570                         Mat4ToQuat(focusmat, quat);
1571                         VECCOPY(loc, focusmat[3]);
1572                         Mat3CpyMat4(mat, focusmat);
1573                         Mat3ToSize(mat, size);
1574                         
1575                         a+= enf;
1576                         tot++;
1577                         
1578                         for(i=0; i<3; i++) {
1579                                 aquat[i+1]+=(quat[i+1]) * enf;
1580                                 aloc[i]+=(loc[i]) * enf;
1581                                 asize[i]+=(size[i]-1.0f) * enf;
1582                         }
1583                         aquat[0]+=(quat[0])*enf;
1584                         Mat4CpyMat4(lastmat, focusmat);
1585                 }
1586                 
1587                 /* If the next constraint is not the same type (or there isn't one),
1588                  *      then evaluate the accumulator & request a clear */
1589                 if ((!con->next)||(con->next && con->next->type!=con->type)) {
1590                         clear= 1;
1591                         Mat4CpyMat4(oldmat, ob->obmat);
1592
1593                         /*      If we have several inputs, do a blend of them */
1594                         if (tot) {
1595                                 if (tot>1) {
1596                                         if (a) {
1597                                                 for (i=0; i<3; i++) {
1598                                                         asize[i]=1.0f + (asize[i]/(a));
1599                                                         aloc[i]=(aloc[i]/a);
1600                                                 }
1601                                                 
1602                                                 NormalQuat(aquat);
1603                                                 
1604                                                 QuatToMat3(aquat, rmat);
1605                                                 SizeToMat3(asize, smat);
1606                                                 Mat3MulMat3(mat, rmat, smat);
1607                                                 Mat4CpyMat3(focusmat, mat);
1608                                                 VECCOPY(focusmat[3], aloc);
1609
1610                                                 evaluate_constraint(con, ob, obtype, obdata, focusmat);
1611                                         }
1612                                         
1613                                 }       
1614                                 /* If we only have one, blend with the current obmat */
1615                                 else {
1616                                         float solution[4][4];
1617                                         float delta[4][4];
1618                                         float imat[4][4];
1619                                         float identity[4][4];
1620                                         float worldmat[4][4];
1621                                         
1622                                         if (con->type!=CONSTRAINT_TYPE_KINEMATIC) {
1623                                                 /* If we're not an IK constraint, solve the constraint then blend it to the previous one */
1624                                                 evaluate_constraint(con, ob, obtype, obdata, lastmat);
1625                                                 
1626                                                 Mat4CpyMat4 (solution, ob->obmat);
1627
1628                                                 /* Interpolate the enforcement */                                       
1629                                                 Mat4Invert (imat, oldmat);
1630                                                 Mat4MulMat4 (delta, solution, imat);
1631                                                 
1632                                                 if (a<1.0) {
1633                                                         Mat4One(identity);
1634                                                         Mat4BlendMat4(delta, identity, delta, a);
1635                                                 }
1636                                                 Mat4MulMat4 (ob->obmat, delta, oldmat);
1637
1638                                         }
1639                                         else{
1640                                                 /* Interpolate the target between the chain's unconstrained endpoint and the effector loc */
1641                                                 if (obtype==TARGET_BONE) {
1642                                                         get_objectspace_bone_matrix(obdata, oldmat, 1, 1);
1643                                                         
1644                                                         Mat4MulMat4(worldmat, oldmat, ob->parent->obmat);
1645
1646                                                         Mat4BlendMat4(focusmat, worldmat, lastmat, a);
1647                                                         
1648                                                         evaluate_constraint(con, ob, obtype, obdata, focusmat);
1649                                                 }
1650                                         }
1651                                 }
1652                         }
1653                 }
1654         }       
1655 }
1656
1657 /* for calculation of the inverse parent transform, only used for editor */
1658 void what_does_parent(Object *ob)
1659 {
1660
1661         clear_workob();
1662         Mat4One(workob.obmat);
1663         Mat4One(workob.parentinv);
1664         workob.parent= ob->parent;
1665         workob.track= ob->track;
1666
1667         workob.trackflag= ob->trackflag;
1668         workob.upflag= ob->upflag;
1669         
1670         workob.partype= ob->partype;
1671         workob.par1= ob->par1;
1672         workob.par2= ob->par2;
1673         workob.par3= ob->par3;
1674
1675         workob.constraints.first = ob->constraints.first;
1676         workob.constraints.last = ob->constraints.last;
1677
1678         strcpy (workob.parsubstr, ob->parsubstr); 
1679
1680         where_is_object(&workob);
1681 }
1682
1683 BoundBox *unit_boundbox()
1684 {
1685         BoundBox *bb;
1686         
1687         bb= MEM_mallocN(sizeof(BoundBox), "bb");
1688
1689         bb->vec[0][0]=bb->vec[1][0]=bb->vec[2][0]=bb->vec[3][0]= -1.0;
1690         bb->vec[4][0]=bb->vec[5][0]=bb->vec[6][0]=bb->vec[7][0]= 1.0;
1691         
1692         bb->vec[0][1]=bb->vec[1][1]=bb->vec[4][1]=bb->vec[5][1]= -1.0;
1693         bb->vec[2][1]=bb->vec[3][1]=bb->vec[6][1]=bb->vec[7][1]= 1.0;
1694
1695         bb->vec[0][2]=bb->vec[3][2]=bb->vec[4][2]=bb->vec[7][2]= -1.0;
1696         bb->vec[1][2]=bb->vec[2][2]=bb->vec[5][2]=bb->vec[6][2]= 1.0;
1697         
1698         return bb;
1699 }
1700
1701 void minmax_object(Object *ob, float *min, float *max)
1702 {
1703         BoundBox bb;
1704         Mesh *me;
1705         Curve *cu;
1706         float vec[3];
1707         int a;
1708         
1709         switch(ob->type) {
1710                 
1711         case OB_CURVE:
1712         case OB_FONT:
1713         case OB_SURF:
1714                 cu= ob->data;
1715                 
1716                 if(cu->bb==0) tex_space_curve(cu);
1717                 bb= *(cu->bb);
1718                 
1719                 for(a=0; a<8; a++) {
1720                         Mat4MulVecfl(ob->obmat, bb.vec[a]);
1721                         DO_MINMAX(bb.vec[a], min, max);
1722                 }
1723                 break;
1724         case OB_ARMATURE:
1725                 if(ob->pose) {
1726                         bPoseChannel *pchan;
1727                         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1728                                 VECCOPY(vec, pchan->pose_head);
1729                                 Mat4MulVecfl(ob->obmat, vec);
1730                                 DO_MINMAX(vec, min, max);
1731                                 VECCOPY(vec, pchan->pose_tail);
1732                                 Mat4MulVecfl(ob->obmat, vec);
1733                                 DO_MINMAX(vec, min, max);
1734                         }
1735                         break;
1736                 }
1737                 /* no break, get_mesh will give NULL and it passes on to default */
1738         case OB_MESH:
1739                 me= get_mesh(ob);
1740                 
1741                 if(me) {
1742                         bb = *mesh_get_bb(me);
1743                         
1744                         for(a=0; a<8; a++) {
1745                                 Mat4MulVecfl(ob->obmat, bb.vec[a]);
1746                                 DO_MINMAX(bb.vec[a], min, max);
1747                         }
1748                 }
1749                 if(min[0] < max[0] ) break;
1750                 
1751                 /* else here no break!!!, mesh can be zero sized */
1752                 
1753         default:
1754                 DO_MINMAX(ob->obmat[3], min, max);
1755
1756                 VECCOPY(vec, ob->obmat[3]);
1757                 VecAddf(vec, vec, ob->size);
1758                 DO_MINMAX(vec, min, max);
1759
1760                 VECCOPY(vec, ob->obmat[3]);
1761                 VecSubf(vec, vec, ob->size);
1762                 DO_MINMAX(vec, min, max);
1763                 break;
1764         }
1765 }
1766
1767 /* the main object update call, for object matrix, constraints, keys and displist (modifiers) */
1768 /* requires flags to be set! */
1769 void object_handle_update(Object *ob)
1770 {
1771         if(ob->recalc & OB_RECALC) {
1772                 
1773                 if(ob->recalc & OB_RECALC_OB) where_is_object(ob);
1774                 
1775                 if(ob->recalc & OB_RECALC_DATA) {
1776                         
1777 //                      printf("recalcdata %s\n", ob->id.name+2);
1778                         /* includes all keys and modifiers */
1779                         if(ob->type==OB_MESH) {
1780                                 makeDispListMesh(ob);
1781                         }
1782                         else if(ob->type==OB_MBALL) {
1783                                 makeDispListMBall(ob);
1784                         } 
1785                         else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
1786                                 makeDispListCurveTypes(ob);
1787                         }
1788                         else if(ob->type==OB_ARMATURE) {
1789                                 /* this actually only happens for reading old files... */
1790                                 if(ob->pose==NULL || (ob->pose->flag & POSE_RECALC))
1791                                         armature_rebuild_pose(ob, ob->data);
1792                                 do_all_actions(ob);
1793                                 where_is_pose(ob);
1794                         }
1795                 }
1796                 
1797                 ob->recalc &= ~OB_RECALC;
1798         }
1799 }
1800
1801