Object Engine: Ported Force Field object drawing.
authorClément Foucault <foucault.clem@gmail.com>
Mon, 10 Apr 2017 20:22:37 +0000 (22:22 +0200)
committerClément Foucault <foucault.clem@gmail.com>
Mon, 10 Apr 2017 20:23:50 +0000 (22:23 +0200)
12 files changed:
release/scripts/startup/bl_ui/properties_physics_field.py
source/blender/draw/intern/draw_cache.c
source/blender/draw/intern/draw_cache.h
source/blender/draw/intern/draw_common.c
source/blender/draw/intern/draw_common.h
source/blender/draw/modes/object_mode.c
source/blender/gpu/CMakeLists.txt
source/blender/gpu/GPU_shader.h
source/blender/gpu/intern/gpu_shader.c
source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_vert.glsl [moved from source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_axis_name_vert.glsl with 84% similarity]
source/blender/gpu/shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl
source/blender/makesdna/DNA_object_force.h

index 2b12fcf982d593540af7754e7ab9d1d39a75eeb5..c01b9b939d5e9582eccada79a8e0421981f8fd60 100644 (file)
@@ -39,7 +39,7 @@ class PhysicButtonsPanel:
 
 class PHYSICS_PT_field(PhysicButtonsPanel, Panel):
     bl_label = "Force Fields"
-    COMPAT_ENGINES = {'BLENDER_RENDER'}
+    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY'}
 
     @classmethod
     def poll(cls, context):
@@ -177,7 +177,7 @@ class PHYSICS_PT_field(PhysicButtonsPanel, Panel):
 
 class PHYSICS_PT_collision(PhysicButtonsPanel, Panel):
     bl_label = "Collision"
-    COMPAT_ENGINES = {'BLENDER_RENDER'}
+    COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY'}
 
     @classmethod
     def poll(cls, context):
