[Bf-blender-cvs] [f2eb589] strand_gpu: Calculate barycentric interpolation weights using a simple kdTree method.
Lukas Tönne
noreply at git.blender.org
Tue Jul 5 09:57:12 CEST 2016
Commit: f2eb589201bcde4cd7a1db1f3dfbf9f54dbb5a58
Author: Lukas Tönne
Date: Sat Jul 2 12:07:15 2016 +0200
Branches: strand_gpu
https://developer.blender.org/rBf2eb589201bcde4cd7a1db1f3dfbf9f54dbb5a58
Calculate barycentric interpolation weights using a simple kdTree method.
This method uses the 3 closest points on the scalp for defining interpolation
weights. This method has drawbacks in cases of thin geometry, but it is
simple to implement.
===================================================================
M source/blender/blenkernel/intern/strands.c
M source/blender/gpu/intern/gpu_strands.c
===================================================================
diff --git a/source/blender/blenkernel/intern/strands.c b/source/blender/blenkernel/intern/strands.c
index cd55968..0489831 100644
--- a/source/blender/blenkernel/intern/strands.c
+++ b/source/blender/blenkernel/intern/strands.c
@@ -33,6 +33,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_kdtree.h"
#include "BLI_math.h"
#include "BKE_DerivedMesh.h"
@@ -195,6 +196,63 @@ void BKE_strands_test_init(struct Strands *strands, struct DerivedMesh *scalp,
strands->totverts = totverts;
}
+static void strands_calc_weights(const Strands *strands, struct DerivedMesh *scalp, StrandRoot *roots, int num_roots)
+{
+ float (*strandloc)[3] = MEM_mallocN(sizeof(float) * 3 * strands->totcurves, "strand locations");
+ KDTree *tree = BLI_kdtree_new(strands->totcurves);
+
+ {
+ int c;
+ const StrandCurve *curve = strands->curves;
+ for (c = 0; c < strands->totcurves; ++c, ++curve) {
+ float nor[3], tang[3];
+ if (BKE_mesh_sample_eval(scalp, &curve->root, strandloc[c], nor, tang))
+ BLI_kdtree_insert(tree, c, strandloc[c]);
+ }
+ BLI_kdtree_balance(tree);
+ }
+
+ int i;
+ StrandRoot *root = roots;
+ for (i = 0; i < num_roots; ++i, ++root) {
+ float loc[3], nor[3], tang[3];
+ if (BKE_mesh_sample_eval(scalp, &root->root, loc, nor, tang)) {
+
+ /* Use the 3 closest strands for interpolation.
+ * Note that we have up to 4 possible weights, but we
+ * only look for a triangle with this method.
+ */
+ KDTreeNearest nearest[3];
+ float *sloc[3] = {NULL};
+ int k, found = BLI_kdtree_find_nearest_n(tree, loc, nearest, 3);
+ for (k = 0; k < found; ++k) {
+ root->control_index[k] = nearest[k].index;
+ sloc[k] = strandloc[nearest[k].index];
+ }
+
+ /* calculate barycentric interpolation weights */
+ if (found == 3) {
+ float closest[3];
+ closest_on_tri_to_point_v3(closest, loc, sloc[0], sloc[1], sloc[2]);
+
+ float w[4];
+ interp_weights_face_v3(w, sloc[0], sloc[1], sloc[2], NULL, closest);
+ copy_v3_v3(root->control_weights, w);
+ }
+ else if (found == 2) {
+ root->control_weights[1] = line_point_factor_v3(loc, sloc[0], sloc[1]);
+ root->control_weights[0] = 1.0f - root->control_weights[1];
+ }
+ else if (found == 1) {
+ root->control_weights[0] = 1.0f;
+ }
+ }
+ }
+
+ BLI_kdtree_free(tree);
+ MEM_freeN(strandloc);
+}
+
StrandRoot *BKE_strands_scatter(Strands *strands,
struct DerivedMesh *scalp, unsigned int amount,
unsigned int seed)
@@ -205,11 +263,10 @@ StrandRoot *BKE_strands_scatter(Strands *strands,
StrandRoot *roots = MEM_mallocN(sizeof(StrandRoot) * amount, "StrandRoot");
StrandRoot *root;
- UNUSED_VARS(strands);
for (i = 0, root = roots; i < amount; ++i, ++root) {
if (BKE_mesh_sample_generate(gen, &root->root)) {
int k;
- /* TODO find weights to "nearest" control strands */
+ /* influencing control strands are determined later */
for (k = 0; k < 4; ++k) {
root->control_index[k] = STRAND_INDEX_NONE;
root->control_weights[k] = 0.0f;
@@ -224,6 +281,8 @@ StrandRoot *BKE_strands_scatter(Strands *strands,
BKE_mesh_sample_free_generator(gen);
+ strands_calc_weights(strands, scalp, roots, amount);
+
return roots;
}
diff --git a/source/blender/gpu/intern/gpu_strands.c b/source/blender/gpu/intern/gpu_strands.c
index db8a05b..1a7434d 100644
--- a/source/blender/gpu/intern/gpu_strands.c
+++ b/source/blender/gpu/intern/gpu_strands.c
@@ -68,8 +68,8 @@ struct GPUStrandsShader {
};
const char *vertex_shader = STRINGIFY(
- in uvec4 guide_index;
- in vec4 guide_weight;
+ in uvec3 guide_index;
+ in vec3 guide_weight;
void main()
{
More information about the Bf-blender-cvs
mailing list