part 1 of cleaning up my little array macro library to be a formal API. also removed...
[blender.git] / source / blender / blenkernel / intern / sca.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  * these all are linked to objects (listbase)
29  * all data is 'direct data', not Blender lib data.
30  */
31
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
35
36 #include <stdio.h>
37 #include <string.h>
38 #include <float.h>
39
40 #include "MEM_guardedalloc.h"
41
42 #include "DNA_text_types.h"
43 #include "DNA_controller_types.h"
44 #include "DNA_sensor_types.h"
45 #include "DNA_actuator_types.h"
46 #include "DNA_object_types.h"
47
48 #include "BLI_blenlib.h"
49 #include "BKE_utildefines.h"
50 #include "BKE_global.h"
51 #include "BKE_main.h"
52 #include "BKE_blender.h"
53 #include "BKE_sca.h"
54
55 /* ******************* SENSORS ************************ */
56
57 void free_sensor(bSensor *sens)
58 {
59         if(sens->links) MEM_freeN(sens->links);
60         if(sens->data) MEM_freeN(sens->data);
61         MEM_freeN(sens);
62         
63 }
64
65 void free_sensors(ListBase *lb)
66 {
67         bSensor *sens;
68         
69         while((sens= lb->first)) {
70                 BLI_remlink(lb, sens);
71                 free_sensor(sens);
72         }
73 }
74
75 bSensor *copy_sensor(bSensor *sens)
76 {
77         bSensor *sensn;
78         
79         sensn= MEM_dupallocN(sens);
80         sensn->flag |= SENS_NEW;
81         if(sens->data) {
82                 sensn->data= MEM_dupallocN(sens->data);
83         }
84
85         if(sens->links) sensn->links= MEM_dupallocN(sens->links);
86         
87         return sensn;
88 }
89
90 void copy_sensors(ListBase *lbn, ListBase *lbo)
91 {
92         bSensor *sens, *sensn;
93         
94         lbn->first= lbn->last= 0;
95         sens= lbo->first;
96         while(sens) {
97                 sensn= copy_sensor(sens);
98                 BLI_addtail(lbn, sensn);
99                 sens= sens->next;
100         }
101 }
102
103 void init_sensor(bSensor *sens)
104 {
105         /* also use when sensor changes type */
106         bNearSensor *ns;
107         bMouseSensor *ms;
108         
109         if(sens->data) MEM_freeN(sens->data);
110         sens->data= NULL;
111         sens->pulse = 0;
112         
113         switch(sens->type) {
114         case SENS_ALWAYS:
115                 sens->pulse = 0;
116                 break;
117         case SENS_TOUCH:
118                 sens->data= MEM_callocN(sizeof(bTouchSensor), "touchsens");
119                 break;
120         case SENS_NEAR:
121                 ns=sens->data= MEM_callocN(sizeof(bNearSensor), "nearsens");
122                 ns->dist= 1.0;
123                 ns->resetdist= 2.0;
124                 break;
125         case SENS_KEYBOARD:
126                 sens->data= MEM_callocN(sizeof(bKeyboardSensor), "keysens");
127                 break;
128         case SENS_PROPERTY:
129                 sens->data= MEM_callocN(sizeof(bPropertySensor), "propsens");
130                 break;
131         case SENS_ACTUATOR:
132                 sens->data= MEM_callocN(sizeof(bActuatorSensor), "actsens");
133                 break;
134         case SENS_DELAY:
135                 sens->data= MEM_callocN(sizeof(bDelaySensor), "delaysens");
136                 break;
137         case SENS_MOUSE:
138                 ms=sens->data= MEM_callocN(sizeof(bMouseSensor), "mousesens");
139                 //XXX ms->type= LEFTMOUSE;
140                 break;
141         case SENS_COLLISION:
142                 sens->data= MEM_callocN(sizeof(bCollisionSensor), "colsens");
143                 break;
144         case SENS_RADAR:
145                 sens->data= MEM_callocN(sizeof(bRadarSensor), "radarsens");
146                 break;
147         case SENS_RANDOM:
148                 sens->data= MEM_callocN(sizeof(bRandomSensor), "randomsens");
149                 break;
150         case SENS_RAY:
151                 sens->data= MEM_callocN(sizeof(bRaySensor), "raysens");
152                 break;
153         case SENS_MESSAGE:
154                 sens->data= MEM_callocN(sizeof(bMessageSensor), "messagesens");
155                 break;
156         case SENS_JOYSTICK:
157                 sens->data= MEM_callocN(sizeof(bJoystickSensor), "joysticksens");
158                 break;
159         default:
160                 ; /* this is very severe... I cannot make any memory for this        */
161                 /* logic brick...                                                    */
162         }
163 }
164
165 bSensor *new_sensor(int type)
166 {
167         bSensor *sens;
168
169         sens= MEM_callocN(sizeof(bSensor), "Sensor");
170         sens->type= type;
171         sens->flag= SENS_SHOW;
172         
173         init_sensor(sens);
174         
175         strcpy(sens->name, "sensor");
176 // XXX  make_unique_prop_names(sens->name);
177         
178         return sens;
179 }
180
181 /* ******************* CONTROLLERS ************************ */
182
183 void unlink_controller(bController *cont)
184 {
185         bSensor *sens;
186         Object *ob;
187         int a, removed;
188         
189         /* check for controller pointers in sensors */
190         ob= G.main->object.first;
191         while(ob) {
192                 sens= ob->sensors.first;
193                 while(sens) {
194                         removed= 0;
195                         for(a=0; a<sens->totlinks; a++) {
196                                 if(removed) (sens->links)[a-1] = (sens->links)[a];
197                                 else if((sens->links)[a] == cont) removed= 1;
198                         }
199                         if(removed) {
200                                 sens->totlinks--;
201                                 
202                                 if(sens->totlinks==0) {
203                                         MEM_freeN(sens->links);
204                                         sens->links= NULL;
205                                 }
206                         }
207                         sens= sens->next;
208                 }
209                 ob= ob->id.next;
210         }
211 }
212
213 void unlink_controllers(ListBase *lb)
214 {
215         bController *cont;
216         
217         for (cont= lb->first; cont; cont= cont->next)
218                 unlink_controller(cont);        
219 }
220
221 void free_controller(bController *cont)
222 {
223         if(cont->links) MEM_freeN(cont->links);
224
225         /* the controller itself */
226         if(cont->data) MEM_freeN(cont->data);
227         MEM_freeN(cont);
228         
229 }
230
231 void free_controllers(ListBase *lb)
232 {
233         bController *cont;
234         
235         while((cont= lb->first)) {
236                 BLI_remlink(lb, cont);
237                 if(cont->slinks) MEM_freeN(cont->slinks);
238                 free_controller(cont);
239         }
240 }
241
242 bController *copy_controller(bController *cont)
243 {
244         bController *contn;
245         
246         cont->mynew=contn= MEM_dupallocN(cont);
247         contn->flag |= CONT_NEW;
248         if(cont->data) {
249                 contn->data= MEM_dupallocN(cont->data);
250         }
251
252         if(cont->links) contn->links= MEM_dupallocN(cont->links);
253         contn->slinks= NULL;
254         contn->totslinks= 0;
255         
256         return contn;
257 }
258
259 void copy_controllers(ListBase *lbn, ListBase *lbo)
260 {
261         bController *cont, *contn;
262         
263         lbn->first= lbn->last= 0;
264         cont= lbo->first;
265         while(cont) {
266                 contn= copy_controller(cont);
267                 BLI_addtail(lbn, contn);
268                 cont= cont->next;
269         }
270 }
271
272 void init_controller(bController *cont)
273 {
274         /* also use when controller changes type, leave actuators... */
275         
276         if(cont->data) MEM_freeN(cont->data);
277         cont->data= 0;
278         
279         switch(cont->type) {
280         case CONT_EXPRESSION:
281                 cont->data= MEM_callocN(sizeof(bExpressionCont), "expcont");
282                 break;
283         case CONT_PYTHON:
284                 cont->data= MEM_callocN(sizeof(bPythonCont), "pycont");
285                 break;
286         }
287 }
288
289 bController *new_controller(int type)
290 {
291         bController *cont;
292
293         cont= MEM_callocN(sizeof(bController), "Controller");
294         cont->type= type;
295         cont->flag= CONT_SHOW;
296
297         init_controller(cont);
298         
299         strcpy(cont->name, "cont");
300 // XXX  make_unique_prop_names(cont->name);
301         
302         return cont;
303 }
304
305 /* ******************* ACTUATORS ************************ */
306
307 void unlink_actuator(bActuator *act)
308 {
309         bController *cont;
310         Object *ob;
311         int a, removed;
312         
313         /* check for actuator pointers in controllers */
314         ob= G.main->object.first;
315         while(ob) {
316                 cont= ob->controllers.first;
317                 while(cont) {
318                         removed= 0;
319                         for(a=0; a<cont->totlinks; a++) {
320                                 if(removed) (cont->links)[a-1] = (cont->links)[a];
321                                 else if((cont->links)[a] == act) removed= 1;
322                         }
323                         if(removed) {
324                                 cont->totlinks--;
325                                 
326                                 if(cont->totlinks==0) {
327                                         MEM_freeN(cont->links);
328                                         cont->links= NULL;
329                                 }
330                         }
331                         cont= cont->next;
332                 }
333                 ob= ob->id.next;
334         }
335 }
336
337 void unlink_actuators(ListBase *lb)
338 {
339         bActuator *act;
340         
341         for (act= lb->first; act; act= act->next)
342                 unlink_actuator(act);
343 }
344
345 void free_actuator(bActuator *act)
346 {
347         if(act->data) MEM_freeN(act->data);
348         MEM_freeN(act);
349 }
350
351 void free_actuators(ListBase *lb)
352 {
353         bActuator *act;
354         
355         while((act= lb->first)) {
356                 BLI_remlink(lb, act);
357                 free_actuator(act);
358         }
359 }
360
361 bActuator *copy_actuator(bActuator *act)
362 {
363         bActuator *actn;
364         
365         act->mynew=actn= MEM_dupallocN(act);
366         actn->flag |= ACT_NEW;
367         if(act->data) {
368                 actn->data= MEM_dupallocN(act->data);
369         }
370         
371         return actn;
372 }
373
374 void copy_actuators(ListBase *lbn, ListBase *lbo)
375 {
376         bActuator *act, *actn;
377         
378         lbn->first= lbn->last= 0;
379         act= lbo->first;
380         while(act) {
381                 actn= copy_actuator(act);
382                 BLI_addtail(lbn, actn);
383                 act= act->next;
384         }
385 }
386
387 void init_actuator(bActuator *act)
388 {
389         /* also use when actuator changes type */
390         bObjectActuator *oa;
391         bSoundActuator *sa;
392         
393         if(act->data) MEM_freeN(act->data);
394         act->data= 0;
395         
396         switch(act->type) {
397         case ACT_ACTION:
398         case ACT_SHAPEACTION:
399                 act->data= MEM_callocN(sizeof(bActionActuator), "actionact");
400                 break;
401         case ACT_SOUND:
402                 sa = act->data= MEM_callocN(sizeof(bSoundActuator), "soundact");
403                 sa->volume = 1.0f;
404                 sa->sound3D.rolloff_factor = 1.0f;
405                 sa->sound3D.reference_distance = 1.0f;
406                 sa->sound3D.max_gain = 1.0f;
407                 sa->sound3D.cone_inner_angle = 360.0f;
408                 sa->sound3D.cone_outer_angle = 360.0f;
409                 sa->sound3D.max_distance = FLT_MAX;
410                 break;
411         case ACT_OBJECT:
412                 act->data= MEM_callocN(sizeof(bObjectActuator), "objectact");
413                 oa= act->data;
414                 oa->flag= 15;
415                 break;
416         case ACT_IPO:
417                 act->data= MEM_callocN(sizeof(bIpoActuator), "ipoact");
418                 break;
419         case ACT_PROPERTY:
420                 act->data= MEM_callocN(sizeof(bPropertyActuator), "propact");
421                 break;
422         case ACT_CAMERA:
423                 act->data= MEM_callocN(sizeof(bCameraActuator), "camact");
424                 break;
425         case ACT_EDIT_OBJECT:
426                 act->data= MEM_callocN(sizeof(bEditObjectActuator), "editobact");
427                 break;
428         case ACT_CONSTRAINT:
429                 act->data= MEM_callocN(sizeof(bConstraintActuator), "cons act");
430                 break;
431         case ACT_SCENE:
432                 act->data= MEM_callocN(sizeof(bSceneActuator), "scene act");
433                 break;
434         case ACT_GROUP:
435                 act->data= MEM_callocN(sizeof(bGroupActuator), "group act");
436                 break;
437         case ACT_RANDOM:
438                 act->data= MEM_callocN(sizeof(bRandomActuator), "random act");
439                 break;
440         case ACT_MESSAGE:
441                 act->data= MEM_callocN(sizeof(bMessageActuator), "message act");
442                 break;
443         case ACT_GAME:
444                 act->data= MEM_callocN(sizeof(bGameActuator), "game act");
445                 break;
446         case ACT_VISIBILITY:
447                 act->data= MEM_callocN(sizeof(bVisibilityActuator), "visibility act");
448                 break;
449     case ACT_2DFILTER:
450         act->data = MEM_callocN(sizeof( bTwoDFilterActuator ), "2d filter act");
451         break;
452     case ACT_PARENT:
453         act->data = MEM_callocN(sizeof( bParentActuator ), "parent act");
454         break;
455         case ACT_STATE:
456         act->data = MEM_callocN(sizeof( bStateActuator ), "state act");
457         break;
458         default:
459                 ; /* this is very severe... I cannot make any memory for this        */
460                 /* logic brick...                                                    */
461         }
462 }
463
464 bActuator *new_actuator(int type)
465 {
466         bActuator *act;
467
468         act= MEM_callocN(sizeof(bActuator), "Actuator");
469         act->type= type;
470         act->flag= ACT_SHOW;
471         
472         init_actuator(act);
473         
474         strcpy(act->name, "act");
475 // XXX  make_unique_prop_names(act->name);
476         
477         return act;
478 }
479
480 /* ******************** GENERAL ******************* */
481
482 void clear_sca_new_poins_ob(Object *ob)
483 {
484         bSensor *sens;
485         bController *cont;
486         bActuator *act;
487         
488         sens= ob->sensors.first;
489         while(sens) {
490                 sens->flag &= ~SENS_NEW;
491                 sens= sens->next;
492         }
493         cont= ob->controllers.first;
494         while(cont) {
495                 cont->mynew= NULL;
496                 cont->flag &= ~CONT_NEW;
497                 cont= cont->next;
498         }
499         act= ob->actuators.first;
500         while(act) {
501                 act->mynew= NULL;
502                 act->flag &= ~ACT_NEW;
503                 act= act->next;
504         }
505 }
506
507 void clear_sca_new_poins()
508 {
509         Object *ob;
510         
511         ob= G.main->object.first;
512         while(ob) {
513                 clear_sca_new_poins_ob(ob);
514                 ob= ob->id.next;        
515         }
516 }
517
518 void set_sca_new_poins_ob(Object *ob)
519 {
520         bSensor *sens;
521         bController *cont;
522         bActuator *act;
523         int a;
524         
525         sens= ob->sensors.first;
526         while(sens) {
527                 if(sens->flag & SENS_NEW) {
528                         for(a=0; a<sens->totlinks; a++) {
529                                 if(sens->links[a] && sens->links[a]->mynew)
530                                         sens->links[a]= sens->links[a]->mynew;
531                         }
532                 }
533                 sens= sens->next;
534         }
535
536         cont= ob->controllers.first;
537         while(cont) {
538                 if(cont->flag & CONT_NEW) {
539                         for(a=0; a<cont->totlinks; a++) {
540                                 if( cont->links[a] && cont->links[a]->mynew)
541                                         cont->links[a]= cont->links[a]->mynew;
542                         }
543                 }
544                 cont= cont->next;
545         }
546         
547         
548         act= ob->actuators.first;
549         while(act) {
550                 if(act->flag & ACT_NEW) {
551                         if(act->type==ACT_EDIT_OBJECT) {
552                                 bEditObjectActuator *eoa= act->data;
553                                 ID_NEW(eoa->ob);
554                         }
555                         else if(act->type==ACT_SCENE) {
556                                 bSceneActuator *sca= act->data;
557                                 ID_NEW(sca->camera);
558                         }
559                         else if(act->type==ACT_CAMERA) {
560                                 bCameraActuator *ca= act->data;
561                                 ID_NEW(ca->ob);
562                         }
563                         else if(act->type==ACT_OBJECT) {
564                                 bObjectActuator *oa= act->data;
565                                 ID_NEW(oa->reference);
566                         }
567                         else if(act->type==ACT_SCENE) {
568                                 bSceneActuator *sca= act->data;
569                                 ID_NEW(sca->camera);
570                         }
571                 }
572                 act= act->next;
573         }
574 }
575
576
577 void set_sca_new_poins()
578 {
579         Object *ob;
580         
581         ob= G.main->object.first;
582         while(ob) {
583                 set_sca_new_poins_ob(ob);
584                 ob= ob->id.next;        
585         }
586 }
587
588 void sca_remove_ob_poin(Object *obt, Object *ob)
589 {
590         bSensor *sens;
591         bMessageSensor *ms;
592         bActuator *act;
593         bCameraActuator *ca;
594         bObjectActuator *oa;
595         bSceneActuator *sa;
596         bEditObjectActuator *eoa;
597         bPropertyActuator *pa;
598         bMessageActuator *ma;
599
600         sens= obt->sensors.first;
601         while(sens) {
602                 switch(sens->type) {
603                 case SENS_MESSAGE:
604                         ms= sens->data;
605                         if(ms->fromObject==ob) ms->fromObject= NULL;
606                 }
607                 sens= sens->next;
608         }
609
610         act= obt->actuators.first;
611         while(act) {
612                 switch(act->type) {
613                 case ACT_CAMERA:
614                         ca= act->data;
615                         if(ca->ob==ob) ca->ob= NULL;
616                         break;
617                 case ACT_OBJECT:
618                         oa= act->data;
619                         if(oa->reference==ob) oa->reference= NULL;
620                         break;
621                 case ACT_PROPERTY:
622                         pa= act->data;
623                         if(pa->ob==ob) pa->ob= NULL;
624                         break;
625                 case ACT_SCENE:
626                         sa= act->data;
627                         if(sa->camera==ob) sa->camera= NULL;
628                         break;
629                 case ACT_EDIT_OBJECT:
630                         eoa= act->data;
631                         if(eoa->ob==ob) eoa->ob= NULL;
632                         break;
633                 case ACT_MESSAGE:
634                         ma= act->data;
635                         if(ma->toObject==ob) ma->toObject= NULL;
636                         break;
637
638                 }
639                 act= act->next;
640         }       
641 }