Keyed physics refresh:
[blender-staging.git] / source / blender / makesrna / intern / rna_particle.c
index 98ed12afd5a95f5c8811d22c4a82fbb4f8f70799..3941175279285b0633eae2fcfb6e263cb000fe10 100644 (file)
@@ -140,6 +140,35 @@ static void rna_Particle_reset(bContext *C, PointerRNA *ptr)
        }
 }
 
+static void rna_Particle_keyed_reset(bContext *C, PointerRNA *ptr)
+{
+       Scene *scene = CTX_data_scene(C);
+
+       if(ptr->type==&RNA_KeyedParticleTarget) {
+               Object *ob = (Object*)ptr->id.data;
+               ParticleSystem *psys = psys_get_current(ob);
+               
+               psys->recalc = PSYS_RECALC_RESET;
+
+               DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+               DAG_scene_sort(scene);
+       }
+}
+
+static void rna_Particle_keyed_redo(bContext *C, PointerRNA *ptr)
+{
+       Scene *scene = CTX_data_scene(C);
+
+       if(ptr->type==&RNA_KeyedParticleTarget) {
+               Object *ob = (Object*)ptr->id.data;
+               ParticleSystem *psys = psys_get_current(ob);
+               
+               psys->recalc = PSYS_RECALC_REDO;
+
+               DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+       }
+}
+
 static void rna_Particle_change_type(bContext *C, PointerRNA *ptr)
 {
        Scene *scene = CTX_data_scene(C);
@@ -161,6 +190,13 @@ static void rna_Particle_change_type(bContext *C, PointerRNA *ptr)
        }
 }
 
+static void rna_Particle_change_physics(bContext *C, PointerRNA *ptr)
+{
+       Scene *scene = CTX_data_scene(C);
+       ParticleSettings *part = ptr->id.data;
+       psys_flush_particle_settings(scene, part, PSYS_RECALC_RESET|PSYS_RECALC_PHYS);
+}
+
 static void rna_Particle_redo_child(bContext *C, PointerRNA *ptr)
 {
        Scene *scene = CTX_data_scene(C);
@@ -299,6 +335,97 @@ static void rna_ParticleSystem_name_get(PointerRNA *ptr, char *str)
                strcpy(str, "");
 }
 
