diff options
-rw-r--r-- | release/ui/buttons_particle.py | 96 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_pointcache.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pointcache.c | 113 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_object_force.h | 8 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_particle_types.h | 7 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object_force.c | 71 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_particle.c | 169 |
8 files changed, 354 insertions, 119 deletions
diff --git a/release/ui/buttons_particle.py b/release/ui/buttons_particle.py index 47d325a5940..f74dfa06427 100644 --- a/release/ui/buttons_particle.py +++ b/release/ui/buttons_particle.py @@ -86,6 +86,12 @@ class PARTICLE_PT_emission(ParticleButtonsPanel): __idname__= "PARTICLE_PT_emission" __label__ = "Emission" + def poll(self, context): + if particle_panel_poll(context): + return not context.particle_system.point_cache.external + else: + return False + def draw(self, context): layout = self.layout @@ -150,37 +156,60 @@ class PARTICLE_PT_cache(ParticleButtonsPanel): cache = psys.point_cache row = layout.row() - row.itemR(cache, "name") + row.itemL(text="File Name:") + row.itemR(cache, "external") - row = layout.row() - - if cache.baked == True: - row.itemO("ptcache.free_bake_particle_system", text="Free Bake") + if cache.external: + split = layout.split(percentage=0.80) + split.itemR(cache, "name", text="") + split.itemR(cache, "index", text="") + + layout.itemL(text="File Path:") + layout.itemR(cache, "filepath", text="") + + layout.itemL(text=cache.info) + + split = layout.split() + + col = split.column(align=True) + col.itemR(part, "start") + col.itemR(part, "end") + + col = split.column(align=True) + col.itemR(part, "lifetime") + col.itemR(part, "random_lifetime", slider=True) else: - row.item_booleanO("ptcache.cache_particle_system", "bake", True, text="Bake") - - subrow = row.row() - subrow.enabled = (cache.frames_skipped or cache.outdated) and particle_panel_enabled(psys) - subrow.itemO("ptcache.cache_particle_system", text="Calculate to Current Frame") + layout.itemR(cache, "name", text="") + + row = layout.row() - row = layout.row() - row.enabled = particle_panel_enabled(psys) - row.itemO("ptcache.bake_from_particles_cache", text="Current Cache to Bake") - row.itemR(cache, "step"); - - row = layout.row() - row.enabled = particle_panel_enabled(psys) - row.itemR(cache, "quick_cache") - row.itemR(cache, "disk_cache") + if cache.baked == True: + row.itemO("ptcache.free_bake_particle_system", text="Free Bake") + else: + row.item_booleanO("ptcache.cache_particle_system", "bake", True, text="Bake") - layout.itemL(text=cache.info) + subrow = row.row() + subrow.enabled = (cache.frames_skipped or cache.outdated) and particle_panel_enabled(psys) + subrow.itemO("ptcache.cache_particle_system", text="Calculate to Current Frame") + + row = layout.row() + row.enabled = particle_panel_enabled(psys) + row.itemO("ptcache.bake_from_particles_cache", text="Current Cache to Bake") + row.itemR(cache, "step"); - layout.itemS() + row = layout.row() + row.enabled = particle_panel_enabled(psys) + row.itemR(cache, "quick_cache") + row.itemR(cache, "disk_cache") - row = layout.row() - row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics") - row.itemO("ptcache.free_bake_all", text="Free All Bakes") - layout.itemO("ptcache.bake_all", text="Update All Dynamics to current frame") + layout.itemL(text=cache.info) + + layout.itemS() + + row = layout.row() + row.item_booleanO("ptcache.bake_all", "bake", True, text="Bake All Dynamics") + row.itemO("ptcache.free_bake_all", text="Free All Bakes") + layout.itemO("ptcache.bake_all", text="Update All Dynamics to current frame") # for particles these are figured out automatically #row.itemR(cache, "start_frame") @@ -193,7 +222,7 @@ class PARTICLE_PT_initial(ParticleButtonsPanel): def poll(self, context): if particle_panel_poll(context): psys = context.particle_system - return psys.settings.physics_type != 'BOIDS' + return psys.settings.physics_type != 'BOIDS' and not psys.point_cache.external else: return False @@ -256,6 +285,12 @@ class PARTICLE_PT_initial(ParticleButtonsPanel): class PARTICLE_PT_physics(ParticleButtonsPanel): __idname__= "PARTICLE_PT_physics" __label__ = "Physics" + + def poll(self, context): + if particle_panel_poll(context): + return not context.particle_system.point_cache.external + else: + return False def draw(self, context): layout = self.layout @@ -399,12 +434,15 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel): psys = context.particle_system if psys==None: return False if psys.settings==None: return False + if psys.point_cache.external: return False return psys.settings.physics_type=='BOIDS' def draw(self, context): boids = context.particle_system.settings.boids layout = self.layout + layout.enabled = particle_panel_enabled(psys) + # Currently boids can only use the first state so these are commented out for now. #row = layout.row() #row.template_list(boids, "states", boids, "active_boid_state_index", compact="True") @@ -764,12 +802,6 @@ class PARTICLE_PT_effectors(ParticleButtonsPanel): __label__ = "Effectors" __default_closed__ = True - def poll(self, context): - psys = context.particle_system - if psys==None: return False - if psys.settings==None: return False - return True; - def draw(self, context): layout = self.layout diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index c5d423c13ba..8062f807055 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -166,4 +166,6 @@ void BKE_ptcache_quick_cache_all(struct Scene *scene); void BKE_ptcache_make_cache(struct PTCacheBaker* baker); void BKE_ptcache_toggle_disk_cache(struct PTCacheID *pid); +void BKE_ptcache_load_external(struct PTCacheID *pid); + #endif diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index b792564f50c..43174343302 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -3982,7 +3982,8 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps /* update alive status and push events */ if(pa->time >= cfra) { pa->alive = pa->time==cfra ? PARS_ALIVE : PARS_UNBORN; - reset_particle(scene, pa, psys, psmd, ob, 0.0f, cfra, NULL, NULL, NULL); + if((psys->pointcache->flag & PTCACHE_EXTERNAL) == 0) + reset_particle(scene, pa, psys, psmd, ob, 0.0f, cfra, NULL, NULL, NULL); } else if(dietime <= cfra){ if(dietime > psys->cfra){ @@ -4303,7 +4304,9 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle oldtotpart = psys->totpart; oldtotchild = psys->totchild; - if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT) + if(psys->pointcache->flag & PTCACHE_EXTERNAL) + totpart = pid.cache->totpoint; + else if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT) totpart = part->grid_res*part->grid_res*part->grid_res; else totpart = psys->part->totpart; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index cde0587772e..4bb571aa8ca 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -181,7 +181,11 @@ static int ptcache_path(PTCacheID *pid, char *filename) lib= (pid)? pid->ob->id.lib: NULL; - if (G.relbase_valid || lib) { + if(pid->cache->flag & PTCACHE_EXTERNAL) { + strcpy(filename, pid->cache->path); + return BLI_add_slash(filename); /* new strlen() */ + } + else if (G.relbase_valid || lib) { char file[MAX_PTCACHE_PATH]; /* we dont want the dir, only the file */ char *blendfilename; @@ -214,14 +218,14 @@ static int BKE_ptcache_id_filename(PTCacheID *pid, char *filename, int cfra, sho filename[0] = '\0'; newname = filename; - if (!G.relbase_valid) return 0; /* save blend file before using disk pointcache */ + if (!G.relbase_valid && (pid->cache->flag & PTCACHE_EXTERNAL)==0) return 0; /* save blend file before using disk pointcache */ /* start with temp dir */ if (do_path) { len = ptcache_path(pid, filename); newname += len; } - if(strcmp(pid->cache->name, "")==0) { + if(strcmp(pid->cache->name, "")==0 && (pid->cache->flag & PTCACHE_EXTERNAL)==0) { idname = (pid->ob->id.name+2); /* convert chars to hex so they are always a valid filename */ while('\0' != *idname) { @@ -238,7 +242,15 @@ static int BKE_ptcache_id_filename(PTCacheID *pid, char *filename, int cfra, sho } if (do_ext) { - snprintf(newname, MAX_PTCACHE_FILE, "_%06d_%02d"PTCACHE_EXT, cfra, pid->stack_index); /* always 6 chars */ + if(pid->cache->flag & PTCACHE_EXTERNAL) { + if(pid->cache->index >= 0) + snprintf(newname, MAX_PTCACHE_FILE, "_%06d_%02d"PTCACHE_EXT, cfra, pid->stack_index); /* always 6 chars */ + else + snprintf(newname, MAX_PTCACHE_FILE, "_%06d"PTCACHE_EXT, cfra); /* always 6 chars */ + } + else { + snprintf(newname, MAX_PTCACHE_FILE, "_%06d_%02d"PTCACHE_EXT, cfra, pid->stack_index); /* always 6 chars */ + } len += 16; } @@ -256,7 +268,7 @@ PTCacheFile *BKE_ptcache_file_open(PTCacheID *pid, int mode, int cfra) if(pid->ob->id.lib && mode == PTCACHE_FILE_WRITE) return NULL; - if (!G.relbase_valid) return NULL; /* save blend file before using disk pointcache */ + if (!G.relbase_valid && (pid->cache->flag & PTCACHE_EXTERNAL)==0) return NULL; /* save blend file before using disk pointcache */ BKE_ptcache_id_filename(pid, filename, cfra, 1, 1); @@ -328,6 +340,21 @@ void BKE_ptcache_update_info(PTCacheID *pid) int totframes = 0; char mem_info[64]; + if(cache->flag & PTCACHE_EXTERNAL) { + int cfra = cache->startframe; + + for(; cfra<=cache->endframe; cfra++) { + if(BKE_ptcache_id_exist(pid, cfra)) + totframes++; + } + + if(totframes) + sprintf(cache->info, "%i points read for %i frames", cache->totpoint, totframes); + else + sprintf(cache->info, "No valid data to read!"); + return; + } + if(cache->flag & PTCACHE_DISK_CACHE) { int cfra = cache->startframe; @@ -743,7 +770,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra) char path_full[MAX_PTCACHE_FILE]; char ext[MAX_PTCACHE_PATH]; - if(!pid->cache) + if(!pid->cache || pid->cache->flag & PTCACHE_BAKED) return; /* don't allow clearing for linked objects */ @@ -1408,3 +1435,77 @@ void BKE_ptcache_toggle_disk_cache(PTCacheID *pid) { BKE_ptcache_update_info(pid); } + +void BKE_ptcache_load_external(PTCacheID *pid) +{ + PointCache *cache = pid->cache; + int len; /* store the length of the string */ + + /* mode is same as fopen's modes */ + DIR *dir; + struct dirent *de; + char path[MAX_PTCACHE_PATH]; + char filename[MAX_PTCACHE_FILE]; + char path_full[MAX_PTCACHE_FILE]; + char ext[MAX_PTCACHE_PATH]; + + if(!cache) + return; + + cache->startframe = MAXFRAME; + cache->endframe = -1; + cache->totpoint = 0; + + ptcache_path(pid, path); + + len = BKE_ptcache_id_filename(pid, filename, 1, 0, 0); /* no path */ + + dir = opendir(path); + if (dir==NULL) + return; + + if(cache->index >= 0) + snprintf(ext, sizeof(ext), "_%02d"PTCACHE_EXT, cache->index); + else + strcpy(ext, PTCACHE_EXT); + + while ((de = readdir(dir)) != NULL) { + if (strstr(de->d_name, ext)) { /* do we have the right extension?*/ + if (strncmp(filename, de->d_name, len ) == 0) { /* do we have the right prefix */ + /* read the number of the file */ + int frame, len2 = strlen(de->d_name); + char num[7]; + + if (len2 > 15) { /* could crash if trying to copy a string out of this range*/ + BLI_strncpy(num, de->d_name + (strlen(de->d_name) - 15), sizeof(num)); + frame = atoi(num); + + cache->startframe = MIN2(cache->startframe, frame); + cache->endframe = MAX2(cache->endframe, frame); + } + } + } + } + closedir(dir); + + if(cache->startframe != MAXFRAME) { + PTCacheFile *pf; + int elemsize = ptcache_pid_elemsize(pid); + int incr = elemsize / sizeof(float); + float *data = NULL; + pf= BKE_ptcache_file_open(pid, PTCACHE_FILE_READ, cache->startframe); + + if(pf) { + data = MEM_callocN(elemsize, "pointcache read data"); + while(BKE_ptcache_file_read_floats(pf, data, incr)) + cache->totpoint++; + + BKE_ptcache_file_close(pf); + MEM_freeN(data); + } + } + + cache->flag &= ~(PTCACHE_OUTDATED|PTCACHE_FRAMES_SKIPPED); + + BKE_ptcache_update_info(pid); +} diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index 6cf20cc25a2..d640e37f48d 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -89,10 +89,15 @@ typedef struct PointCache { int endframe; /* simulation end frame */ int editframe; /* frame being edited (runtime only) */ int last_exact; /* last exact frame that's cached */ - int xdata_type; /* type of extra data */ + + /* for external cache files */ + int totpoint; /* number of cached points */ + int index, rt; /* modifier stack index */ + char name[64]; char prev_name[64]; char info[64]; + char path[240]; /* file path */ struct ListBase mem_cache; } PointCache; @@ -267,6 +272,7 @@ typedef struct SoftBody { #define PTCACHE_DISK_CACHE 64 #define PTCACHE_QUICK_CACHE 128 #define PTCACHE_FRAMES_SKIPPED 256 +#define PTCACHE_EXTERNAL 512 /* PTCACHE_OUTDATED + PTCACHE_FRAMES_SKIPPED */ #define PTCACHE_REDO_NEEDED 258 diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 2d8a186d3f4..3d1dfff61cd 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -233,13 +233,6 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in struct KDTree *tree; /* used for interactions with self and other systems */ }ParticleSystem; -/* general particle maximums */ -/* no special why's, just seem reasonable */ -/* changing these (atleast upwards) should not cause any major problems */ -#define MAX_PARTS 100000 /* real particles/system */ -#define MAX_PART_CHILDREN 10000 /* child particles/real particles */ -#define MAX_BOIDNEIGHBOURS 10 /* neigbours considered/boid */ - /* part->type */ /* hair is allways baked static in object/geometry space */ /* other types (normal particles) are in global space and not static baked */ diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 2ec8d9ea41e..965b70714dc 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -105,6 +105,7 @@ static void rna_Cache_toggle_disk_cache(bContext *C, PointerRNA *ptr) static void rna_Cache_idname_change(bContext *C, PointerRNA *ptr) { + Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); PointCache *cache = (PointCache*)ptr->data; PTCacheID *pid = NULL, *pid2= NULL; @@ -119,33 +120,50 @@ static void rna_Cache_idname_change(bContext *C, PointerRNA *ptr) BKE_ptcache_ids_from_object(&pidlist, ob); - for(pid=pidlist.first; pid; pid=pid->next) { - if(pid->cache==cache) - pid2 = pid; - else if(strcmp(cache->name, "") && strcmp(cache->name,pid->cache->name)==0) { - /*TODO: report "name exists" to user */ - strcpy(cache->name, cache->prev_name); - new_name = 0; + if(cache->flag & PTCACHE_EXTERNAL) { + for(pid=pidlist.first; pid; pid=pid->next) { + if(pid->cache==cache) + break; } + + if(!pid) + return; + + cache->flag |= (PTCACHE_BAKED|PTCACHE_DISK_CACHE|PTCACHE_SIMULATION_VALID); + cache->flag &= ~(PTCACHE_OUTDATED|PTCACHE_FRAMES_SKIPPED); + + BKE_ptcache_load_external(pid); + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); } + else { + for(pid=pidlist.first; pid; pid=pid->next) { + if(pid->cache==cache) + pid2 = pid; + else if(strcmp(cache->name, "") && strcmp(cache->name,pid->cache->name)==0) { + /*TODO: report "name exists" to user */ + strcpy(cache->name, cache->prev_name); + new_name = 0; + } + } - if(new_name) { - if(pid2 && cache->flag & PTCACHE_DISK_CACHE) { - strcpy(name, cache->name); - strcpy(cache->name, cache->prev_name); + if(new_name) { + if(pid2 && cache->flag & PTCACHE_DISK_CACHE) { + strcpy(name, cache->name); + strcpy(cache->name, cache->prev_name); - cache->flag &= ~PTCACHE_DISK_CACHE; + cache->flag &= ~PTCACHE_DISK_CACHE; - BKE_ptcache_toggle_disk_cache(pid2); + BKE_ptcache_toggle_disk_cache(pid2); - strcpy(cache->name, name); + strcpy(cache->name, name); - cache->flag |= PTCACHE_DISK_CACHE; + cache->flag |= PTCACHE_DISK_CACHE; - BKE_ptcache_toggle_disk_cache(pid2); - } + BKE_ptcache_toggle_disk_cache(pid2); + } - strcpy(cache->prev_name, cache->name); + strcpy(cache->prev_name, cache->name); + } } BLI_freelistN(&pidlist); @@ -365,11 +383,16 @@ static void rna_def_pointcache(BlenderRNA *brna) RNA_def_property_ui_text(prop, "End", "Frame on which the simulation stops."); prop= RNA_def_property(srna, "step", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "step"); RNA_def_property_range(prop, 1, 20); RNA_def_property_ui_text(prop, "Cache Step", "Number of frames between cached frames."); RNA_def_property_update(prop, NC_OBJECT, "rna_Cache_change"); + prop= RNA_def_property(srna, "index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "index"); + RNA_def_property_range(prop, -1, 100); + RNA_def_property_ui_text(prop, "Cache Index", "Index number of cache files."); + RNA_def_property_update(prop, NC_OBJECT, "rna_Cache_idname_change"); + /* flags */ prop= RNA_def_property(srna, "baked", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_BAKED); @@ -398,6 +421,11 @@ static void rna_def_pointcache(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Name", "Cache name"); RNA_def_property_update(prop, NC_OBJECT, "rna_Cache_idname_change"); + prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_DIRPATH); + RNA_def_property_string_sdna(prop, NULL, "path"); + RNA_def_property_ui_text(prop, "File Path", "Cache file path."); + RNA_def_property_update(prop, NC_OBJECT, "rna_Cache_idname_change"); + prop= RNA_def_property(srna, "quick_cache", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_QUICK_CACHE); RNA_def_property_ui_text(prop, "Quick Cache", "Update simulation with cache steps"); @@ -407,6 +435,11 @@ static void rna_def_pointcache(BlenderRNA *brna) RNA_def_property_string_sdna(prop, NULL, "info"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Cache Info", "Info on current cache status."); + + prop= RNA_def_property(srna, "external", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", PTCACHE_EXTERNAL); + RNA_def_property_ui_text(prop, "External", "Read cache from an external location"); + RNA_def_property_update(prop, NC_OBJECT, "rna_Cache_idname_change"); } static void rna_def_collision(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index f07351f0a30..4caf915e7ea 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -616,33 +616,65 @@ static void rna_def_particle(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Stick Object", "Object that particle sticks to when dead"); -// ParticleKey state; /* normally current global coordinates or */ -// /* in sticky object space if dead & sticky */ -// -// ParticleKey prev_state; /* previous state */ + /* Particle State & Previous State */ + prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_VECTOR); + RNA_def_property_float_sdna(prop, NULL, "state.co"); + RNA_def_property_ui_text(prop, "Particle Location", ""); + + prop= RNA_def_property(srna, "velocity", PROP_FLOAT, PROP_VECTOR); + RNA_def_property_float_sdna(prop, NULL, "state.vel"); + RNA_def_property_ui_text(prop, "Particle Velocity", ""); + + prop= RNA_def_property(srna, "angular_velocity", PROP_FLOAT, PROP_VECTOR); + RNA_def_property_float_sdna(prop, NULL, "state.ave"); + RNA_def_property_ui_text(prop, "Angular Velocity", ""); + + prop= RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_ROTATION); + RNA_def_property_float_sdna(prop, NULL, "state.rot"); + RNA_def_property_ui_text(prop, "Rotation", ""); -// prop= RNA_def_property(srna, "hair", PROP_COLLECTION, PROP_NONE); -// RNA_def_property_collection_sdna(prop, NULL, "hair", "???totalHair???"); //don't know what the hair array size is -// RNA_def_property_struct_type(prop, "HairKey"); -// RNA_def_property_ui_text(prop, "Hair", ""); + prop= RNA_def_property(srna, "prev_location", PROP_FLOAT, PROP_VECTOR); + RNA_def_property_float_sdna(prop, NULL, "prev_state.co"); + RNA_def_property_ui_text(prop, "Previous Particle Location", ""); + + prop= RNA_def_property(srna, "prev_velocity", PROP_FLOAT, PROP_VECTOR); + RNA_def_property_float_sdna(prop, NULL, "prev_state.vel"); + RNA_def_property_ui_text(prop, "Previous Particle Velocity", ""); + + prop= RNA_def_property(srna, "prev_angular_velocity", PROP_FLOAT, PROP_VECTOR); + RNA_def_property_float_sdna(prop, NULL, "prev_state.ave"); + RNA_def_property_ui_text(prop, "Previous Angular Velocity", ""); + + prop= RNA_def_property(srna, "prev_rotation", PROP_FLOAT, PROP_ROTATION); + RNA_def_property_float_sdna(prop, NULL, "prev_state.rot"); + RNA_def_property_ui_text(prop, "Previous Rotation", ""); + + /* Hair & Keyed Keys */ + + prop= RNA_def_property(srna, "hair", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "hair", "totkey"); + RNA_def_property_struct_type(prop, "ParticleHairKey"); + RNA_def_property_ui_text(prop, "Hair", ""); prop= RNA_def_property(srna, "keys", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "keys", "totkey"); RNA_def_property_struct_type(prop, "ParticleKey"); RNA_def_property_ui_text(prop, "Keyed States", ""); - prop= RNA_def_property(srna, "random_rotation", PROP_FLOAT, PROP_NONE); + /* Random variables */ + + prop= RNA_def_property(srna, "random_rotation", PROP_FLOAT, PROP_ROTATION); RNA_def_property_float_sdna(prop, NULL, "r_rot"); // RNA_def_property_range(prop, lowerLimitf, upperLimitf); RNA_def_property_ui_text(prop, "Random Rotation", ""); - prop= RNA_def_property(srna, "random_a_velocity", PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(srna, "random_a_velocity", PROP_FLOAT, PROP_VECTOR); RNA_def_property_float_sdna(prop, NULL, "r_ave"); // RNA_def_property_range(prop, lowerLimitf, upperLimitf); - RNA_def_property_ui_text(prop, "Random erm.. Velocity", "");//TODO: fix name + RNA_def_property_ui_text(prop, "Random Angular Velocity", ""); - prop= RNA_def_property(srna, "random_velocity", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "r_ve");//optional if prop names are the same + prop= RNA_def_property(srna, "random_velocity", PROP_FLOAT, PROP_VECTOR); + RNA_def_property_float_sdna(prop, NULL, "r_ve"); // RNA_def_property_range(prop, lowerLimitf, upperLimitf); RNA_def_property_ui_text(prop, "Random Velocity", ""); @@ -650,9 +682,10 @@ static void rna_def_particle(BlenderRNA *brna) // float fuv[4], foffset; /* coordinates on face/edge number "num" and depth along*/ // /* face normal for volume emission */ - prop= RNA_def_property(srna, "time", PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(srna, "birthtime", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "time"); // RNA_def_property_range(prop, lowerLimitf, upperLimitf); - RNA_def_property_ui_text(prop, "Time", ""); + RNA_def_property_ui_text(prop, "Birth Time", ""); prop= RNA_def_property(srna, "lifetime", PROP_FLOAT, PROP_NONE); // RNA_def_property_range(prop, lowerLimitf, upperLimitf); @@ -663,11 +696,6 @@ static void rna_def_particle(BlenderRNA *brna) // RNA_def_property_range(prop, lowerLimitf, upperLimitf); RNA_def_property_ui_text(prop, "Die Time", ""); -// prop= RNA_def_property(srna, "banking_angle", PROP_FLOAT, PROP_NONE); -// RNA_def_property_float_sdna(prop, NULL, "bank"); -//// RNA_def_property_range(prop, lowerLimitf, upperLimitf); -// RNA_def_property_ui_text(prop, "Banking Angle", ""); - prop= RNA_def_property(srna, "size", PROP_FLOAT, PROP_NONE); // RNA_def_property_range(prop, lowerLimitf, upperLimitf); RNA_def_property_ui_text(prop, "Size", ""); @@ -1133,12 +1161,14 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "draw_step", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 0, 7); + RNA_def_property_ui_range(prop, 0, 10, 1, 0); RNA_def_property_ui_text(prop, "Steps", "How many steps paths are drawn with (power of 2)"); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); prop= RNA_def_property(srna, "render_step", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "ren_step"); RNA_def_property_range(prop, 0, 9); + RNA_def_property_ui_range(prop, 0, 20, 1, 0); RNA_def_property_ui_text(prop, "Render", "How many steps paths are rendered with (power of 2)"); prop= RNA_def_property(srna, "hair_step", PROP_INT, PROP_NONE); @@ -1206,7 +1236,8 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "billboard_uv_split", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "bb_uv_split"); - RNA_def_property_range(prop, 1, 10); + RNA_def_property_range(prop, 1, 100); + RNA_def_property_ui_range(prop, 1, 10, 1, 0); RNA_def_property_ui_text(prop, "UV Split", "Amount of rows/columns to split uv coordinates for billboards"); prop= RNA_def_property(srna, "billboard_animation", PROP_ENUM, PROP_NONE); @@ -1234,7 +1265,8 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "billboard_offset", PROP_FLOAT, PROP_VECTOR); RNA_def_property_float_sdna(prop, NULL, "bb_offset"); RNA_def_property_array(prop, 2); - RNA_def_property_range(prop, -1.0f, 1.0f); + RNA_def_property_range(prop, -100.0f, 100.0f); + RNA_def_property_ui_range(prop, -1.0, 1.0, 0.1, 3); RNA_def_property_ui_text(prop, "Billboard Offset", ""); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); @@ -1314,7 +1346,11 @@ static void rna_def_particle_settings(BlenderRNA *brna) 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); + /* This limit is for those freaks who have the machine power to handle it. */ + /* 10M particles take around 2.2 Gb of memory / disk space in saved file and */ + /* each cached frame takes around 0.5 Gb of memory / disk space depending on cache mode. */ + RNA_def_property_range(prop, 0, 10000000); + RNA_def_property_ui_range(prop, 0, 100000, 1, 0); RNA_def_property_ui_text(prop, "Amount", "Total number of particles."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); @@ -1328,7 +1364,8 @@ static void rna_def_particle_settings(BlenderRNA *brna) 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_range(prop, 1, 46); /* ~100k particles in a cube */ + RNA_def_property_ui_range(prop, 1, 215, 1, 0); /* ~10M particles in a cube */ 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"); @@ -1341,7 +1378,8 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "object_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "obfac"); - RNA_def_property_range(prop, -1.0f, 1.0f); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, -1.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Object", "Let the object give the particle a starting speed"); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); @@ -1353,7 +1391,8 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "particle_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "partfac"); - RNA_def_property_range(prop, -10.0f, 10.0f); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, -1.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Particle", "Let the target particle give the particle a starting speed."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); @@ -1401,13 +1440,15 @@ static void rna_def_particle_settings(BlenderRNA *brna) /* physical properties */ prop= RNA_def_property(srna, "mass", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.01f, 100.0f); + RNA_def_property_range(prop, 0.001f, 100000.0f); + RNA_def_property_ui_range(prop, 0.01f, 100.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Mass", "Specify the mass of the particles"); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); prop= RNA_def_property(srna, "particle_size", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "size"); - RNA_def_property_range(prop, 0.01f, 100.0f); + RNA_def_property_range(prop, 0.001f, 100000.0f); + RNA_def_property_ui_range(prop, 0.01f, 100.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Size", "The size of the particles"); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); @@ -1466,13 +1507,15 @@ static void rna_def_particle_settings(BlenderRNA *brna) /* children */ prop= RNA_def_property(srna, "child_nbr", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "child_nbr");//optional if prop names are the same - RNA_def_property_range(prop, 0, MAX_PART_CHILDREN); + RNA_def_property_range(prop, 0, 100000); + RNA_def_property_ui_range(prop, 0, 1000, 1, 0); RNA_def_property_ui_text(prop, "Children Per Parent", "Amount of children/parent"); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "rendered_child_nbr", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "ren_child_nbr"); - RNA_def_property_range(prop, 0, MAX_PART_CHILDREN); + RNA_def_property_range(prop, 0, 100000); + RNA_def_property_ui_range(prop, 0, 10000, 1, 0); RNA_def_property_ui_text(prop, "Rendered Children", "Amount of children/parent for rendering."); prop= RNA_def_property(srna, "virtual_parents", PROP_FLOAT, PROP_NONE); @@ -1483,7 +1526,8 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "child_size", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "childsize"); - RNA_def_property_range(prop, 0.01f, 100.0f); + RNA_def_property_range(prop, 0.001f, 100000.0f); + RNA_def_property_ui_range(prop, 0.01f, 100.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Child Size", "A multiplier for the child particle size."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); @@ -1522,13 +1566,15 @@ static void rna_def_particle_settings(BlenderRNA *brna) /* kink */ prop= RNA_def_property(srna, "kink_amplitude", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "kink_amp"); - RNA_def_property_range(prop, 0.0f, 10.0f); + RNA_def_property_range(prop, -100000.0f, 100000.0f); + RNA_def_property_ui_range(prop, -10.0f, 10.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Amplitude", "The amplitude of the offset."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "kink_frequency", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "kink_freq"); - RNA_def_property_range(prop, 0.0f, 10.0f); + RNA_def_property_range(prop, -100000.0f, 100000.0f); + RNA_def_property_ui_range(prop, -10.0f, 10.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Frequency", "The frequency of the offset (1/total length)"); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); @@ -1540,24 +1586,28 @@ static void rna_def_particle_settings(BlenderRNA *brna) /* rough */ prop= RNA_def_property(srna, "rough1", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.0f, 10.0f); + RNA_def_property_range(prop, 0.0f, 100000.0f); + RNA_def_property_ui_range(prop, 0.0f, 10.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Rough1", "Amount of location dependent rough."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "rough1_size", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.01f, 10.0f); + RNA_def_property_range(prop, 0.01f, 100000.0f); + RNA_def_property_ui_range(prop, 0.01f, 10.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Size1", "Size of location dependent rough."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "rough2", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rough2"); - RNA_def_property_range(prop, 0.0f, 10.0f); + RNA_def_property_range(prop, 0.0f, 100000.0f); + RNA_def_property_ui_range(prop, 0.0f, 10.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Rough2", "Amount of random rough."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); prop= RNA_def_property(srna, "rough2_size", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rough2_size"); - RNA_def_property_range(prop, 0.01f, 10.0f); + RNA_def_property_range(prop, 0.01f, 100000.0f); + RNA_def_property_ui_range(prop, 0.01f, 10.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Size2", "Size of random rough."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); @@ -1569,7 +1619,8 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "rough_endpoint", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "rough_end"); - RNA_def_property_range(prop, 0.0f, 10.0f); + RNA_def_property_range(prop, 0.0f, 100000.0f); + RNA_def_property_ui_range(prop, 0.0f, 10.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Rough Endpoint", "Amount of end point rough."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo_child"); @@ -1600,13 +1651,15 @@ static void rna_def_particle_settings(BlenderRNA *brna) /* drawing stuff */ prop= RNA_def_property(srna, "line_length_tail", PROP_FLOAT, PROP_NONE); RNA_def_property_float_funcs(prop, "rna_PartSetting_linelentail_get", "rna_PartSetting_linelentail_set", NULL); - RNA_def_property_range(prop, 0.0f, 10.0f); + RNA_def_property_range(prop, 0.0f, 100000.0f); + RNA_def_property_ui_range(prop, 0.0f, 10.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Back", "Length of the line's tail"); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); prop= RNA_def_property(srna, "line_length_head", PROP_FLOAT, PROP_NONE); RNA_def_property_float_funcs(prop, "rna_PartSetting_linelenhead_get", "rna_PartSetting_linelenhead_set", NULL); - RNA_def_property_range(prop, 0.0f, 10.0f); + RNA_def_property_range(prop, 0.0f, 100000.0f); + RNA_def_property_ui_range(prop, 0.0f, 10.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Head", "Length of the line's head"); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_redo"); @@ -1624,14 +1677,16 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "trail_count", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "trail_count"); - RNA_def_property_range(prop, 1.0f, 100.0f); + RNA_def_property_range(prop, 1, 100000); + RNA_def_property_ui_range(prop, 1, 100, 1, 0); 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_range(prop, 1.0f, 10000.0f); + RNA_def_property_ui_range(prop, 1.0f, 100.0f, 0.1, 3); 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"); @@ -1674,61 +1729,71 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "eweight_all", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[0]"); - RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "All", "All effector's weight."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_spherical", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[1]"); - RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Spherical", "Spherical effector weight."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_vortex", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[2]"); - RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Vortex", "Vortex effector weight."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_magnetic", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[3]"); - RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Magnetic", "Magnetic effector weight."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_wind", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[4]"); - RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Wind", "Wind effector weight."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_curveguide", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[5]"); - RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Curve Guide", "Curve guide effector weight."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_texture", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[6]"); - RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Magnetic", "Texture effector weight."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_harmonic", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[7]"); - RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Harmonic", "Harmonic effector weight."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_charge", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[8]"); - RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Charge", "Charge effector weight."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); prop= RNA_def_property(srna, "eweight_lennardjones", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "effector_weight[9]"); - RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Lennard-Jones", "Lennard-Jones effector weight."); RNA_def_property_update(prop, NC_OBJECT|ND_PARTICLE, "rna_Particle_reset"); |