index 892df42072d4b39380f7dd2d4c4b5d8847c37b97..89ffa0101456a1dc23fc0e98d2f155bee25ec2ad 100644 (file)
@@ -40,6 +40,7 @@
 static struct DRWShapeCache {
        Batch *drw_single_vertice;
        Batch *drw_fullscreen_quad;
+       Batch *drw_screenspace_circle;
        Batch *drw_plain_axes;
        Batch *drw_single_arrow;
        Batch *drw_cube;
@@ -51,6 +52,11 @@ static struct DRWShapeCache {
        Batch *drw_empty_cone;
        Batch *drw_arrows;
        Batch *drw_axis_names;
+       Batch *drw_field_wind;
+       Batch *drw_field_force;
+       Batch *drw_field_vortex;
+       Batch *drw_field_tube_limit;
+       Batch *drw_field_cone_limit;
        Batch *drw_lamp;
        Batch *drw_lamp_sunrays;
        Batch *drw_lamp_area;
@@ -96,6 +102,16 @@ void DRW_shape_cache_free(void)
                Batch_discard_all(SHC.drw_arrows);
        if (SHC.drw_axis_names)
                Batch_discard_all(SHC.drw_axis_names);
+       if (SHC.drw_field_wind)
+               Batch_discard_all(SHC.drw_field_wind);
+       if (SHC.drw_field_force)
+               Batch_discard_all(SHC.drw_field_force);
+       if (SHC.drw_field_vortex)
+               Batch_discard_all(SHC.drw_field_vortex);
+       if (SHC.drw_field_tube_limit)
+               Batch_discard_all(SHC.drw_field_tube_limit);
+       if (SHC.drw_field_cone_limit)
+               Batch_discard_all(SHC.drw_field_cone_limit);
        if (SHC.drw_lamp)
                Batch_discard_all(SHC.drw_lamp);
        if (SHC.drw_lamp_sunrays)
@@ -399,7 +415,6 @@ Batch *DRW_cache_single_line_get(void)
        return SHC.drw_line;
 }
 
-
 Batch *DRW_cache_single_line_endpoints_get(void)
 {
        /* Z axis line */
@@ -425,6 +440,34 @@ Batch *DRW_cache_single_line_endpoints_get(void)
        return SHC.drw_line_endpoints;
 }
 
+Batch *DRW_cache_screenspace_circle_get(void)
+{
+#define CIRCLE_RESOL 32
+       if (!SHC.drw_screenspace_circle) {
+               float v[3] = {0.0f, 0.0f, 0.0f};
+
+               /* Position Only 3D format */
+               static VertexFormat format = { 0 };
+               static unsigned int pos_id;
+               if (format.attrib_ct == 0) {
+                       pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+               }
+
+               VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+               VertexBuffer_allocate_data(vbo, CIRCLE_RESOL + 1);
+
+               for (int a = 0; a <= CIRCLE_RESOL; a++) {
+                       v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+                       v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+                       VertexBuffer_set_attrib(vbo, pos_id, a, v);
+               }
+
+               SHC.drw_screenspace_circle = Batch_create(PRIM_LINE_STRIP, vbo, NULL);
+       }
+       return SHC.drw_screenspace_circle;
+#undef CIRCLE_RESOL
+}
+
 /* Empties */
 Batch *DRW_cache_plain_axes_get(void)
 {
@@ -627,6 +670,216 @@ Batch *DRW_cache_axis_names_get(void)
        return SHC.drw_axis_names;
 }
 
+/* Force Field */
+Batch *DRW_cache_field_wind_get(void)
+{
+#define CIRCLE_RESOL 32
+       if (!SHC.drw_field_wind) {
+               float v[3] = {0.0f, 0.0f, 0.0f};
+
+               /* Position Only 3D format */
+               static VertexFormat format = { 0 };
+               static unsigned int pos_id;
+               if (format.attrib_ct == 0) {
+                       pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+               }
+
+               VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+               VertexBuffer_allocate_data(vbo, CIRCLE_RESOL * 2 * 4);
+
+               for (int i = 0; i < 4; i++) {
+                       float z = 0.05f * (float)i;
+                       for (int a = 0; a < CIRCLE_RESOL; a++) {
+                               v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+                               v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+                               v[2] = z;
+                               VertexBuffer_set_attrib(vbo, pos_id, i * CIRCLE_RESOL * 2 + a * 2, v);
+
+                               v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+                               v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+                               v[2] = z;
+                               VertexBuffer_set_attrib(vbo, pos_id, i * CIRCLE_RESOL * 2 + a * 2 + 1, v);
+                       }
+               }
+
+               SHC.drw_field_wind = Batch_create(PRIM_LINES, vbo, NULL);
+       }
+       return SHC.drw_field_wind;
+#undef CIRCLE_RESOL
+}
+
+Batch *DRW_cache_field_force_get(void)
+{
+#define CIRCLE_RESOL 32
+       if (!SHC.drw_field_force) {
+               float v[3] = {0.0f, 0.0f, 0.0f};
+
+               /* Position Only 3D format */
+               static VertexFormat format = { 0 };
+               static unsigned int pos_id;
+               if (format.attrib_ct == 0) {
+                       pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+               }
+
+               VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+               VertexBuffer_allocate_data(vbo, CIRCLE_RESOL * 2 * 3);
+
+               for (int i = 0; i < 3; i++) {
+                       float radius = 1.0f + 0.5f * (float)i;
+                       for (int a = 0; a < CIRCLE_RESOL; a++) {
+                               v[0] = radius * sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+                               v[1] = radius * cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+                               v[2] = 0.0f;
+                               VertexBuffer_set_attrib(vbo, pos_id, i * CIRCLE_RESOL * 2 + a * 2, v);
+
+                               v[0] = radius * sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+                               v[1] = radius * cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+                               v[2] = 0.0f;
+                               VertexBuffer_set_attrib(vbo, pos_id, i * CIRCLE_RESOL * 2 + a * 2 + 1, v);
+                       }
+               }
+
+               SHC.drw_field_force = Batch_create(PRIM_LINES, vbo, NULL);
+       }
+       return SHC.drw_field_force;
+#undef CIRCLE_RESOL
+}
+
+Batch *DRW_cache_field_vortex_get(void)
+{
+#define SPIRAL_RESOL 32
+       if (!SHC.drw_field_vortex) {
+               float v[3] = {0.0f, 0.0f, 0.0f};
+               unsigned int v_idx = 0;
+
+               /* Position Only 3D format */
+               static VertexFormat format = { 0 };
+               static unsigned int pos_id;
+               if (format.attrib_ct == 0) {
+                       pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+               }
+
+               VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+               VertexBuffer_allocate_data(vbo, SPIRAL_RESOL * 2 + 1);
+
+               for (int a = SPIRAL_RESOL; a > -1; a--) {
+                       v[0] = sinf((2.0f * M_PI * a) / ((float)SPIRAL_RESOL)) * (a / (float)SPIRAL_RESOL);
+                       v[1] = cosf((2.0f * M_PI * a) / ((float)SPIRAL_RESOL)) * (a / (float)SPIRAL_RESOL);
+
+                       VertexBuffer_set_attrib(vbo, pos_id, v_idx++, v);
+               }
+
+               for (int a = 1; a <= SPIRAL_RESOL; a++) {
+                       v[0] = -sinf((2.0f * M_PI * a) / ((float)SPIRAL_RESOL)) * (a / (float)SPIRAL_RESOL);
+                       v[1] = -cosf((2.0f * M_PI * a) / ((float)SPIRAL_RESOL)) * (a / (float)SPIRAL_RESOL);
+
+                       VertexBuffer_set_attrib(vbo, pos_id, v_idx++, v);
+               }
+
+               SHC.drw_field_vortex = Batch_create(PRIM_LINE_STRIP, vbo, NULL);
+       }
+       return SHC.drw_field_vortex;
+#undef SPIRAL_RESOL
+}
+
+Batch *DRW_cache_field_tube_limit_get(void)
+{
+#define CIRCLE_RESOL 32
+       if (!SHC.drw_field_tube_limit) {
+               float v[3] = {0.0f, 0.0f, 0.0f};
+               unsigned int v_idx = 0;
+
+               /* Position Only 3D format */
+               static VertexFormat format = { 0 };
+               static unsigned int pos_id;
+               if (format.attrib_ct == 0) {
+                       pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+               }
+
+               VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+               VertexBuffer_allocate_data(vbo, CIRCLE_RESOL * 2 * 2 + 8);
+
+               /* Caps */
+               for (int i = 0; i < 2; i++) {
+                       float z = (float)i * 2.0f - 1.0f;
+                       for (int a = 0; a < CIRCLE_RESOL; a++) {
+                               v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+                               v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+                               v[2] = z;
+                               VertexBuffer_set_attrib(vbo, pos_id, v_idx++, v);
+
+                               v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+                               v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+                               v[2] = z;
+                               VertexBuffer_set_attrib(vbo, pos_id, v_idx++, v);
+                       }
+               }
+               /* Side Edges */
+               for (int a = 0; a < 4; a++) {
+                       for (int i = 0; i < 2; i++) {
+                               float z = (float)i * 2.0f - 1.0f;
+                               v[0] = sinf((2.0f * M_PI * a) / 4.0f);
+                               v[1] = cosf((2.0f * M_PI * a) / 4.0f);
+                               v[2] = z;
+                               VertexBuffer_set_attrib(vbo, pos_id, v_idx++, v);
+                       }
+               }
+
+               SHC.drw_field_tube_limit = Batch_create(PRIM_LINES, vbo, NULL);
+       }
+       return SHC.drw_field_tube_limit;
+#undef CIRCLE_RESOL
+}
+
+Batch *DRW_cache_field_cone_limit_get(void)
+{
+#define CIRCLE_RESOL 32
+       if (!SHC.drw_field_cone_limit) {
+               float v[3] = {0.0f, 0.0f, 0.0f};
+               unsigned int v_idx = 0;
+
+               /* Position Only 3D format */
+               static VertexFormat format = { 0 };
+               static unsigned int pos_id;
+               if (format.attrib_ct == 0) {
+                       pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
+               }
+
+               VertexBuffer *vbo = VertexBuffer_create_with_format(&format);
+               VertexBuffer_allocate_data(vbo, CIRCLE_RESOL * 2 * 2 + 8);
+
+               /* Caps */
+               for (int i = 0; i < 2; i++) {
+                       float z = (float)i * 2.0f - 1.0f;
+                       for (int a = 0; a < CIRCLE_RESOL; a++) {
+                               v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+                               v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
+                               v[2] = z;
+                               VertexBuffer_set_attrib(vbo, pos_id, v_idx++, v);
+
+                               v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+                               v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL));
+                               v[2] = z;
+                               VertexBuffer_set_attrib(vbo, pos_id, v_idx++, v);
+                       }
+               }
+               /* Side Edges */
+               for (int a = 0; a < 4; a++) {
+                       for (int i = 0; i < 2; i++) {
+                               float z = (float)i * 2.0f - 1.0f;
+                               v[0] = z * sinf((2.0f * M_PI * a) / 4.0f);
+                               v[1] = z * cosf((2.0f * M_PI * a) / 4.0f);
+                               v[2] = z;
+                               VertexBuffer_set_attrib(vbo, pos_id, v_idx++, v);
+                       }
+               }
+
+               SHC.drw_field_cone_limit = Batch_create(PRIM_LINES, vbo, NULL);
+       }
+       return SHC.drw_field_cone_limit;
+#undef CIRCLE_RESOL
+}
+
 /* Lamps */
 Batch *DRW_cache_lamp_get(void)
 {
index 0af7f3d08b1905fff1d338af4ae9aa9c005e389b..94d3f57a8321c4604a5e9194e4f133837d04a65c 100644 (file)
@@ -36,6 +36,7 @@ struct Batch *DRW_cache_fullscreen_quad_get(void);
 struct Batch *DRW_cache_single_vert_get(void);
 struct Batch *DRW_cache_single_line_get(void);
 struct Batch *DRW_cache_single_line_endpoints_get(void);
+struct Batch *DRW_cache_screenspace_circle_get(void);
 
 /* Empties */
 struct Batch *DRW_cache_plain_axes_get(void);
@@ -48,6 +49,13 @@ struct Batch *DRW_cache_empty_cone_get(void);
 struct Batch *DRW_cache_arrows_get(void);
 struct Batch *DRW_cache_axis_names_get(void);
 
+/* Force Field */
+struct Batch *DRW_cache_field_wind_get(void);
+struct Batch *DRW_cache_field_force_get(void);
+struct Batch *DRW_cache_field_vortex_get(void);
+struct Batch *DRW_cache_field_tube_limit_get(void);
+struct Batch *DRW_cache_field_cone_limit_get(void);
+
 /* Lamps */
 struct Batch *DRW_cache_lamp_get(void);
 struct Batch *DRW_cache_lamp_sunrays_get(void);
index 0ec2ed67ca20e5e721bbf29d2f85e8301b3a29b0..e463956c9b2544909186f6f3050081656421409e 100644 (file)
@@ -187,6 +187,19 @@ DRWShadingGroup *shgroup_instance_objspace_wire(DRWPass *pass, struct Batch *geo
        return grp;
 }
 
+DRWShadingGroup *shgroup_instance_screen_aligned(DRWPass *pass, struct Batch *geom)
+{
+       GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED);
+
+       DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
+       DRW_shgroup_attrib_float(grp, "color", 3);
+       DRW_shgroup_attrib_float(grp, "size", 1);
+       DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+       DRW_shgroup_uniform_vec3(grp, "screen_vecs", DRW_viewport_screenvecs_get(), 2);
+
+       return grp;
+}
+
 DRWShadingGroup *shgroup_instance_axis_names(DRWPass *pass, struct Batch *geom)
 {
        GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS);
