Blender V2.61 - r43446

sca.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): none yet.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  * these all are linked to objects (listbase)
00027  * all data is 'direct data', not Blender lib data.
00028  */
00029 
00035 #include <stdio.h>
00036 #include <string.h>
00037 #include <float.h>
00038 
00039 #include "MEM_guardedalloc.h"
00040 
00041 #include "DNA_controller_types.h"
00042 #include "DNA_sensor_types.h"
00043 #include "DNA_actuator_types.h"
00044 #include "DNA_object_types.h"
00045 
00046 #include "BLI_blenlib.h"
00047 #include "BKE_utildefines.h"
00048 #include "BKE_global.h"
00049 #include "BKE_main.h"
00050 #include "BKE_library.h"
00051 #include "BKE_sca.h"
00052 
00053 /* ******************* SENSORS ************************ */
00054 
00055 void free_sensor(bSensor *sens)
00056 {
00057     if(sens->links) MEM_freeN(sens->links);
00058     if(sens->data) MEM_freeN(sens->data);
00059     MEM_freeN(sens);
00060     
00061 }
00062 
00063 void free_sensors(ListBase *lb)
00064 {
00065     bSensor *sens;
00066     
00067     while((sens= lb->first)) {
00068         BLI_remlink(lb, sens);
00069         free_sensor(sens);
00070     }
00071 }
00072 
00073 bSensor *copy_sensor(bSensor *sens)
00074 {
00075     bSensor *sensn;
00076     
00077     sensn= MEM_dupallocN(sens);
00078     sensn->flag |= SENS_NEW;
00079     if(sens->data) {
00080         sensn->data= MEM_dupallocN(sens->data);
00081     }
00082 
00083     if(sens->links) sensn->links= MEM_dupallocN(sens->links);
00084     
00085     return sensn;
00086 }
00087 
00088 void copy_sensors(ListBase *lbn, ListBase *lbo)
00089 {
00090     bSensor *sens, *sensn;
00091     
00092     lbn->first= lbn->last= NULL;
00093     sens= lbo->first;
00094     while(sens) {
00095         sensn= copy_sensor(sens);
00096         BLI_addtail(lbn, sensn);
00097         sens= sens->next;
00098     }
00099 }
00100 
00101 void init_sensor(bSensor *sens)
00102 {
00103     /* also use when sensor changes type */
00104     bNearSensor *ns;
00105     bMouseSensor *ms;
00106     bJoystickSensor *js;
00107     bRaySensor *rs;
00108     
00109     if(sens->data) MEM_freeN(sens->data);
00110     sens->data= NULL;
00111     sens->pulse = 0;
00112     
00113     switch(sens->type) {
00114     case SENS_ALWAYS:
00115         sens->pulse = 0;
00116         break;
00117     case SENS_TOUCH:
00118         sens->data= MEM_callocN(sizeof(bTouchSensor), "touchsens");
00119         break;
00120     case SENS_NEAR:
00121         ns=sens->data= MEM_callocN(sizeof(bNearSensor), "nearsens");
00122         ns->dist= 1.0;
00123         ns->resetdist= 2.0;
00124         break;
00125     case SENS_KEYBOARD:
00126         sens->data= MEM_callocN(sizeof(bKeyboardSensor), "keysens");
00127         break;
00128     case SENS_PROPERTY:
00129         sens->data= MEM_callocN(sizeof(bPropertySensor), "propsens");
00130         break;
00131     case SENS_ARMATURE:
00132         sens->data= MEM_callocN(sizeof(bArmatureSensor), "armsens");
00133         break;
00134     case SENS_ACTUATOR:
00135         sens->data= MEM_callocN(sizeof(bActuatorSensor), "actsens");
00136         break;
00137     case SENS_DELAY:
00138         sens->data= MEM_callocN(sizeof(bDelaySensor), "delaysens");
00139         break;
00140     case SENS_MOUSE:
00141         ms=sens->data= MEM_callocN(sizeof(bMouseSensor), "mousesens");
00142         ms->type= 1; // LEFTMOUSE workaround because Mouse Sensor types enum starts in 1
00143         break;
00144     case SENS_COLLISION:
00145         sens->data= MEM_callocN(sizeof(bCollisionSensor), "colsens");
00146         break;
00147     case SENS_RADAR:
00148         sens->data= MEM_callocN(sizeof(bRadarSensor), "radarsens");
00149         break;
00150     case SENS_RANDOM:
00151         sens->data= MEM_callocN(sizeof(bRandomSensor), "randomsens");
00152         break;
00153     case SENS_RAY:
00154         sens->data= MEM_callocN(sizeof(bRaySensor), "raysens");
00155         rs = sens->data;
00156         rs->range = 0.01f;
00157         break;
00158     case SENS_MESSAGE:
00159         sens->data= MEM_callocN(sizeof(bMessageSensor), "messagesens");
00160         break;
00161     case SENS_JOYSTICK:
00162         sens->data= MEM_callocN(sizeof(bJoystickSensor), "joysticksens");
00163         js= sens->data;
00164         js->hatf = SENS_JOY_HAT_UP;
00165         js->axis = 1;
00166         js->hat = 1;
00167         break;
00168     default:
00169         ; /* this is very severe... I cannot make any memory for this        */
00170         /* logic brick...                                                    */
00171     }
00172 }
00173 
00174 bSensor *new_sensor(int type)
00175 {
00176     bSensor *sens;
00177 
00178     sens= MEM_callocN(sizeof(bSensor), "Sensor");
00179     sens->type= type;
00180     sens->flag= SENS_SHOW;
00181     
00182     init_sensor(sens);
00183     
00184     strcpy(sens->name, "sensor");
00185 // XXX  make_unique_prop_names(sens->name);
00186     
00187     return sens;
00188 }
00189 
00190 /* ******************* CONTROLLERS ************************ */
00191 
00192 void unlink_controller(bController *cont)
00193 {
00194     bSensor *sens;
00195     Object *ob;
00196     
00197     /* check for controller pointers in sensors */
00198     ob= G.main->object.first;
00199     while(ob) {
00200         sens= ob->sensors.first;
00201         while(sens) {
00202             unlink_logicbricks((void **)&cont, (void ***)&(sens->links), &sens->totlinks);
00203             sens= sens->next;
00204         }
00205         ob= ob->id.next;
00206     }
00207 }
00208 
00209 void unlink_controllers(ListBase *lb)
00210 {
00211     bController *cont;
00212     
00213     for (cont= lb->first; cont; cont= cont->next)
00214         unlink_controller(cont);    
00215 }
00216 
00217 void free_controller(bController *cont)
00218 {
00219     if(cont->links) MEM_freeN(cont->links);
00220 
00221     /* the controller itself */
00222     if(cont->data) MEM_freeN(cont->data);
00223     MEM_freeN(cont);
00224     
00225 }
00226 
00227 void free_controllers(ListBase *lb)
00228 {
00229     bController *cont;
00230     
00231     while((cont= lb->first)) {
00232         BLI_remlink(lb, cont);
00233         if(cont->slinks) MEM_freeN(cont->slinks);
00234         free_controller(cont);
00235     }
00236 }
00237 
00238 bController *copy_controller(bController *cont)
00239 {
00240     bController *contn;
00241     
00242     cont->mynew=contn= MEM_dupallocN(cont);
00243     contn->flag |= CONT_NEW;
00244     if(cont->data) {
00245         contn->data= MEM_dupallocN(cont->data);
00246     }
00247 
00248     if(cont->links) contn->links= MEM_dupallocN(cont->links);
00249     contn->slinks= NULL;
00250     contn->totslinks= 0;
00251     
00252     return contn;
00253 }
00254 
00255 void copy_controllers(ListBase *lbn, ListBase *lbo)
00256 {
00257     bController *cont, *contn;
00258     
00259     lbn->first= lbn->last= NULL;
00260     cont= lbo->first;
00261     while(cont) {
00262         contn= copy_controller(cont);
00263         BLI_addtail(lbn, contn);
00264         cont= cont->next;
00265     }
00266 }
00267 
00268 void init_controller(bController *cont)
00269 {
00270     /* also use when controller changes type, leave actuators... */
00271     
00272     if(cont->data) MEM_freeN(cont->data);
00273     cont->data= NULL;
00274     
00275     switch(cont->type) {
00276     case CONT_EXPRESSION:
00277         cont->data= MEM_callocN(sizeof(bExpressionCont), "expcont");
00278         break;
00279     case CONT_PYTHON:
00280         cont->data= MEM_callocN(sizeof(bPythonCont), "pycont");
00281         break;
00282     }
00283 }
00284 
00285 bController *new_controller(int type)
00286 {
00287     bController *cont;
00288 
00289     cont= MEM_callocN(sizeof(bController), "Controller");
00290     cont->type= type;
00291     cont->flag= CONT_SHOW;
00292 
00293     init_controller(cont);
00294     
00295     strcpy(cont->name, "cont");
00296 // XXX  make_unique_prop_names(cont->name);
00297     
00298     return cont;
00299 }
00300 
00301 /* ******************* ACTUATORS ************************ */
00302 
00303 void unlink_actuator(bActuator *act)
00304 {
00305     bController *cont;
00306     Object *ob;
00307     
00308     /* check for actuator pointers in controllers */
00309     ob= G.main->object.first;
00310     while(ob) {
00311         cont= ob->controllers.first;
00312         while(cont) {
00313             unlink_logicbricks((void **)&act, (void ***)&(cont->links), &cont->totlinks);
00314             cont= cont->next;
00315         }
00316         ob= ob->id.next;
00317     }
00318 }
00319 
00320 void unlink_actuators(ListBase *lb)
00321 {
00322     bActuator *act;
00323     
00324     for (act= lb->first; act; act= act->next)
00325         unlink_actuator(act);
00326 }
00327 
00328 void free_actuator(bActuator *act)
00329 {
00330     bSoundActuator *sa;
00331 
00332     if(act->data) {
00333         switch (act->type) {
00334         case ACT_SOUND:
00335             sa = (bSoundActuator *) act->data;
00336             if(sa->sound)
00337                 id_us_min((ID *) sa->sound);
00338             break;
00339         }
00340 
00341         MEM_freeN(act->data);
00342     }
00343     MEM_freeN(act);
00344 }
00345 
00346 void free_actuators(ListBase *lb)
00347 {
00348     bActuator *act;
00349     
00350     while((act= lb->first)) {
00351         BLI_remlink(lb, act);
00352         free_actuator(act);
00353     }
00354 }
00355 
00356 bActuator *copy_actuator(bActuator *act)
00357 {
00358     bActuator *actn;
00359     bSoundActuator *sa;
00360     
00361     act->mynew=actn= MEM_dupallocN(act);
00362     actn->flag |= ACT_NEW;
00363     if(act->data) {
00364         actn->data= MEM_dupallocN(act->data);
00365     }
00366     
00367     switch (act->type) {
00368         case ACT_SOUND:
00369             sa= (bSoundActuator *)act->data;
00370             if(sa->sound)
00371                 id_us_plus((ID *) sa->sound);
00372             break;
00373     }
00374     return actn;
00375 }
00376 
00377 void copy_actuators(ListBase *lbn, ListBase *lbo)
00378 {
00379     bActuator *act, *actn;
00380     
00381     lbn->first= lbn->last= NULL;
00382     act= lbo->first;
00383     while(act) {
00384         actn= copy_actuator(act);
00385         BLI_addtail(lbn, actn);
00386         act= act->next;
00387     }
00388 }
00389 
00390 void init_actuator(bActuator *act)
00391 {
00392     /* also use when actuator changes type */
00393     bCameraActuator *ca;
00394     bObjectActuator *oa;
00395     bRandomActuator *ra;
00396     bSoundActuator *sa;
00397     bSteeringActuator *sta;
00398     
00399     if(act->data) MEM_freeN(act->data);
00400     act->data= NULL;
00401     
00402     switch(act->type) {
00403     case ACT_ACTION:
00404     case ACT_SHAPEACTION:
00405         act->data= MEM_callocN(sizeof(bActionActuator), "actionact");
00406         break;
00407     case ACT_SOUND:
00408         sa = act->data= MEM_callocN(sizeof(bSoundActuator), "soundact");
00409         sa->volume = 1.0f;
00410         sa->sound3D.rolloff_factor = 1.0f;
00411         sa->sound3D.reference_distance = 1.0f;
00412         sa->sound3D.max_gain = 1.0f;
00413         sa->sound3D.cone_inner_angle = 360.0f;
00414         sa->sound3D.cone_outer_angle = 360.0f;
00415         sa->sound3D.max_distance = FLT_MAX;
00416         break;
00417     case ACT_OBJECT:
00418         act->data= MEM_callocN(sizeof(bObjectActuator), "objectact");
00419         oa= act->data;
00420         oa->flag= 15;
00421         break;
00422     case ACT_IPO:
00423         act->data= MEM_callocN(sizeof(bIpoActuator), "ipoact");
00424         break;
00425     case ACT_PROPERTY:
00426         act->data= MEM_callocN(sizeof(bPropertyActuator), "propact");
00427         break;
00428     case ACT_CAMERA:
00429         act->data= MEM_callocN(sizeof(bCameraActuator), "camact");
00430         ca = act->data;
00431         ca->axis = OB_POSX;
00432         ca->damping = 1.0/32.0;
00433         break;
00434     case ACT_EDIT_OBJECT:
00435         act->data= MEM_callocN(sizeof(bEditObjectActuator), "editobact");
00436         break;
00437     case ACT_CONSTRAINT:
00438         act->data= MEM_callocN(sizeof(bConstraintActuator), "cons act");
00439         break;
00440     case ACT_SCENE:
00441         act->data= MEM_callocN(sizeof(bSceneActuator), "scene act");
00442         break;
00443     case ACT_GROUP:
00444         act->data= MEM_callocN(sizeof(bGroupActuator), "group act");
00445         break;
00446     case ACT_RANDOM:
00447         act->data= MEM_callocN(sizeof(bRandomActuator), "random act");
00448         ra=act->data;
00449         ra->float_arg_1 = 0.1f;
00450         break;
00451     case ACT_MESSAGE:
00452         act->data= MEM_callocN(sizeof(bMessageActuator), "message act");
00453         break;
00454     case ACT_GAME:
00455         act->data= MEM_callocN(sizeof(bGameActuator), "game act");
00456         break;
00457     case ACT_VISIBILITY:
00458         act->data= MEM_callocN(sizeof(bVisibilityActuator), "visibility act");
00459         break;
00460     case ACT_2DFILTER:
00461         act->data = MEM_callocN(sizeof( bTwoDFilterActuator ), "2d filter act");
00462         break;
00463     case ACT_PARENT:
00464         act->data = MEM_callocN(sizeof( bParentActuator ), "parent act");
00465         break;
00466     case ACT_STATE:
00467         act->data = MEM_callocN(sizeof( bStateActuator ), "state act");
00468         break;
00469     case ACT_ARMATURE:
00470         act->data = MEM_callocN(sizeof( bArmatureActuator ), "armature act");
00471         break;
00472     case ACT_STEERING:
00473         act->data = MEM_callocN(sizeof( bSteeringActuator), "steering act");
00474         sta = act->data;
00475         sta->acceleration = 3.f;
00476         sta->turnspeed = 120.f;
00477         sta->dist = 1.f;
00478         sta->velocity= 3.f;
00479         sta->flag = ACT_STEERING_AUTOMATICFACING;
00480         sta->facingaxis = 1;
00481         break;
00482     default:
00483         ; /* this is very severe... I cannot make any memory for this        */
00484         /* logic brick...                                                    */
00485     }
00486 }
00487 
00488 bActuator *new_actuator(int type)
00489 {
00490     bActuator *act;
00491 
00492     act= MEM_callocN(sizeof(bActuator), "Actuator");
00493     act->type= type;
00494     act->flag= ACT_SHOW;
00495     
00496     init_actuator(act);
00497     
00498     strcpy(act->name, "act");
00499 // XXX  make_unique_prop_names(act->name);
00500     
00501     return act;
00502 }
00503 
00504 /* ******************** GENERAL ******************* */
00505 void clear_sca_new_poins_ob(Object *ob)
00506 {
00507     bSensor *sens;
00508     bController *cont;
00509     bActuator *act;
00510     
00511     sens= ob->sensors.first;
00512     while(sens) {
00513         sens->flag &= ~SENS_NEW;
00514         sens= sens->next;
00515     }
00516     cont= ob->controllers.first;
00517     while(cont) {
00518         cont->mynew= NULL;
00519         cont->flag &= ~CONT_NEW;
00520         cont= cont->next;
00521     }
00522     act= ob->actuators.first;
00523     while(act) {
00524         act->mynew= NULL;
00525         act->flag &= ~ACT_NEW;
00526         act= act->next;
00527     }
00528 }
00529 
00530 void clear_sca_new_poins(void)
00531 {
00532     Object *ob;
00533     
00534     ob= G.main->object.first;
00535     while(ob) {
00536         clear_sca_new_poins_ob(ob);
00537         ob= ob->id.next;    
00538     }
00539 }
00540 
00541 void set_sca_new_poins_ob(Object *ob)
00542 {
00543     bSensor *sens;
00544     bController *cont;
00545     bActuator *act;
00546     int a;
00547     
00548     sens= ob->sensors.first;
00549     while(sens) {
00550         if(sens->flag & SENS_NEW) {
00551             for(a=0; a<sens->totlinks; a++) {
00552                 if(sens->links[a] && sens->links[a]->mynew)
00553                     sens->links[a]= sens->links[a]->mynew;
00554             }
00555         }
00556         sens= sens->next;
00557     }
00558 
00559     cont= ob->controllers.first;
00560     while(cont) {
00561         if(cont->flag & CONT_NEW) {
00562             for(a=0; a<cont->totlinks; a++) {
00563                 if( cont->links[a] && cont->links[a]->mynew)
00564                     cont->links[a]= cont->links[a]->mynew;
00565             }
00566         }
00567         cont= cont->next;
00568     }
00569     
00570     
00571     act= ob->actuators.first;
00572     while(act) {
00573         if(act->flag & ACT_NEW) {
00574             if(act->type==ACT_EDIT_OBJECT) {
00575                 bEditObjectActuator *eoa= act->data;
00576                 ID_NEW(eoa->ob);
00577             }
00578             else if(act->type==ACT_SCENE) {
00579                 bSceneActuator *sca= act->data;
00580                 ID_NEW(sca->camera);
00581             }
00582             else if(act->type==ACT_CAMERA) {
00583                 bCameraActuator *ca= act->data;
00584                 ID_NEW(ca->ob);
00585             }
00586             else if(act->type==ACT_OBJECT) {
00587                 bObjectActuator *oa= act->data;
00588                 ID_NEW(oa->reference);
00589             }
00590             else if(act->type==ACT_MESSAGE) {
00591                 bMessageActuator *ma= act->data;
00592                 ID_NEW(ma->toObject);
00593             }
00594             else if(act->type==ACT_PARENT) {
00595                 bParentActuator *para = act->data;
00596                 ID_NEW(para->ob);
00597             }
00598             else if(act->type==ACT_ARMATURE) {
00599                 bArmatureActuator *aa = act->data;
00600                 ID_NEW(aa->target);
00601                 ID_NEW(aa->subtarget);
00602             }
00603             else if(act->type==ACT_PROPERTY) {
00604                 bPropertyActuator *pa= act->data;
00605                 ID_NEW(pa->ob);
00606             }
00607             else if(act->type==ACT_STEERING) {
00608                 bSteeringActuator *sta = act->data;
00609                 ID_NEW(sta->navmesh);
00610                 ID_NEW(sta->target);
00611             }
00612         }
00613         act= act->next;
00614     }
00615 }
00616 
00617 
00618 void set_sca_new_poins(void)
00619 {
00620     Object *ob;
00621     
00622     ob= G.main->object.first;
00623     while(ob) {
00624         set_sca_new_poins_ob(ob);
00625         ob= ob->id.next;    
00626     }
00627 }
00628 
00629 void sca_remove_ob_poin(Object *obt, Object *ob)
00630 {
00631     bSensor *sens;
00632     bMessageSensor *ms;
00633     bActuator *act;
00634     bCameraActuator *ca;
00635     bObjectActuator *oa;
00636     bSceneActuator *sa;
00637     bEditObjectActuator *eoa;
00638     bPropertyActuator *pa;
00639     bMessageActuator *ma;
00640     bParentActuator *para;
00641     bArmatureActuator *aa;
00642     bSteeringActuator *sta;
00643 
00644 
00645     sens= obt->sensors.first;
00646     while(sens) {
00647         switch(sens->type) {
00648         case SENS_MESSAGE:
00649             ms= sens->data;
00650             if(ms->fromObject==ob) ms->fromObject= NULL;
00651         }
00652         sens= sens->next;
00653     }
00654 
00655     act= obt->actuators.first;
00656     while(act) {
00657         switch(act->type) {
00658         case ACT_CAMERA:
00659             ca= act->data;
00660             if(ca->ob==ob) ca->ob= NULL;
00661             break;
00662         case ACT_OBJECT:
00663             oa= act->data;
00664             if(oa->reference==ob) oa->reference= NULL;
00665             break;
00666         case ACT_PROPERTY:
00667             pa= act->data;
00668             if(pa->ob==ob) pa->ob= NULL;
00669             break;
00670         case ACT_SCENE:
00671             sa= act->data;
00672             if(sa->camera==ob) sa->camera= NULL;
00673             break;
00674         case ACT_EDIT_OBJECT:
00675             eoa= act->data;
00676             if(eoa->ob==ob) eoa->ob= NULL;
00677             break;
00678         case ACT_MESSAGE:
00679             ma= act->data;
00680             if(ma->toObject==ob) ma->toObject= NULL;
00681             break;
00682         case ACT_PARENT:
00683             para = act->data;
00684             if (para->ob==ob) para->ob = NULL;
00685             break;
00686         case ACT_ARMATURE:
00687             aa = act->data;
00688             if (aa->target == ob) aa->target = NULL;
00689             if (aa->subtarget == ob) aa->subtarget = NULL;
00690             break;
00691         case ACT_STEERING:
00692             sta = act->data;
00693             if (sta->navmesh == ob) sta->navmesh = NULL;
00694             if (sta->target == ob) sta->target = NULL;
00695         }
00696         act= act->next;
00697     }   
00698 }
00699 
00700 /* ******************** INTERFACE ******************* */
00701 void sca_move_sensor(bSensor *sens_to_move, Object *ob, int move_up)
00702 {
00703     bSensor *sens, *tmp;
00704 
00705     int val;
00706     val = move_up ? 1:2;
00707 
00708     /* make sure this sensor belongs to this object */
00709     sens= ob->sensors.first;
00710     while(sens) {
00711         if(sens == sens_to_move) break;
00712         sens= sens->next;
00713     }
00714     if(!sens) return;
00715 
00716     /* move up */
00717     if( val==1 && sens->prev) {
00718         for (tmp=sens->prev; tmp; tmp=tmp->prev) {
00719             if (tmp->flag & SENS_VISIBLE)
00720                 break;
00721         }
00722         if (tmp) {
00723             BLI_remlink(&ob->sensors, sens);
00724             BLI_insertlinkbefore(&ob->sensors, tmp, sens);
00725         }
00726     }
00727     /* move down */
00728     else if( val==2 && sens->next) {
00729         for (tmp=sens->next; tmp; tmp=tmp->next) {
00730             if (tmp->flag & SENS_VISIBLE)
00731                 break;
00732         }
00733         if (tmp) {
00734             BLI_remlink(&ob->sensors, sens);
00735             BLI_insertlink(&ob->sensors, tmp, sens);
00736         }
00737     }
00738 }
00739 
00740 void sca_move_controller(bController *cont_to_move, Object *ob, int move_up)
00741 {
00742     bController *cont, *tmp;
00743 
00744     int val;
00745     val = move_up ? 1:2;
00746 
00747     /* make sure this controller belongs to this object */
00748     cont= ob->controllers.first;
00749     while(cont) {
00750         if(cont == cont_to_move) break;
00751         cont= cont->next;
00752     }
00753     if(!cont) return;
00754 
00755     /* move up */
00756     if( val==1 && cont->prev) {
00757         /* locate the controller that has the same state mask but is earlier in the list */
00758         tmp = cont->prev;
00759         while(tmp) {
00760             if(tmp->state_mask & cont->state_mask) 
00761                 break;
00762             tmp = tmp->prev;
00763         }
00764         if (tmp) {
00765             BLI_remlink(&ob->controllers, cont);
00766             BLI_insertlinkbefore(&ob->controllers, tmp, cont);
00767         }
00768     }
00769 
00770     /* move down */
00771     else if( val==2 && cont->next) {
00772         tmp = cont->next;
00773         while(tmp) {
00774             if(tmp->state_mask & cont->state_mask) 
00775                 break;
00776             tmp = tmp->next;
00777         }
00778         BLI_remlink(&ob->controllers, cont);
00779         BLI_insertlink(&ob->controllers, tmp, cont);
00780     }
00781 }
00782 
00783 void sca_move_actuator(bActuator *act_to_move, Object *ob, int move_up)
00784 {
00785     bActuator *act, *tmp;
00786     int val;
00787 
00788     val = move_up ? 1:2;
00789 
00790     /* make sure this actuator belongs to this object */
00791     act= ob->actuators.first;
00792     while(act) {
00793         if(act == act_to_move) break;
00794         act= act->next;
00795     }
00796     if(!act) return;
00797 
00798     /* move up */
00799     if( val==1 && act->prev) {
00800         /* locate the first visible actuators before this one */
00801         for (tmp = act->prev; tmp; tmp=tmp->prev) {
00802             if (tmp->flag & ACT_VISIBLE)
00803                 break;
00804         }
00805         if (tmp) {
00806             BLI_remlink(&ob->actuators, act);
00807             BLI_insertlinkbefore(&ob->actuators, tmp, act);
00808         }
00809     }
00810     /* move down */
00811     else if( val==2 && act->next) {
00812         /* locate the first visible actuators after this one */
00813         for (tmp=act->next; tmp; tmp=tmp->next) {
00814             if (tmp->flag & ACT_VISIBLE)
00815                 break;
00816         }
00817         if (tmp) {
00818             BLI_remlink(&ob->actuators, act);
00819             BLI_insertlink(&ob->actuators, tmp, act);
00820         }
00821     }
00822 }
00823 
00824 void link_logicbricks(void **poin, void ***ppoin, short *tot, short size)
00825 {
00826     void **old_links= NULL;
00827     
00828     int ibrick;
00829 
00830     /* check if the bricks are already linked */
00831     for (ibrick=0; ibrick < *tot; ibrick++) {
00832         if ((*ppoin)[ibrick] == *poin)
00833             return;
00834     }
00835 
00836     if (*ppoin) {
00837         old_links= *ppoin;
00838 
00839         (*tot) ++;
00840         *ppoin = MEM_callocN((*tot)*size, "new link");
00841     
00842         for (ibrick=0; ibrick < *(tot) - 1; ibrick++) {
00843             (*ppoin)[ibrick] = old_links[ibrick];
00844         }
00845         (*ppoin)[ibrick] = *poin;
00846 
00847         if(old_links) MEM_freeN(old_links);
00848     }
00849     else {
00850         (*tot) = 1;
00851         *ppoin = MEM_callocN((*tot)*size, "new link");
00852         (*ppoin)[0] = *poin;
00853     }
00854 }
00855 
00856 void unlink_logicbricks(void **poin, void ***ppoin, short *tot)
00857 {
00858     int ibrick, removed;
00859 
00860     removed= 0;
00861     for (ibrick=0; ibrick < *tot; ibrick++) {
00862         if(removed) (*ppoin)[ibrick - removed] = (*ppoin)[ibrick];
00863         else if((*ppoin)[ibrick] == *poin) removed = 1;
00864     }
00865 
00866     if (removed) {
00867         (*tot) --;
00868 
00869         if(*tot == 0) {
00870             MEM_freeN(*ppoin);
00871             (*ppoin)= NULL;
00872         }
00873         return;
00874     }
00875 }