One of the things you have to do if you work with foam is to write research reports. These are done at the end of a phase of work, and give a personal record of the decisions and path you took for an individual project. This is a good way to accumulate knowledge and compare different ways of working. This is my one for the groworld project and mostly comes from this blog actually, as well as a bit more detail about what was going on at the time.
A script that uses some material from last weeks intensive writing sweatshop. We generated a huge amount of nonsense of varying degrees, most of which didn’t make it into the novel and went into a “waste dump”. This text was exploited for the performances in various ways, my attempt picks words from the text and connects them together with a 3D spring model graph – a sort of parallel to what my mind was doing while taking part. The code is here.
Edit – finally managed to upload a video of this…
I’ve spent a lot of time this week concentrating on internationalisation (shortened to i18n in coder speak) for the fluxus scratchpad editor. I didn’t have much luck finding comprehensible help online, most of this was done from memory of porting Evolva to Japanese years ago. I thought a blog post about it might be good for anyone treading this path in the future.
The gnome character map was very useful, as was this website which includes a bit more information.
Firstly the history of how text is dealt with is a rather shameful mess of assumptions and out of date compromises. With higher level programming languages this is almost a solved problem, but in C++ it’s not at all. It would also possibly be less of an issue if we could use an editor widget from a normal windowing toolkit, but we can’t as we need to render text in OpenGL with all sorts of whizzbang livecoding zooming effects.
It’s an often told story, first there was ascii, and assumptions of everyone speaking english, and 8bit having to be enough (actually 7bits) for all characters needed in text. Then a whole host of ascii extensions for different parts of the world, using the unused top 127 values of ascii for special characters, while the Japanese for example having their own system entirely called Shift_JIS.
Then in an effort to sort out this mess, lots of committees were formed and Unicode was the result – with the following aim: “Unicode provides a unique number for every character, no matter what the platform, no matter what the program, no matter what the language.”
In order to do this, unicode needs to support 107,000 possible characters – enough for all the languages ever spoken (including exotic scripts such as ancient Egyptian hieroglyphics, Canadian Aboriginal syllabics and Byzantine music scripts) and lots of room for new ones too. In order to do this, you need at least 32 bits, on their own 16, and obviously 8 bits are not enough.
The problem is that ascii is so prevalent, and 32bits per character is a lot for embedded devices, so unicode comprises multiple encoding formats. utf-32 is the easy, but memory eating one, where all characters are the same size, and there is utf-16 and utf-8 which encode variable length characters to save space. utf-8 has the interesting extra property of being compatible with ascii, it reserves the single byte ascii codes and uses the upper 128 values as control codes to signify multibyte chars. For this reason, utf-8 has become the text encoding of the internet, and therefore a standard for plain text files pretty much everywhere.
In the fluxus scratchpad, I decided to use utf-32 for all internal strings – using the std::wstring class, and encode from and to utf-8 at all points of input and output. The reason for this is that fairly simple operations like finding the length of a string, or moving back a single character is complicated with utf-8 – you need to detect the multibyte characters at each point. Using utf-32 it’s much simpler, but you also need to be able to read and write utf8/ascii files.
Ok, that’s the strategy, and you’d think there would be lots of code online to do conversions between these formats – or even standard libraries in C++ to do this. No. The only code I found was buggy (a ‘>’ instead of a ‘>>’ which took me too long to find) but some working code is here. In those functions string is assumed to contain ascii or utf-8 and wstrings are assumed to be utf-32 (even this is going to have to change on the windows version where wstrings are 16bit, sigh).
So, a big search replace for string to wstring in the scratchpad code with conversions in the loading, saving and entry and exit points for the PLT Scheme interpreter, and all was good…
Except keyboard input. I’m still trying to get to the bottom of this and find out what is an artifact of using GLUT and what is the underlying operating system, but at the moment it looks like the mac sends utf-8 keyboard codes, so multiple calls to the glutKeyboardFunc callback per keypress for multibyte chars. On Linux it seems like just the first utf-8 byte gets through, I can’t find where the others get stashed. The minimal information online seems to indicate that this is stretching the abilities of the GLUT toolkit somewhat so I’ve given up for now at least.
The last thing to do was switch the fluxus editor font from the minimal Bitstream Vera Sans Mono to the more characterful Deja Vu Sans Mono which other than having many more glyphs looks exactly the same.
Portuguese help in fluxus – from utf-8 in the code doc comments, to a utf-8 helpstrings file, read in by the scheme interpreter, converted by the scratchpad to utf-32 and rendered by fluxus’s OpenGL glyph renderer.
Exquisite_Code.. February 15 – 19th & 20th 2010.. 10-6pm daily.. E:vent Gallery, 96 Teesdale St. London. E2.. 8 Writers pitched 8 hours a day for 5 days against despotic edit-code.. Yield: one book.. Print. Launch. Read. Evaluate.
Forget insulation from the cold nagging existential doubt or refuge in stories comforting the General Intellect; a dark Forest of Things is foregrounded in exquisite_code, a radical constructivist experiment that hothouses a collaborative writing production.
Eight international writers will work eight hours a day for five days generating text-prompts, text and edit-software in unrelenting micro-sessions to create a cadaverous exquisite_code life-novel . Text will be produced in response to prompts conspired by the writers at the end of each session. But only after bespoke edit-software has wormed its way through it, cutting, chewing and spitting gobbets of the text into a dump from which the life-novel will be elaborated. This edit-worm is itself interrogated and re-written in scheduled code writing sprints by the writers. At all times all participants are available for public scrutiny and interaction, and all writing will be on live display whilst continuously extruded as hardcopy from line printers.
The event will culminate in a Saturday night exquisite_code LAUNCH PARTY (7.30 -11.30pm) on 20th February at E:vent Gallery with extracts of the novel presented to the public through human-machine readings, performances and detournements made by participants from the week’s accumulated materials. Publication of all code, prompts and final text will be by way of print-on-demand publication in collaboration with Mute.
Leif Elggren [SWE] writer/artist/performer; Mara Goldwyn [US] writer/performer; Dave Griffiths [UK/FI] artist/coder/performer; Brendan Howell [US/DE] writer/coder/artist; Jonathan Kemp [UK] writer/artist; Laura Oldfield Ford [UK] writer/artist; Eleanora Oreggia [IT/NL] writer/coder/artist/performer; Sabrina Small [US] writer/artist; / with additional performances from Martin Howse [UK/DE]; Preslav Literary School [UK/DE]; and Ryan Jordan [UK]
E:vent Gallery is near Bethnal Green Tube Station. Buses 106, 254, 253, 48 and 55 pass close by. see http://www.eventnetwork.org.uk/contact.
This is an exquisite_code production in collaboration with E:vent Gallery, London, Openmute.org, and supported by Arts Council England.
Still distracted, tried using the new (voxels->blobby) command to use the marching cubes algo in fluxus to mesh the feedback into a solid shape. The code is posted below.
(clear) ; make some voxels (define vx (build-voxels 50 50 50)) ; do the feedback (for ((i (in-range 0 40))) (with-primitive vx ; not sure what's happening here (voxels-sphere-influence (vector 0 0 0) (vector 1 1 1) 0.2) (voxels-calc-gradient) ; <- probably repeated application of this... (voxels-point-light (vector 0 0 0) (vmul (vector 1 1 1) 0.5)))) ; <- and then this does the trick ; make a blobby from the resulting voxels (define bb (voxels->blobby vx)) (destroy vx) ; dont need the voxels anymore ; convert to polygons (define pb (with-state (scale 5) (blobby->poly bb))) (destroy bb) ; don't need the blobby any more ; calculate normals and make shiny (with-primitive pb (recalc-normals 1) (shinyness 50) (specular (vector 1 1 1))) ; slap on some lights (light-diffuse 0 (vector 0.1 0.1 0.1)) (light-specular 0 (vector 0 0 0)) (let ((l (make-light 'point 'free))) (light-diffuse l (vector 1 1 1)) (light-position l (vector 0 30 10)) (light-specular l (vector 1 1 1))) (let ((l (make-light 'point 'free))) (light-diffuse l (vector 0 0 0.6)) (light-position l (vector 0 -50 50)) (light-specular l (vector 0 1 1))) (clear-colour 0.5)
Trying to write some documentation for the voxels primitive in fluxus, I was completely sidetracked by this accidental discovery: