/** * $Id:$ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * * The contents of this file may be used under the terms of either the GNU * General Public License Version 2 or later (the "GPL", see * http://www.gnu.org/licenses/gpl.html ), or the Blender License 1.0 or * later (the "BL", see http://www.blender.org/BL/ ) which has to be * bought from the Blender Foundation to become active, in which case the * above mentioned GPL option does not apply. * * The Original Code is Copyright (C) 2002 by NaN Holding BV. * All rights reserved. * * The Original Code is: all of this file. * * Contributor(s): none yet. * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ /* sca.c june 2000 * * sensor/controller/actuator code * * these all are linked to objects (listbase) * * all data is 'direct data', not Blender lib data. * * ton roosendaal * Version: $Id: sca.c,v 1.19 2000/09/25 22:02:54 ton Exp $ */ #include "blender.h" #include "graphics.h" /* for keyvals */ #include "sound.h" #include "game.h" /* ******************* SENSORS ************************ */ void free_sensor(bSensor *sens) { if(sens->links) freeN(sens->links); if(sens->data) freeN(sens->data); freeN(sens); } void free_sensors(ListBase *lb) { bSensor *sens; while((sens= lb->first)) { remlink(lb, sens); free_sensor(sens); } } bSensor *copy_sensor(bSensor *sens) { bSensor *sensn; sensn= dupallocN(sens); sensn->flag |= SENS_NEW; if(sens->data) { sensn->data= dupallocN(sens->data); } if(sens->links) sensn->links= dupallocN(sens->links); return sensn; } void copy_sensors(ListBase *lbn, ListBase *lbo) { bSensor *sens, *sensn; lbn->first= lbn->last= 0; sens= lbo->first; while(sens) { sensn= copy_sensor(sens); addtail(lbn, sensn); sens= sens->next; } } void init_sensor(bSensor *sens) { /* also use when sensor changes type */ bNearSensor *ns; bTouchSensor *ts; bKeyboardSensor *ks; bPropertySensor *ps; bMouseSensor *ms; if(sens->data) freeN(sens->data); sens->data= NULL; switch(sens->type) { case SENS_TOUCH: ts=sens->data= callocN(sizeof(bTouchSensor), "touchsens"); break; case SENS_NEAR: ns=sens->data= callocN(sizeof(bNearSensor), "nearsens"); ns->dist= 1.0; ns->resetdist= 2.0; break; case SENS_KEYBOARD: ks=sens->data= callocN(sizeof(bKeyboardSensor), "keysens"); break; case SENS_PROPERTY: ps=sens->data= callocN(sizeof(bPropertySensor), "propsens"); break; case SENS_MOUSE: ms=sens->data= callocN(sizeof(bMouseSensor), "mousesens"); ms->type= LEFTMOUSE; break; case SENS_COLLISION: sens->data= callocN(sizeof(bCollisionSensor), "colsens"); break; case SENS_RADAR: sens->data= callocN(sizeof(bRadarSensor), "radarsens"); break; } } bSensor *new_sensor(int type) { bSensor *sens; sens= callocN(sizeof(bSensor), "Sensor"); sens->type= type; sens->flag= SENS_SHOW; init_sensor(sens); strcpy(sens->name, "sensor"); make_unique_prop_names(sens->name); return sens; } /* ******************* CONTROLLERS ************************ */ void free_controller(bController *cont) { bSensor *sens; Object *ob; int a, removed; /* check for controller pointers in sensors */ ob= G.main->object.first; while(ob) { sens= ob->sensors.first; while(sens) { removed= 0; for(a=0; atotlinks; a++) { if(removed) (sens->links)[a-1] = (sens->links)[a]; else if((sens->links)[a] == cont) removed= 1; } if(removed) { sens->totlinks--; if(sens->totlinks==0) { freeN(sens->links); sens->links= NULL; } } sens= sens->next; } ob= ob->id.next; } if(cont->links) freeN(cont->links); /* the controller itself */ if(cont->data) freeN(cont->data); freeN(cont); } void free_controllers(ListBase *lb) { bController *cont; while((cont= lb->first)) { remlink(lb, cont); if(cont->slinks) freeN(cont->slinks); free_controller(cont); } } bController *copy_controller(bController *cont) { bController *contn; cont->mynew=contn= dupallocN(cont); contn->flag |= CONT_NEW; if(cont->data) { contn->data= dupallocN(cont->data); } if(cont->links) contn->links= dupallocN(cont->links); contn->slinks= NULL; contn->totslinks= 0; return contn; } void copy_controllers(ListBase *lbn, ListBase *lbo) { bController *cont, *contn; lbn->first= lbn->last= 0; cont= lbo->first; while(cont) { contn= copy_controller(cont); addtail(lbn, contn); cont= cont->next; } } void init_controller(bController *cont) { bExpressionCont *ec; /* also use when controller changes type, leave actuators... */ if(cont->data) freeN(cont->data); cont->data= 0; switch(cont->type) { case CONT_EXPRESSION: ec= cont->data= callocN(sizeof(bExpressionCont), "expcont"); break; case CONT_PYTHON: cont->data= callocN(sizeof(bPythonCont), "pycont"); break; } } bController *new_controller(int type) { bController *cont; cont= callocN(sizeof(bController), "Controller"); cont->type= type; cont->flag= CONT_SHOW; init_controller(cont); strcpy(cont->name, "cont"); make_unique_prop_names(cont->name); return cont; } /* ******************* ACTUATORS ************************ */ void free_actuator(bActuator *act) { bController *cont; Object *ob; int a, removed; /* check for actuator pointers in controllers */ ob= G.main->object.first; while(ob) { cont= ob->controllers.first; while(cont) { removed= 0; for(a=0; atotlinks; a++) { if(removed) (cont->links)[a-1] = (cont->links)[a]; else if((cont->links)[a] == act) removed= 1; } if(removed) { cont->totlinks--; if(cont->totlinks==0) { freeN(cont->links); cont->links= NULL; } } cont= cont->next; } ob= ob->id.next; } if(act->data) freeN(act->data); freeN(act); } void free_actuators(ListBase *lb) { bActuator *act; while((act= lb->first)) { remlink(lb, act); free_actuator(act); } } bActuator *copy_actuator(bActuator *act) { bActuator *actn; act->mynew=actn= dupallocN(act); actn->flag |= ACT_NEW; if(act->data) { actn->data= dupallocN(act->data); } return actn; } void copy_actuators(ListBase *lbn, ListBase *lbo) { bActuator *act, *actn; lbn->first= lbn->last= 0; act= lbo->first; while(act) { actn= copy_actuator(act); addtail(lbn, actn); act= act->next; } } void init_actuator(bActuator *act) { /* also use when actuator changes type */ bObjectActuator *oa; if(act->data) freeN(act->data); act->data= 0; switch(act->type) { case ACT_SOUND: act->data= callocN(sizeof(bSoundActuator), "soundact"); break; case ACT_OBJECT: act->data= callocN(sizeof(bObjectActuator), "objectact"); oa= act->data; oa->flag= 15; break; case ACT_IPO: act->data= callocN(sizeof(bIpoActuator), "ipoact"); break; case ACT_PROPERTY: act->data= callocN(sizeof(bPropertyActuator), "propact"); break; case ACT_CAMERA: act->data= callocN(sizeof(bCameraActuator), "camact"); break; case ACT_EDIT_OBJECT: act->data= callocN(sizeof(bEditObjectActuator), "editobact"); break; case ACT_CONSTRAINT: act->data= callocN(sizeof(bConstraintActuator), "cons act"); break; case ACT_SCENE: act->data= callocN(sizeof(bSceneActuator), "scene act"); break; case ACT_GROUP: act->data= callocN(sizeof(bGroupActuator), "group act"); break; } } bActuator *new_actuator(int type) { bActuator *act; act= callocN(sizeof(bActuator), "Actuator"); act->type= type; act->flag= ACT_SHOW; init_actuator(act); strcpy(act->name, "act"); make_unique_prop_names(act->name); return act; } /* ******************** GENERAL ******************* */ void clear_sca_new_poins_ob(Object *ob) { bSensor *sens; bController *cont; bActuator *act; sens= ob->sensors.first; while(sens) { sens->flag &= ~SENS_NEW; sens= sens->next; } cont= ob->controllers.first; while(cont) { cont->mynew= NULL; cont->flag &= ~CONT_NEW; cont= cont->next; } act= ob->actuators.first; while(act) { act->mynew= NULL; act->flag &= ~ACT_NEW; act= act->next; } } void clear_sca_new_poins() { Object *ob; ob= G.main->object.first; while(ob) { clear_sca_new_poins_ob(ob); ob= ob->id.next; } } void set_sca_new_poins_ob(Object *ob) { bSensor *sens; bController *cont; bActuator *act; int a; sens= ob->sensors.first; while(sens) { if(sens->flag & SENS_NEW) { for(a=0; atotlinks; a++) { if(sens->links[a] && sens->links[a]->mynew) sens->links[a]= sens->links[a]->mynew; } } sens= sens->next; } cont= ob->controllers.first; while(cont) { if(cont->flag & CONT_NEW) { for(a=0; atotlinks; a++) { if( cont->links[a] && cont->links[a]->mynew) cont->links[a]= cont->links[a]->mynew; } } cont= cont->next; } act= ob->actuators.first; while(act) { if(act->flag & ACT_NEW) { if(act->type==ACT_EDIT_OBJECT) { bEditObjectActuator *eoa= act->data; ID_NEW(eoa->ob); } else if(act->type==ACT_SCENE) { bSceneActuator *sca= act->data; ID_NEW(sca->camera); } else if(act->type==ACT_CAMERA) { bCameraActuator *ca= act->data; ID_NEW(ca->ob); } else if(act->type==ACT_SCENE) { bSceneActuator *sca= act->data; ID_NEW(sca->camera); } } act= act->next; } } void set_sca_new_poins() { Object *ob; int a; ob= G.main->object.first; while(ob) { set_sca_new_poins_ob(ob); ob= ob->id.next; } } void sca_remove_ob_poin(Object *obt, Object *ob) { bSensor *sens; bActuator *act; bCameraActuator *ca; bSceneActuator *sa; bEditObjectActuator *eoa; bPropertyActuator *pa; act= obt->actuators.first; while(act) { switch(act->type) { case ACT_CAMERA: ca= act->data; if(ca->ob==ob) ca->ob= NULL; break; case ACT_PROPERTY: pa= act->data; if(pa->ob==ob) pa->ob= NULL; break; case ACT_SCENE: sa= act->data; if(sa->camera==ob) sa->camera= NULL; break; case ACT_EDIT_OBJECT: eoa= act->data; if(eoa->ob==ob) eoa->ob= NULL; break; } act= act->next; } }