Showing posts with label prototyping. Show all posts
Showing posts with label prototyping. Show all posts

Sunday, March 31, 2013

[TUTORIAL] Visualizing Depth in Unity, part 2

    The joys of having a laptop capable of development, I'm seriously in love with my Ultrabook.  This isn't just me shilling for the company, I'm totally sold on this thing.  Apple did right by forcing people to figure out how to build smaller, lighter laptops that still pack serious development punch.  For reference, I'm currently working off of a Gigabyte U2442, would be nice to get something that has a Core i7 CPU, but this one's a Core i5 at 3.1 with a mobile Geforce 6xx, so I'm happy with it.  Made it easy for me to bang out this second depth sample from the comfort of a...actually I think it was a bar as opposed to a coffee shop...


The Technolust, i sorta haz it...

    I mentioned in my last post I'd been messing around with some other methods for visualizing depth from the Creative Camera, I took a few moments after GDC to decompress and finish this one up, it sorta builds off the last sample.  Instead of visualizing a texture, I'm using the depth to set attributes on some particles to get that point cloudy effect that everyone seems to know and love.  This one's a bit more complex, mainly because I added a few parameters to tweak the visualization, but if you've got some Unity under your belt, none of this will be that tricky, and in fact, you'll probably see pretty quickly how setting particle data is very similar to setting pixel data.  I should also note that the technique presented here could apply to any sort of 3d camera, pretty much if you can get an array of depth values from your input device, you can make this work.  So here's what we're trying to accomplish when all's said and coded:


    Since this is a Unity project, we'll need to set up a scene first.  All that's required for this is a particle system, which you can create from the GameObject menu (GameObject > Create Other > Particle System).  Set the particle system's transforms (translate and rotate) to 0,0,0 and uncheck all the options except for Renderer.  Next, set the Main Camera's transform to 160,120,-240, and our scene is ready to go.  That all in place, we can get to coding.  We'll only need a single behavior for this test, which we'll put on the particle system.  I called mine PDepth, but you'll call it Delicious (or whatever else suits your fancy)!  First, let's set up our particle grid and visualization controls:

//We'll use these to control our particle system
public float MaxPointSize;
public int XRes, YRes;

private ParticleSystem.Particle[] points;
private int mXStep, mYStep;

  • MaxPointSize: This controls the size of our particles
  • XRes, YRes: These control the number of particles in our grid
  • points: This container holds our individual particle objects
  • mXStep, mYStep: These control the spacing between particles (this is calculated, not set manually)

    With those in place, we can populate our particle grid and get some stuff on screen.  Here's what our initial Start() and Update() methods should look like:

void Start()
{
    points = new ParticleSystem.Particle[XRes*YRes];
    mXStep = 320/XRes;
    mYStep = 240/YRes;

    int pid=0;
    for(int y=0;y<240;y+=mYStep)
    {
        for(int x=0;x<320;x+=mXStep)
        {
            points[pid].position = new Vector3(x,y,0);
            points[pid].color = Color.white;
            points[pid].size = MaxPointSize;
            ++pid;
        }
    }
}

void Update()
{
    particleSystem.SetParticles(points, points.Length);
}

    If you're wondering where the values 320 and 240 came from, we're making some assumptions about the size of our depth map to set the initial bounds.  Once we add in the actual depth query, we'll fix that and not have to rely on hardcodes.  Otherwise, if all went according to plan, we should have a pretty grid of white particles.  Be sure to set some values for XRes, YRes, and MaxPointSize in the Inspector!  For this example, I've used the following settings:
  • XRes: 160
  • YRes: 120
  • MaxPointSize: 5

    As I mentioned earlier, this procedure actually isn't too much different from the previous sample, in that we're building a block of data from the depth map then loading it into a container object, just in this case we're using an array of ParticleSystem.Particle objects instead of a Color array, and we're calling SetParticles() instead of SetPixels().  That in mind, you've probably already started figuring out how to integrate the code and concepts from the previous tutorial into this project, so let's go ahead and plow forward.  First, well need to add a few more members to our behaviour:

public float MaxPointSize;
public int XRes, YRes;
public float MaxSceneDepth, MaxWorldDepth;

