"Fix" for [#30098] Particle rotation wrong / explode modifier
authorJanne Karhu <jhkarh@gmail.com>
Sun, 18 Mar 2012 21:33:00 +0000 (21:33 +0000)
committerJanne Karhu <jhkarh@gmail.com>
Sun, 18 Mar 2012 21:33:00 +0000 (21:33 +0000)
- The main problem was that in order to be accurate all particle
  rotations have to be calculated incrementally so the only working
  solution is to store rotations to the point cache (previously
  this was only done for dynamic rotations). This can nearly double
  the point cache size so it's not ideal to have this as a default
  as in many cases you don't care about particle rotations.
- Particle rotation panel now has a new "enable" checkbox that
  enables rotation calculations and the storing of rotations to
  point cache.
- Old files will have rotations enabled via do_versions so that in
  the worst case old files will only get bigger point caches, but no
  sudden loss of particle rotations.

release/scripts/startup/bl_ui/properties_particle.py
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/pointcache.c
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_particle_types.h
source/blender/makesrna/intern/rna_particle.c

index 4e511f18cd4dfd76650780a1160325573576590d..c987ceb2562e103e12b0c22d50c59967df3dd8b1 100644 (file)
@@ -380,6 +380,7 @@ class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel):
 
 class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel):
     bl_label = "Rotation"
+    bl_options = {'DEFAULT_CLOSED'}
     COMPAT_ENGINES = {'BLENDER_RENDER'}
 
     @classmethod
@@ -394,6 +395,15 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel):
         else:
             return False
 
+    def draw_header(self, context):
+        psys = context.particle_system
+        if psys:
+            part = psys.settings
+        else:
+            part = context.space_data.pin_id
+
+        self.layout.prop(part, "use_rotations", text="")
+
     def draw(self, context):
         layout = self.layout
 
@@ -403,7 +413,7 @@ class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel):
         else:
             part = context.space_data.pin_id
 
-        layout.enabled = particle_panel_enabled(context, psys)
+        layout.enabled = particle_panel_enabled(context, psys) and part.use_rotations
 
         layout.prop(part, "use_dynamic_rotation")
 
index 8b34bafc417d9a8a5fb639ccf72909803f1d16eb..c3e7e4531b9b95573422c03e2469f207f584d608 100644 (file)
@@ -2684,6 +2684,12 @@ static void basic_rotate(ParticleSettings *part, ParticleData *pa, float dfra, f
 {
        float rotfac, rot1[4], rot2[4]={1.0,0.0,0.0,0.0}, dtime=dfra*timestep;
 
+       if((part->flag & PART_ROTATIONS)==0) {
+               pa->state.rot[0]=1.0f;
+               pa->state.rot[1]=pa->state.rot[2]=pa->state.rot[3]=0;
+               return;
+       }
+
        if((part->flag & PART_ROT_DYN)==0) {
                if(part->avemode==PART_AVE_SPIN) {
                        float angle;
index b3c242178f1e6fa202836f201f94a1ebe95bcdf0..622c3ebe1194321887274aa8d7395f814fb0194d 100644 (file)
@@ -315,9 +315,10 @@ static void ptcache_particle_read(int index, void *psys_v, void **data, float cf
                }
        }
 
-       /* determine rotation from velocity */
+       /* default to no rotation */
        if(data[BPHYS_DATA_LOCATION] && !data[BPHYS_DATA_ROTATION]) {
-               vec_to_quat( pa->state.rot,pa->state.vel, OB_NEGX, OB_POSZ);
+               pa->state.rot[0]=1.0f;
+               pa->state.rot[1]=pa->state.rot[2]=pa->state.rot[3]=0;
        }
 }
 static void ptcache_particle_interpolate(int index, void *psys_v, void **data, float cfra, float cfra1, float cfra2, float *old_data)
@@ -815,13 +816,14 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *p
                pid->read_extra_data = ptcache_particle_extra_read;
        }
 
-       if(psys->part->rotmode!=PART_ROT_VEL
-               || psys->part->avemode!=PART_AVE_SPIN || psys->part->avefac!=0.0f)
-               pid->data_types|= (1<<BPHYS_DATA_AVELOCITY) | (1<<BPHYS_DATA_ROTATION);
-
-       if(psys->part->flag & PART_ROT_DYN)
+       if(psys->part->flag & PART_ROTATIONS) {
                pid->data_types|= (1<<BPHYS_DATA_ROTATION);
 
+               if(psys->part->rotmode!=PART_ROT_VEL
+                       || psys->part->avemode!=PART_AVE_SPIN || psys->part->avefac!=0.0f)
+                       pid->data_types|= (1<<BPHYS_DATA_AVELOCITY);
+       }
+
        pid->info_types= (1<<BPHYS_DATA_TIMES);
 
        pid->default_step = 10;
index 6dc2dea44f0fab002f9649e40da89c0b86770717..95a76dac6167c82d4595a9ebf63a83dfb386a914 100644 (file)
@@ -13292,6 +13292,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
        }
 
+       {
+               /* Default for old files is to save particle rotations to pointcache */
+               ParticleSettings *part;
+               for (part = main->particle.first; part; part = part->id.next)
+                       part->flag |= PART_ROTATIONS;
+       }
+
        /* put compatibility code here until next subversion bump */
        {
 
index 220ee69b442f861bce7ea78e044dd7848977b5f4..5bb4d1009e9811a0e636f71cc0aebe6f7c3943c9 100644 (file)
@@ -321,7 +321,7 @@ typedef struct ParticleSystem
 #define PART_TRAND                     128     
 #define PART_EDISTR                    256     /* particle/face from face areas */
 
-//#define PART_STICKY                  512     /*collided particles can stick to collider*/
+#define PART_ROTATIONS         512     /* calculate particle rotations (and store them in pointcache) */
 #define PART_DIE_ON_COL                (1<<12)
 #define PART_SIZE_DEFL         (1<<13) /* swept sphere deflections */
 #define PART_ROT_DYN           (1<<14) /* dynamic rotation */
index a83195acfe79eb08d42e62dd42d34b5ece6aaa73..35b5ca571cb94695841195e6b0a4db7e67673a7e 100644 (file)
@@ -1661,6 +1661,12 @@ static void rna_def_particle_settings(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Size Deflect", "Use particle's size in deflection");
        RNA_def_property_update(prop, 0, "rna_Particle_reset");
 
+       prop = RNA_def_property(srna, "use_rotations", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_ROTATIONS);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_ui_text(prop, "Rotations", "Calculate particle rotations");
+       RNA_def_property_update(prop, 0, "rna_Particle_reset");
+
        prop = RNA_def_property(srna, "use_dynamic_rotation", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_ROT_DYN);
        RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);