[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [23116] branches/blender2.5/blender: Hair dynamics with cloth simulation
Janne Karhu
jhkarh at utu.fi
Fri Sep 11 00:32:33 CEST 2009
Revision: 23116
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23116
Author: jhk
Date: 2009-09-11 00:32:33 +0200 (Fri, 11 Sep 2009)
Log Message:
-----------
Hair dynamics with cloth simulation
- Hair dynamics have their own panel in particle settings with the settings from cloth panel that apply to hair.
- Basic internal friction force to quickly emulate self collisions and volume preservation. (Still very early code, but gives some idea of what's possible).
- Softbody simulation is no longer used for hair.
* Old files with sb dynamics should just load the hair without dynamics so new dynamics can be applied.
* Invasion of particles exceptions in sb code is finally over.
- Collisions with other objects are disabled for now and will be worked out in the future.
Other changes/fixes:
- Particle mode editing flag wasn't saved properly.
- Some old files with edited hair didn't load correctly.
- Disabled delete & specials menu in particle mode for non-hair editing.
- Fixed yet one more cloth & softbody pointcache update issue.
- Disconnect/connect hair now uses only the deformed mesh so it works correctly also for subsurfed emitters.
- Hair editing now updates correctly with a moving emitter.
Modified Paths:
--------------
branches/blender2.5/blender/release/ui/buttons_particle.py
branches/blender2.5/blender/source/blender/blenkernel/BKE_cloth.h
branches/blender2.5/blender/source/blender/blenkernel/BKE_particle.h
branches/blender2.5/blender/source/blender/blenkernel/intern/cloth.c
branches/blender2.5/blender/source/blender/blenkernel/intern/implicit.c
branches/blender2.5/blender/source/blender/blenkernel/intern/object.c
branches/blender2.5/blender/source/blender/blenkernel/intern/particle.c
branches/blender2.5/blender/source/blender/blenkernel/intern/particle_system.c
branches/blender2.5/blender/source/blender/blenkernel/intern/pointcache.c
branches/blender2.5/blender/source/blender/blenkernel/intern/softbody.c
branches/blender2.5/blender/source/blender/blenloader/intern/readfile.c
branches/blender2.5/blender/source/blender/blenloader/intern/writefile.c
branches/blender2.5/blender/source/blender/editors/physics/editparticle.c
branches/blender2.5/blender/source/blender/editors/space_buttons/buttons_ops.c
branches/blender2.5/blender/source/blender/editors/space_view3d/drawobject.c
branches/blender2.5/blender/source/blender/makesdna/DNA_cloth_types.h
branches/blender2.5/blender/source/blender/makesdna/DNA_object_force.h
branches/blender2.5/blender/source/blender/makesdna/DNA_particle_types.h
branches/blender2.5/blender/source/blender/makesrna/intern/rna_cloth.c
branches/blender2.5/blender/source/blender/makesrna/intern/rna_particle.c
Modified: branches/blender2.5/blender/release/ui/buttons_particle.py
===================================================================
--- branches/blender2.5/blender/release/ui/buttons_particle.py 2009-09-10 20:41:18 UTC (rev 23115)
+++ branches/blender2.5/blender/release/ui/buttons_particle.py 2009-09-10 22:32:33 UTC (rev 23116)
@@ -154,8 +154,10 @@
if psys.edited==True:
if psys.global_hair:
layout.itemO("particle.connect_hair")
+ layout.itemL(text="Hair is disconnected.")
else:
layout.itemO("particle.disconnect_hair")
+ layout.itemL(text="")
elif part.type=='REACTOR':
split.enabled = particle_panel_enabled(psys)
split.itemR(psys, "reactor_target_object")
@@ -212,6 +214,53 @@
elif part.distribution=='GRID':
row.itemR(part, "grid_resolution")
+class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel):
+ __label__ = "Hair dynamics"
+ __default_closed__ = True
+
+ def poll(self, context):
+ psys = context.particle_system
+ if psys==None: return False
+ if psys.settings==None: return False
+ return psys.settings.type == 'HAIR'
+
+ def draw_header(self, context):
+ #cloth = context.cloth.collision_settings
+
+ #self.layout.active = cloth_panel_enabled(context.cloth)
+ #self.layout.itemR(cloth, "enable_collision", text="")
+ psys = context.particle_system
+ self.layout.itemR(psys, "hair_dynamics", text="")
+
+ def draw(self, context):
+ layout = self.layout
+
+ psys = context.particle_system
+ part = psys.settings
+ cloth = psys.cloth.settings
+
+ layout.enabled = psys.hair_dynamics
+
+ split = layout.split()
+
+ col = split.column()
+ col.itemL(text="Quality:")
+ col.itemR(cloth, "quality", text="Steps",slider=True)
+ col.itemL(text="Gravity:")
+ col.itemR(cloth, "gravity", text="")
+
+ col = split.column()
+ col.itemL(text="Material:")
+ sub = col.column(align=True)
+ sub.itemR(cloth, "pin_stiffness", text="Stiffness")
+ sub.itemR(cloth, "mass")
+ col.itemL(text="Damping:")
+ sub = col.column(align=True)
+ sub.itemR(cloth, "spring_damping", text="Spring")
+ sub.itemR(cloth, "air_damping", text="Air")
+
+ layout.itemR(cloth, "internal_friction", slider="True")
+
class PARTICLE_PT_cache(ParticleButtonsPanel):
__label__ = "Cache"
__default_closed__ = True
@@ -223,14 +272,14 @@
phystype = psys.settings.physics_type
if phystype == 'NO' or phystype == 'KEYED':
return False
- return psys.settings.type in ('EMITTER', 'REACTOR')
+ return psys.settings.type in ('EMITTER', 'REACTOR') or (psys.settings.type == 'HAIR' and psys.hair_dynamics)
def draw(self, context):
layout = self.layout
psys = context.particle_system
- point_cache_ui(self, psys.point_cache, particle_panel_enabled(psys), 1, 0)
+ point_cache_ui(self, psys.point_cache, particle_panel_enabled(psys), not psys.hair_dynamics, 0)
class PARTICLE_PT_initial(ParticleButtonsPanel):
__label__ = "Velocity"
@@ -897,6 +946,7 @@
#row.itemR(psys, "vertex_group_field_negate", text="")
bpy.types.register(PARTICLE_PT_particles)
+bpy.types.register(PARTICLE_PT_hair_dynamics)
bpy.types.register(PARTICLE_PT_cache)
bpy.types.register(PARTICLE_PT_emission)
bpy.types.register(PARTICLE_PT_initial)
Modified: branches/blender2.5/blender/source/blender/blenkernel/BKE_cloth.h
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/BKE_cloth.h 2009-09-10 20:41:18 UTC (rev 23115)
+++ branches/blender2.5/blender/source/blender/blenkernel/BKE_cloth.h 2009-09-10 22:32:33 UTC (rev 23116)
@@ -176,7 +176,8 @@
CLOTH_SIMSETTINGS_FLAG_GOAL = ( 1 << 3 ), // we have goals enabled
CLOTH_SIMSETTINGS_FLAG_TEARING = ( 1 << 4 ),// true if tearing is enabled
CLOTH_SIMSETTINGS_FLAG_SCALING = ( 1 << 8 ), /* is advanced scaling active? */
- CLOTH_SIMSETTINGS_FLAG_CCACHE_EDIT = (1 << 12) /* edit cache in editmode */
+ CLOTH_SIMSETTINGS_FLAG_CCACHE_EDIT = (1 << 12), /* edit cache in editmode */
+ CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS = (1 << 13) /* don't allow spring compression */
} CLOTH_SIMSETTINGS_FLAGS;
/* COLLISION FLAGS */
Modified: branches/blender2.5/blender/source/blender/blenkernel/BKE_particle.h
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/BKE_particle.h 2009-09-10 20:41:18 UTC (rev 23115)
+++ branches/blender2.5/blender/source/blender/blenkernel/BKE_particle.h 2009-09-10 22:32:33 UTC (rev 23116)
@@ -208,7 +208,7 @@
void psys_free_settings(struct ParticleSettings *part);
void free_child_path_cache(struct ParticleSystem *psys);
void psys_free_path_cache(struct ParticleSystem *psys, struct PTCacheEdit *edit);
-void free_hair(struct ParticleSystem *psys, int softbody);
+void free_hair(struct Object *ob, struct ParticleSystem *psys, int dynamics);
void free_keyed_keys(struct ParticleSystem *psys);
void psys_free_particles(struct ParticleSystem *psys);
void psys_free(struct Object * ob, struct ParticleSystem * psys);
Modified: branches/blender2.5/blender/source/blender/blenkernel/intern/cloth.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/intern/cloth.c 2009-09-10 20:41:18 UTC (rev 23115)
+++ branches/blender2.5/blender/source/blender/blenkernel/intern/cloth.c 2009-09-10 22:32:33 UTC (rev 23116)
@@ -496,9 +496,11 @@
if(!do_init_cloth(ob, clmd, result, framenr))
return result;
- if(framenr == startframe && cache->flag & PTCACHE_REDO_NEEDED) {
+ if(framenr == startframe) {
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+ do_init_cloth(ob, clmd, result, framenr);
cache->simframe= framenr;
+ cache->flag |= PTCACHE_SIMULATION_VALID;
cache->flag &= ~PTCACHE_REDO_NEEDED;
return result;
}
@@ -530,37 +532,26 @@
return result;
}
- if(framenr == startframe) {
- implicit_set_positions(clmd);
+ /* if on second frame, write cache for first frame */
+ if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
+ BKE_ptcache_write_cache(&pid, startframe);
- cache->simframe= framenr;
- cache->flag |= PTCACHE_SIMULATION_VALID;
+ clmd->sim_parms->timescale *= framenr - cache->simframe;
- /* don't write cache on first frame, but on second frame write
- * cache for frame 1 and 2 */
- }
- else {
- /* if on second frame, write cache for first frame */
- if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
- BKE_ptcache_write_cache(&pid, startframe);
+ /* do simulation */
+ cache->flag |= PTCACHE_SIMULATION_VALID;
+ cache->simframe= framenr;
- clmd->sim_parms->timescale *= framenr - cache->simframe;
-
- /* do simulation */
- cache->flag |= PTCACHE_SIMULATION_VALID;
- cache->simframe= framenr;
-
- if(!do_step_cloth(ob, clmd, result, framenr)) {
- cache->flag &= ~PTCACHE_SIMULATION_VALID;
- cache->simframe= 0;
- cache->last_exact= 0;
- }
- else
- BKE_ptcache_write_cache(&pid, framenr);
-
- cloth_to_object (ob, clmd, result);
+ if(!do_step_cloth(ob, clmd, result, framenr)) {
+ cache->flag &= ~PTCACHE_SIMULATION_VALID;
+ cache->simframe= 0;
+ cache->last_exact= 0;
}
+ else
+ BKE_ptcache_write_cache(&pid, framenr);
+ cloth_to_object (ob, clmd, result);
+
return result;
}
Modified: branches/blender2.5/blender/source/blender/blenkernel/intern/implicit.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/intern/implicit.c 2009-09-10 20:41:18 UTC (rev 23115)
+++ branches/blender2.5/blender/source/blender/blenkernel/intern/implicit.c 2009-09-10 22:32:33 UTC (rev 23116)
@@ -1183,7 +1183,8 @@
//return ( (I-outerprod(dir,dir))*Min(1.0f,rest/length) - I) * -k;
mul_fvectorT_fvector(to, dir, dir);
sub_fmatrix_fmatrix(to, I, to);
- mul_fmatrix_S(to, (((L/length)> 1.0f) ? (1.0f): (L/length)));
+
+ mul_fmatrix_S(to, (L/length));
sub_fmatrix_fmatrix(to, to, I);
mul_fmatrix_S(to, -k);
}
@@ -1218,6 +1219,8 @@
float nulldfdx[3][3]={ {0,0,0}, {0,0,0}, {0,0,0}};
float scaling = 0.0;
+
+ int no_compress = clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS;
VECCOPY(s->f, nullf);
cp_fmatrix(s->dfdx, nulldfdx);
@@ -1254,7 +1257,7 @@
// calculate force of structural + shear springs
if((s->type & CLOTH_SPRING_TYPE_STRUCTURAL) || (s->type & CLOTH_SPRING_TYPE_SHEAR))
{
- if(length > L) // only on elonglation
+ if(length > L || no_compress)
{
s->flags |= CLOTH_SPRING_FLAG_NEEDED;
@@ -1393,6 +1396,84 @@
return (INPR(wind, vertexnormal));
}
+typedef struct HairGridVert {
+ float velocity[3];
+ float density;
+} HairGridVert;
+/* Smoothing of hair velocities:
+ * adapted from
+ Volumetric Methods for Simulation and Rendering of Hair
+ by Lena Petrovic, Mark Henne and John Anderson
+ * Pixar Technical Memo #06-08, Pixar Animation Studios
+ */
+static void hair_velocity_smoothing(float smoothfac, lfVector *lF, lfVector *lX, lfVector *lV, int numverts)
+{
+ /* TODO: this is an initial implementation and should be made much better in due time */
+
+ /* 10x10x10 grid gives nice initial results */
+ HairGridVert grid[10][10][10];
+ float gmin[3], gmax[3], density;
+ int v = 0;
+ int i = 0;
+ int j = 0;
+ int k = 0;
+ lfVector temp;
+
+ INIT_MINMAX(gmin, gmax);
+
+ for(i = 0; i < numverts; i++)
+ DO_MINMAX(lX[i], gmin, gmax);
+
+ /* initialize grid */
+ for(i = 0; i < 10; i++) {
+ for(j = 0; j < 10; j++) {
+ for(k = 0; k < 10; k++) {
+ grid[i][j][k].velocity[0] = 0.0f;
+ grid[i][j][k].velocity[1] = 0.0f;
+ grid[i][j][k].velocity[2] = 0.0f;
+ grid[i][j][k].density = 0.0f;
+ }
+ }
+ }
+
+ /* gather velocities & density */
+ for(v = 0; v < numverts; v++) {
+ i = (int)( (lX[v][0] - gmin[0]) / (gmax[0] - gmin[0]) * 9.99f );
+ j = (int)( (lX[v][1] - gmin[1]) / (gmax[1] - gmin[1]) * 9.99f );
+ k = (int)( (lX[v][2] - gmin[2]) / (gmax[2] - gmin[2]) * 9.99f );
+
+ grid[i][j][k].velocity[0] += lV[v][0];
+ grid[i][j][k].velocity[1] += lV[v][1];
+ grid[i][j][k].velocity[2] += lV[v][2];
+ grid[i][j][k].density += 1.0f;
+ }
+
+ /* divide velocity with density */
+ for(i = 0; i < 10; i++) {
+ for(j = 0; j < 10; j++) {
+ for(k = 0; k < 10; k++) {
+ density = grid[i][j][k].density;
+ if(density > 0.0f) {
+ grid[i][j][k].velocity[0] /= density;
+ grid[i][j][k].velocity[1] /= density;
+ grid[i][j][k].velocity[2] /= density;
+ }
+ }
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list