Categories
Journals

A letter to no-one in particular

(Not to say if you’re reading this that you, kind reader, are “no-one in particular” in all contexts. You’re definitely someone. Language is a blunt instrument that way.)

I have a draft journal entry which spans all of 2019. It was all about getting my diagnosis, the various trials and tribulations of that year, everything else. It was a hard year, 2019.

The last line of the 2019 journal was “2020, please be good to us”.

2020 was a seemingly infinite landscape of shittiness, with the odd gold nugget poking out. Some good and useful things came out of 2020, but mostly it was just shit. And more shit. Shit with the thickened consistency of suffocating, pitiless mud.

Many of us found ourselves in front of a proverbial Mirror of Truth, caked in all of this woe and desperation and exhaustion. We didn’t recognise ourselves anymore. We’d let other people down. Other people had let us down. Never mind that we were flat out keeping ourselves going in deeply unfamiliar territory, taxed and challenged in ways we could scarcely fathom, as the old ways of living became more and more like a strange dream – as though we’d come back from a holiday which all felt unreal and impossible and even a little frightening from our present moment.

I was worried for 2021 – not relieved, if I’m honest. There would be a lot of clean-up and mending and fixing. Further disintegration seemed inevitable. The work to rebuild the mess into something better was overwhelming to even think about, running on fumes as we are.

Still, running on fumes is marginally better than permanently conked out.

Categories
Journals

Sit rep

It’s near the end of October.

Here in Western Australia, we’re still conducting testing for COVID 19, but despite that there’s no official evidence of community transmission at all. Current COVID cases in WA are either travellers returning from overseas or the crew members of seafaring vessels.

Our state border is still closed and there are minimum-area-per-customer limits. But that’s about it.

We’re a long way from anywhere, so we’re doing relatively OK here.

But even without COVID to worry about, I’ve had a bit of a crappy run. Mostly related to job stress and knock-on effects, being too tired and anxious to make things out of hours, etc.

After a month-long break, I’ve remembered the day job is food on the table and a roof over my head and the resources to bring my own ideas and passions to fruition.

But there’s a bunch of resentment and paranoia and negativity and disengagement and weltschmerz fogging my brain, which has been getting worse over time. 2020 added to it, but it’s been simmering since I shelved AMITS in 2017.

How dare they make me so busy and stressed out that I put three years of effort on the back burner and look like a complete waster after what I said on that stage at Blender Conference oh god i am such a bloody embarrassment i wasted the time and kindness of so many amazing people who the hell did i think i was fooling (etc)

Understanding that connection between stress and anxiety and creative drop-off hasn’t helped deal with that feeling of indignation at all.

Indignation is a hell of a drug to kick, truly.

But this indignation gets me nowhere. And with enough time, nowhere is death.

And I want to be somewhere again.

Categories
Blender Stuff by other people that I helped with

I fixed a bug in Blender!

Summary: I found a bug in one of Blender’s Grease Pencil modifiers. In the process of prepping The Best Bug Report Ever, I fixed the bug instead with help and encouragement from Grease Pencil’s module owners. Read on if you’re interested in how Grease Pencil makes its lines thick and thin, how Grease Pencil’s Thickness modifier does the thing, and how my fix works (in Plain English). Big thanks to Antonio Vazquez and Mathias Mendiola for their patience, encouragement and guidance!

I wanted to test Blender’s Grease Pencil system out as an inking tool, because it allows me to go back and edit my lines a bit after I’ve drawn them. If a line is a bit wobbly or it doesn’t curve nicely or the width doesn’t taper properly, I can sculpt it and fix it after I put the line down, even going point by point if need be.

It was while I was wrestling with ways to adjust particularly lumpy stroke width with the Thickness modifier that I discovered a bug.

The bug and its habitat

The Thickness modifier for Blender’s Grease Pencil adjusts the thickness of Grease Pencil strokes. The Thickness modifier has a Normalize mode which sets the entire stroke to an even width.