private PXCUPipeline mSession;
private short[] mDepthBuffer;
private int[] mDepthSize;
private ParticleSystem.Particle[] points;
private int mXStep, mYStep;

  • MaxSceneDepth: The maximum Z-amount for particle positions
  • MaxWorldDepth: The maximum distance from the camera to search for depth points
  • mDepthBuffer: Intermediate container for depth values from the camera
  • mDepthSize: Depth map dimensions queried from the camera. We'll replace our hardcoded 320,240 with this

    The only major additions we need to make to our Start() method involve spinning up the camera and using some of that information to properly set up our particle system.  Our new Start() looks like this:

void Start()
{
    mDepthSize = new int[2];
    mSession = new PXCUPipeline();
    mSession.Init(PXCUPipeline.Mode.DEPTH_QVGA);
    mSession.QueryDepthMapSize(mDepthSize);
    mDepthBuffer = new short[mDepthSize[0]*mDepthSize[1]];

    points = new ParticleSystem.Particle[XRes*YRes];
    mXStep = mDepthSize[0]/XRes;
    mYStep = mDepthSize[1]/YRes;

    int pid=0;
    for(int y=0;y<mDepthSize[1];y+=mYStep)
    {
        for(int x=0;x<mDepthSize[0];x+=mXStep)
        {
            points[pid].position = new Vector3(x,y,0);
            points[pid].color = Color.white;
            points[pid].size = MaxPointSize;
            ++pid;
        }
    }
}

    The bulk of the changes are going to be in the Update() method.  The big difference between working with a particle cloud and a texture as in the previous example is that we need to know the x and y positions for each particle, thus the nested loops as opposed to a single loop for pixel data.  This makes the code a bit more verbose, but not a ton more difficult to grok, so let's take a stab at building a new Update() method:

void Update()
{
    if(mSession.AcquireFrame(false))
    {
        mSession.QueryDepthMap(mDepthBuffer);
        int pid=0;
        for(int dy=0;dy<mDepthSize[1];dy+=mYStep)
        {
            for(int dx=0;dx<mDepthSize[0];dx+=mXStep)
            {
                int didx = dy*mDepthSize[0]+dx;

                if((int)mDepthBuffer[didx]>=32000)
                {
                    points[pid].position = new Vector3(dx,mDepthSize[1]-dy,0);
                    points[pid].size = 0.1f;
                }
                else
                {
                    points[pid].position = new Vector3(dx, mDepthSize[1]-dy, lmap((float)mDepthBuffer[didx],0,MaxWorldDepth,0,MaxSceneDepth));
                    float cv = 1.0f-lmap((float)mDepthBuffer[didx],0,MaxWorldDepth,0.15f,1.0f);
                    points[pid].color = new Color(cv, cv, 0.15f);
                    points[pid].size = MaxPointSize;
                }
                ++pid;
            }
        }
        mSession.ReleaseFrame();
    }

    particleSystem.SetParticles(points, points.Length);
}

    So like I said, a bit more verbose, but hopefully not terribly difficult to understand.  A few things to be aware of:

int didx = dy*mDepthSize[0]+dx;

    We use the variable didx as an index into the depth buffer.  The reason we do this is because our particles don't correspond 1:1 to values in the depth buffer, so we use each particle's x and y position to do the depth buffer lookup.  In the next example, we'll take a look at how we can actually have a 1:1 depth buffer to particle setup using generic types.

if((int)mDepthBuffer[didx]>=32000)
{
...
}
else
{
...
}

    Here, the reason we test against a depth value of 32000 is because this is what the Perceptual Computing SDK uses as the error term.  So if the SDK can't resolve a depth value for a given pixel, it sends back 32000 or more.  In this case, if we find an error term, we make the particle really small, but in the next example, we'll look at how we can skip that particle altogether if we have an error value.  Finally, remember we need to implement some sort of range remapping function, I call mine lmap as a homage to Cinder's remap, but you can call it whatever, again, it's basically just:

float lmap(float v, float mn0, float mx0, float mn1, float mx1)
{
    return mn1+(v-mn0)*(mx1-mn1)/(mx0-mn0);
}

    So that's that, in the next sample, we'll look at some different ways to map the depth buffer to a particle cloud and use the PerC SDK's UV mapping feature to add some color from the RGB stream to the particles.  Until then, email me, follow me on Twitter, find me on facebook, or otherwise feel free to stalk me socially however you prefer.  Cheers!


