Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
| Show First 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| static bool dependsOnTime(GpencilModifierData *md) | static bool dependsOnTime(GpencilModifierData *md) | ||||
| { | { | ||||
| NoiseGpencilModifierData *mmd = (NoiseGpencilModifierData *)md; | NoiseGpencilModifierData *mmd = (NoiseGpencilModifierData *)md; | ||||
| return (mmd->flag & GP_NOISE_USE_RANDOM) != 0; | return (mmd->flag & GP_NOISE_USE_RANDOM) != 0; | ||||
| } | } | ||||
| static float *noise_table(int len, int seed) | static float *noise_table(int len, int offset, int seed) | ||||
| { | { | ||||
| float *table = MEM_callocN(sizeof(float) * len, __func__); | float *table = MEM_callocN(sizeof(float) * len, __func__); | ||||
| for (int i = 0; i < len; i++) { | for (int i = 0; i < len; i++) { | ||||
| table[i] = BLI_hash_int_01(BLI_hash_int_2d(seed, i + 1)); | table[i] = BLI_hash_int_01(BLI_hash_int_2d(seed, i + offset + 1)); | ||||
| } | } | ||||
| return table; | return table; | ||||
| } | } | ||||
| BLI_INLINE float table_sample(float *table, float x) | BLI_INLINE float table_sample(float *table, float x) | ||||
| { | { | ||||
| return interpf(table[(int)ceilf(x)], table[(int)floor(x)], fractf(x)); | return interpf(table[(int)ceilf(x)], table[(int)floor(x)], fractf(x)); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | static void deformStroke(GpencilModifierData *md, | ||||
| if (mmd->flag & GP_NOISE_USE_RANDOM) { | if (mmd->flag & GP_NOISE_USE_RANDOM) { | ||||
| seed += ((int)DEG_get_ctime(depsgraph)) / mmd->step; | seed += ((int)DEG_get_ctime(depsgraph)) / mmd->step; | ||||
| } | } | ||||
| /* Sanitize as it can create out of bound reads. */ | /* Sanitize as it can create out of bound reads. */ | ||||
| float noise_scale = clamp_f(mmd->noise_scale, 0.0f, 1.0f); | float noise_scale = clamp_f(mmd->noise_scale, 0.0f, 1.0f); | ||||
| int len = ceilf(gps->totpoints * noise_scale) + 1; | int len = ceilf(gps->totpoints * noise_scale) + 2; | ||||
| float *noise_table_position = (mmd->factor > 0.0f) ? noise_table(len, seed + 2) : NULL; | float *noise_table_position = (mmd->factor > 0.0f) ? | ||||
| float *noise_table_strength = (mmd->factor_strength > 0.0f) ? noise_table(len, seed + 3) : NULL; | noise_table(len, (int)floor(mmd->noise_offset), seed + 2) : | ||||
| float *noise_table_thickness = (mmd->factor_thickness > 0.0f) ? noise_table(len, seed) : NULL; | NULL; | ||||
| float *noise_table_uvs = (mmd->factor_uvs > 0.0f) ? noise_table(len, seed + 4) : NULL; | float *noise_table_strength = (mmd->factor_strength > 0.0f) ? | ||||
| noise_table(len, (int)floor(mmd->noise_offset), seed + 3) : | |||||
| NULL; | |||||
| float *noise_table_thickness = (mmd->factor_thickness > 0.0f) ? | |||||
| noise_table(len, (int)floor(mmd->noise_offset), seed) : | |||||
| NULL; | |||||
| float *noise_table_uvs = (mmd->factor_uvs > 0.0f) ? | |||||
| noise_table(len, (int)floor(mmd->noise_offset), seed + 4) : | |||||
| NULL; | |||||
| /* Calculate stroke normal. */ | /* Calculate stroke normal. */ | ||||
| if (gps->totpoints > 2) { | if (gps->totpoints > 2) { | ||||
| BKE_gpencil_stroke_normal(gps, normal); | BKE_gpencil_stroke_normal(gps, normal); | ||||
| if (is_zero_v3(normal)) { | if (is_zero_v3(normal)) { | ||||
| copy_v3_fl(normal, 1.0f); | copy_v3_fl(normal, 1.0f); | ||||
| } | } | ||||
| } | } | ||||
| Show All 32 Lines | if (mmd->factor > 0.0f) { | ||||
| else { | else { | ||||
| /* Last point reuse the penultimate normal (still stored in vec1) | /* Last point reuse the penultimate normal (still stored in vec1) | ||||
| * because the previous point is already modified. */ | * because the previous point is already modified. */ | ||||
| } | } | ||||
| /* Vector orthogonal to normal. */ | /* Vector orthogonal to normal. */ | ||||
| cross_v3_v3v3(vec2, vec1, normal); | cross_v3_v3v3(vec2, vec1, normal); | ||||
| normalize_v3(vec2); | normalize_v3(vec2); | ||||
| float noise = table_sample(noise_table_position, i * noise_scale); | float noise = table_sample(noise_table_position, | ||||
| i * noise_scale + fractf(mmd->noise_offset)); | |||||
| madd_v3_v3fl(&pt->x, vec2, (noise * 2.0f - 1.0f) * weight * mmd->factor * 0.1f); | madd_v3_v3fl(&pt->x, vec2, (noise * 2.0f - 1.0f) * weight * mmd->factor * 0.1f); | ||||
| } | } | ||||
| if (mmd->factor_thickness > 0.0f) { | if (mmd->factor_thickness > 0.0f) { | ||||
| float noise = table_sample(noise_table_thickness, i * noise_scale); | float noise = table_sample(noise_table_thickness, | ||||
| i * noise_scale + fractf(mmd->noise_offset)); | |||||
| pt->pressure *= max_ff(1.0f + (noise * 2.0f - 1.0f) * weight * mmd->factor_thickness, 0.0f); | pt->pressure *= max_ff(1.0f + (noise * 2.0f - 1.0f) * weight * mmd->factor_thickness, 0.0f); | ||||
| CLAMP_MIN(pt->pressure, GPENCIL_STRENGTH_MIN); | CLAMP_MIN(pt->pressure, GPENCIL_STRENGTH_MIN); | ||||
| } | } | ||||
| if (mmd->factor_strength > 0.0f) { | if (mmd->factor_strength > 0.0f) { | ||||
| float noise = table_sample(noise_table_strength, i * noise_scale); | float noise = table_sample(noise_table_strength, | ||||
| i * noise_scale + fractf(mmd->noise_offset)); | |||||
| pt->strength *= max_ff(1.0f - noise * weight * mmd->factor_strength, 0.0f); | pt->strength *= max_ff(1.0f - noise * weight * mmd->factor_strength, 0.0f); | ||||
| CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); | CLAMP(pt->strength, GPENCIL_STRENGTH_MIN, 1.0f); | ||||
| } | } | ||||
| if (mmd->factor_uvs > 0.0f) { | if (mmd->factor_uvs > 0.0f) { | ||||
| float noise = table_sample(noise_table_uvs, i * noise_scale); | float noise = table_sample(noise_table_uvs, i * noise_scale + fractf(mmd->noise_offset)); | ||||
| pt->uv_rot += (noise * 2.0f - 1.0f) * weight * mmd->factor_uvs * M_PI_2; | pt->uv_rot += (noise * 2.0f - 1.0f) * weight * mmd->factor_uvs * M_PI_2; | ||||
| CLAMP(pt->uv_rot, -M_PI_2, M_PI_2); | CLAMP(pt->uv_rot, -M_PI_2, M_PI_2); | ||||
| } | } | ||||
| } | } | ||||
| MEM_SAFE_FREE(noise_table_position); | MEM_SAFE_FREE(noise_table_position); | ||||
| MEM_SAFE_FREE(noise_table_strength); | MEM_SAFE_FREE(noise_table_strength); | ||||
| MEM_SAFE_FREE(noise_table_thickness); | MEM_SAFE_FREE(noise_table_thickness); | ||||
| Show All 33 Lines | static void panel_draw(const bContext *UNUSED(C), Panel *panel) | ||||
| uiLayoutSetPropSep(layout, true); | uiLayoutSetPropSep(layout, true); | ||||
| col = uiLayoutColumn(layout, false); | col = uiLayoutColumn(layout, false); | ||||
| uiItemR(col, ptr, "factor", 0, IFACE_("Position"), ICON_NONE); | uiItemR(col, ptr, "factor", 0, IFACE_("Position"), ICON_NONE); | ||||
| uiItemR(col, ptr, "factor_strength", 0, IFACE_("Strength"), ICON_NONE); | uiItemR(col, ptr, "factor_strength", 0, IFACE_("Strength"), ICON_NONE); | ||||
| uiItemR(col, ptr, "factor_thickness", 0, IFACE_("Thickness"), ICON_NONE); | uiItemR(col, ptr, "factor_thickness", 0, IFACE_("Thickness"), ICON_NONE); | ||||
| uiItemR(col, ptr, "factor_uvs", 0, IFACE_("UV"), ICON_NONE); | uiItemR(col, ptr, "factor_uvs", 0, IFACE_("UV"), ICON_NONE); | ||||
| uiItemR(col, ptr, "noise_scale", 0, NULL, ICON_NONE); | uiItemR(col, ptr, "noise_scale", 0, NULL, ICON_NONE); | ||||
| uiItemR(col, ptr, "noise_offset", 0, NULL, ICON_NONE); | |||||
| uiItemR(col, ptr, "seed", 0, NULL, ICON_NONE); | |||||
| gpencil_modifier_panel_end(layout, ptr); | gpencil_modifier_panel_end(layout, ptr); | ||||
| } | } | ||||
| static void random_header_draw(const bContext *UNUSED(C), Panel *panel) | static void random_header_draw(const bContext *UNUSED(C), Panel *panel) | ||||
| { | { | ||||
| uiLayout *layout = panel->layout; | uiLayout *layout = panel->layout; | ||||
| PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL); | PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL); | ||||
| uiItemR(layout, ptr, "random", 0, IFACE_("Randomize"), ICON_NONE); | uiItemR(layout, ptr, "random", 0, IFACE_("Randomize"), ICON_NONE); | ||||
| } | } | ||||
| static void random_panel_draw(const bContext *UNUSED(C), Panel *panel) | static void random_panel_draw(const bContext *UNUSED(C), Panel *panel) | ||||
| { | { | ||||
| uiLayout *layout = panel->layout; | uiLayout *layout = panel->layout; | ||||
| PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL); | PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL); | ||||
| uiLayoutSetPropSep(layout, true); | uiLayoutSetPropSep(layout, true); | ||||
| uiLayoutSetActive(layout, RNA_boolean_get(ptr, "random")); | uiLayoutSetActive(layout, RNA_boolean_get(ptr, "random")); | ||||
| uiItemR(layout, ptr, "step", 0, NULL, ICON_NONE); | uiItemR(layout, ptr, "step", 0, NULL, ICON_NONE); | ||||
| uiItemR(layout, ptr, "seed", 0, NULL, ICON_NONE); | |||||
| } | } | ||||
| static void mask_panel_draw(const bContext *UNUSED(C), Panel *panel) | static void mask_panel_draw(const bContext *UNUSED(C), Panel *panel) | ||||
| { | { | ||||
| gpencil_modifier_masking_panel_draw(panel, true, true); | gpencil_modifier_masking_panel_draw(panel, true, true); | ||||
| } | } | ||||
| static void panelRegister(ARegionType *region_type) | static void panelRegister(ARegionType *region_type) | ||||
| Show All 38 Lines | |||||