<![CDATA[Nikita Dudnik]]>http://nikdudnik.com/Ghost 0.11Tue, 03 Dec 2019 03:41:53 GMT60<![CDATA[Making 3D GFX for the cinema on low budget and three.js]]>My friends from Lateral Summer are making a short movie called The Rift.
It's a sci-fi movie and some scenes have screens with unusual user interfaces. Guys asked me for help to make them happen. The most troublesome part was stylized 3d globe. You can see it around 00:48

]]>
http://nikdudnik.com/making-3d-gfx-for-the-cinema-on-low-budget-and-three-js/a0982999-e453-42ce-8b31-09b660d178e9Mon, 14 Apr 2014 21:40:07 GMTMy friends from Lateral Summer are making a short movie called The Rift.
It's a sci-fi movie and some scenes have screens with unusual user interfaces. Guys asked me for help to make them happen. The most troublesome part was stylized 3d globe. You can see it around 00:48 in the trailer.

A static image of the globe.
A static image of the globe

I followed this tutorial to make a basic monochrome 3d globe but had to go my own way because I needed more:
1. colored bars
2. animated bar growth
3. UI to control the animation

Colored Bars

To color the bars I've used an excellent library RainbowVis-JS. You give this library an array of colors, a range defined by two numbers, then you can get an interpolated color mapped to a number from the range. For example if your range is from 1 to 200 and you have five colors it's not a problem to ask for color at 15.5.

Three.js lets you set color for each of the vertices of your geometry. That gives smoothly colored bars.

Animated Bars Growth

My 3d globe was built from quite a alot of cubes so I had to merge them into one THREE.Geometry object to make everything work fast. This made animating the globe harder because I had to use morph maps. I had no idea how to use them but digging into three.js examples helped a lot and after several hours and half of my hairs pulled out I could morph my procedurally generated geometry like a boss.

Super-short tutorial on morphing

Build your base THREE.Geometry object.
Build another THREE.Geometry object with the same amount of vertices.
Put the vertices of the second object into the morph map of the first one.

baseObject.morphTargets.push({name:"target0", vertices: anotherObject.vertices});

Make a mesh out of the baseObject with morphTargets enabled.

total = new THREE.Mesh(everything, new THREE.MeshBasicMaterial({ vertexColors: THREE.VertexColors, morphTargets: true }));

Yay! You can morph now.

total.morphTargetInfluences[0] = 0.7;

UI To Control The Animation

I started with a very simple user interface using dat.GUI library.
It's a minimalistic GUI library from Google, outstanding in it's simplicity. It was a nice fit but it wasn't suitable for animation. Thus I tried to integrate an existing JavaScript based timeline-style animation component but it was outdated, buggy and hard to use for any real work.

Then I had an idea: what if I could control animation from outside through OSC (open sound controls) then it would be possible to use any of the existing OSC compatible timelines (Duration, Vezér).

To make this happen I took node-webkit which lets you build desktop applications on top of JavaScript, HTML5 and node.js. The funky thing is it combines browser and node.js environments into one powerful super weapon.

There is a ready to use node.js library called node-osc. It makes OSC communications simple and... doesn't work out of the box with the latest node-webkit on OS X. I had to use version 0.8.5 and cast a magic spell.

Why use magic? The problem is some modules are binary and have to be recompiled for your node-webkit's runtime architecture. There is a tool for this in a form of npm module. So it's easy to install.

npm install nw-gyp

In my case the offender was binpack module and I had to cast this spell inside the module's folder:

nw-gyp rebuild --target=0.8.5

I also had some problems parsing OSC messages but the dynamic nature of node-webkit's runtime and access to the console made it simple to hack the format on the fly.

In the end I had an app with some beautiful graphics in it controllable from outside. Perfect!

But that wasn't the end. When my friend tried to screengrab the animation there was a lot of frame-drops.
I had to find the way to render the animation to disk.

Rendering To Disk

Thanks god node-webkit lets you use both client side JS libs and node.js API. Hello fs.writeFile! It worked like a charm for some string I plugged into the command but I needed some real image data grabbed from a Web GL canvas.

Saving One Frame

I tried to get image from canvas with using canvas.toDataURL but it didn't work.
To make it work I had to initialize three.js renderer like this:

renderer = new THREE.WebGLRenderer({antialias:true, preserveDrawingBuffer: true});

preserveDrawingBuffer is the key.

It took me some time to figure out how to save a PNG. It wasn't obvious how to convert data/url which I could grab from canvas into binary image data. I figured it out by googling, trying and failing until I succeeded.

var image = renderer.domElement.toDataURL('image/png').slice(22);
fs.writeFile( 'aFrame.png', new Buffer(image, 'base64'));