+static PointerRNA rna_ParticleSystem_active_keyed_target_get(PointerRNA *ptr)
+{
+       ParticleSystem *psys= (ParticleSystem*)ptr->data;
+       KeyedParticleTarget *kpt = psys->keyed_targets.first;
+
+       for(; kpt; kpt=kpt->next) {
+               if(kpt->flag & KEYED_TARGET_CURRENT)
+                       return rna_pointer_inherit_refine(ptr, &RNA_KeyedParticleTarget, kpt);
+       }
+       return rna_pointer_inherit_refine(ptr, &RNA_KeyedParticleTarget, NULL);
+}
+static void rna_ParticleSystem_active_keyed_target_index_range(PointerRNA *ptr, int *min, int *max)
+{
+       ParticleSystem *psys= (ParticleSystem*)ptr->data;
+       *min= 0;
+       *max= BLI_countlist(&psys->keyed_targets)-1;
+       *max= MAX2(0, *max);
+}
+
+static int rna_ParticleSystem_active_keyed_target_index_get(PointerRNA *ptr)
+{
+       ParticleSystem *psys= (ParticleSystem*)ptr->data;
+       KeyedParticleTarget *kpt = psys->keyed_targets.first;
+       int i=0;
+
+       for(; kpt; kpt=kpt->next, i++)
+               if(kpt->flag & KEYED_TARGET_CURRENT)
+                       return i;
+
+       return 0;
+}
+
+static void rna_ParticleSystem_active_keyed_target_index_set(struct PointerRNA *ptr, int value)
+{
+       ParticleSystem *psys= (ParticleSystem*)ptr->data;
+       KeyedParticleTarget *kpt = psys->keyed_targets.first;
+       int i=0;
+
+       for(; kpt; kpt=kpt->next, i++) {
+               if(i==value)
+                       kpt->flag |= KEYED_TARGET_CURRENT;
+               else
+                       kpt->flag &= ~KEYED_TARGET_CURRENT;
+       }
+}
+static int rna_KeyedParticleTarget_name_length(PointerRNA *ptr)
+{
+       KeyedParticleTarget *kpt= ptr->data;
+
+       if(kpt->flag & KEYED_TARGET_VALID) {
+               if(kpt->ob)
+                       return strlen(kpt->ob->id.name+2) + 4;
+               else
+                       return 20;
+       }
+       else
+               return 15;
+       
+       return 0;
+}
+
+static void rna_KeyedParticleTarget_name_get(PointerRNA *ptr, char *str)
+{
+       KeyedParticleTarget *kpt= ptr->data;
+
+       if(kpt->flag & KEYED_TARGET_VALID) {
+               if(kpt->ob)
+                       sprintf(str, "%s: %i", kpt->ob->id.name+2, kpt->psys);
+               else
+                       sprintf(str, "Particle System: %i", kpt->psys);
+
+       }
+       else
+               strcpy(str, "Invalid target!");
+}
+
+static EnumPropertyItem from_items[] = {
+       {PART_FROM_VERT, "VERT", 0, "Vertexes", ""},
+       {PART_FROM_FACE, "FACE", 0, "Faces", ""},
+       {PART_FROM_VOLUME, "VOLUME", 0, "Volume", ""},
+       {0, NULL, 0, NULL, NULL}
+};
+
+static EnumPropertyItem reactor_from_items[] = {
+       {PART_FROM_VERT, "VERT", 0, "Vertexes", ""},
+       {PART_FROM_FACE, "FACE", 0, "Faces", ""},
+       {PART_FROM_VOLUME, "VOLUME", 0, "Volume", ""},
+       {PART_FROM_PARTICLE, "PARTICLE", 0, "Particle", ""},
+       {0, NULL, 0, NULL, NULL}
+};
+
 static EnumPropertyItem *rna_Particle_from_itemf(bContext *C, PointerRNA *ptr, int *free)
 {
        ParticleSettings *part = ptr->id.data;
@@ -660,16 +787,19 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        /* flag */
        prop= RNA_def_property(srna, "react_start_end", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_REACT_STA_END);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_ui_text(prop, "Start/End", "Give birth to unreacted particles eventually.");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        prop= RNA_def_property(srna, "react_multiple", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_REACT_MULTIPLE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_ui_text(prop, "Multi React", "React multiple times.");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        prop= RNA_def_property(srna, "loop", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_LOOP);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_ui_text(prop, "Loop", "Loop particle lives.");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
@@ -690,54 +820,46 @@ static void rna_def_particle_settings(BlenderRNA *brna)
 
        prop= RNA_def_property(srna, "trand", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_TRAND);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_ui_text(prop, "Random", "Emit in random order of elements");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        prop= RNA_def_property(srna, "even_distribution", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_EDISTR);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_ui_text(prop, "Even Distribution", "Use even distribution from faces based on face areas or edge lengths.");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        prop= RNA_def_property(srna, "sticky", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_STICKY);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_ui_text(prop, "Sticky", "Particles stick to collided objects if they die in the collision.");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        prop= RNA_def_property(srna, "die_on_collision", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_DIE_ON_COL);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_ui_text(prop, "Die on hit", "Particles die when they collide with a deflector object.");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        prop= RNA_def_property(srna, "size_deflect", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_SIZE_DEFL);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_ui_text(prop, "Size Deflect", "Use particle's size in deflection.");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        prop= RNA_def_property(srna, "rotation_dynamic", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_ROT_DYN);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_ui_text(prop, "Dynamic", "Sets rotation to dynamic/constant");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        prop= RNA_def_property(srna, "sizemass", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_SIZEMASS);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_ui_text(prop, "Mass from Size", "Multiply mass with particle size.");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
-       prop= RNA_def_property(srna, "abs_length", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_ABS_LENGTH);
-       RNA_def_property_ui_text(prop, "Abs Length", "Use maximum length for children");
-       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo");
-
-       //prop= RNA_def_property(srna, "absolute_time", PROP_BOOLEAN, PROP_NONE);
-       //RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_ABS_TIME);
-       //RNA_def_property_ui_text(prop, "Absolute Time", "Set all ipos that work on particles to be calculated in absolute/relative time.");
-       //RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
-
-       //prop= RNA_def_property(srna, "global_time", PROP_BOOLEAN, PROP_NONE);
-       //RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_GLOB_TIME);
-       //RNA_def_property_ui_text(prop, "Global Time", "Set all ipos that work on particles to be calculated in global/object time.");
-       //RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
-
        prop= RNA_def_property(srna, "boids_2d", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_BOIDS_2D);
        RNA_def_property_ui_text(prop, "Boids 2D", "Constrain boids to a surface");
@@ -796,18 +918,21 @@ static void rna_def_particle_settings(BlenderRNA *brna)
 
        prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_items(prop, type_items);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_ui_text(prop, "Type", "");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_change_type");
 
        prop= RNA_def_property(srna, "emit_from", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "from");
        RNA_def_property_enum_items(prop, part_reactor_from_items);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Particle_from_itemf");
        RNA_def_property_ui_text(prop, "Emit From", "Where to emit particles from");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        prop= RNA_def_property(srna, "distribution", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "distr");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_enum_items(prop, dist_items);
        RNA_def_property_ui_text(prop, "Distribution", "How to distribute particles on selected element");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
@@ -815,24 +940,28 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        /* physics modes */
        prop= RNA_def_property(srna, "physics_type", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "phystype");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_enum_items(prop, phys_type_items);
        RNA_def_property_ui_text(prop, "Physics Type", "Particle physics type");
-       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
+       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_change_physics");
 
        prop= RNA_def_property(srna, "rotation_mode", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "rotmode");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_enum_items(prop, rot_mode_items);
        RNA_def_property_ui_text(prop, "Rotation", "Particles initial rotation");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        prop= RNA_def_property(srna, "angular_velocity_mode", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "avemode");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_enum_items(prop, ave_mode_items);
        RNA_def_property_ui_text(prop, "Angular Velocity Mode", "Particle angular velocity mode.");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        prop= RNA_def_property(srna, "react_event", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "reactevent");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_enum_items(prop, react_event_items);
        RNA_def_property_ui_text(prop, "React On", "The event of target particles to react on.");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
@@ -843,11 +972,6 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Velocity", "Show particle velocity");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo");
 
-       //prop= RNA_def_property(srna, "draw_path_length", PROP_BOOLEAN, PROP_NONE);
-       //RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_PATH_LEN);
-       //RNA_def_property_ui_text(prop, "Path length", "Draw path length");
-       //RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo");
-
        prop= RNA_def_property(srna, "show_size", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_SIZE);
        RNA_def_property_ui_text(prop, "Size", "Show particle size");
@@ -936,7 +1060,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_enum_sdna(prop, NULL, "childtype");
        RNA_def_property_enum_items(prop, child_type_items);
        RNA_def_property_ui_text(prop, "Children From", "Create child particles");
-       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo");
+       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child");
 
        prop= RNA_def_property(srna, "draw_step", PROP_INT, PROP_NONE);
        RNA_def_property_range(prop, 0, 7);
@@ -1091,12 +1215,15 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        prop= RNA_def_property(srna, "start", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "sta");//optional if prop names are the same
        RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_float_funcs(prop, NULL, "rna_PartSettings_start_set", NULL);
        RNA_def_property_ui_text(prop, "Start", "Frame # to start emitting particles.");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        prop= RNA_def_property(srna, "end", PROP_FLOAT, PROP_NONE);
        RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF);