Under the hood, “thickness” is a property of the strokes themselves. The strokes are made up of a series of points, and each point has a “pressure” value – the pressure of the graphics tablet for that point. Stroke thickness times point pressure determines the width of the stroke at that point.

Normalize works by setting the thickness for the stroke to whatever the modifier says it should be, then it sets the pressure for all its points to 1.0 – exactly the same pressure on each point means the width of the line becomes even. You can select a particular Vertex Group or Grease Pencil Layer in Normalize mode to target particular strokes and points for evening up while leaving the rest alone… or at least, that’s how it should have worked.

The bug was that the modifier was changing the width of all the strokes whether they had points in that vertex group or not. The effects of a modifier are not meant to leak like that.

I found Grease Pencil expert user Mathias Mendiola on blender.chat – he created the Grease Pencil Fundamentals course on Blender Cloud. He asked me to report a bug.

The best bug report ever

Now, reporting a bug to a fellow developer is not something I take lightly and I wanted to do it properly as a courtesy.

A good bug report should do the following:

  • reports a bug which hasn’t already been reported (let alone fixed), saving coders more administrative work
  • describes the problem clearly, concisely and precisely (less room for misinterpretation)
  • describes the environment and context the problem occurs in (which version of the software, e.g. stable or build hash on splash screen; which operating system, CPU and graphics card, etc)
  • describes expectations of what should happen (maybe the user’s expectations are not what developers expect them to be)
  • gives explicit instructions on how to replicate the bug with as few steps as possible, or alternatively provides data which shows the bug occurring

That last bit – how to replicate the bug – is super important. If the coder can’t replicate the bug, it’s much more difficult to fix it. If the coder is obliged to fix the bug anyway, they may have to spend a significant amount of time devising their own replication which may or may not be the same as what the user does when they trigger the bug, and even if it’s the same thing the user is doing it’s still time the coder has to spend pinpointing the source of the bug. Reproducing information which a user already knows (but hasn’t passed on) is not a good use of a coder’s time.

Since I’m a programmer myself and I build Blender from source, I wanted my bug report to go further than just instructions on how to replicate the bug – although I’d do that too. Once a coder confirms the bug is there and accepts it, the next step involves finding the bit of code that’s going wrong. I decided to find that bit of code as an exercise and to be extra helpful – one less thing for the coder to do.

Tracking down the bug

I poked around Visual Studio and eventually found the code inside source/blender/bf_gpencil_modifiers/MOD_gpencilthick.c. The function which contains the procedure for the Thickness modifier to modify thickness is called deformStroke.

By now, I wanted to pry even further and figure out what deformStroke was doing wrong so that I could even quote a particular line number in the bug report – again, one less thing for the coder to do. After hours of squinting, I figured out that even with Vertex Groups switched on, deformStroke was changing the thickness of the strokes whether they had points in the vertex group or not. That was fine if the whole stroke was getting normalised, but not if the stroke had some but not all points in the vertex group, or no points at all.. hmm..

Since I was on holidays and had no obligation to be awake and ready for work the next day, and I had Visual Studio open anyway, I decided to have a crack at fixing it myself – without any expectations of success or failure. If I couldn’t fix it, at least I put what I’d already tried in the bug report. Yet again, one less thing for the coder to do.

Failing to report the bug

After a few more hours of tinkering, headscratching, reading code, compiling, swearing and recompiling, I didn’t have a bug report – I had a fix for the bug. It was only a partial fix – for cases where a stroke has a mixture of affected and unaffected points, my original patch left that stroke alone – but in Normalize mode, the modifier had stopped affecting points and strokes outside the Vertex Group and that’s what I wanted it to do.

The fix

My change was to make the function scan over each point in the stroke. When it finds a point within the vertex group, it changes a variable called gps_has_affected_points from FALSE to TRUE. (gps stands for “Grease Pencil stroke”.) When it finds a point outside the vertex group, it sets another variable called gps_has_unaffected_points from FALSE to TRUE. Once both of these are set to TRUE, it stops scanning – neither of them can go back to being false.

