[Bf-blender-cvs] [08f18a5] strand_gpu: Store buffer textures for the rotating frame on control curves.

Lukas Tönne noreply at git.blender.org
Wed Jul 13 14:01:38 CEST 2016


Commit: 08f18a52c2586a50e36bd1ce9f4613b6cb22980e
Author: Lukas Tönne
Date:   Tue Jul 12 11:50:42 2016 +0200
Branches: strand_gpu
https://developer.blender.org/rB08f18a52c2586a50e36bd1ce9f4613b6cb22980e

Store buffer textures for the rotating frame on control curves.

This frame will allow better deformation effects for bent curves.

===================================================================

M	source/blender/blenkernel/BKE_strands.h
M	source/blender/blenkernel/intern/strands.c
M	source/blender/gpu/GPU_buffers.h
M	source/blender/gpu/intern/gpu_buffers.c
M	source/blender/gpu/intern/gpu_strands.c
M	source/blender/gpu/shaders/gpu_shader_strand_geom.glsl
M	source/blender/gpu/shaders/gpu_shader_strand_vert.glsl

===================================================================

diff --git a/source/blender/blenkernel/BKE_strands.h b/source/blender/blenkernel/BKE_strands.h
index 23ae9cb..b167ba9 100644
--- a/source/blender/blenkernel/BKE_strands.h
+++ b/source/blender/blenkernel/BKE_strands.h
@@ -62,6 +62,8 @@ bool BKE_strands_get_fiber_matrix(const struct StrandFiber *fiber, struct Derive
 
 typedef struct StrandCurveCache {
 	float (*verts)[3];
+	float (*normals)[3];
+	float (*tangents)[3];
 	int maxverts;
 } StrandCurveCache;
 
diff --git a/source/blender/blenkernel/intern/strands.c b/source/blender/blenkernel/intern/strands.c
index 07ded24..75ed2f7 100644
--- a/source/blender/blenkernel/intern/strands.c
+++ b/source/blender/blenkernel/intern/strands.c
@@ -186,6 +186,8 @@ StrandCurveCache *BKE_strand_curve_cache_create(const Strands *strands, int subd
 	StrandCurveCache *cache = MEM_callocN(sizeof(StrandCurveCache), "StrandCurveCache");
 	cache->maxverts = maxverts;
 	cache->verts = MEM_mallocN(sizeof(float) * 3 * maxverts, "StrandCurveCache verts");
+	cache->normals = MEM_mallocN(sizeof(float) * 3 * maxverts, "StrandCurveCache normals");
+	cache->tangents = MEM_mallocN(sizeof(float) * 3 * maxverts, "StrandCurveCache tangents");
 	
 	return cache;
 }
@@ -200,6 +202,8 @@ StrandCurveCache *BKE_strand_curve_cache_create_bm(BMesh *bm, int subdiv)
 	StrandCurveCache *cache = MEM_callocN(sizeof(StrandCurveCache), "StrandCurveCache");
 	cache->maxverts = maxverts;
 	cache->verts = MEM_mallocN(sizeof(float) * 3 * maxverts, "StrandCurveCache verts");
+	cache->normals = MEM_mallocN(sizeof(float) * 3 * maxverts, "StrandCurveCache normals");
+	cache->tangents = MEM_mallocN(sizeof(float) * 3 * maxverts, "StrandCurveCache tangents");
 	
 	return cache;
 }
@@ -209,6 +213,10 @@ void BKE_strand_curve_cache_free(StrandCurveCache *cache)
 	if (cache) {
 		if (cache->verts)
 			MEM_freeN(cache->verts);
+		if (cache->normals)
+			MEM_freeN(cache->normals);
+		if (cache->tangents)
+			MEM_freeN(cache->tangents);
 		MEM_freeN(cache);
 	}
 }
@@ -242,6 +250,36 @@ static int curve_cache_subdivide(StrandCurveCache *cache, int orig_num_verts, in
 	return num_verts;
 }
 
+static void curve_cache_transport_frame(StrandCurveCache *cache, int num_verts,
+                                        const float normal[3], const float tangent[3])
+{
+	const float (*verts)[3] = cache->verts;
+	float (*dir)[3] = cache->normals;
+	float (*codir)[3] = cache->tangents;
+	float prev_dir[3], prev_codir[3];
+	
+	copy_v3_v3(prev_dir, normal);
+	copy_v3_v3(prev_codir, tangent);
+	
+	for (int i = 0; i < num_verts - 1; ++i) {
+		float rot[3][3];
+		
+		/* segment direction */
+		sub_v3_v3v3(dir[i], verts[i+1], verts[i]);
+		normalize_v3(dir[i]);
+		
+		/* rotate the frame */
+		rotation_between_vecs_to_mat3(rot, prev_dir, dir[i]);
+		mul_v3_m3v3(codir[i], rot, prev_codir);
+		
+		copy_v3_v3(prev_dir, dir[i]);
+		copy_v3_v3(prev_codir, codir[i]);
+	}
+	/* last segment without rotation */
+	copy_v3_v3(dir[num_verts-1], prev_dir);
+	copy_v3_v3(codir[num_verts-1], prev_codir);
+}
+
 int BKE_strand_curve_cache_calc(const StrandVertex *orig_verts, int orig_num_verts,
                                 StrandCurveCache *cache, float rootmat[4][4], int subdiv)
 {
@@ -256,7 +294,9 @@ int BKE_strand_curve_cache_calc(const StrandVertex *orig_verts, int orig_num_ver
 		}
 	}
 	