+
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_float_funcs(prop, NULL, "rna_PartSettings_end_set", NULL);
        RNA_def_property_ui_text(prop, "End", "Frame # to stop emitting particles.");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
@@ -1119,38 +1246,35 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        prop= RNA_def_property(srna, "jitter_factor", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_float_sdna(prop, NULL, "jitfac");
        RNA_def_property_range(prop, 0.0f, 2.0f);
        RNA_def_property_ui_text(prop, "Amount", "Amount of jitter applied to the sampling.");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
-       prop= RNA_def_property(srna, "keyed_time", PROP_FLOAT, PROP_NONE);
-       RNA_def_property_range(prop, 0.0f, 1.0f);
-       RNA_def_property_ui_text(prop, "Time", "Keyed key time relative to remaining particle life.");
-       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
-
        prop= RNA_def_property(srna, "effect_hair", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "eff_hair");
        RNA_def_property_range(prop, 0.0f, 1.0f);
        RNA_def_property_ui_text(prop, "Stiffnes", "Hair stiffness for effectors");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo");
 
-       //float rt; TODO:find where rt is used - can't find it in UI
-
        prop= RNA_def_property(srna, "amount", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_int_sdna(prop, NULL, "totpart");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_range(prop, 0, 100000);
        RNA_def_property_ui_text(prop, "Amount", "Total number of particles.");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        prop= RNA_def_property(srna, "userjit", PROP_INT, PROP_UNSIGNED);//TODO: can we get a better name for userjit?
        RNA_def_property_int_sdna(prop, NULL, "userjit");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_range(prop, 0, 1000);
        RNA_def_property_ui_text(prop, "P/F", "Emission locations / face (0 = automatic).");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        prop= RNA_def_property(srna, "grid_resolution", PROP_INT, PROP_UNSIGNED);
        RNA_def_property_int_sdna(prop, NULL, "grid_res");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
        RNA_def_property_range(prop, 1, 100);
        RNA_def_property_ui_text(prop, "Resolution", "The resolution of the particle grid.");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
@@ -1273,19 +1397,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Damp", "Specify the amount of damping");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
-       /* length */
-       //TODO: is this readonly?
-       prop= RNA_def_property(srna, "length", PROP_FLOAT, PROP_NONE);
-       RNA_def_property_float_sdna(prop, NULL, "length");
-//     RNA_def_property_range(prop, 0.0f, upperLimitf);//TODO: limits
-       RNA_def_property_ui_text(prop, "Length", "");
-
-       prop= RNA_def_property(srna, "absolute_length", PROP_FLOAT, PROP_NONE);
-       RNA_def_property_float_sdna(prop, NULL, "abslength");
-       RNA_def_property_range(prop, 0.0f, 10000.0f);
-       RNA_def_property_ui_text(prop, "Max Length", "Absolute maximum path length for children, in blender units.");
-       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo");
-
+       /* random length */
        prop= RNA_def_property(srna, "random_length", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "randlength");
        RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -1334,13 +1446,6 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Child Roundness", "Roundness of children around parent.");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child");
 
-       //TODO: is this readonly?
-       prop= RNA_def_property(srna, "child_spread", PROP_FLOAT, PROP_NONE);
-       RNA_def_property_float_sdna(prop, NULL, "childspread");
-//     RNA_def_property_range(prop, 0.0f, upperLimitf); TODO: limits
-       RNA_def_property_ui_text(prop, "Child Spread", "");
-       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child");
-
        /* clumping */
        prop= RNA_def_property(srna, "clump_factor", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "clumpfac");
@@ -1414,6 +1519,18 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Shape", "Shape of end point rough");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child");
 