What comes next depends on whether one or both of those variables are TRUE or FALSE.

If the stroke doesn’t have any unaffected points (
gps_has_affected_points is TRUE and
gps_has_unaffected_points remains FALSE), it’s safe to normalise the stroke by changing its the width and set all the points to 1.0. If it had both affected and unaffected points (both variables TRUE), originally I skipped handling it. (I tried to experimentally iterate a formula but then gave up and coded around it.) I left the code factored in such a way so that if need be, someone who knew the Grease Pencil system better than me could add the unhandled case in with the right maths. Something an expert coder could do in a second, probably.

I submitted patch D5483 at developer.blender.org at around 2:00am my time. Then I went to bed.

Getting the fix accepted

Now, submitting a patch doesn’t mean there was nothing for the coders to do, only that they had a code submission which fixes a bug. But was it readable code? Was it efficient code? Did it follow the appropriate formatting standards? Did the code change cover everything it needed to cover without introducing any regressions? For a module owner to accept code, it means they accept responsibility for what the code does and how it does it.

The next day, Grease Pencil module owner Antonio Vazquez had reviewed my patch. He thanked me for the code and encouraged me to handle the partially affected stroke case. I agreed it shouldn’t be left half done and did not make excuses that I was too tired to want to finish it all in one hit, and that it would be better for users if it didn’t just ignore certain cases (which were too hard for me to work out at two o’clock in the morning).

I spent a couple of extra hours on Friday reading other bits of Grease Pencil code to figure out the maths to convert stroke thickness to point pressure given a particular stroke thickness. After having no luck tracing through the code with Visual Studio for an answer, I did a brute force text search for where “thickness” and “pressure” occurred on the same line. It turned out to be simple algebra – target stroke thickness (from the modifier) divided by current stroke thickness results in the right pressure value.

Easy maths, right? Kind of.

Fun with numbers, C style

I knew enough about C to know it’s quite particular about the way it represents particular kinds of number. For instance, point pressure is a floating point (fractional) number and stroke thickness is an integer (whole number). If you divide two integers in C, you don’t get the remainder back. So if you want the remainder (which I did), you need to cast (convert) the integers to a floating point number instead. Then you can divide them to get a point pressure. (This converting may seem like a massive pain in the arse, and friendlier higher-level languages are happy to do those conversions under the hood, but the trade-off is that C runs at speeds which leave higher-level languages in the dust by comparison.)

I got the partial stroke normalisation case working on Friday evening and submitted an updated patch.

Antonio’s follow-up review on Saturday noted that Blender doesn’t do same-line comments, but that he was OK with the code of the patch. He added an extra line to clamp the width to a safe minimum – something an expert coder would know to do – and committed my updated patch to Blender’s master branch as a bugfix on Saturday.

My first Blender commit

The commit hash for my fix is a477c2e0e079 and I’m listed as the contributor. It’s not the first commit I’ve been named in (I helped fix a build bug a little while ago) but it’s the first commit where I’ve written actual code to fix something and been identified as a contributor. Yay!

Fixing that bug took me about six and a half hours, give or take. Much of that time was spent reading through unfamiliar code in a language I haven’t used before. And even if it was a small obscure bug, something very few people would notice or care about that much, it’s fun to see my name come up in Blender’s commit logs and nice to know I helped Blender work a little better than it did before.



Categories
Blender Stuff by other people Stuff by other people that I helped with

I was a spider!

I recently did some voice acting work for animator Jeannot Landry (Blender Pirate). He wanted an Australian male voice for Roby, a cute peacock spider in his short “The Last Dance?”

In addition to voicing the character, I rewrote and extended Jeannot’s script to push the comedy some more and make the dialogue feel more authentically Aussie as requested. I was also a second set of eyes during animation blocking.

Hope you enjoy it! (A note to arachnophobes and people who are uneasy about spiders: Roby is a relatively naturalistic jumping spider in terms of the way he looks and moves. He also gets pretty close to the POV by the end of the movie. Hopefully the cute factor helps!)