@@ -200,6 +213,18 @@ DRWShadingGroup *shgroup_instance_axis_names(DRWPass *pass, struct Batch *geom)
        return grp;
 }
 
+DRWShadingGroup *shgroup_instance_scaled(DRWPass *pass, struct Batch *geom)
+{
+       GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE);
+
+       DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom);
+       DRW_shgroup_attrib_float(grp, "color", 3);
+       DRW_shgroup_attrib_float(grp, "size", 3);
+       DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16);
+
+       return grp;
+}
+
 DRWShadingGroup *shgroup_instance(DRWPass *pass, struct Batch *geom)
 {
        GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE);
@@ -324,3 +349,28 @@ int DRW_object_wire_theme_get(Object *ob, SceneLayer *sl, float **color)
 
        return theme_id;
 }
+
+/* XXX This is utter shit, better find something more general */
+float *DRW_color_background_blend_get(int theme_id)
+{
+       static float colors[11][4];
+       float *ret;
+
+       switch (theme_id) {
+               case TH_WIRE_EDIT:    ret = colors[0]; break;
+               case TH_ACTIVE:       ret = colors[1]; break;
+               case TH_SELECT:       ret = colors[2]; break;
+               case TH_GROUP:        ret = colors[3]; break;
+               case TH_GROUP_ACTIVE: ret = colors[4]; break;
+               case TH_TRANSFORM:    ret = colors[5]; break;
+               case OB_SPEAKER:      ret = colors[6]; break;
+               case OB_CAMERA:       ret = colors[7]; break;
+               case OB_EMPTY:        ret = colors[8]; break;
+               case OB_LAMP:         ret = colors[9]; break;
+               default:              ret = colors[10]; break;
+       }
+
+       UI_GetThemeColorBlendShade4fv(theme_id, TH_BACK, 0.5, -16, ret);
+
+       return ret;
+}
\ No newline at end of file
index e8e7cf40432717c5eab7a84484b64cd37585cd18..be41103f907aaf86bd8ec591bab8cc9a0813cfee 100644 (file)
@@ -92,13 +92,16 @@ struct DRWShadingGroup *shgroup_groundpoints_uniform_color(struct DRWPass *pass,
 struct DRWShadingGroup *shgroup_instance_screenspace(struct DRWPass *pass, struct Batch *geom, float *size);
 struct DRWShadingGroup *shgroup_instance_objspace_solid(struct DRWPass *pass, struct Batch *geom, float (*obmat)[4]);
 struct DRWShadingGroup *shgroup_instance_objspace_wire(struct DRWPass *pass, struct Batch *geom, float (*obmat)[4]);
+struct DRWShadingGroup *shgroup_instance_screen_aligned(struct DRWPass *pass, struct Batch *geom);
 struct DRWShadingGroup *shgroup_instance_axis_names(struct DRWPass *pass, struct Batch *geom);
+struct DRWShadingGroup *shgroup_instance_scaled(struct DRWPass *pass, struct Batch *geom);
 struct DRWShadingGroup *shgroup_instance(struct DRWPass *pass, struct Batch *geom);
 struct DRWShadingGroup *shgroup_camera_instance(struct DRWPass *pass, struct Batch *geom);
 struct DRWShadingGroup *shgroup_distance_lines_instance(struct DRWPass *pass, struct Batch *geom);
 struct DRWShadingGroup *shgroup_spot_instance(struct DRWPass *pass, struct Batch *geom);
 
 int DRW_object_wire_theme_get(struct Object *ob, struct SceneLayer *sl, float **color);
+float *DRW_color_background_blend_get(int theme_id);
 
 /* draw_armature.c */
 void DRW_shgroup_armature_object(
index 5588a8075fe98c1d16700a8a56d09a66453d4105..1d89455e3ee3b84a2a1d42d269910e14ebd77ff2 100644 (file)
 #include "DNA_userdef_types.h"
 #include "DNA_armature_types.h"
 #include "DNA_camera_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_object_force.h"
 #include "DNA_view3d_types.h"
 #include "DNA_world_types.h"
 
+#include "BKE_anim.h"
 #include "BKE_camera.h"
+#include "BKE_curve.h"
 #include "BKE_global.h"
 
 #include "ED_view3d.h"
@@ -114,6 +118,15 @@ typedef struct g_data{
        DRWShadingGroup *arrows;
        DRWShadingGroup *axis_names;
 
+       /* Force Field */
+       DRWShadingGroup *field_wind;
+       DRWShadingGroup *field_force;
+       DRWShadingGroup *field_vortex;
+       DRWShadingGroup *field_curve_sta;
+       DRWShadingGroup *field_curve_end;
+       DRWShadingGroup *field_tube_limit;
+       DRWShadingGroup *field_cone_limit;
+
        /* Speaker */
        DRWShadingGroup *speaker;
 
@@ -572,6 +585,19 @@ static void OBJECT_cache_init(void *vedata)
                geom = DRW_cache_axis_names_get();
                stl->g_data->axis_names = shgroup_instance_axis_names(psl->non_meshes, geom);
 
+               /* Force Field */
+               geom = DRW_cache_field_wind_get();
+               stl->g_data->field_wind = shgroup_instance_scaled(psl->non_meshes, geom);
+
+               geom = DRW_cache_field_force_get();
+               stl->g_data->field_force = shgroup_instance_screen_aligned(psl->non_meshes, geom);
+
+               geom = DRW_cache_field_vortex_get();
+               stl->g_data->field_vortex = shgroup_instance_scaled(psl->non_meshes, geom);
+
+               geom = DRW_cache_screenspace_circle_get();
+               stl->g_data->field_curve_sta = shgroup_instance_screen_aligned(psl->non_meshes, geom);
+
                /* Speaker */
                geom = DRW_cache_speaker_get();
                stl->g_data->speaker = shgroup_instance(psl->non_meshes, geom);
@@ -640,9 +666,23 @@ static void OBJECT_cache_init(void *vedata)
                geom = DRW_cache_square_get();
                stl->g_data->lamp_spot_blend_rect = shgroup_instance(psl->non_meshes, geom);
 
+               /* -------- STIPPLES ------- */
+               /* TODO port to shader stipple */
+
                /* Relationship Lines */
                stl->g_data->relationship_lines = shgroup_dynlines_uniform_color(psl->non_meshes, ts.colorWire);
                DRW_shgroup_state_set(stl->g_data->relationship_lines, DRW_STATE_STIPPLE_3);
+
+               /* Force Field Curve Guide End (here because of stipple) */
+               geom = DRW_cache_screenspace_circle_get();
+               stl->g_data->field_curve_end = shgroup_instance_screen_aligned(psl->non_meshes, geom);
+
+               /* Force Field Limits */
+               geom = DRW_cache_field_tube_limit_get();
+               stl->g_data->field_tube_limit = shgroup_instance_scaled(psl->non_meshes, geom);
+
+               geom = DRW_cache_field_cone_limit_get();
+               stl->g_data->field_cone_limit = shgroup_instance_scaled(psl->non_meshes, geom);
        }
 
        {
@@ -889,6 +929,105 @@ static void DRW_shgroup_empty(OBJECT_StorageList *stl, Object *ob, SceneLayer *s
        }
 }
 
+static void DRW_shgroup_forcefield(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl)
+{
+       int theme_id = DRW_object_wire_theme_get(ob, sl, NULL);
+       float *color = DRW_color_background_blend_get(theme_id);
+       PartDeflect *pd = ob->pd;
+       Curve *cu = (ob->type == OB_CURVE) ? ob->data : NULL;
+
+       /* TODO Move this to depsgraph */
+       float tmp[3];
+       copy_v3_fl(pd->drawvec1, ob->empty_drawsize);
+
+       switch (pd->forcefield) {
+               case PFIELD_WIND:
+                       pd->drawvec1[2] = pd->f_strength;
+                       break;
+               case PFIELD_VORTEX:
+                       if (pd->f_strength < 0.0f) {
+                               pd->drawvec1[1] = -pd->drawvec1[1];
+                       }
+                       break;
+               case PFIELD_GUIDE:
+                       if (cu && (cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_cache->path->data) {
+                               where_on_path(ob, 0.0f, pd->drawvec1, tmp, NULL, NULL, NULL);
+                               where_on_path(ob, 1.0f, pd->drawvec2, tmp, NULL, NULL, NULL);
+                       }
+                       break;
+       }
+
+       if (pd->falloff == PFIELD_FALL_TUBE) {
+               pd->drawvec_falloff_max[0] = pd->drawvec_falloff_max[1] = (pd->flag & PFIELD_USEMAXR) ? pd->maxrad : 1.0f;
+               pd->drawvec_falloff_max[2] = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f;
+
+               pd->drawvec_falloff_min[0] = pd->drawvec_falloff_min[1] = (pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f;
+               pd->drawvec_falloff_min[2] = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f;
+       }
+       else if (pd->falloff == PFIELD_FALL_CONE) {
+               float radius, distance;
+
+               radius = DEG2RADF((pd->flag & PFIELD_USEMAXR) ? pd->maxrad : 1.0f);
+               distance = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f;
+               pd->drawvec_falloff_max[0] = pd->drawvec_falloff_max[1] = distance * sinf(radius);
+               pd->drawvec_falloff_max[2] = distance * cosf(radius);
+
+               radius = DEG2RADF((pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f);
+               distance = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f;
+
+               pd->drawvec_falloff_min[0] = pd->drawvec_falloff_min[1] = distance * sinf(radius);
+               pd->drawvec_falloff_min[2] = distance * cosf(radius);
+       }
+       /* End of things that should go to depthgraph */
+
+       switch (pd->forcefield) {
+               case PFIELD_WIND:
+                       DRW_shgroup_dynamic_call_add(stl->g_data->field_wind, color, &pd->drawvec1, ob->obmat);
+                       break;
+               case PFIELD_FORCE:
+                       DRW_shgroup_dynamic_call_add(stl->g_data->field_force, color, &pd->drawvec1, ob->obmat);
+                       break;
+               case PFIELD_VORTEX:
+                       DRW_shgroup_dynamic_call_add(stl->g_data->field_vortex, color, &pd->drawvec1, ob->obmat);
+                       break;
+               case PFIELD_GUIDE:
+                       if (cu && (cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_cache->path->data) {
+                               DRW_shgroup_dynamic_call_add(stl->g_data->field_curve_sta, color, &pd->f_strength, ob->obmat);
+                               DRW_shgroup_dynamic_call_add(stl->g_data->field_curve_end, color, &pd->f_strength, ob->obmat);
+                       }
+                       break;
+       }
+
+       if (pd->falloff == PFIELD_FALL_SPHERE) {
+               /* as last, guide curve alters it */
+               if ((pd->flag & PFIELD_USEMAX) != 0) {
+                       DRW_shgroup_dynamic_call_add(stl->g_data->field_curve_end, color, &pd->maxdist, ob->obmat);
+               }
+
+               if ((pd->flag & PFIELD_USEMIN) != 0) {
+                       DRW_shgroup_dynamic_call_add(stl->g_data->field_curve_end, color, &pd->mindist, ob->obmat);
+               }
+       }
+       else if (pd->falloff == PFIELD_FALL_TUBE) {
+               if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) {
+                       DRW_shgroup_dynamic_call_add(stl->g_data->field_tube_limit, color, &pd->drawvec_falloff_max, ob->obmat);
+               }
+
+               if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) {
+                       DRW_shgroup_dynamic_call_add(stl->g_data->field_tube_limit, color, &pd->drawvec_falloff_min, ob->obmat);
+               }
+       }
+       else if (pd->falloff == PFIELD_FALL_CONE) {
+               if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) {
+                       DRW_shgroup_dynamic_call_add(stl->g_data->field_cone_limit, color, &pd->drawvec_falloff_max, ob->obmat);
+               }
+
+               if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) {
+                       DRW_shgroup_dynamic_call_add(stl->g_data->field_cone_limit, color, &pd->drawvec_falloff_min, ob->obmat);
+               }
+       }
+}
+
 static void DRW_shgroup_speaker(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl)
 {
        float *color;
@@ -980,6 +1119,10 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
                        break;
        }
 
+       if (ob->pd && ob->pd->forcefield) {
+               DRW_shgroup_forcefield(stl, ob, sl);
+       }
+
        DRW_shgroup_object_center(stl, ob);
        DRW_shgroup_relationship_lines(stl, ob);
 }
index 6a61b93e621ee35b0e3a850a14cfcb933ccf858f..f2b13d860dd536176a7670e2373f3ecdce99373b 100644 (file)
@@ -157,7 +157,7 @@ data_to_c_simple(shaders/gpu_shader_instance_vert.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_instance_screenspace_variying_color_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_instance_screen_aligned_axis_name_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_instance_screen_aligned_vert.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_instance_camera_vert.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_instance_distance_line_vert.glsl SRC)
 data_to_c_simple(shaders/gpu_shader_instance_edges_variying_color_geom.glsl SRC)
index 5eb137c69c61ece0f86eeeae3416e3a4018edccd..6783dee72010466cbfea4cddc3d5ed9aa0c57929 100644 (file)
@@ -155,9 +155,11 @@ typedef enum GPUBuiltinShader {
        GPU_SHADER_DISTANCE_LINES,
        /* axis name */
        GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS,
+       GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED,
        /* instance */
        GPU_SHADER_INSTANCE_UNIFORM_COLOR,
-       GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE,
+       GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE, /* Uniformly scaled */
+       GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE,
        GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR,
 
        GPU_NUM_BUILTIN_SHADERS /* (not an actual shader) */
index 984bad1f6c0f8ff32f849b7643cb5ee2577fe1da..7ea148e15d62e05e4bf2df52a12ff53f37e78491 100644 (file)
@@ -80,7 +80,7 @@ extern char datatoc_gpu_shader_instance_vert_glsl[];
 extern char datatoc_gpu_shader_instance_variying_size_variying_color_vert_glsl[];
 extern char datatoc_gpu_shader_instance_objectspace_variying_color_vert_glsl[];
 extern char datatoc_gpu_shader_instance_screenspace_variying_color_vert_glsl[];
-extern char datatoc_gpu_shader_instance_screen_aligned_axis_name_vert_glsl[];
+extern char datatoc_gpu_shader_instance_screen_aligned_vert_glsl[];
 extern char datatoc_gpu_shader_instance_camera_vert_glsl[];
 extern char datatoc_gpu_shader_instance_distance_line_vert_glsl[];
 extern char datatoc_gpu_shader_instance_edges_variying_color_geom_glsl[];
@@ -712,8 +712,10 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
                                                               datatoc_gpu_shader_flat_color_frag_glsl},
                [GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR] = { datatoc_gpu_shader_instance_screenspace_variying_color_vert_glsl,
                                                               datatoc_gpu_shader_flat_color_frag_glsl},
-               [GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS] = { datatoc_gpu_shader_instance_screen_aligned_axis_name_vert_glsl,
+               [GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS] = { datatoc_gpu_shader_instance_screen_aligned_vert_glsl,
                                                                 datatoc_gpu_shader_flat_color_frag_glsl},
+               [GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED] = { datatoc_gpu_shader_instance_screen_aligned_vert_glsl,
+                                                           datatoc_gpu_shader_flat_color_frag_glsl},
 
                [GPU_SHADER_CAMERA] = { datatoc_gpu_shader_instance_camera_vert_glsl,
                                        datatoc_gpu_shader_flat_color_frag_glsl},
@@ -754,6 +756,9 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
                [GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE] = 
                    { datatoc_gpu_shader_instance_variying_size_variying_color_vert_glsl,
                      datatoc_gpu_shader_flat_color_frag_glsl },
+               [GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE] =
+                   { datatoc_gpu_shader_instance_variying_size_variying_color_vert_glsl,
+                     datatoc_gpu_shader_flat_color_frag_glsl },
                [GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR] = { datatoc_gpu_shader_instance_edges_variying_color_vert_glsl,
                                                               datatoc_gpu_shader_flat_color_frag_glsl,
                                                               datatoc_gpu_shader_instance_edges_variying_color_geom_glsl},
@@ -763,6 +768,8 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
                /* just a few special cases */
                const char *defines = (shader == GPU_SHADER_SMOKE_COBA) ? "#define USE_COBA;\n" :
                                      (shader == GPU_SHADER_SIMPLE_LIGHTING) ? "#define USE_NORMALS;\n" :
+                                     (shader == GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE) ? "#define UNIFORM_SCALE;\n" :
+                                     (shader == GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS) ? "#define AXIS_NAME;\n" :
                                      (shader == GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR) ? "#define USE_INSTANCE_COLOR;\n" : NULL;
 
                const GPUShaderStages *stages = builtin_shader_stages + shader;
similarity index 84%
rename from source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_axis_name_vert.glsl
rename to source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_vert.glsl
index a39bfde41ee409a8d7cae747c4f47bb85816831f..2ee74b3eae000dc408542fa527bcb6395c7912b3 100644 (file)
@@ -14,16 +14,19 @@ flat out vec4 finalColor;
 
 void main()
 {
-       vec3 offset;
+       vec3 offset = vec3(0.0);
 
+#ifdef AXIS_NAME
        if (pos.z == 0.0)
                offset = vec3(1.125, 0.0, 0.0);
        else if (pos.z == 1.0)
                offset = vec3(0.0, 1.125, 0.0);
        else
                offset = vec3(0.0, 0.0, 1.125);
+       offset *= size;
+#endif
 
        vec3 screen_pos = screen_vecs[0].xyz * pos.x + screen_vecs[1].xyz * pos.y;
-       gl_Position = ViewProjectionMatrix * (InstanceModelMatrix * vec4(offset * size, 1.0) + vec4(screen_pos * size, 0.0));
+       gl_Position = ViewProjectionMatrix * (InstanceModelMatrix * vec4(offset, 1.0) + vec4(screen_pos * size, 0.0));
        finalColor = vec4(color, 1.0);
 }
index 9ade68644fe24b12259e98c125bd57bb3ad52726..10a2ba61a2ca16c3ecdafeedf18de4a4e75ac2c4 100644 (file)
@@ -7,7 +7,11 @@ in vec3 pos;
 /* ---- Per instance Attribs ---- */
 in mat4 InstanceModelMatrix;
 in vec3 color;
+#ifdef UNIFORM_SCALE
 in float size;
+#else
+in vec3 size;
+#endif
 
 flat out vec4 finalColor;
 
index ed14c4b9311d66df465e6df6ab6cd50250c05488..9413a21633b316579b5169fc43ff68e7ebc51c0f 100644 (file)
@@ -112,6 +112,12 @@ typedef struct PartDeflect {
        float f_noise;          /* noise of force                                               */
        int seed;                       /* noise random seed                                    */
 
+       /* Display Size */
+       float drawvec1[4]; /* Runtime only : start of the curve or draw scale */
+       float drawvec2[4]; /* Runtime only : end of the curve */
+       float drawvec_falloff_min[3], pad1; /* Runtime only */
+       float drawvec_falloff_max[3], pad2; /* Runtime only */
+
        struct Object *f_source; /* force source object */
 } PartDeflect;