+       prop= RNA_def_property(srna, "child_length", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "clength");
+       RNA_def_property_range(prop, 0.0f, 1.0f);
+       RNA_def_property_ui_text(prop, "Length", "Length of child paths");
+       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child");
+
+       prop= RNA_def_property(srna, "child_length_thres", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "clength_thres");
+       RNA_def_property_range(prop, 0.0f, 1.0f);
+       RNA_def_property_ui_text(prop, "Threshold", "Amount of particles left untouched by child path length.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child");
+
        /* branching */
        prop= RNA_def_property(srna, "branch_threshold", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "branch_thres");
@@ -1451,7 +1568,14 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_range(prop, 1.0f, 100.0f);
        RNA_def_property_ui_text(prop, "Trail Count", "Number of trail particles.");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo");
-       
+
+       /* keyed particles */
+       prop= RNA_def_property(srna, "keyed_loops", PROP_INT, PROP_NONE);
+       RNA_def_property_int_sdna(prop, NULL, "keyed_loops");
+       RNA_def_property_range(prop, 1.0f, 100.0f);
+       RNA_def_property_ui_text(prop, "Loop count", "Number of times the keys are looped.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo");
+
        /* boids */
        prop= RNA_def_property(srna, "max_velocity", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "max_vel");
@@ -1494,14 +1618,6 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Ground Z", "Default Z value");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
-       /*TODO: not sure how to deal with this
-       prop= RNA_def_property(srna, "boid_factor", PROP_FLOAT, PROP_VECTOR);
-       RNA_def_property_float_sdna(prop, NULL, "boidfac");
-       RNA_def_property_ui_text(prop, "Boid Factor", "");
-
-       //char boidrule[8];
-       */
-
        prop= RNA_def_property(srna, "dupli_group", PROP_POINTER, PROP_NONE);
        RNA_def_property_pointer_sdna(prop, NULL, "dup_group");
        RNA_def_property_struct_type(prop, "Group");