-	return curve_cache_subdivide(cache, orig_num_verts, subdiv);
+	int num_verts = curve_cache_subdivide(cache, orig_num_verts, subdiv);
+	curve_cache_transport_frame(cache, num_verts, rootmat[2], rootmat[0]);
+	return num_verts;
 }
 
 int BKE_strand_curve_cache_calc_bm(BMVert *root, int orig_num_verts, StrandCurveCache *cache, float rootmat[4][4], int subdiv)
@@ -276,7 +316,9 @@ int BKE_strand_curve_cache_calc_bm(BMVert *root, int orig_num_verts, StrandCurve
 		}
 	}
 	
-	return curve_cache_subdivide(cache, orig_num_verts, subdiv);
+	int num_verts = curve_cache_subdivide(cache, orig_num_verts, subdiv);
+	curve_cache_transport_frame(cache, num_verts, rootmat[2], rootmat[0]);
+	return num_verts;
 }
 
 int BKE_strand_curve_cache_size(int orig_num_verts, int subdiv)
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index c30020a..d3666a0 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -152,8 +152,10 @@ typedef struct GPUBufferTexture {
 typedef struct GPUDrawStrands {
 	GPUBuffer *strand_points;
 	GPUBuffer *strand_edges;
-	GPUBuffer *control_points;
 	GPUBuffer *control_curves;
+	GPUBuffer *control_points;
+	GPUBuffer *control_normals;
+	GPUBuffer *control_tangents;
 	GPUBuffer *fibers;
 	GPUBuffer *fiber_points;
 	GPUBuffer *fiber_edges;
@@ -166,6 +168,8 @@ typedef struct GPUDrawStrands {
 
 	/* GL texture id for control point texture buffer */
 	GPUBufferTexture control_points_tex;
+	GPUBufferTexture control_normals_tex;
+	GPUBufferTexture control_tangents_tex;
 	GPUBufferTexture control_curves_tex;
 	GPUBufferTexture fiber_position_tex;
 	GPUBufferTexture fiber_normal_tex;
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index b0c221b..3276b6e 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -2146,6 +2146,8 @@ typedef enum GPUStrandBufferType {
 	GPU_STRAND_BUFFER_STRAND_EDGE,
 	GPU_STRAND_BUFFER_CONTROL_VERTEX,
 	GPU_STRAND_BUFFER_CONTROL_CURVE,
+	GPU_STRAND_BUFFER_CONTROL_NORMAL,
+	GPU_STRAND_BUFFER_CONTROL_TANGENT,
 	/* fiber buffers */
 	GPU_STRAND_BUFFER_FIBER_VERTEX,
 	GPU_STRAND_BUFFER_FIBER_EDGE,
@@ -2165,6 +2167,8 @@ static GLenum gpu_strands_buffer_gl_type(GPUStrandBufferType type)
 	switch (type) {
 		case GPU_STRAND_BUFFER_STRAND_VERTEX:
 		case GPU_STRAND_BUFFER_CONTROL_VERTEX:
+		case GPU_STRAND_BUFFER_CONTROL_NORMAL:
+		case GPU_STRAND_BUFFER_CONTROL_TANGENT:
 		case GPU_STRAND_BUFFER_FIBER:
 		case GPU_STRAND_BUFFER_FIBER_VERTEX:
 		case GPU_STRAND_BUFFER_FIBER_POSITION:
@@ -2191,10 +2195,14 @@ static GPUBuffer **gpu_strands_buffer_from_type(GPUDrawStrands *gds, GPUStrandBu
 			return &gds->strand_points;
 		case GPU_STRAND_BUFFER_STRAND_EDGE:
 			return &gds->strand_edges;
-		case GPU_STRAND_BUFFER_CONTROL_VERTEX:
-			return &gds->control_points;
 		case GPU_STRAND_BUFFER_CONTROL_CURVE:
 			return &gds->control_curves;
+		case GPU_STRAND_BUFFER_CONTROL_VERTEX:
+			return &gds->control_points;
+		case GPU_STRAND_BUFFER_CONTROL_NORMAL:
+			return &gds->control_normals;
+		case GPU_STRAND_BUFFER_CONTROL_TANGENT:
+			return &gds->control_tangents;
 		case GPU_STRAND_BUFFER_FIBER:
 			return &gds->fibers;
 		case GPU_STRAND_BUFFER_FIBER_VERTEX:
@@ -2222,12 +2230,18 @@ static GPUBufferTexture *gpu_strands_buffer_texture_from_type(GPUDrawStrands *gd
                                                               GPUStrandBufferType type, GLenum *format)
 {
 	switch (type) {
-		case GPU_STRAND_BUFFER_CONTROL_VERTEX:
-			*format = GL_RGB32F;
-			return &gds->control_points_tex;
 		case GPU_STRAND_BUFFER_CONTROL_CURVE:
 			*format = GL_RG32UI;
 			return &gds->control_curves_tex;
+		case GPU_STRAND_BUFFER_CONTROL_VERTEX:
+			*format = GL_RGB32F;
+			return &gds->control_points_tex;
+		case GPU_STRAND_BUFFER_CONTROL_NORMAL:
+			*format = GL_RGB32F;
+			return &gds->control_normals_tex;
+		case GPU_STRAND_BUFFER_CONTROL_TANGENT:
+			*format = GL_RGB32F;
+			return &gds->control_tangents_tex;
 		case GPU_STRAND_BUFFER_FIBER_POSITION:
 			*format = GL_RGB32F;
 			return &gds->fiber_position_tex;
@@ -2260,10 +2274,14 @@ static size_t gpu_strands_buffer_size_from_type(GPUDrawStrands *gpu_buffer, GPUS
 			return sizeof(float) * 3 * gpu_buffer->strand_totverts;
 		case GPU_STRAND_BUFFER_STRAND_EDGE:
 			return sizeof(int) * 2 * gpu_buffer->strand_totedges;
-		case GPU_STRAND_BUFFER_CONTROL_VERTEX:
-			return sizeof(float) * 3 * gpu_buffer->control_totverts;
 		case GPU_STRAND_BUFFER_CONTROL_CURVE:
 			return sizeof(int) * 2 * gpu_buffer->control_totcurves;
+		case GPU_STRAND_BUFFER_CONTROL_VERTEX:
+			return sizeof(float) * 3 * gpu_buffer->control_totverts;
+		case GPU_STRAND_BUFFER_CONTROL_NORMAL:
+			return sizeof(float) * 3 * gpu_buffer->control_totverts;
+		case GPU_STRAND_BUFFER_CONTROL_TANGENT:
+			return sizeof(float) * 3 * gpu_buffer->control_totverts;
 		case GPU_STRAND_BUFFER_FIBER:
 			return sizeof(GPUFiber) * gpu_buffer->totfibers;
 		case GPU_STRAND_BUFFER_FIBER_VERTEX:
@@ -2575,7 +2593,46 @@ static void strands_copy_strand_edge_data(GPUDrawStrandsParams *params, unsigned
 	}
 }
 
-static void strands_copy_control_vertex_data(GPUDrawStrandsParams *params, float (*varray)[3])
+static void strands_copy_control_cache_attribute_data(StrandCurveCache *cache, int num_verts,
+                                                      void **pvarray, GPUStrandBufferType type)
+{
+	void *varray = *pvarray;
+	
+	switch (type) {
+		case GPU_STRAND_BUFFER_CONTROL_VERTEX: {
+			float (*vert)[3] = cache->verts;
+			for (int v = 0; v < num_verts; ++v, ++vert) {
+				copy_v3_v3((float *)varray, *vert);
+				varray = (float *)varray + 3;
+			}
+			break;
+		}
+		case GPU_STRAND_BUFFER_CONTROL_NORMAL: {
+			float (*nor)[3] = cache->normals;
+			for (int v = 0; v < num_verts; ++v, ++nor) {
+				copy_v3_v3((float *)varray, *nor);
+				varray = (float *)varray + 3;
+			}
+			break;
+		}
+		case GPU_STRAND_BUFFER_CONTROL_TANGENT: {
+			float (*tang)[3] = cache->tangents;
+			for (int v = 0; v < num_verts; ++v, ++tang) {
+				copy_v3_v3((float *)varray, *tang);
+				varray = (float *)varray + 3;
+			}
+			break;
+		}
+		default:
+			BLI_assert(false);
+			break;
+	}
+	
+	*pvarray = varray;
+}
+
+static void strands_copy_control_attribute_data(GPUDrawStrandsParams *params, void *varray,
+                                                GPUStrandBufferType type)
 {
 	if (params->edit) {
 		BMesh *bm = params->edit->base.bm;
@@ -2594,10 +2651,7 @@ static void strands_copy_control_vertex_data(GPUDrawStrandsParams *params, float
 			int orig_num_verts = BM_strand_verts_count(root);
 			int num_verts = BKE_strand_curve_cache_calc_bm(root, orig_num_verts, cache, rootmat, params->subdiv);
 			
-			float (*vert)[3] = cache->verts;
-			for (int v = 0; v < num_verts; ++v, ++vert) {
-				copy_v3_v3(*varray++, *vert);
-			}
+			strands_copy_control_cache_attribute_data(c

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list