What can i say, i love OpenNI...

Wednesday, March 27, 2013

[TUTORIAL] Depth maps and Ultrabooks

    Went to a really great hack-a-thon this past weekend at the Sacramento Hacker Lab to help coach some folks through working with the Perceptual Computing SDK and got to see some really cool work being done, everything from a next-generation theremin to a telepresence bot, all powered by the Creative 3D Camera and Perceptual Computing SDK.  Does me good to actually get out into the community and see people just dive right in and start building stuff.  Compound that with the GDC Dev Day that personally I think went amazingly well (standing room only at one point!) and it's been a good GDC for Perceptual Computing so far.  But now comes the really hard part, which is that PerC needs to not become a victim of its own success.  As the technology gets into more hands, now it becomes about not burning through goodwill by breaking features, being uncommunicative, or not keeping up with the ecosystem.  But I digress...

    Wanted to share a little Unity tip I got asked about a few times during the hack-a-thon, and that's how to visualize the depth map.  The SDK ships with a sample for visualizing the label map, and visualizing the color map is a fairly trivial change, but visualizing the depth map requires a little bit of doing.  It's actually pretty trivial from a working standpoint, so let's take a look at what's required.

    To get a depth map into a usable Texture2D, the basic flow is:
  • Grab the depth buffer into a short array
  • Walk the array of depth values and and remap them into 0-1 range
  • Store the remapped value in a Color array
  • Load the Color array into a Texture2D
    If that seems really simple, fear not, it actually is, so let's take a look at some code and see how we accomplish this.  Here's a really simple Unity behavior that populates the texture object from the depth map.  I'll leave assigning the texture as an exercise to the readers:

using UnityEngine;
using System.Collections;

public class Test : MonoBehaviour
{
    private PXCUPipeline mSession;
    private int[] mDepthSize;
    private short[] mDepthBuffer;
    private int mSize;

    private Texture2D mDepthMap;
    private Color[] mDepthPixels;

    void Start()
    {
        mDepthSize = new int[2];
        mSession = new PXCUPipeline();
        mSession.Init(PXCUPipeline.Mode.DEPTH_QVGA);
        mSession.QueryDepthMapSize(mDepthSize);
        mSize = mDepthSize[0]*mDepthSize[1];

        mDepthMap = new Texture2D(mDepthSize[0], mDepthSize[1], TextureFormat.ARGB32, false);
        mDepthBuffer = new short[mSize];
        mDepthPixels = new Color[mSize];
        for(int i=0;i<mSize;++i)
        {
            mDepthPixels[i] = Color.black;
        }
    }

    void Update()
    {
        if(mSession.AcquireFrame(false))
        {
            mSession.QueryDepthMap(mDepthBuffer);
            for(int i=0;i<mSize;++i)
            {
                float v = 1.0f-lmap((float)mDepthBuffer[i],0,1800.f,0,1.f);
                mDepthPixels[i] = new Color(v,v,v);
                mDepthMap.SetPixels(mDepthPixels);
                mDepthMap.Apply();
            }
            mSession.ReleaseFrame();
        }
    }

    float lmap(float val, float min0, float max0, float min1, float max1)
    {
        return min1 + (val-min0)*(max1-min1)/(max0-min0);
    }
}

    So like i said, fairly simple, albeit verbose technique, but should be fairly easy to wrap it up into a simple function for quick future use.  This same technique can also be used to visualize the IR map with some very minor tweaks.  I've actually been doing alot of stupid depth map tricks the last few days.  I'm at GDC all this week so I'm not sure how much dev time I'll get to be able to polish a few more of these up but maybe the weekend'll afford me some cycles if i'm not in full on crash out recovery mode...

Saturday, December 29, 2012

C4CNC101 - Section 1: Intro To Functions