@@ -1537,6 +1653,52 @@ static void rna_def_particle_settings(BlenderRNA *brna)
 //     struct PartDeflect *pd2;
 }
 
+static void rna_def_keyed_particle_target(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       srna = RNA_def_struct(brna, "KeyedParticleTarget", NULL);
+       RNA_def_struct_ui_text(srna, "Keyed Particle Target", "Target particle system for keyed particles.");
+
+       prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_funcs(prop, "rna_KeyedParticleTarget_name_get", "rna_KeyedParticleTarget_name_length", NULL);
+       RNA_def_property_ui_text(prop, "Name", "Keyed particle target name.");
+       RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+       RNA_def_struct_name_property(srna, prop);
+
+       prop= RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
+       RNA_def_property_pointer_sdna(prop, NULL, "ob");
+       RNA_def_property_flag(prop, PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "Target Object", "The object that has the target particle system (empty if same object).");
+       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_keyed_reset");
+
+       prop= RNA_def_property(srna, "system", PROP_INT, PROP_UNSIGNED);
+       RNA_def_property_int_sdna(prop, NULL, "psys");
+       RNA_def_property_range(prop, 1, INT_MAX);
+       RNA_def_property_ui_text(prop, "Target Particle System", "The index of particle system on the target object.");
+       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_keyed_reset");
+
+       prop= RNA_def_property(srna, "time", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "time");
+       RNA_def_property_range(prop, 0.0, 30000.0f); //TODO: replace 30000 with MAXFRAMEF when available in 2.5
+       RNA_def_property_ui_text(prop, "Time", "");
+       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_keyed_redo");
+
+       prop= RNA_def_property(srna, "duration", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "duration");
+       RNA_def_property_range(prop, 0.0, 30000.0f); //TODO: replace 30000 with MAXFRAMEF when available in 2.5
+       RNA_def_property_ui_text(prop, "Duration", "");
+       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_keyed_redo");
+
+       prop= RNA_def_property(srna, "valid", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYED_TARGET_VALID);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
+       RNA_def_property_ui_text(prop, "Valid", "Keyed particles target is valid.");
+
+       
+
+}
 static void rna_def_particle_system(BlenderRNA *brna)
 {
        StructRNA *srna;
@@ -1604,34 +1766,33 @@ static void rna_def_particle_system(BlenderRNA *brna)
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        /* boids */
-       prop= RNA_def_property(srna, "boids_surface_object", PROP_POINTER, PROP_NONE);
-       RNA_def_property_pointer_sdna(prop, NULL, "keyed_ob");
-       RNA_def_property_flag(prop, PROP_EDITABLE);
-       RNA_def_property_ui_text(prop, "Boids Surface Object", "For boids physics systems, constrain boids to this object's surface.");
-       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
+       //prop= RNA_def_property(srna, "boids_surface_object", PROP_POINTER, PROP_NONE);
+       //RNA_def_property_pointer_sdna(prop, NULL, "keyed_ob");
+       //RNA_def_property_flag(prop, PROP_EDITABLE);
+       //RNA_def_property_ui_text(prop, "Boids Surface Object", "For boids physics systems, constrain boids to this object's surface.");
+       //RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        /* keyed */
-       prop= RNA_def_property(srna, "keyed_object", PROP_POINTER, PROP_NONE);
-       RNA_def_property_pointer_sdna(prop, NULL, "keyed_ob");
-       RNA_def_property_flag(prop, PROP_EDITABLE);
-       RNA_def_property_ui_text(prop, "Keyed Object", "For keyed physics systems, the object that has the target particle system.");
-       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
+       prop= RNA_def_property(srna, "keyed_timing", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", PSYS_KEYED_TIMING);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
+       RNA_def_property_ui_text(prop, "Keyed timing", "Use key times");
+       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo");
 
-       prop= RNA_def_property(srna, "keyed_particle_system", PROP_INT, PROP_UNSIGNED);
-       RNA_def_property_int_sdna(prop, NULL, "keyed_psys");
-       RNA_def_property_range(prop, 1, INT_MAX);
-       RNA_def_property_ui_text(prop, "Keyed Particle System", "For keyed physics systems, index of particle system on the keyed object.");
-       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
+       prop= RNA_def_property(srna, "keyed_targets", PROP_COLLECTION, PROP_NONE);
+       RNA_def_property_collection_sdna(prop, NULL, "keyed_targets", NULL);
+       RNA_def_property_struct_type(prop, "KeyedParticleTarget");
+       RNA_def_property_ui_text(prop, "Keyed Targets", "Target particle systems for keyed particles");
 
-       prop= RNA_def_property(srna, "keyed_first", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "flag", PSYS_FIRST_KEYED);
-       RNA_def_property_ui_text(prop, "Keyed First", "Set the system to be the starting point of keyed particles");
-       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
+       prop= RNA_def_property(srna, "active_keyed_target", PROP_POINTER, PROP_NONE);
+       RNA_def_property_struct_type(prop, "KeyedParticleTarget");
+       RNA_def_property_pointer_funcs(prop, "rna_ParticleSystem_active_keyed_target_get", NULL, NULL);
+       RNA_def_property_ui_text(prop, "Active Particle System", "Active particle system being displayed");
+
+       prop= RNA_def_property(srna, "active_keyed_target_index", PROP_INT, PROP_UNSIGNED);
+       RNA_def_property_int_funcs(prop, "rna_ParticleSystem_active_keyed_target_index_get", "rna_ParticleSystem_active_keyed_target_index_set", "rna_ParticleSystem_active_keyed_target_index_range");
+       RNA_def_property_ui_text(prop, "Active Particle System Index", "Index of active particle system slot.");
 
-       prop= RNA_def_property(srna, "keyed_timed", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "flag", PSYS_KEYED_TIME);
-       RNA_def_property_ui_text(prop, "Keyed Timed", "Use intermediate key times for keyed particles (setting for starting point only).");
-       RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset");
 
        /* billboard */
        prop= RNA_def_property(srna, "billboard_normal_uv", PROP_STRING, PROP_NONE);
@@ -1782,7 +1943,6 @@ static void rna_def_particle_system(BlenderRNA *brna)
        RNA_def_property_flag(prop, PROP_EDITABLE);
        RNA_def_property_ui_text(prop, "Parent", "Use this object's coordinate system instead of global coordinate system.");
        RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo");
-
 }
 
 void RNA_def_particle(BlenderRNA *brna)
@@ -1791,6 +1951,7 @@ void RNA_def_particle(BlenderRNA *brna)
        rna_def_particle_key(brna);
        rna_def_child_particle(brna);
        rna_def_particle(brna);
+       rna_def_keyed_particle_target(brna);
        rna_def_particle_system(brna);
        rna_def_particle_settings(brna);
 }