[Bf-blender-cvs] [2c004a257ed] hair_object: Apply the hair curve transformation to vertices when drawing.
Lukas Tönne
noreply at git.blender.org
Wed Nov 28 09:28:09 CET 2018
Commit: 2c004a257ed6c84559730b1934cc1e4217fa3b01
Author: Lukas Tönne
Date: Wed Nov 28 08:27:06 2018 +0000
Branches: hair_object
https://developer.blender.org/rB2c004a257ed6c84559730b1934cc1e4217fa3b01
Apply the hair curve transformation to vertices when drawing.
===================================================================
M source/blender/blenkernel/BKE_hair_iterators.h
M source/blender/blenkernel/intern/hair.c
M source/blender/draw/intern/draw_cache_impl_hair.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_hair_iterators.h b/source/blender/blenkernel/BKE_hair_iterators.h
index 769102ca920..c835fc7d403 100644
--- a/source/blender/blenkernel/BKE_hair_iterators.h
+++ b/source/blender/blenkernel/BKE_hair_iterators.h
@@ -252,6 +252,15 @@ BLI_INLINE HairFiberVertex* BKE_hair_iter__curve_verts_next(HairIterator *iter)
(ele) = BKE_hair_iter__follicle_curves_next((iter)), \
(curvevar) = (iter)->data.follicle_curves.curve)
+#define BKE_HAIR_ITER_FOLLICLE_CURVES_INDEX(ele, curvevar, iter, curve_data, indexvar) \
+ for ((ele) = BKE_hair_iter__follicle_curves_init((iter), (curve_data)), \
+ (curvevar) = (iter)->data.follicle_curves.curve, \
+ (indexvar = 0); \
+ BKE_hair_iter__follicle_curves_valid(iter); \
+ (ele) = BKE_hair_iter__follicle_curves_next((iter)), \
+ (curvevar) = (iter)->data.follicle_curves.curve, \
+ ++(indexvar))
+
#define BKE_HAIR_ITER_CURVE_VERTS(ele, iter, curve_data, curve) \
for ((ele) = BKE_hair_iter__curve_verts_init((iter), (curve_data), (curve)); \
BKE_hair_iter__curve_verts_valid(iter); \
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index 7f1ed9309d3..402d9936f70 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -619,7 +619,7 @@ void BKE_hair_ensure_follicle_space(const Mesh *scalp, HairCurveData *curve_data
float (*tang)[3] = tangents;
const HairFollicle *follicle = BKE_hair_get_follicles(curve_data);
for (int i = 0; i < num_follicles; ++i) {
- BKE_mesh_sample_eval(scalp, &follicle->mesh_sample, co, nor, tang);
+ BKE_mesh_sample_eval(scalp, &follicle->mesh_sample, *co, *nor, *tang);
++co;
++nor;
diff --git a/source/blender/draw/intern/draw_cache_impl_hair.c b/source/blender/draw/intern/draw_cache_impl_hair.c
index a47a63346f9..faea1e8b129 100644
--- a/source/blender/draw/intern/draw_cache_impl_hair.c
+++ b/source/blender/draw/intern/draw_cache_impl_hair.c
@@ -174,27 +174,47 @@ static void hair_batch_cache_ensure_count(
}
}
+static bool hair_get_local_space(const float (*orco)[3], const float (*normals)[3], const float (*tangents)[3], int index, float r[4][4])
+{
+ if (!orco || !normals || !tangents) {
+ unit_m4(r);
+ return false;
+ }
+
+ copy_v3_v3(r[1], tangents[index]);
+ copy_v3_v3(r[2], normals[index]);
+ cross_v3_v3v3(r[0], r[1], r[2]);
+ copy_v3_v3(r[3], orco[index]);
+ return true;
+}
+
static void hair_batch_cache_fill_segments_proc_pos(
const HairCurveData *curve_data,
GPUVertBufRaw *attr_step)
{
const HairFiberVertex *verts = BKE_hair_get_verts(curve_data);
+ float (*orco)[3] = CustomData_get_layer(&curve_data->fdata, CD_ORCO);
+ float (*normals)[3] = CustomData_get_layer(&curve_data->fdata, CD_NORMAL);
+ float (*tangents)[3] = CustomData_get_layer(&curve_data->fdata, CD_TANGENT);
HairIterator iter;
HairFollicle *follicle;
HairFiberCurve *curve;
- BKE_HAIR_ITER_FOLLICLE_CURVES(follicle, curve, &iter, curve_data) {
+ int curve_idx;
+ BKE_HAIR_ITER_FOLLICLE_CURVES_INDEX(follicle, curve, &iter, curve_data, curve_idx) {
if (curve->numverts < 2) {
continue;
}
+ float hmat[4][4];
+ hair_get_local_space(orco, normals, tangents, curve_idx, hmat);
const HairFiberVertex *vert_start = &verts[curve->vertstart];
float total_len = 0.0f;
const float *co_prev = NULL;
float *seg_data_first;
for (int j = 0; j < curve->numverts; j++) {
float *seg_data = (float *)GPU_vertbuf_raw_step(attr_step);
- copy_v3_v3(seg_data, vert_start[j].co);
+ mul_v3_m4v3(seg_data, hmat, vert_start[j].co);
if (co_prev) {
- total_len += len_v3v3(co_prev, vert_start[j].co);
+ total_len += len_v3v3(co_prev, seg_data);
}
else {
seg_data_first = seg_data;
@@ -452,8 +472,8 @@ static void hair_batch_cache_ensure_final_count(
HairFiberCurve *curve;
BKE_HAIR_ITER_FOLLICLE_CURVES(follicle, curve, &iter, curve_data) {
/* +1 for primitive restart */
- cache->elems_len += ((curve->numverts - 1) << subdiv + 1) * thickness_res;
- cache->point_len += (curve->numverts - 1) << subdiv + 1;
+ cache->elems_len += (((curve->numverts - 1) << subdiv) + 2) * thickness_res;
+ cache->point_len += ((curve->numverts - 1) << subdiv) + 1;
}
}
@@ -492,7 +512,7 @@ static int hair_batch_cache_fill_segments_indices(
continue;
}
- const int res = ((curve->numverts - 1) << subdiv) * thickness_res;
+ const int res = (((curve->numverts - 1) << subdiv) + 1) * thickness_res;
for (int k = 0; k < res; k++) {
GPU_indexbuf_add_generic_vert(elb, curr_point++);
}
@@ -672,14 +692,20 @@ static int hair_batch_cache_fill_segments(
{
int curr_point = 0;
const HairFiberVertex *verts = BKE_hair_get_verts(curve_data);
+ float (*orco)[3] = CustomData_get_layer(&curve_data->fdata, CD_ORCO);
+ float (*normals)[3] = CustomData_get_layer(&curve_data->fdata, CD_NORMAL);
+ float (*tangents)[3] = CustomData_get_layer(&curve_data->fdata, CD_TANGENT);
const HairFollicle *follicle;
const HairFiberCurve *curve;
HairIterator iter;
- BKE_HAIR_ITER_FOLLICLE_CURVES(follicle, curve, &iter, curve_data) {
+ int curve_idx;
+ BKE_HAIR_ITER_FOLLICLE_CURVES_INDEX(follicle, curve, &iter, curve_data, curve_idx) {
if (curve->numverts < 2) {
continue;
}
+ float hmat[4][4];
+ hair_get_local_space(orco, normals, tangents, curve_idx, hmat);
for (int k = 0; k < scalp_attr->num_uv_layers; k++) {
BKE_mesh_sample_eval_uv(scalp, &follicle->mesh_sample, k, scalp_attr->hair_uv[k]);
}
@@ -694,10 +720,13 @@ static int hair_batch_cache_fill_segments(
const HairFiberVertex *vert = vert_start + j;
const HairFiberVertex *vert_prev = (j > 0 ? vert_start + j - 1 : vert_start + j);
const HairFiberVertex *vert_next = (j < curve->numverts-1 ? vert_start + j + 1 : vert_start + j);
+ float co[3];
+ mul_v3_m4v3(co, hmat, vert->co);
float tangent[3];
sub_v3_v3v3(tangent, vert_next->co, vert_prev->co);
+ mul_mat3_m4_v3(hmat, tangent);
- GPU_vertbuf_attr_set(hair_cache->pos, attr_id->pos, curr_point, vert->co);
+ GPU_vertbuf_attr_set(hair_cache->pos, attr_id->pos, curr_point, co);
GPU_vertbuf_attr_set(hair_cache->pos, attr_id->tan, curr_point, tangent);
GPU_vertbuf_attr_set(hair_cache->pos, attr_id->ind, curr_point, &j);
More information about the Bf-blender-cvs
mailing list