Check out the Blender Pirate’s YouTube channel for more of Jeannot’s work!

Categories
Japanese

Japanese for sumo fans

Part of the reason I started learning Japanese again was because I started following Grand Sumo. New sumo fans are confronted with a lot of untranslated terminology which takes a good while to get up to speed on. After a scant ten months of sumo fandom, I can tell makushita (third division) from makunouchi (top division) and oshidashi (shovey-outy) from oshitaoshi (shovey-downy).

Is any of this Japanese terminology useful in the context of learning Japanese though? I wanted to know if common sumo terms like ashitori, tsukebito, oshidashi or shitatenage could give me a leg-up on my vocab and grammar. It turns out the answer is yes – if you break them up a bit and do your homework. This is what I hope to show you how to do.

The basics

If you’re completely new to Japanese, read on. If not, feel free to skip to the next section.

Japanese has a couple of gotchas we need to be aware of before we turn jargon into useful language. Fortunately it’s also an extremely regular language compared to English with all its exceptions.. well, regular except in the way it’s written. More on that later.

Sound groups

The sounds of Japanese group together a little bit differently than in English. Mostly it’s like ka-ki-ku-ke-ko or na-ni-nu-ne-no, but sometimes you get ta-chi-tsu-te-to, sa-shi-su-se-so or ha-hi-fu-he-ho. While we’d say that the sound at the beginning of “tea” and “turtle” are the same, the sounds at the beginning of “cheese” and “turtle” are different. In Japanese, they’re variations of the same sound. The same goes for “sap” and “sheep”. To spell a sound like at the beginning of “sharp” they smoosh “shi” together with “ya”.

Sound changes

The Japanese word for person is hito. When it’s compounded with certain words, it becomes -bito. This change happens all over and it’s the bane of every novice Japanese learner. The Japanese call it rendaku (“sequential voicing”). All you need to remember is that in some names and compound words, k becomes g (mae + kashira = maegashira), t becomes d, h becomes b (kin + hoshi = kinboshi), s becomes z (oo + seki = oozeki), ts can also become z (yoko + tsuna = yokozuna) and ch becomes j.

Kanji and kana

Japanese has three distinct writing systems on top of the ones you already know. (Japanese uses Roman letters like the ones you’re reading and Arabic numbers like 234.)

The two phonetic (what-you-write-is-what-it-sounds-like) writing systems are called kana, both with about 50 letters which each represent a phonetic unit called a mora (“syllable-but-not-quite”). There’s hiragana which is used for native words and katakana which is often used to spell out abstract noises and foreign words.

The two kana systems are pretty easy to tell apart. This is cursive round squishy hiragana: これがひらがな。This is angular sharp stabby katakana: アフリカパソコン。

Japanese also uses a complicated system of characters called kanji. There’s maybe about 50,000 kanji characters, but people are only expected to know a couple of thousand of them by the time they finish school. Kanji are relevant to learning Japanese with sumo because the names of the rikishi and stables are all spelt almost entirely using kanji.

Kanji are however slippery because they often sound different depending on which word they’re being used in. Even just looking in top division sumo, we can find the kanji 大, meaning “big” or “great”, realised as three different sounds: Chiyotairyu 千代大龍, Daieisho 大栄翔 and the rank of oozeki 大関. (Sidenote: Chiyotairyu’s name means “Eternal Great Dragon” and that’s pretty awesome.)

I mention the different kinds of writing because they have helpful clues.

Mining sumo jargon for verbs

Kimarite are sumo’s winning techniques. Each of them has a name like oshidashi, abisetaoshi, uwatenage, yorikiri and so on. Sumo fans learn the more common ones by heart.

Many of these terms are actually compound verbs in “stem” form. One giveaway for this is if you see kanji intermixed with kana: 押 (oshidashi), 浴 (abisetaoshi), 上手投 (uwatenage – one kana still counts) and 寄 (yorikiri). The other giveaway is the sound: notice how there’s a lot of something-y-something-y? That’s the telltale sound of Japan’s doing words having little word parties, that is.