DISCLAIMER:
(1) If you are already familiar with functions, variables, types, otherwise coding basics, C4CNC101 is not for you.  I'd recommend taking a look at something like The Nature Of Code if you're interested in getting up and running with processing.
(2) A familiarity with digital art in general, including coordinate systems, pixels, etc will be extremely helpful.  If you've ever used Photoshop, Illustrator, or any other digital art program, 2d or 3d, you should be good to go.
(3) If you're a programmer, you'll probably find tons of inconsistencies or things i'm glossing over.  My goal here is not to teach programming, it's more to get people who want to get into using code as a tool to create or augment the creation of art up and running, enough to give them the foundation knowledge to research deeper if they so choose.  I've done alot of thinking about this and I believe the information as I've presented it is true in spirit and in the scope of processing.

header
    Ok, so hopefully by now you've downloaded and installed processing, signed up for an OpenProcessing account, and joined the C4CNC Classroom on OpenProcessing.  The first step is really the only requirement, but i do recommend at least peeking around OpenProcessing to get an idea of what's possible.  I'll warn you in advance that if you're just starting out, it can be pretty easy to get overwhelmed by the breadth and depth of content therein, but fear not!  Hopefully by the time we're through these first five lessons, you'll know enough to read through some of the sketches and even build your own sketches based off of them.  As I mentioned in the last post, if you come across any sketches or effects you'd like to remix, breakdown, or dive into deeper, let me know and I'll work something out for a future set of tutorials.  Alright, so let's begin!

    First, let's conceptualize a computer program as nothing more than a set of commands or instructions that processes information and produces results based on the specifics of the information and the commands.  While that's a bit of an oversimplification, on some level this holds true for any program, from the small visualization sketches we'll be writing here, all the way up to full on operating systems like Windows or Linux.  We call these instructions functions and we call the information data.  So let's write our first program.  Open processing and type the following function:

ellipse(50, 50, 50, 50);

    Once that's in place, press the Run button (it looks like a 'Play' button) in the upper left hand corner.  Alternately, you can check out the sketch on OpenProcessing(1-1: Basic Functions), although I highly recommend you follow along by typing the code yourself to get the most out of these lessons.  Either way, you should see something like the following:

Step1_0

CODERSPEAK: When we issue a command in a program, we say we are calling the function or making a function call, and when we provide data to a function, we say we are passing an argument (or arguments).  So when we issue a command and give it some information, we are calling a function with arguments.

    This may not look like much, but it's actually a valid processing sketch, so congrats.  In some languages, Python for example, a single function like this could also comprise a valid and complete program, so not bad for a first step!  Sure, it's not very exciting and doesn't do much, but we'll get there.

    Now, let's take a moment and break down our function call.  For our intents and purposes, every function call will be a name followed by a set of parentheses.  If we're passing arguments to the function, they'll be between the parentheses, separated by commas.  And finally, we end our function call with a semicolon, so processing knows to move on to the next function.  Thus, the skeleton for any function call is:

functionName(argument1, argument2, argument3, etc);

    Recall that we started out by defining a program as a set of commands(functions) that processes information(data) to produce a result.  Arguments are how we provide the data to a function.  In cases where we're passing multiple arguments, each argument is used by the function to perform a specific task along the way to producing the final result.  So in the case of our first sketch here, as the programmer we're telling processing to:

Draw an ellipse with a position of 50 pixels along the x-axis and 50 pixels along the y-axis, and a size of 50 pixels along the x-axis and 50 pixels along the y-axis.

    Most, if not all, publicly available coding tools and environments have references that describe (some in more detail than others) what each argument does.  For example, take a look at the reference page for the ellipse() function, which not only details the arguments, but also provides some useful tips on calling ellipse().

    Alright, so let's practice a bit by adding a few more functions.  Add another function before the ellipse() call, so your sketch contains the following function calls.  Note that we're changing some of the arguments to the ellipse() call, and you should feel free to change any of the arguments to any of the functions.  Experimentation is a key to learning!

size(400, 400);
ellipse(200, 200, 50, 50);

    As you can probably tell from the result, the size() function sets the size in pixels of our sketch's window.  Even though both functions take a different number of arguments and produce markedly different results, you can see that they both follow the same skeleton we outlined above, i.e.:

functionName(argument1, argument2, argument3, etc);

    Before we get a little more advanced, let's add a few more basic processing functions, again for practice, and also to see how we can affect what we're drawing on-screen so we can start getting an idea of the kind of drawing functionality that processing makes available to our sketches.  We're going to add three more function calls in-between our size() call and our ellipse() call: background(), stroke(), and fill().  Type these functions in as presented below:

size(400, 400);
background(0, 0, 0);
stroke(255, 255, 255);
fill(0, 128, 255);
ellipse(200, 200, 100, 100);

    As the saying goes, the more things change, the more things stay the same.  As we add functions, we see the results compound and the output become more complex, but in the end, all functions are called in the same manner using the same syntax.  Feeling comfortable typing in functions?  Then give the following exercises a try and see what you come up with.  Questions?  Please post them in the comments!

footer
EXERCISE 1: Draw 5 different ellipses with different radii and in different locations.  Be sure to check out the Processing Language Reference for ellipse() for more details on how the ellipse() function works.  Try changing some of the arguments to the other functions as well!
Exercise 1-1

EXERCISE 2: Take a look at the Language Reference for background(), stroke(), and fill().  Now, take the previous exercise and change the stroke and fill color for each ellipse. While you're at it, change the background color to something a bit friendlier than black, it's getting a bit gloomy in here...
Exercise 1-2

CODERSPEAK: You might be wondering how processing knows what to do when we call any of the functions presented here.  Well, most, if not all programming languages and environments come with a set of pre-existing functions and data that we use to build up our programs initially, which you'll often hear referred to as built-ins or library functions.  When writing programs, you'll use a combination of both built-in functions and data, as well as functions and data you define yourself.  We'll discuss this process in the next couple lessons.






PREVIOUS ARTICLES
Foreword
Project Preview

Saturday, April 14, 2012

prototyper's toolbox: pythonic edition

        I had a really good convo with a co-worker today and I realized I miss working in Python just a wee bit.  For prototyping especially, why wouldn't you use Python?   I'm surprised the thought hasn't really hit me until just now, but you know, the fast turnaround provided by working in an interpreted environment is fairly ideal for rapid prototyping, no?

        As much as I like Unity, it's definitely getting to the point where i'm having to do enough custom implementation that it's putting a damper in my relevant iteration time.  Don't get me wrong, i'm enjoying getting to dip my toes into other languages and features (learning P/Invoke has been pretty cool), but i feel like a Python based prototyping environment might get me a little further a little faster.  More often than not, Python modules work in whatever your Python environment is, and I understand that's not a 1-to-1 comparison as Unity is not a pure .NET environment, but still...

        So in my wanderings last night, I dug up a few different tools that seem like things I'll want to be diving into next.  I went to bed super early, so I haven't spent a ton of time with alot of these resources, but enough to feel like these will all be useful in the future.  Once i get done with this current demo cycle, I'm going to get out of Unityland and start writing standalone apps, just to get more practice writing big software projects.  I feel like I'll have more flexibility in a pure python environment and I'll probably get more done faster. Props to my co-worker Chris for inspiring my search...



Modules/Libraries
        Most of these provide the full suite of lower-level functionality you need for prototyping/building media applications (event loop processing, input management, etc), just import whatever else you need alongside them and you're good to go.  Fair warning, some of these are NUI/MT specific, but then, that's really what I'm into these days.  I gotta say it's also made me realize how much of a gadgetwhore I am, but man, I hate spending money on them, which is probably why i don't have one.  That and it also makes me realize how much of a touch interface freak I am.  I can't say I'm huge on gestures, but touch is cool.  I actually found a fairly extensive list of game engines that would probably be make great generic event loop/input/rendering managers too, that's for another blogpost...

android-pythonPython for Android
I'm not 100% sure why i put this here but it seemed like a cool little aside. I only glanced over the docs a bit, so I can't make any recommendations, but I will say it's definitely more of a power tool than a ready to go development resource. More and more i keep finding reasons to want to get that Android device i keep threatening to get, but then i think, ugh, do i really want to spend money on another gadget? "Another", like i own a bunch of them already...

pygame_projects pygame and PyKinect
I lumped both of these together because most of the PyKinect samples run on pygame anyway, altho nothing precludes you from using your event loop manager (heretoforth referred to as ELMs) of choice. While this isn't necessarily MT, if you want to get started with NUI prototyping, this is honestly the way I'd recommend going. The Kinect SDK is super easy to write code against, you'll be doing crazy things in no time.

vpython_projectsVPython
Alright kids, gather around, and let me tell you a tale of POVRay...yes, I just dated myself horribly, but then, i'm constantly getting told that I'm too old for...certain people anyway, so i guess it is what it is. But really, that's about what we have here, even to the point where VPython lets you export to POVRay renderable files. How cool is that? Also includes its own version of IDLE, but I'm going to have to frown on that...

kivy_projectskivy
From what I understand, this is the way to go for Python MT development. I found a few other options (PyMT, etc), but this seems to be the one everyone recommends. If you're an experienced pythonista or have an established development environment, you can skip some of the weird setup requirements and dive right in. Get started now and whip some cool stuff up for their next contest!

tuio_projectspyTUIO
No discussion of MT development would be complete without including some TUIO bindings, so here you go! There are a few dependencies you might want to be aware of too (most notably reacTIVision), but once you've get everything down, this is another great way to get up and running with minimal hardware investment and setup. Make your own Reactable, actually, i've just hit on a plan...



Art IDEs
        Sure you could sit in a coffee shop and write a book, but let's be honest, if any chick looks over your shoulder and sees you rockin some cool interactive art in one of these apps, there's an icebreaker. Show her your camera or other input device, get her to play around with it a bit and it's all over except for the part where you embarrass yourself horribly trying to ask her out...Probably better to just get a bunch of buddies together and rock some interactive art jams on your laptops, takes me back to the days of laptop jamming with Live.  Or at least I think it would, i'll know more tomorrow, actually going to a group Processing session of sorts, should be fun. May even be the beginning of my social life...

nodebox_projectsNodebox 2
If you're a Maya or Houdini Tech Artist, or just an ICE freak, this one's for you.  I actually came across Nodebox a while back, but got a sad panda because it was MacOS only, altho I suppose it would have been a good use for my still not very used Macbook Pro. But yeah, this is basically Processing with a hypergraph attached to it, how cool is that? And Python to boot, so it's like Maya, but light and stable...ish.

shoebot_projectsShoebot
Shoebot is the best-ish of both worlds in that you can run it from its own IDE or you can import it into existing Python projects. It's also a...well, let's say derivative, for lack of a better term, of Nodebox, so most of the docs you find for one apply to the other. Not to down on the work of the Shoebot guys, it's a "derivative" like pyprocessing or pycessing are derivatives of Processing.



Additional Reading
        A few last little tidbits to keep your head in the MT game, skip this if you're not interested in this sort of thing.

txzone_header31Txzone
All sorts of really fun musings here, not much of a learning resource, but great for inspiration and keeping up with what all's out there for the MT pythonista...


pymt_projectsGetting Started With MT Dev In Python
Some dated and slightly specific tutorials, but definitely great for a quick dip of your toes into the whole world of Python MT/NUI development.


Part 1 | Part 2 | Part 3 | Part 4




        I've got some pretty cool interactive art projects in the pipe right now, no ETA on any of them yet, but hopefully I'll be able to post some stuff up in the near future.  Got some longer term "milestones", altho I'm not sure milestone is the proper term since they tend to equate to public releases or showings of some sort...Nothing like a little pressure.

Wednesday, April 11, 2012

with trees

        Updated to include Teck's suggestions so it looks less like machine and more like man(god?).  Now we get something that looks like this:

treecut2

Yes, this looks much better methinks.  Only slight changes, just dropping in new terms really:

Tuesday, April 10, 2012

there is unrest in the forest

        You know, the thing with Unity is not so much the presence or lack thereof features, it's the same issue alot of software has, and that's the lack of not just documentation, but useful, relevant documentation.  I feel like too many companies assume that it's ok to just put out basic documentation for new users and then let the community pick up the slack.  That's alright I suppose, but that doesn't mean you can slack on the basic documentation.  For instance:
function GetHeight (x : int, y : int) : float
Description
Gets the height at a certain point x,y
Really?  A function called GetHeight() that returns a height value?  No Shit?  How about some information about the input parameters?  What is the expected range of values, for instance?  How about the return value, what do the units come back as?  You know, little things, back to that whole idea of useful and relevant, right?  Sheesh.