Another problem was solved. The next one was harder. Somehow I had to record incoming animation data and then render and save it to disk in non-realtime manner.

Caching, Rendering and Saving

I added one more OSC parameter to start/stop animation data recording. Then I added shortcut to start saving the frames to the disc. I had to clean up my animation code because it wasn't taking in account OSC messages frequency which I had to use to control framerate of the animation (think FPS).

I also had to program completely different animation loop ot should I say render and save loop which was using recorded animation data instead of listening to the incoming OSC messages. It also compensated for the delay caused by write to disc operation and was starting the next frame rendering only when the current frame was saved to disk.

The key to success here is requestAnimationFrame.

Remember that we already have animation data recorded. The algorithm for rendering and saving is simple. "then" means the next step happens asynchronously as callback from previous operation. It's doable because requestAnimationFrame has callback parameter as well as fs.writeFile.

  1. updateAndRender currentFrame
  2. requestAnimationFrame then saveImage
  3. saveImage then requestAnimationFrame then increase currentFrame and go to 1

This doesn't include end loop condition for the sake of simplicity and demonstration of the core idea.

Overall I had a lot of problems but the result worth it. I learned a lot and researched a general approach to rendering canvas-based motion graphics to disc.

You can see the code at https://github.com/Nek/Rift/blob/master/js/app/main.js

If you're on a Mac you can also try it in action but it's a multistep process:
1. download and unzip node-webkit v8.5.0
http://dl.node-webkit.org/v0.8.5/node-webkit-v0.8.5-osx-ia32.zip
2. download packaged Rift Globe https://www.dropbox.com/s/wnogs6wby09ykz3/RiftGlobe.nw
3. download Duration timeline sequencer http://www.duration.cc/
4. download and unzip a preset for the sequencer https://www.dropbox.com/s/gzniwwtwfxnexhk/RiftCurves.zip
5. run Duration and open the preset which can be done by clicking on the text in the upper left corner of Duration's window
6. run Rift Globe on node-webkit (by double clicking on it)
7. hit play inside Duration and observe node-webkit's window

All praises, insults, questions and critics are welcome!

]]>
<![CDATA[Get interesting music from SoundCloud with clojure]]>Music

I'm an avid music lover. I listen to a lot of different genres. I always look for something new and it usually takes a lot of time to find something interesting to listen to.

The appearence of SoundCloud made the task a bit easier. I can just subscribe to

]]>
http://nikdudnik.com/get-interesting-music-from-soundcloud-with-clojure/c375d204-eaff-48b8-9cd3-5662ca8d74eaSat, 01 Feb 2014 10:59:10 GMTMusic

I'm an avid music lover. I listen to a lot of different genres. I always look for something new and it usually takes a lot of time to find something interesting to listen to.

The appearence of SoundCloud made the task a bit easier. I can just subscribe to my favourite labels, magazines and artists music feeds and then listen through the aggregated feed from time to time.

The problem is I don't want to spend my time listening to everything from the feed. There are also podcasts and mixes in it I want to skip. It'd also be good to get just the most reposted and favorited tracks.

Clojure and Light Table

Clojure is the tool for the task. Even the low level of proficiency in it is enough to do something interesting. The core language is very simple. There isn't much to study. And while the community isn't too large it has some really smart people which build some high quality tools for the less smart people (me included).

Last but not least the entry barrier to Clojure is much lower now because you can use Light Table instead of Emacs. Emacs is rather cryptic for the beginners and takes a lot of time to learn. Ligh Table has more conventional UI still allowing the interactive programming approach.

Interactive programming is an important concept. It's an approach that let's you iterate very fast without resetting your program's state. I feel like this doesn't mean a lot until you try so give it five minutes and you'll be amazed.

Interactive Programming

The interactive programming is enabled by the right combination of a programming language and an editor.
I want to show how fun and productive it is with the practical example.

To go throught it you have to use Clojure and Light Table. Most of the tutorial is inside the comments to the code. Follow the instructions below to get to it.

  1. Download Light Table
    http://www.lighttable.com/
  2. Download or clone the tutorial
    https://github.com/Nek/blog-music-finder
  3. Open src/music_finder/core.clj with LightTable and follow the instructions from the file.

Postscript

I also make music. Check out my music tracks and sound experiments at https://soundcloud.com/nek.

If you are a programmer making music you'd probably should take a look at my older post (it's also a good example of interactive programming): Overtone + Pure Date = ♥.

]]>
<![CDATA[Using Trello as personal task management system]]>

If you are a very wilful person and you're already great at managing your time, skip this article and save yourself some time. If, however, you're an ordinary human being, bear with me — my formula of good productivity tool doesn't include willpower and being smart all the time into the

]]>
http://nikdudnik.com/trello-as-personal-tasks-management-system/4ea09b33-5e6e-43a2-9c58-a06ffec630ecMon, 06 Jan 2014 05:00:00 GMT