How can we use this though? Japanese has two (and a bit) groups of verb. There’s Group I which has a stem form ending in -i, and Group II where the stem form might end in -e or -i. If you want to extract verbs from kimarite names, you can start by splitting them up where a -i or -e occurs. This might net you two verb stems. It might not. The two irregular verbs aren’t worth mentioning here.

To get a “plain form” verb which you can use in sentences and look up in dictionaries, you can change the final -i to an -u (remembering that -chi becomes -tsu and -shi becomes -su). For Group II verbs, you add -ru if the stem ends in -e. Some stems ending in -i are actually Group II which means having to add -ru to them. You can try one if you get no luck with the other.

And no matter what, you can take the stem form, whack -masu on the end and have a ready to go polite verb.

Let’s give it a whirl!

First, let’s try oshidashi. Split the word up to get oshi 押し and dashi 出し. Change from stem to plain form to get osu 押す and dasu 出す. Wouldn’t you know it: osu means “push” or “overwhelm” and dasu means “put out”. To overwhelm and put out.

Let’s see what we can do with 浴せ倒し – abisetaoshi! Split it up to get abise 浴せ and taoshi 倒し. Abise ends in -e which means it might be a Group II verb, so we add a whole -ru to the end and look for abiseru 浴せる. The other half taoshi becomes taosu 倒す. Again we’re in luck: abiseru means “pour something on” and taosu means “knock down”. Oh the words we already know.

Kimarite are not always verb stems, however. My absolute favourite kimarite is ashitori 足取り where one rikishi picks up the other rikishi’s leg and hops them out backwards. This looks like it’s spelled a bit different to the first two examples though. There’s no kana dividing the two characters. We can find toru 取る meaning “pick up”, but we won’t find asu because the word we’re after is actually ashi 足 meaning “leg” or “foot”. The lack of kana is the big clue there. (If we look for a verb like 足す we’ll find the word “to add”. And it’s pronounced tasu.)

There’s a similar thing waiting for us with uwatenage 上手投げ. Are we looking for uwateru and nageru? Not quite. Again, the relative lack of kana in the spelling is the clue here. While nageru 投げる definitely means “to throw” (also “to launch”), uwateru isn’t a word. Looking for just uwate turns up “over-arm grip”. When you see -te- 手 in the name of a kimarite, it often refers to an action of the arm or hand – te 手 means hand or arm. And the character 上 has the implication of above or over. Literally: over-arm throw.

Wait on, there’s a -te at the end of kimarite. And there’s a lot of kana in its Japanese spelling: 決まり手. So is kimaru a verb too? Yep! It means “to be decided” or “to be settled” – as in, settling a match. One of the many meanings of te is “technique”. Kimarite literally means “deciding technique”. Nice!

Finally, let’s look at yorikiri 寄り切り – the standard issue frontal force-out beloved of top division’s belt-focussed wrestlers. Using the methods above, we get yoru 寄る and kiru 切る. Yoru means “get up close” (among other things) and kiru means.. “cut”? Sort of. As the second part of a compound verb, kiru acts as an auxilliary verb. (English auxiliary verbs include ought and must along with go when it’s used in sentences like “go suck eggs”.) So instead of “cut”, kiru means “to finish and complete”. That means in the word yorikiri we have the notion of getting up close to someone with an implication that something is completed.. like shoving them out of a ring! 🙂

Of course, if you’re more of a foodie than a sumo fan, perhaps you’d prefer to break up words like teriyaki 照り焼き – you’ll soon discover teru 照る (to shine) and yaku 焼く (to barbecue) lurking within. It works for yakitori as well.

I hope you enjoyed this peek into vocabulary building and that I’ve inspired you to find out more. Thanks for reading and here’s to a great 2019 January Basho! (魁聖関、頑張れ!)