...Captain Obvious is Obvious, Captain...

        My ire comes from a perfect case, one of today's tasks was to spawn trees on a Terrain based on the heightmap.  All the pieces are there, it's actually quite a simple process, but again, it's just not knowing the little things that results in probably a bit more experimentation than necessary.  Really I'm just whining, but i've run into so many cases of this sort of thing with so many software packages I've used (looking at you, Maya), that at some point you just wanna contract out and document the stuff yourself for them.

        So rant over, if you're interested in doing this sort of thing yourself, here's some code that might be useful:



        Obviously you'd want to add some sort of noise to the tree placement and maybe even add some simple tree variants so it doesn't look like a military haircut, but this code produces a good starting point, something like this:


treecut

        You could probably get even more headway by sampling other maps or attributes to add a bit more spottiness to the placement or maybe even do a radial tap per sample step, something like that. Dunno, if you make any useful changes to this, let me know! Otherwise I'm just going to do it myself and...well, i guess that's not that bad.

Friday, April 6, 2012

thoughts with sounds

        Nothing really earthshaking here except whatever you might come up with on your own;)  Haven't blogged in way too long and left some things hanging, which I promise I'll get back to in the near future, just had a real interesting time of late with some slight work randomization in the form of the build machine, but it's been a great project!  I'm actually really intrigues to setup a python tools pipe that uses some form of CI, minus the build step...or maybe plus the build step for custom extensions.  Dunno tho, this is the sort of thing I think i need to do in moderation, hehe, not to slag on past lives or anything, but dipping my toes back into pure pipeline work reminds me that I like not having to do pure pipeline work all the time!  Given some of this new info, I think I'll probably push back part 2 of the Unity/Git tutorial and expand it to being a complete Unity/Git/CI tutorial once I get Unity builds figured out.  Shouldn't be too hard...

        Taking a page from my co-worker Chris, I've started gathering little snippets of media on youtube and vimeo that I can draw inspiration from, I'm realizing I need to shift my focus a bit to really stay up in this game.  It's such a different thing we're trying to do here, ideas need to come from different places.


kuato
Taking a bit of advice from this guy...

        One of the more fun videos came by way of another co-worker, which is driving some other stuff I'm thinking about right now, too.  Looking at this sort of thing does really solidify how much I enjoy having tactile components beyond just a touchscreen.  Something to keep thinking about.  Check it out, fun times:



        Hmm...lastly I started playing around with another prototyping framework, trying to find a good sandbox for doing sound driven gfx or gfx driven sound or whatever other combination of those things I can come up with.  I gotta admit I was a little charmed to see it come up in a tk windows, of course my first thought was "aww, i miss IDLE".  But yeah, check out Pure Data, it's a bit sparsely documented, but it's fun.  If you're familiar with patch-"programming", you'll feel right at home here (without having to pay for Max/MSP!).


pd640

    Ok just kidding.  Lastly for real, here's some fun generative audio stuff to get you through any boring times you might encounter this weekend.  I wonder what an evolution on this idea of generative music might look like...



Otomata - Try this online!


Tonematrix - This one too!

Tuesday, March 20, 2012

prototyper's toolbox

        Nothing special here, just a bunch of tools I've been using recently to do rapid prototyping.  It's such an alien concept to me to just throw a bunch of hardware and software into a blender and see what comes out, but it's pretty freakin fun.

banner
Unity
Probably needs no explanation, really good platform for prototyping as it's open enough to do things that aren't necessarily games.

oF_0
openFrameworks
Everything you need to create rich interactive applications under one roof. This is the model for what easy-to-use SDKs should be.

processing_cover
Processing
It's like an IDE for doing cool graphical stuffs. For you Pythonistas, check out pyprocessing as well.

vvvv
vvvv
Just found out about this the other day, node based madness.

ArenaLogo
OpenNI
Definitive framework for natural interaction (gestures, etc). A bit of a learning curve, but good to know.

        So what are some of your favorite rapid prototyping tools?  And if you say UDK, i swear i WILL hunt you down and punch you in the heart...