|
Blender
V2.59
|
00001 /* 00002 * $Id: particle_boids.c 35242 2011-02-27 20:29:51Z jesterking $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2009 Janne Karhu. 00021 * All rights reserved. 00022 * 00023 * Contributor(s): Blender Foundation 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include <stdlib.h> 00034 00035 #include "MEM_guardedalloc.h" 00036 00037 #include "DNA_particle_types.h" 00038 #include "DNA_scene_types.h" 00039 00040 #include "BLI_listbase.h" 00041 #include "BLI_utildefines.h" 00042 00043 #include "BKE_boids.h" 00044 #include "BKE_context.h" 00045 #include "BKE_depsgraph.h" 00046 #include "BKE_main.h" 00047 #include "BKE_particle.h" 00048 00049 #include "RNA_access.h" 00050 #include "RNA_enum_types.h" 00051 #include "RNA_define.h" 00052 00053 #include "WM_api.h" 00054 #include "WM_types.h" 00055 00056 #include "physics_intern.h" 00057 00058 /************************ add/del boid rule operators *********************/ 00059 static int rule_add_exec(bContext *C, wmOperator *op) 00060 { 00061 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); 00062 ParticleSystem *psys= ptr.data; 00063 Object *ob= ptr.id.data; 00064 ParticleSettings *part; 00065 int type= RNA_enum_get(op->ptr, "type"); 00066 00067 BoidRule *rule; 00068 BoidState *state; 00069 00070 if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) 00071 return OPERATOR_CANCELLED; 00072 00073 part = psys->part; 00074 00075 state = boid_get_current_state(part->boids); 00076 00077 00078 for(rule=state->rules.first; rule; rule=rule->next) 00079 rule->flag &= ~BOIDRULE_CURRENT; 00080 00081 rule = boid_new_rule(type); 00082 rule->flag |= BOIDRULE_CURRENT; 00083 00084 BLI_addtail(&state->rules, rule); 00085 00086 DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); 00087 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00088 00089 return OPERATOR_FINISHED; 00090 } 00091 00092 void BOID_OT_rule_add(wmOperatorType *ot) 00093 { 00094 /* identifiers */ 00095 ot->name= "Add Boid Rule"; 00096 ot->description = "Add a boid rule to the current boid state"; 00097 ot->idname= "BOID_OT_rule_add"; 00098 00099 /* api callbacks */ 00100 ot->invoke= WM_menu_invoke; 00101 ot->exec= rule_add_exec; 00102 00103 /* flags */ 00104 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00105 00106 ot->prop= RNA_def_enum(ot->srna, "type", boidrule_type_items, 0, "Type", ""); 00107 } 00108 static int rule_del_exec(bContext *C, wmOperator *UNUSED(op)) 00109 { 00110 Main *bmain = CTX_data_main(C); 00111 Scene *scene = CTX_data_scene(C); 00112 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); 00113 ParticleSystem *psys= ptr.data; 00114 Object *ob = ptr.id.data; 00115 BoidRule *rule; 00116 BoidState *state; 00117 00118 if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) 00119 return OPERATOR_CANCELLED; 00120 00121 state = boid_get_current_state(psys->part->boids); 00122 00123 00124 for(rule=state->rules.first; rule; rule=rule->next) { 00125 if(rule->flag & BOIDRULE_CURRENT) { 00126 BLI_remlink(&state->rules, rule); 00127 MEM_freeN(rule); 00128 break; 00129 } 00130 00131 } 00132 rule = state->rules.first; 00133 00134 if(rule) 00135 rule->flag |= BOIDRULE_CURRENT; 00136 00137 DAG_scene_sort(bmain, scene); 00138 DAG_id_tag_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); 00139 00140 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00141 00142 return OPERATOR_FINISHED; 00143 } 00144 00145 void BOID_OT_rule_del(wmOperatorType *ot) 00146 { 00147 /* identifiers */ 00148 ot->name= "Remove Boid Rule"; 00149 ot->idname= "BOID_OT_rule_del"; 00150 00151 /* api callbacks */ 00152 ot->exec= rule_del_exec; 00153 00154 /* flags */ 00155 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00156 } 00157 00158 /************************ move up/down boid rule operators *********************/ 00159 static int rule_move_up_exec(bContext *C, wmOperator *UNUSED(op)) 00160 { 00161 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); 00162 ParticleSystem *psys= ptr.data; 00163 Object *ob = ptr.id.data; 00164 BoidRule *rule; 00165 BoidState *state; 00166 00167 if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) 00168 return OPERATOR_CANCELLED; 00169 00170 state = boid_get_current_state(psys->part->boids); 00171 for(rule = state->rules.first; rule; rule=rule->next) { 00172 if(rule->flag & BOIDRULE_CURRENT && rule->prev) { 00173 BLI_remlink(&state->rules, rule); 00174 BLI_insertlink(&state->rules, rule->prev->prev, rule); 00175 00176 DAG_id_tag_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); 00177 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00178 break; 00179 } 00180 } 00181 00182 return OPERATOR_FINISHED; 00183 } 00184 00185 void BOID_OT_rule_move_up(wmOperatorType *ot) 00186 { 00187 ot->name= "Move Up Boid Rule"; 00188 ot->description= "Move boid rule up in the list"; 00189 ot->idname= "BOID_OT_rule_move_up"; 00190 00191 ot->exec= rule_move_up_exec; 00192 00193 /* flags */ 00194 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00195 } 00196 00197 static int rule_move_down_exec(bContext *C, wmOperator *UNUSED(op)) 00198 { 00199 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); 00200 ParticleSystem *psys= ptr.data; 00201 Object *ob = ptr.id.data; 00202 BoidRule *rule; 00203 BoidState *state; 00204 00205 if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) 00206 return OPERATOR_CANCELLED; 00207 00208 state = boid_get_current_state(psys->part->boids); 00209 for(rule = state->rules.first; rule; rule=rule->next) { 00210 if(rule->flag & BOIDRULE_CURRENT && rule->next) { 00211 BLI_remlink(&state->rules, rule); 00212 BLI_insertlink(&state->rules, rule->next, rule); 00213 00214 DAG_id_tag_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); 00215 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00216 break; 00217 } 00218 } 00219 00220 return OPERATOR_FINISHED; 00221 } 00222 00223 void BOID_OT_rule_move_down(wmOperatorType *ot) 00224 { 00225 ot->name= "Move Down Boid Rule"; 00226 ot->description= "Move boid rule down in the list"; 00227 ot->idname= "BOID_OT_rule_move_down"; 00228 00229 ot->exec= rule_move_down_exec; 00230 00231 /* flags */ 00232 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00233 } 00234 00235 00236 /************************ add/del boid state operators *********************/ 00237 static int state_add_exec(bContext *C, wmOperator *UNUSED(op)) 00238 { 00239 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); 00240 ParticleSystem *psys= ptr.data; 00241 Object *ob= ptr.id.data; 00242 ParticleSettings *part; 00243 BoidState *state; 00244 00245 if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) 00246 return OPERATOR_CANCELLED; 00247 00248 part = psys->part; 00249 00250 for(state=part->boids->states.first; state; state=state->next) 00251 state->flag &= ~BOIDSTATE_CURRENT; 00252 00253 state = boid_new_state(part->boids); 00254 state->flag |= BOIDSTATE_CURRENT; 00255 00256 BLI_addtail(&part->boids->states, state); 00257 00258 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00259 00260 return OPERATOR_FINISHED; 00261 } 00262 00263 void BOID_OT_state_add(wmOperatorType *ot) 00264 { 00265 /* identifiers */ 00266 ot->name= "Add Boid State"; 00267 ot->description = "Add a boid state to the particle system"; 00268 ot->idname= "BOID_OT_state_add"; 00269 00270 /* api callbacks */ 00271 ot->exec= state_add_exec; 00272 00273 /* flags */ 00274 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00275 } 00276 static int state_del_exec(bContext *C, wmOperator *UNUSED(op)) 00277 { 00278 Main *bmain = CTX_data_main(C); 00279 Scene *scene = CTX_data_scene(C); 00280 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); 00281 ParticleSystem *psys= ptr.data; 00282 Object *ob = ptr.id.data; 00283 ParticleSettings *part; 00284 BoidState *state; 00285 00286 if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) 00287 return OPERATOR_CANCELLED; 00288 00289 part = psys->part; 00290 00291 for(state=part->boids->states.first; state; state=state->next) { 00292 if(state->flag & BOIDSTATE_CURRENT) { 00293 BLI_remlink(&part->boids->states, state); 00294 MEM_freeN(state); 00295 break; 00296 } 00297 00298 } 00299 00300 /* there must be at least one state */ 00301 if(!part->boids->states.first) { 00302 state = boid_new_state(part->boids); 00303 BLI_addtail(&part->boids->states, state); 00304 } 00305 else 00306 state = part->boids->states.first; 00307 00308 state->flag |= BOIDSTATE_CURRENT; 00309 00310 DAG_scene_sort(bmain, scene); 00311 DAG_id_tag_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); 00312 00313 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00314 00315 return OPERATOR_FINISHED; 00316 } 00317 00318 void BOID_OT_state_del(wmOperatorType *ot) 00319 { 00320 /* identifiers */ 00321 ot->name= "Remove Boid State"; 00322 ot->idname= "BOID_OT_state_del"; 00323 00324 /* api callbacks */ 00325 ot->exec= state_del_exec; 00326 00327 /* flags */ 00328 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00329 } 00330 00331 /************************ move up/down boid state operators *********************/ 00332 static int state_move_up_exec(bContext *C, wmOperator *UNUSED(op)) 00333 { 00334 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); 00335 ParticleSystem *psys= ptr.data; 00336 Object *ob = ptr.id.data; 00337 BoidSettings *boids; 00338 BoidState *state; 00339 00340 if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) 00341 return OPERATOR_CANCELLED; 00342 00343 boids = psys->part->boids; 00344 00345 for(state = boids->states.first; state; state=state->next) { 00346 if(state->flag & BOIDSTATE_CURRENT && state->prev) { 00347 BLI_remlink(&boids->states, state); 00348 BLI_insertlink(&boids->states, state->prev->prev, state); 00349 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00350 break; 00351 } 00352 } 00353 00354 return OPERATOR_FINISHED; 00355 } 00356 00357 void BOID_OT_state_move_up(wmOperatorType *ot) 00358 { 00359 ot->name= "Move Up Boid State"; 00360 ot->description= "Move boid state up in the list"; 00361 ot->idname= "BOID_OT_state_move_up"; 00362 00363 ot->exec= state_move_up_exec; 00364 00365 /* flags */ 00366 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00367 } 00368 00369 static int state_move_down_exec(bContext *C, wmOperator *UNUSED(op)) 00370 { 00371 PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem); 00372 ParticleSystem *psys= ptr.data; 00373 BoidSettings *boids; 00374 BoidState *state; 00375 00376 if(!psys || !psys->part || psys->part->phystype != PART_PHYS_BOIDS) 00377 return OPERATOR_CANCELLED; 00378 00379 boids = psys->part->boids; 00380 00381 for(state = boids->states.first; state; state=state->next) { 00382 if(state->flag & BOIDSTATE_CURRENT && state->next) { 00383 BLI_remlink(&boids->states, state); 00384 BLI_insertlink(&boids->states, state->next, state); 00385 DAG_id_tag_update(&psys->part->id, OB_RECALC_DATA|PSYS_RECALC_RESET); 00386 break; 00387 } 00388 } 00389 00390 return OPERATOR_FINISHED; 00391 } 00392 00393 void BOID_OT_state_move_down(wmOperatorType *ot) 00394 { 00395 ot->name= "Move Down Boid State"; 00396 ot->description= "Move boid state down in the list"; 00397 ot->idname= "BOID_OT_state_move_down"; 00398 00399 ot->exec= state_move_down_exec; 00400 00401 /* flags */ 00402 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00403 } 00404