If you are a very wilful person and you're already great at managing your time, skip this article and save yourself some time. If, however, you're an ordinary human being, bear with me — my formula of good productivity tool doesn't include willpower and being smart all the time into the equation. I'm also sure that out–of–the–box solutions don't work and you have to figure out what works best for you and you only.

Introduction

There was a lot of hype going on around the GTD time-management technique in last years. I've read the book and tried to apply it to my daily routine — and it didn't work for me. You have to be very smart applying it to your life and that's just not gonna happen if you're not a very determined person — not a lot of us actually are.

What does work for me are several visualisation techniques that let you offload your mental models into something tangible. My favourite two tools are Mind Mapping and Kanban. Mind Mapping helps you offload everything about particular thing into something actionable, represented in Kanban cards.

Turning ideas into cards helps a lot with the conscious part of the process but what about the things you can't control, automatic human behaviors and habits? The inner mechanics of those things involve your emotions and trying to control them with reason doesn't work too well in the long-term perspective.

There is a technique that can help. It's called Autofocus and it's a neat hack to workaround your procrastination and habitual laziness. You can read everything about it on the site of it's author Mark Foster.

Autofocus lets you choose what you want to do now rather than what you think you have to do, building the momentum and going from comfortable tasks to the hard ones.

I took some ideas from Kanban and Autofocus to build the system that works for me.

Using Trello

Trello is an excellent tool to manage projects collaboratively Kanban–style. It also happens to be an excellent personal tasks management system.

I have two boards: !Backlog and !Ongoing.

!Backlog contains Inbox list and several project lists. Inbox consists of ideas and tasks for the future. The projects in !Backlog are either not started or on hold.

!Backlog

The !Ongoing board has several project lists followed by Doing and Done lists. All the projects in the !Ongoing board are active.

!Ongoing

You've already noticed those little coloured labels on some of the cards. I use them to mark the tasks related to something important. There are several things I have to keep in balance to feel well, so additional visual clues help me make decisions faster.

  • money – work I get paid for
  • respect – non-profit projects
  • soul – hobbies, music making and drawing
  • venture – my own possibly profitable projects

Labels

Main workflow:
1. I go through the Doing list to find the task I want to do.
2. I do the task and repeat the process from the start.
3. If there is no task I want to do I start going through the project lists from right to the left.
4. When I feel like doing something about one of the projects I go through it's list and move a task or two into the Doing list.
5. If there are no projects to do I go to the !Backlog and move several projects into the !Ongoing.
6. Repeat.

I put a limit on the amount of tasks in the Doing list and on the amount of simultaneous ongoing projects. If something urgent kicks in I put it on top of the Doing list and allow myself to go over the limit.

From time to time I review my lists to prioritise projects and tasks inside the projects. The more important the task, the higher on the list it is. The more important the project the closer to the Doing list it is. And those coloured labels are really helpful with prioritisation.

If I want to put the project on hold I move it back to the !Backlog.
I never move single-step tasks to the backlog – I either do them or cancel them completely.

That's it!

There are some drawbacks though. I miss the ability to put something into the Inbox fast (e.g. from my mobile phone) and I'd like to have some kind of data visulisation for the Done list. But I'm a software developer and I'm going to solve these problems using my skills and Trello API.

Thanks for reading and let me know how do you manage your tasks — and if this article was in any way helpful or insightful.

]]>
<![CDATA[Overtone + Pure Data = ♥]]>I had an idea of playing with granular synthesis in Overtone but I had no luck making t-grains ugen work. In the same time I found an excellent PD project called Granita courtesy of Lorenzo Sutton which did everything I wanted.

The problem with PD is it's approach to UI

]]>
http://nikdudnik.com/overtone-pure-data-love/c31960d9-e337-4915-a790-9f3d834ecb1bFri, 13 Dec 2013 22:48:46 GMTI had an idea of playing with granular synthesis in Overtone but I had no luck making t-grains ugen work. In the same time I found an excellent PD project called Granita courtesy of Lorenzo Sutton which did everything I wanted.

The problem with PD is it's approach to UI construction which is a real PITA. On the other hand Overtone's way of doing things just rocks. I like to sketch whatever I make with emacs-live and nrepl. It's so much better then anything else for a mixed live-coding, notational composition approach to music making. Both PD and Overtone support OSC communication. My solution is to control PD's patch through OSC from Overtone.

This video shows my current state of affairs.

You can find all the code on GitHub.
https://github.com/Nek/Overtone-Granita-OSC
https://github.com/Nek/Granita-OSC

]]>