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. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to