diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2014-08-26 21:29:16 +0400 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2015-01-20 11:29:21 +0300 |
commit | 5f41b19463bb4af38880ecda0839c2a20cf45d74 (patch) | |
tree | 42ec2f12bad4e876ec304f34afc73ff5687287d8 | |
parent | 4cd6111159715f8efb52d7ce38f99d0bdb8f0cb5 (diff) |
New voxel texture mode "Hair", for displaying the internal hair volume
structure as a texture.
This is mostly a debugging feature that may be removed again later.
-rw-r--r-- | release/scripts/startup/bl_ui/properties_texture.py | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_cloth.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/implicit.c | 124 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_texture_types.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_texture.c | 1 | ||||
-rw-r--r-- | source/blender/render/intern/source/voxeldata.c | 26 |
6 files changed, 137 insertions, 20 deletions
diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index e491d3a7761..675655e7035 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -771,6 +771,8 @@ class TEXTURE_PT_voxeldata(TextureButtonsPanel, Panel): elif vd.file_format == 'SMOKE': layout.prop(vd, "domain_object") layout.prop(vd, "smoke_data_type") + elif vd.file_format == 'HAIR': + layout.prop(vd, "domain_object") elif vd.file_format == 'IMAGE_SEQUENCE': layout.template_ID(tex, "image", open="image.open") layout.template_image(tex, "image", tex.image_user, compact=True) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 757d63e6ec1..a6e1058f86e 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -42,6 +42,7 @@ struct MFace; struct DerivedMesh; struct ClothModifierData; struct CollisionTree; +struct VoxelData; #define DO_INLINE MALWAYS_INLINE @@ -196,6 +197,8 @@ int implicit_free (struct ClothModifierData *clmd ); int implicit_solver (struct Object *ob, float frame, struct ClothModifierData *clmd, struct ListBase *effectors ); void implicit_set_positions (struct ClothModifierData *clmd ); +bool implicit_hair_volume_get_texture_data(struct Object *UNUSED(ob), struct ClothModifierData *clmd, struct ListBase *UNUSED(effectors), struct VoxelData *vd); + ///////////////////////////////////////////////// // cloth.c //////////////////////////////////////////////// diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 9264aa2d8b9..56d0d7dd0e5 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -36,6 +36,7 @@ #include "DNA_object_types.h" #include "DNA_object_force.h" #include "DNA_meshdata_types.h" +#include "DNA_texture_types.h" #include "BLI_math.h" #include "BLI_linklist.h" @@ -1293,34 +1294,33 @@ static void hair_velocity_collision(const HairGridVert *collgrid, const float gm } } -static void hair_volume_forces(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, unsigned int numverts) +static void hair_volume_get_boundbox(lfVector *lX, unsigned int numverts, float gmin[3], float gmax[3]) +{ + int i; + + INIT_MINMAX(gmin, gmax); + for (i = 0; i < numverts; i++) + DO_MINMAX(lX[i], gmin, gmax); +} + +static HairGridVert *hair_volume_create_hair_grid(ClothModifierData *clmd, lfVector *lX, lfVector *lV, unsigned int numverts) { int size = hair_grid_size(hair_grid_res); HairGridVert *hairgrid; - HairGridVert *collgrid; - ListBase *colliders; - ColliderCache *col = NULL; float gmin[3], gmax[3], density; /* 2.0f is an experimental value that seems to give good results */ float smoothfac = 2.0f * clmd->sim_parms->velocity_smooth; - float collfac = 2.0f * clmd->sim_parms->collider_friction; unsigned int v = 0; int i = 0; - INIT_MINMAX(gmin, gmax); - for (i = 0; i < numverts; i++) - DO_MINMAX(lX[i], gmin, gmax); + hair_volume_get_boundbox(lX, numverts, gmin, gmax); hairgrid = MEM_mallocN(sizeof(HairGridVert) * size, "hair voxel data"); - collgrid = MEM_mallocN(sizeof(HairGridVert) * size, "hair collider voxel data"); /* initialize grid */ for (i = 0; i < size; ++i) { zero_v3(hairgrid[i].velocity); hairgrid[i].density = 0.0f; - - zero_v3(collgrid[i].velocity); - collgrid[i].density = 0.0f; } /* gather velocities & density */ @@ -1335,6 +1335,42 @@ static void hair_volume_forces(ClothModifierData *clmd, lfVector *lF, lfVector * } } + /* divide velocity with density */ + for (i = 0; i < size; i++) { + density = hairgrid[i].density; + if (density > 0.0f) { + hairgrid[i].velocity[0] /= density; + hairgrid[i].velocity[1] /= density; + hairgrid[i].velocity[2] /= density; + } + } + + return hairgrid; +} + + +static HairGridVert *hair_volume_create_collision_grid(ClothModifierData *clmd, lfVector *lX, unsigned int numverts) +{ + int size = hair_grid_size(hair_grid_res); + HairGridVert *collgrid; + ListBase *colliders; + ColliderCache *col = NULL; + float gmin[3], gmax[3], density; + /* 2.0f is an experimental value that seems to give good results */ + float collfac = 2.0f * clmd->sim_parms->collider_friction; + unsigned int v = 0; + int i = 0; + + hair_volume_get_boundbox(lX, numverts, gmin, gmax); + + collgrid = MEM_mallocN(sizeof(HairGridVert) * size, "hair collider voxel data"); + + /* initialize grid */ + for (i = 0; i < size; ++i) { + zero_v3(collgrid[i].velocity); + collgrid[i].density = 0.0f; + } + /* gather colliders */ colliders = get_collider_cache(clmd->scene, NULL, NULL); if (colliders && collfac > 0.0f) { @@ -1359,13 +1395,6 @@ static void hair_volume_forces(ClothModifierData *clmd, lfVector *lF, lfVector * /* divide velocity with density */ for (i = 0; i < size; i++) { - density = hairgrid[i].density; - if (density > 0.0f) { - hairgrid[i].velocity[0] /= density; - hairgrid[i].velocity[1] /= density; - hairgrid[i].velocity[2] /= density; - } - density = collgrid[i].density; if (density > 0.0f) { collgrid[i].velocity[0] /= density; @@ -1373,6 +1402,21 @@ static void hair_volume_forces(ClothModifierData *clmd, lfVector *lF, lfVector * collgrid[i].velocity[2] /= density; } } + + return collgrid; +} + +static void hair_volume_forces(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVector *lV, unsigned int numverts) +{ + HairGridVert *hairgrid, *collgrid; + float gmin[3], gmax[3]; + /* 2.0f is an experimental value that seems to give good results */ + float smoothfac = 2.0f * clmd->sim_parms->velocity_smooth; + float collfac = 2.0f * clmd->sim_parms->collider_friction; + + hair_volume_get_boundbox(lX, numverts, gmin, gmax); + hairgrid = hair_volume_create_hair_grid(clmd, lX, lV, numverts); + collgrid = hair_volume_create_collision_grid(clmd, lX, numverts); hair_velocity_smoothing(hairgrid, gmin, gmax, smoothfac, lF, lX, lV, numverts); hair_velocity_collision(collgrid, gmin, gmax, collfac, lF, lX, lV, numverts); @@ -1381,6 +1425,47 @@ static void hair_volume_forces(ClothModifierData *clmd, lfVector *lF, lfVector * MEM_freeN(collgrid); } +bool implicit_hair_volume_get_texture_data(Object *UNUSED(ob), ClothModifierData *clmd, ListBase *UNUSED(effectors), VoxelData *vd) +{ + lfVector *lX, *lV; + HairGridVert *hairgrid/*, *collgrid*/; + int numverts; + int totres, i; + + if (!clmd->clothObject || !clmd->clothObject->implicit) + return false; + + lX = clmd->clothObject->implicit->X; + lV = clmd->clothObject->implicit->V; + numverts = clmd->clothObject->numverts; + + hairgrid = hair_volume_create_hair_grid(clmd, lX, lV, numverts); +// collgrid = hair_volume_create_collision_grid(clmd, lX, numverts); + + vd->resol[0] = hair_grid_res; + vd->resol[1] = hair_grid_res; + vd->resol[2] = hair_grid_res; + + totres = hair_grid_size(hair_grid_res); + + vd->data_type = TEX_VD_INTENSITY; + if (totres > 0) { + vd->dataset = (float *)MEM_mapallocN(sizeof(float) * (totres), "hair volume texture data"); + for (i = 0; i < totres; ++i) { + vd->dataset[i] = hairgrid[i].density; + } + } + else + vd->dataset = NULL; + + MEM_freeN(hairgrid); +// MEM_freeN(collgrid); + + return true; +} + +/* ================================ */ + static void cloth_calc_force(ClothModifierData *clmd, float UNUSED(frame), lfVector *lF, lfVector *lX, lfVector *lV, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, ListBase *effectors, float time, fmatrix3x3 *M) { /* Collect forces and derivatives: F, dFdX, dFdV */ @@ -1798,4 +1883,3 @@ void implicit_set_positions(ClothModifierData *clmd) if (G.debug_value > 0) printf("implicit_set_positions\n"); } - diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 042645eeb76..4209ce8168d 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -617,6 +617,7 @@ enum { #define TEX_VD_RAW_16BIT 2 #define TEX_VD_IMAGE_SEQUENCE 3 #define TEX_VD_SMOKE 4 +#define TEX_VD_HAIR 5 /* for voxels which use VoxelData->source_path */ #define TEX_VD_IS_SOURCE_PATH(_format) (ELEM(_format, TEX_VD_BLENDERVOXEL, TEX_VD_RAW_8BIT, TEX_VD_RAW_16BIT)) diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 188a30d23ce..26644ba1a5d 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -1851,6 +1851,7 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna) {TEX_VD_IMAGE_SEQUENCE, "IMAGE_SEQUENCE", 0, "Image Sequence", "Generate voxels from a sequence of image slices"}, {TEX_VD_SMOKE, "SMOKE", 0, "Smoke", "Render voxels from a Blender smoke simulation"}, + {TEX_VD_HAIR, "HAIR", 0, "Hair", "Render voxels from a Blender hair simulation"}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index f21a1e5fa9b..d360282d985 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -51,6 +51,7 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" +#include "BKE_cloth.h" #include "BKE_global.h" #include "BKE_image.h" #include "BKE_main.h" @@ -61,6 +62,7 @@ #include "DNA_texture_types.h" #include "DNA_object_force.h" #include "DNA_object_types.h" +#include "DNA_particle_types.h" #include "DNA_modifier_types.h" #include "DNA_smoke_types.h" @@ -364,6 +366,27 @@ static void init_frame_smoke(VoxelData *vd, int cfra) #endif } +static void init_frame_hair(VoxelData *vd, int UNUSED(cfra)) +{ + Object *ob; + ModifierData *md; + bool found = false; + + vd->dataset = NULL; + if (vd->object == NULL) return; + ob = vd->object; + + if ((md = (ModifierData *)modifiers_findByType(ob, eModifierType_ParticleSystem))) { + ParticleSystemModifierData *pmd = (ParticleSystemModifierData *)md; + + if (pmd->psys && pmd->psys->clmd) { + found |= implicit_hair_volume_get_texture_data(ob, pmd->psys->clmd, NULL, vd); + } + } + + vd->ok = found; +} + void cache_voxeldata(Tex *tex, int scene_frame) { VoxelData *vd = tex->vd; @@ -397,6 +420,9 @@ void cache_voxeldata(Tex *tex, int scene_frame) case TEX_VD_SMOKE: init_frame_smoke(vd, scene_frame); return; + case TEX_VD_HAIR: + init_frame_hair(vd, scene_frame); + return; case TEX_VD_BLENDERVOXEL: BLI_path_abs(path, G.main->name); if (!BLI_exists(path)) return; |