[Bf-blender-cvs] [dda2bdd8195] greasepencil-object: GPencil: Improves Dot Texture rotation

Antonioya noreply at git.blender.org
Fri Apr 12 11:15:09 CEST 2019


Commit: dda2bdd8195151d7010d8ad7576272b51d546714
Author: Antonioya
Date:   Fri Apr 12 11:14:30 2019 +0200
Branches: greasepencil-object
https://developer.blender.org/rBdda2bdd8195151d7010d8ad7576272b51d546714

GPencil: Improves Dot Texture rotation

Before when you use textures in a Dot stroke, the texture did not rotate with the stroke and always kept locked to North (0, 1).

Now, the rotation of the texture is calculated using the previous point to determine the direction of the stroke and rotate the texture following the drawing path.

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

M	source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
M	source/blender/draw/engines/gpencil/gpencil_engine.h
M	source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl
M	source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl

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

diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
index b72a6ebebbd..3bcc963c966 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
@@ -95,6 +95,7 @@ void DRW_gpencil_get_point_geom(GpencilBatchCacheElem *be, bGPDstroke *gps, shor
 		be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
 		be->thickness_id = GPU_vertformat_attr_add(&be->format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
 		be->uvdata_id = GPU_vertformat_attr_add(&be->format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+		be->prev_pos_id = GPU_vertformat_attr_add(&be->format, "prev_pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
 
 		be->vbo = GPU_vertbuf_create_with_format(&be->format);
 		GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex);
@@ -123,6 +124,26 @@ void DRW_gpencil_get_point_geom(GpencilBatchCacheElem *be, bGPDstroke *gps, shor
 		GPU_vertbuf_attr_set(be->vbo, be->uvdata_id, be->vbo_len, uvdata);
 
 		GPU_vertbuf_attr_set(be->vbo, be->pos_id, be->vbo_len, &pt->x);
+
+		/* use previous point to determine stroke direction */
+		bGPDspoint *pt2 = NULL;
+		if (i == 0) {
+			if (gps->totpoints > 1) {
+				/* extrapolate a point before first point */
+				float fpt[3];
+				pt2 = &gps->points[1];
+				interp_v3_v3v3(fpt, &pt2->x, &pt->x, 1.5f);
+				GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, fpt);
+			}
+			else {
+				GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, &pt->x);
+			}
+		}
+		else {
+			pt2 = &gps->points[i - 1];
+			GPU_vertbuf_attr_set(be->vbo, be->prev_pos_id, be->vbo_len, &pt2->x);
+		}
+
 		be->vbo_len++;
 	}
 }
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index d85ba1c22f6..8ae48094153 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -340,6 +340,7 @@ typedef struct GpencilBatchCacheElem {
 	uint color_id;
 	uint thickness_id;
 	uint uvdata_id;
+	uint prev_pos_id;
 
 	/* size for VBO alloc */
 	int tot_vertex;
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl
index acbe3cf8d7e..22eb18e85a9 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl
@@ -8,6 +8,7 @@ layout(triangle_strip, max_vertices = 4) out;
 in vec4 finalColor[1];
 in float finalThickness[1];
 in vec2 finaluvdata[1];
+in vec4 finalprev_pos[1];
 
 out vec4 mColor;
 out vec2 mTexCoord;
@@ -15,6 +16,9 @@ out vec2 mTexCoord;
 #define GP_XRAY_FRONT 0
 #define GP_XRAY_3DSPACE 1
 
+#define M_PI        3.14159265358979323846  /* pi */
+#define M_2PI       6.28318530717958647692  /* 2*pi */
+
 /* project 3d point to 2d on screen space */
 vec2 toScreenSpace(vec4 vertex)
 {
@@ -45,32 +49,85 @@ vec2 rotateUV(vec2 uv, float angle)
 	return rot_uv + vec2(0.5f, 0.5f);
 }
 
+vec2 rotatePoint(vec2 center, vec2 point, float angle)
+{
+	/* translate center of rotation to the center */
+	vec2 new_point = point - center;
+	vec2 rot_point;
+	rot_point.x = new_point.x * cos(angle) - new_point.y * sin(angle);
+	rot_point.y = new_point.y * cos(angle) + new_point.x * sin(angle);
+	return rot_point + center;
+}
+
+/* calculate angle of the stroke using previous point as reference.
+ * the angle is calculated using the x axis (1, 0) and 0 degrees */
+float getAngle(vec2 pt0, vec2 pt1)
+{
+	/* do not rotate one point only (no reference to rotate) */
+	if (pt0 == pt1) {
+		return 0.0;
+	}	
+
+	/* default horizontal line (x-axis) in screen space */
+	vec2 v0 = vec2(1.0, 0.0);
+	
+	/* vector of direction */
+	vec2 vn = vec2(normalize(pt1 - pt0));
+	
+	/* angle signed (funtion ported from angle_signed_v2v2) */
+	float perp_dot = (v0[1] * vn[0]) - (v0[0] * vn[1]);
+	float angle = atan(perp_dot, dot(v0, vn));
+	
+	/* get full circle rotation */
+	if (angle > 0.0) {
+		angle = M_PI + (M_PI - angle);
+	}
+	else {
+		angle *= -1.0;
+	}
+
+	return angle;
+}
+
 void main(void)
 {
-	/* receive point */
+	/* receive points */
 	vec4 P0 = gl_in[0].gl_Position;
 	vec2 sp0 = toScreenSpace(P0);
 
+	vec4 P1 = finalprev_pos[0];
+	vec2 sp1 = toScreenSpace(P1);
+    vec2 point;
+
 	float size = finalThickness[0];
+	vec2 center = vec2(sp0.x, sp0.y);
+	
+	/* get angle of stroke to rotate texture */
+	float angle = getAngle(sp0, sp1);
+
 	/* generate the triangle strip */
 	mTexCoord = rotateUV(vec2(0, 1), finaluvdata[0].y);
 	mColor = finalColor[0];
-	gl_Position = vec4(vec2(sp0.x - size, sp0.y + size) / Viewport, getZdepth(P0), 1.0);
+	point = rotatePoint(center, vec2(sp0.x - size, sp0.y + size), angle);
+	gl_Position = vec4(point / Viewport, getZdepth(P0), 1.0);
 	EmitVertex();
 
 	mTexCoord = rotateUV(vec2(0, 0), finaluvdata[0].y);
 	mColor = finalColor[0];
-	gl_Position = vec4(vec2(sp0.x - size, sp0.y - size) / Viewport, getZdepth(P0), 1.0);
+	point = rotatePoint(center, vec2(sp0.x - size, sp0.y - size), angle);
+	gl_Position = vec4(point / Viewport, getZdepth(P0), 1.0);
 	EmitVertex();
 
 	mTexCoord = rotateUV(vec2(1, 1), finaluvdata[0].y);
 	mColor = finalColor[0];
-	gl_Position = vec4(vec2(sp0.x + size, sp0.y + size) / Viewport, getZdepth(P0), 1.0);
+	point = rotatePoint(center, vec2(sp0.x + size, sp0.y + size), angle);
+	gl_Position = vec4(point / Viewport, getZdepth(P0), 1.0);
 	EmitVertex();
 
 	mTexCoord = rotateUV(vec2(1, 0), finaluvdata[0].y);
 	mColor = finalColor[0];
-	gl_Position = vec4(vec2(sp0.x + size, sp0.y - size) / Viewport, getZdepth(P0), 1.0);
+	point = rotatePoint(center, vec2(sp0.x + size, sp0.y - size), angle);
+	gl_Position = vec4(point / Viewport, getZdepth(P0), 1.0);
 	EmitVertex();
 
 	EndPrimitive();
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl
index 2606bbf878e..7deca544176 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl
@@ -13,10 +13,12 @@ in vec3 pos;
 in vec4 color;
 in float thickness;
 in vec2 uvdata;
+in vec3 prev_pos;
 
 out vec4 finalColor;
 out float finalThickness;
 out vec2 finaluvdata;
+out vec4 finalprev_pos;
 
 #define TRUE 1
 
@@ -30,7 +32,8 @@ float defaultpixsize = pixsize * (1000.0 / pixfactor);
 
 void main()
 {
-	gl_Position = ModelViewProjectionMatrix * vec4( pos, 1.0 );
+	gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
+	finalprev_pos = ModelViewProjectionMatrix * vec4(prev_pos, 1.0);
 	finalColor = color;
 
 	if (keep_size == TRUE) {



More information about the Bf-blender-cvs mailing list