891 lines
19 KiB
C
891 lines
19 KiB
C
/*
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
* All rights reserved.
|
|
*
|
|
* The Original Code is: all of this file.
|
|
*
|
|
* Contributor(s): none yet.
|
|
*
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
* these all are linked to objects (listbase)
|
|
* all data is 'direct data', not Blender lib data.
|
|
*/
|
|
|
|
/** \file blender/blenkernel/intern/sca.c
|
|
* \ingroup bke
|
|
*/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <float.h>
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
#include "DNA_controller_types.h"
|
|
#include "DNA_sensor_types.h"
|
|
#include "DNA_actuator_types.h"
|
|
#include "DNA_object_types.h"
|
|
|
|
#include "BLI_blenlib.h"
|
|
#include "BLI_math.h"
|
|
#include "BKE_global.h"
|
|
#include "BKE_main.h"
|
|
#include "BKE_library.h"
|
|
#include "BKE_sca.h"
|
|
|
|
/* ******************* SENSORS ************************ */
|
|
|
|
void free_sensor(bSensor *sens)
|
|
{
|
|
if (sens->links) MEM_freeN(sens->links);
|
|
if (sens->data) MEM_freeN(sens->data);
|
|
MEM_freeN(sens);
|
|
|
|
}
|
|
|
|
void free_sensors(ListBase *lb)
|
|
{
|
|
bSensor *sens;
|
|
|
|
while ((sens = BLI_pophead(lb))) {
|
|
free_sensor(sens);
|
|
}
|
|
}
|
|
|
|
bSensor *copy_sensor(bSensor *sens)
|
|
{
|
|
bSensor *sensn;
|
|
|
|
sensn= MEM_dupallocN(sens);
|
|
sensn->flag |= SENS_NEW;
|
|
if (sens->data) {
|
|
sensn->data= MEM_dupallocN(sens->data);
|
|
}
|
|
|
|
if (sens->links) sensn->links= MEM_dupallocN(sens->links);
|
|
|
|
return sensn;
|
|
}
|
|
|
|
void copy_sensors(ListBase *lbn, ListBase *lbo)
|
|
{
|
|
bSensor *sens, *sensn;
|
|
|
|
lbn->first= lbn->last= NULL;
|
|
sens= lbo->first;
|
|
while (sens) {
|
|
sensn= copy_sensor(sens);
|
|
BLI_addtail(lbn, sensn);
|
|
sens= sens->next;
|
|
}
|
|
}
|
|
|
|
void init_sensor(bSensor *sens)
|
|
{
|
|
/* also use when sensor changes type */
|
|
bNearSensor *ns;
|
|
bMouseSensor *ms;
|
|
bJoystickSensor *js;
|
|
bRaySensor *rs;
|
|
|
|
if (sens->data) MEM_freeN(sens->data);
|
|
sens->data= NULL;
|
|
sens->pulse = 0;
|
|
|
|
switch (sens->type) {
|
|
case SENS_ALWAYS:
|
|
sens->pulse = 0;
|
|
break;
|
|
case SENS_NEAR:
|
|
ns=sens->data= MEM_callocN(sizeof(bNearSensor), "nearsens");
|
|
ns->dist= 1.0;
|
|
ns->resetdist= 2.0;
|
|
break;
|
|
case SENS_KEYBOARD:
|
|
sens->data= MEM_callocN(sizeof(bKeyboardSensor), "keysens");
|
|
break;
|
|
case SENS_PROPERTY:
|
|
sens->data= MEM_callocN(sizeof(bPropertySensor), "propsens");
|
|
break;
|
|
case SENS_ARMATURE:
|
|
sens->data= MEM_callocN(sizeof(bArmatureSensor), "armsens");
|
|
break;
|
|
case SENS_ACTUATOR:
|
|
sens->data= MEM_callocN(sizeof(bActuatorSensor), "actsens");
|
|
break;
|
|
case SENS_DELAY:
|
|
sens->data= MEM_callocN(sizeof(bDelaySensor), "delaysens");
|
|
break;
|
|
case SENS_MOUSE:
|
|
ms=sens->data= MEM_callocN(sizeof(bMouseSensor), "mousesens");
|
|
ms->type= 1; // LEFTMOUSE workaround because Mouse Sensor types enum starts in 1
|
|
break;
|
|
case SENS_COLLISION:
|
|
sens->data= MEM_callocN(sizeof(bCollisionSensor), "colsens");
|
|
break;
|
|
case SENS_RADAR:
|
|
sens->data= MEM_callocN(sizeof(bRadarSensor), "radarsens");
|
|
break;
|
|
case SENS_RANDOM:
|
|
sens->data= MEM_callocN(sizeof(bRandomSensor), "randomsens");
|
|
break;
|
|
case SENS_RAY:
|
|
sens->data= MEM_callocN(sizeof(bRaySensor), "raysens");
|
|
rs = sens->data;
|
|
rs->range = 0.01f;
|
|
break;
|
|
case SENS_MESSAGE:
|
|
sens->data= MEM_callocN(sizeof(bMessageSensor), "messagesens");
|
|
break;
|
|
case SENS_JOYSTICK:
|
|
sens->data= MEM_callocN(sizeof(bJoystickSensor), "joysticksens");
|
|
js= sens->data;
|
|
js->hatf = SENS_JOY_HAT_UP;
|
|
js->axis = 1;
|
|
js->hat = 1;
|
|
break;
|
|
default:
|
|
; /* this is very severe... I cannot make any memory for this */
|
|
/* logic brick... */
|
|
}
|
|
}
|
|
|
|
bSensor *new_sensor(int type)
|
|
{
|
|
bSensor *sens;
|
|
|
|
sens= MEM_callocN(sizeof(bSensor), "Sensor");
|
|
sens->type= type;
|
|
sens->flag= SENS_SHOW;
|
|
|
|
init_sensor(sens);
|
|
|
|
strcpy(sens->name, "sensor");
|
|
// XXX make_unique_prop_names(sens->name);
|
|
|
|
return sens;
|
|
}
|
|
|
|
/* ******************* CONTROLLERS ************************ */
|
|
|
|
void unlink_controller(bController *cont)
|
|
{
|
|
bSensor *sens;
|
|
Object *ob;
|
|
|
|
/* check for controller pointers in sensors */
|
|
ob= G.main->object.first;
|
|
while (ob) {
|
|
sens= ob->sensors.first;
|
|
while (sens) {
|
|
unlink_logicbricks((void **)&cont, (void ***)&(sens->links), &sens->totlinks);
|
|
sens= sens->next;
|
|
}
|
|
ob= ob->id.next;
|
|
}
|
|
}
|
|
|
|
void unlink_controllers(ListBase *lb)
|
|
{
|
|
bController *cont;
|
|
|
|
for (cont= lb->first; cont; cont= cont->next)
|
|
unlink_controller(cont);
|
|
}
|
|
|
|
void free_controller(bController *cont)
|
|
{
|
|
if (cont->links) MEM_freeN(cont->links);
|
|
|
|
/* the controller itself */
|
|
if (cont->data) MEM_freeN(cont->data);
|
|
MEM_freeN(cont);
|
|
|
|
}
|
|
|
|
void free_controllers(ListBase *lb)
|
|
{
|
|
bController *cont;
|
|
|
|
while ((cont = BLI_pophead(lb))) {
|
|
if (cont->slinks)
|
|
MEM_freeN(cont->slinks);
|
|
free_controller(cont);
|
|
}
|
|
}
|
|
|
|
bController *copy_controller(bController *cont)
|
|
{
|
|
bController *contn;
|
|
|
|
cont->mynew=contn= MEM_dupallocN(cont);
|
|
contn->flag |= CONT_NEW;
|
|
if (cont->data) {
|
|
contn->data= MEM_dupallocN(cont->data);
|
|
}
|
|
|
|
if (cont->links) contn->links= MEM_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= NULL;
|
|
cont= lbo->first;
|
|
while (cont) {
|
|
contn= copy_controller(cont);
|
|
BLI_addtail(lbn, contn);
|
|
cont= cont->next;
|
|
}
|
|
}
|
|
|
|
void init_controller(bController *cont)
|
|
{
|
|
/* also use when controller changes type, leave actuators... */
|
|
|
|
if (cont->data) MEM_freeN(cont->data);
|
|
cont->data= NULL;
|
|
|
|
switch (cont->type) {
|
|
case CONT_EXPRESSION:
|
|
cont->data= MEM_callocN(sizeof(bExpressionCont), "expcont");
|
|
break;
|
|
case CONT_PYTHON:
|
|
cont->data= MEM_callocN(sizeof(bPythonCont), "pycont");
|
|
break;
|
|
}
|
|
}
|
|
|
|
bController *new_controller(int type)
|
|
{
|
|
bController *cont;
|
|
|
|
cont= MEM_callocN(sizeof(bController), "Controller");
|
|
cont->type= type;
|
|
cont->flag= CONT_SHOW;
|
|
|
|
init_controller(cont);
|
|
|
|
strcpy(cont->name, "cont");
|
|
// XXX make_unique_prop_names(cont->name);
|
|
|
|
return cont;
|
|
}
|
|
|
|
/* ******************* ACTUATORS ************************ */
|
|
|
|
void unlink_actuator(bActuator *act)
|
|
{
|
|
bController *cont;
|
|
Object *ob;
|
|
|
|
/* check for actuator pointers in controllers */
|
|
ob= G.main->object.first;
|
|
while (ob) {
|
|
cont= ob->controllers.first;
|
|
while (cont) {
|
|
unlink_logicbricks((void **)&act, (void ***)&(cont->links), &cont->totlinks);
|
|
cont= cont->next;
|
|
}
|
|
ob= ob->id.next;
|
|
}
|
|
}
|
|
|
|
void unlink_actuators(ListBase *lb)
|
|
{
|
|
bActuator *act;
|
|
|
|
for (act= lb->first; act; act= act->next)
|
|
unlink_actuator(act);
|
|
}
|
|
|
|
void free_actuator(bActuator *act)
|
|
{
|
|
bSoundActuator *sa;
|
|
|
|
if (act->data) {
|
|
switch (act->type) {
|
|
case ACT_SOUND:
|
|
sa = (bSoundActuator *) act->data;
|
|
if (sa->sound)
|
|
id_us_min((ID *) sa->sound);
|
|
break;
|
|
}
|
|
|
|
MEM_freeN(act->data);
|
|
}
|
|
MEM_freeN(act);
|
|
}
|
|
|
|
void free_actuators(ListBase *lb)
|
|
{
|
|
bActuator *act;
|
|
|
|
while ((act = BLI_pophead(lb))) {
|
|
free_actuator(act);
|
|
}
|
|
}
|
|
|
|
bActuator *copy_actuator(bActuator *act)
|
|
{
|
|
bActuator *actn;
|
|
bSoundActuator *sa;
|
|
|
|
act->mynew=actn= MEM_dupallocN(act);
|
|
actn->flag |= ACT_NEW;
|
|
if (act->data) {
|
|
actn->data= MEM_dupallocN(act->data);
|
|
}
|
|
|
|
switch (act->type) {
|
|
case ACT_SOUND:
|
|
sa= (bSoundActuator *)act->data;
|
|
if (sa->sound)
|
|
id_us_plus((ID *) sa->sound);
|
|
break;
|
|
}
|
|
return actn;
|
|
}
|
|
|
|
void copy_actuators(ListBase *lbn, ListBase *lbo)
|
|
{
|
|
bActuator *act, *actn;
|
|
|
|
lbn->first= lbn->last= NULL;
|
|
act= lbo->first;
|
|
while (act) {
|
|
actn= copy_actuator(act);
|
|
BLI_addtail(lbn, actn);
|
|
act= act->next;
|
|
}
|
|
}
|
|
|
|
void init_actuator(bActuator *act)
|
|
{
|
|
/* also use when actuator changes type */
|
|
bCameraActuator *ca;
|
|
bObjectActuator *oa;
|
|
bRandomActuator *ra;
|
|
bSoundActuator *sa;
|
|
bSteeringActuator *sta;
|
|
bArmatureActuator *arma;
|
|
|
|
if (act->data) MEM_freeN(act->data);
|
|
act->data= NULL;
|
|
|
|
switch (act->type) {
|
|
case ACT_ACTION:
|
|
case ACT_SHAPEACTION:
|
|
act->data= MEM_callocN(sizeof(bActionActuator), "actionact");
|
|
break;
|
|
case ACT_SOUND:
|
|
sa = act->data= MEM_callocN(sizeof(bSoundActuator), "soundact");
|
|
sa->volume = 1.0f;
|
|
sa->sound3D.rolloff_factor = 1.0f;
|
|
sa->sound3D.reference_distance = 1.0f;
|
|
sa->sound3D.max_gain = 1.0f;
|
|
sa->sound3D.cone_inner_angle = DEG2RADF(360.0f);
|
|
sa->sound3D.cone_outer_angle = DEG2RADF(360.0f);
|
|
sa->sound3D.max_distance = FLT_MAX;
|
|
break;
|
|
case ACT_OBJECT:
|
|
act->data= MEM_callocN(sizeof(bObjectActuator), "objectact");
|
|
oa= act->data;
|
|
oa->flag= 15;
|
|
break;
|
|
case ACT_IPO:
|
|
act->data= MEM_callocN(sizeof(bIpoActuator), "ipoact");
|
|
break;
|
|
case ACT_PROPERTY:
|
|
act->data= MEM_callocN(sizeof(bPropertyActuator), "propact");
|
|
break;
|
|
case ACT_CAMERA:
|
|
act->data= MEM_callocN(sizeof(bCameraActuator), "camact");
|
|
ca = act->data;
|
|
ca->axis = OB_POSX;
|
|
ca->damping = 1.0/32.0;
|
|
break;
|
|
case ACT_EDIT_OBJECT:
|
|
act->data= MEM_callocN(sizeof(bEditObjectActuator), "editobact");
|
|
break;
|
|
case ACT_CONSTRAINT:
|
|
act->data= MEM_callocN(sizeof(bConstraintActuator), "cons act");
|
|
break;
|
|
case ACT_SCENE:
|
|
act->data= MEM_callocN(sizeof(bSceneActuator), "scene act");
|
|
break;
|
|
case ACT_GROUP:
|
|
act->data= MEM_callocN(sizeof(bGroupActuator), "group act");
|
|
break;
|
|
case ACT_RANDOM:
|
|
act->data= MEM_callocN(sizeof(bRandomActuator), "random act");
|
|
ra=act->data;
|
|
ra->float_arg_1 = 0.1f;
|
|
break;
|
|
case ACT_MESSAGE:
|
|
act->data= MEM_callocN(sizeof(bMessageActuator), "message act");
|
|
break;
|
|
case ACT_GAME:
|
|
act->data= MEM_callocN(sizeof(bGameActuator), "game act");
|
|
break;
|
|
case ACT_VISIBILITY:
|
|
act->data= MEM_callocN(sizeof(bVisibilityActuator), "visibility act");
|
|
break;
|
|
case ACT_2DFILTER:
|
|
act->data = MEM_callocN(sizeof( bTwoDFilterActuator ), "2d filter act");
|
|
break;
|
|
case ACT_PARENT:
|
|
act->data = MEM_callocN(sizeof( bParentActuator ), "parent act");
|
|
break;
|
|
case ACT_STATE:
|
|
act->data = MEM_callocN(sizeof( bStateActuator ), "state act");
|
|
break;
|
|
case ACT_ARMATURE:
|
|
act->data = MEM_callocN(sizeof( bArmatureActuator ), "armature act");
|
|
arma = act->data;
|
|
arma->influence = 1.f;
|
|
break;
|
|
case ACT_STEERING:
|
|
act->data = MEM_callocN(sizeof( bSteeringActuator), "steering act");
|
|
sta = act->data;
|
|
sta->acceleration = 3.f;
|
|
sta->turnspeed = 120.f;
|
|
sta->dist = 1.f;
|
|
sta->velocity= 3.f;
|
|
sta->flag = ACT_STEERING_AUTOMATICFACING;
|
|
sta->facingaxis = 1;
|
|
break;
|
|
default:
|
|
; /* this is very severe... I cannot make any memory for this */
|
|
/* logic brick... */
|
|
}
|
|
}
|
|
|
|
bActuator *new_actuator(int type)
|
|
{
|
|
bActuator *act;
|
|
|
|
act= MEM_callocN(sizeof(bActuator), "Actuator");
|
|
act->type= type;
|
|
act->flag= ACT_SHOW;
|
|
|
|
init_actuator(act);
|
|
|
|
strcpy(act->name, "act");
|
|
// XXX 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(void)
|
|
{
|
|
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; a<sens->totlinks; 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; a<cont->totlinks; 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_OBJECT) {
|
|
bObjectActuator *oa= act->data;
|
|
ID_NEW(oa->reference);
|
|
}
|
|
else if (act->type==ACT_MESSAGE) {
|
|
bMessageActuator *ma= act->data;
|
|
ID_NEW(ma->toObject);
|
|
}
|
|
else if (act->type==ACT_PARENT) {
|
|
bParentActuator *para = act->data;
|
|
ID_NEW(para->ob);
|
|
}
|
|
else if (act->type==ACT_ARMATURE) {
|
|
bArmatureActuator *aa = act->data;
|
|
ID_NEW(aa->target);
|
|
ID_NEW(aa->subtarget);
|
|
}
|
|
else if (act->type==ACT_PROPERTY) {
|
|
bPropertyActuator *pa= act->data;
|
|
ID_NEW(pa->ob);
|
|
}
|
|
else if (act->type==ACT_STEERING) {
|
|
bSteeringActuator *sta = act->data;
|
|
ID_NEW(sta->navmesh);
|
|
ID_NEW(sta->target);
|
|
}
|
|
}
|
|
act= act->next;
|
|
}
|
|
}
|
|
|
|
|
|
void set_sca_new_poins(void)
|
|
{
|
|
Object *ob;
|
|
|
|
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;
|
|
bMessageSensor *ms;
|
|
bActuator *act;
|
|
bCameraActuator *ca;
|
|
bObjectActuator *oa;
|
|
bSceneActuator *sa;
|
|
bEditObjectActuator *eoa;
|
|
bPropertyActuator *pa;
|
|
bMessageActuator *ma;
|
|
bParentActuator *para;
|
|
bArmatureActuator *aa;
|
|
bSteeringActuator *sta;
|
|
|
|
|
|
sens= obt->sensors.first;
|
|
while (sens) {
|
|
switch (sens->type) {
|
|
case SENS_MESSAGE:
|
|
ms= sens->data;
|
|
if (ms->fromObject==ob) ms->fromObject= NULL;
|
|
}
|
|
sens= sens->next;
|
|
}
|
|
|
|
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_OBJECT:
|
|
oa= act->data;
|
|
if (oa->reference==ob) oa->reference= 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;
|
|
case ACT_MESSAGE:
|
|
ma= act->data;
|
|
if (ma->toObject==ob) ma->toObject= NULL;
|
|
break;
|
|
case ACT_PARENT:
|
|
para = act->data;
|
|
if (para->ob==ob) para->ob = NULL;
|
|
break;
|
|
case ACT_ARMATURE:
|
|
aa = act->data;
|
|
if (aa->target == ob) aa->target = NULL;
|
|
if (aa->subtarget == ob) aa->subtarget = NULL;
|
|
break;
|
|
case ACT_STEERING:
|
|
sta = act->data;
|
|
if (sta->navmesh == ob) sta->navmesh = NULL;
|
|
if (sta->target == ob) sta->target = NULL;
|
|
}
|
|
act= act->next;
|
|
}
|
|
}
|
|
|
|
/* ******************** INTERFACE ******************* */
|
|
void sca_move_sensor(bSensor *sens_to_move, Object *ob, int move_up)
|
|
{
|
|
bSensor *sens, *tmp;
|
|
|
|
int val;
|
|
val = move_up ? 1 : 2;
|
|
|
|
/* make sure this sensor belongs to this object */
|
|
sens= ob->sensors.first;
|
|
while (sens) {
|
|
if (sens == sens_to_move) break;
|
|
sens= sens->next;
|
|
}
|
|
if (!sens) return;
|
|
|
|
/* move up */
|
|
if (val == 1 && sens->prev) {
|
|
for (tmp=sens->prev; tmp; tmp=tmp->prev) {
|
|
if (tmp->flag & SENS_VISIBLE)
|
|
break;
|
|
}
|
|
if (tmp) {
|
|
BLI_remlink(&ob->sensors, sens);
|
|
BLI_insertlinkbefore(&ob->sensors, tmp, sens);
|
|
}
|
|
}
|
|
/* move down */
|
|
else if (val == 2 && sens->next) {
|
|
for (tmp=sens->next; tmp; tmp=tmp->next) {
|
|
if (tmp->flag & SENS_VISIBLE)
|
|
break;
|
|
}
|
|
if (tmp) {
|
|
BLI_remlink(&ob->sensors, sens);
|
|
BLI_insertlinkafter(&ob->sensors, tmp, sens);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sca_move_controller(bController *cont_to_move, Object *ob, int move_up)
|
|
{
|
|
bController *cont, *tmp;
|
|
|
|
int val;
|
|
val = move_up ? 1 : 2;
|
|
|
|
/* make sure this controller belongs to this object */
|
|
cont= ob->controllers.first;
|
|
while (cont) {
|
|
if (cont == cont_to_move) break;
|
|
cont= cont->next;
|
|
}
|
|
if (!cont) return;
|
|
|
|
/* move up */
|
|
if (val == 1 && cont->prev) {
|
|
/* locate the controller that has the same state mask but is earlier in the list */
|
|
tmp = cont->prev;
|
|
while (tmp) {
|
|
if (tmp->state_mask & cont->state_mask)
|
|
break;
|
|
tmp = tmp->prev;
|
|
}
|
|
if (tmp) {
|
|
BLI_remlink(&ob->controllers, cont);
|
|
BLI_insertlinkbefore(&ob->controllers, tmp, cont);
|
|
}
|
|
}
|
|
|
|
/* move down */
|
|
else if (val == 2 && cont->next) {
|
|
tmp = cont->next;
|
|
while (tmp) {
|
|
if (tmp->state_mask & cont->state_mask)
|
|
break;
|
|
tmp = tmp->next;
|
|
}
|
|
BLI_remlink(&ob->controllers, cont);
|
|
BLI_insertlinkafter(&ob->controllers, tmp, cont);
|
|
}
|
|
}
|
|
|
|
void sca_move_actuator(bActuator *act_to_move, Object *ob, int move_up)
|
|
{
|
|
bActuator *act, *tmp;
|
|
int val;
|
|
|
|
val = move_up ? 1 : 2;
|
|
|
|
/* make sure this actuator belongs to this object */
|
|
act= ob->actuators.first;
|
|
while (act) {
|
|
if (act == act_to_move) break;
|
|
act= act->next;
|
|
}
|
|
if (!act) return;
|
|
|
|
/* move up */
|
|
if (val == 1 && act->prev) {
|
|
/* locate the first visible actuators before this one */
|
|
for (tmp = act->prev; tmp; tmp=tmp->prev) {
|
|
if (tmp->flag & ACT_VISIBLE)
|
|
break;
|
|
}
|
|
if (tmp) {
|
|
BLI_remlink(&ob->actuators, act);
|
|
BLI_insertlinkbefore(&ob->actuators, tmp, act);
|
|
}
|
|
}
|
|
/* move down */
|
|
else if (val == 2 && act->next) {
|
|
/* locate the first visible actuators after this one */
|
|
for (tmp=act->next; tmp; tmp=tmp->next) {
|
|
if (tmp->flag & ACT_VISIBLE)
|
|
break;
|
|
}
|
|
if (tmp) {
|
|
BLI_remlink(&ob->actuators, act);
|
|
BLI_insertlinkafter(&ob->actuators, tmp, act);
|
|
}
|
|
}
|
|
}
|
|
|
|
void link_logicbricks(void **poin, void ***ppoin, short *tot, short size)
|
|
{
|
|
void **old_links= NULL;
|
|
|
|
int ibrick;
|
|
|
|
/* check if the bricks are already linked */
|
|
for (ibrick=0; ibrick < *tot; ibrick++) {
|
|
if ((*ppoin)[ibrick] == *poin)
|
|
return;
|
|
}
|
|
|
|
if (*ppoin) {
|
|
old_links= *ppoin;
|
|
|
|
(*tot) ++;
|
|
*ppoin = MEM_callocN((*tot)*size, "new link");
|
|
|
|
for (ibrick=0; ibrick < *(tot) - 1; ibrick++) {
|
|
(*ppoin)[ibrick] = old_links[ibrick];
|
|
}
|
|
(*ppoin)[ibrick] = *poin;
|
|
|
|
if (old_links) MEM_freeN(old_links);
|
|
}
|
|
else {
|
|
(*tot) = 1;
|
|
*ppoin = MEM_callocN((*tot)*size, "new link");
|
|
(*ppoin)[0] = *poin;
|
|
}
|
|
}
|
|
|
|
void unlink_logicbricks(void **poin, void ***ppoin, short *tot)
|
|
{
|
|
int ibrick, removed;
|
|
|
|
removed= 0;
|
|
for (ibrick=0; ibrick < *tot; ibrick++) {
|
|
if (removed) (*ppoin)[ibrick - removed] = (*ppoin)[ibrick];
|
|
else if ((*ppoin)[ibrick] == *poin) removed = 1;
|
|
}
|
|
|
|
if (removed) {
|
|
(*tot) --;
|
|
|
|
if (*tot == 0) {
|
|
MEM_freeN(*ppoin);
|
|
(*ppoin)= NULL;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
const char *sca_state_name_get(Object *ob, short bit)
|
|
{
|
|
bController *cont;
|
|
unsigned int mask;
|
|
|
|
mask = (1<<bit);
|
|
cont = ob->controllers.first;
|
|
while (cont) {
|
|
if (cont->state_mask & mask) {
|
|
return cont->name;
|
|
}
|
|
cont = cont->next;
|
|
}
|
|
return NULL;
|
|
}
|
|
|