Some of what I do

Kinect Head Tracker V2

Revisiting a 10-Year-Old Kinect Head Tracker

A while back I came across an old Kinect head-tracking project whose last meaningful commit was nearly ten years ago. The idea was solid, the math was fine, and the output was useful — but it wasn’t particularly stable when used for more than a few minutes, or if it lost your face.

I’ve been spending more time in my racing and driving simulator lately. While I have a solid cockpit setup with a single 42" display, not being able to naturally look around the car felt limiting. I knew there were webcam-based solutions, but I couldn’t find mine — what I did find was a Kinect 360.

The Kinect isn’t just a camera; it provides depth data. That led me down the path of looking for Kinect-based head tracking, which is how I discovered this old GitHub project.

This post documents why I forked it, what I focused on fixing, and how that work became Kinect Head Tracker V2.


Context: An Old but Useful Project

I wasn’t involved in the original development. The project was already done and essentially abandoned when I found it. The Kinect v1 SDKs haven’t changed much over the years, so the underlying approach was still valid.

The issue wasn’t functionality. The issue was reliability.

In real use — especially for sim racing or driving games — the application could run into problems after extended runtime: tracking would stop updating correctly-and the app would crash, memory usage would creep (and eventually crash), or the face-tracking pipeline would quietly fail and the app would, you guessed it, crash.

What I wanted was a head-tracking data source that could be run continuously without needing attention. I specialized in Windows application development for a lot of years so I knew this was a foundation I could work with and build this app right!

What I Focused On

Instead of adding new features, the work focused almost entirely on making the existing functionality dependable. Most of the effort went into areas that aren’t obvious from the outside:

  • Memory and resource management: tightening up image handling and unmanaged resources so the process doesn’t degrade over time.
  • Face-tracking recovery: ensuring that losing a face — due to movement, lighting changes, or occlusion — doesn’t leave the system in a null state or another bad state.
  • Long-session behavior: validating stability over extended runtimes rather than short test runs. This was a crucial to validate the memory management, tracking engine stability and recovery over time and power event changes.
  • Clear separation of responsibilities: keeping tracking logic isolated from networking and output.

None of this changes what the software does — it changes how reliably it does it.

Kinect Head Tracker V2

The result of that work is Kinect Head Tracker V2. Functionally, it’s still a Kinect 360 face-tracking application that outputs head-pose data. In practice, it’s far more predictable under real-world use.

One architectural decision that made a meaningful difference was maintaining a strict boundary between:

  • The tracking engine — responsible only for Kinect initialization, face tracking, and pose extraction.
  • The transport layer — optional UDP streaming, controlled explicitly, with no tracking logic mixed in.

That separation keeps the data source clean and makes failures easier to reason about when they do occur.

v2.1: Refinement

v2.1 builds on the stable base from v2.0 with incremental improvements rather than major changes. The focus here was refinement: cleaner control flow, clearer UI behavior, and fewer edge cases that require restarting the application.

At this point the tracker behaves like a product rather than a prototype — something that can be run and left alone.

The Public Fork

My fork of the project is available here: 
https://github.com/tensioncore/KinectHeadTrackerV2

It’s published so others can use it, inspect it, or build on it without having to rediscover and fix the same stability issues I found.


What’s Next

v2.2: Signed Windows Distribution

V2.2 will ship as properly code-signed Windows application with an installer.

The basic settings in the GUI now will all be functionally complete. Being able to ship the product as an installer and being properly code signed will allow anyone to download and run it without an security warnings about Unknown developer - The code will be timestamped and code signed, and you won't need to build it from source!

v3: Expanded Capabilities

v3 is where more advanced features will begin to appear. These are planned additions rather than promises, and include:

  • Support for Kinect v2 hardware
  • Direct FreeTrack output to simulators, eliminating the need for OpenTrack.
  • Additional configuration and quality-of-life improvements for sim setups
  • Color/Depth data visualization toggle

The primary constraint going forward is that new features shouldn’t compromise the stability established in v2.

A Fresh Coat of Paint

For a long time, the layout and design of nickdodd.com have been close to what I wanted — but the site itself felt empty. It didn’t do a great job of explaining who I am or the range of things I actually do.

I’ve always struggled with the “I do a little bit of everything — how do I present that on a website?” problem. The result was a site that looked fine, but didn’t really communicate the depth or variety of my work.

Recently, I spent some focused time refining things with that in mind.

The goal wasn’t to list everything or overwhelm anyone, but to present a clearer cross-section of my skills and experience in a way that feels approachable and intentional. That meant improving the photography galleries, adding a Wedding Photography section to better show that style of work, and introducing a proper contact page that makes it easier to reach out.

One of my favorite things about this site is that it’s always been built entirely by me — no blog platforms, no CMS, no frameworks beyond a heavily customized Skeleton CSS layout. Every update is a hands-on software project, and every change is deliberate.

This refresh is a step toward making the site feel more informed, more representative, and more useful — both for new visitors and for people who’ve been here before.

There’s more to come, but for now, this feels like a solid foundation.

— Nick

Reflection

With a little over a week until I get married, I’ve found myself reflecting a lot lately. If you know me, you know I work a lot. It’s not like me to spend much time in reflection — I’m usually looking forward, moving ahead. But Jamie and I have been together for nearly nine years now, and one of my biggest takeaways is just how much I’ve grown in that time.

Back in 2016, we were both just kids. In some ways, even in our mid-30s, we still are — but we’ve grown a lot, both of us. When my last relationship ended, I didn’t know it then, but it was for the better. 2016 was one of the hardest years of my life for more reasons than I care to unpack here, but in that same year I had arguably the best summer of my life. I learned who truly mattered, who didn’t, made friends I still have today, and started one of the most surreal jobs anyone could imagine — one I still hold to this day.

The day before 2016 began — New Year’s Eve — I met Jamie. I didn’t know it then, but she’d become one of the most important people I’d ever meet: my closest friend, my true partner, and in just over a week — nearly ten years after that first meeting — my wife.

When I proposed to Jamie on Christmas Day in 2023, I didn’t expect anything to really change. We’d already built a life together. But in the months since, I’ve realized things do feel different. My perspective has shifted — on myself, the people around me, and especially my relationship with Jamie. A boss and friend asked me recently if I thought marriage would change anything. At first, I almost said no, but instead I found myself admitting: “I’ll probably cool it on the partying, and give Jamie even more of the respect she deserves, since she’ll be my wife after all.” Not that I’ve been disrespectful, but I can get carried away when I drink. Truthfully, that’s less of an issue now — we’ve both slowed down on drinking these last few years — but still, it was an honest answer.

At the end of the day, Jamie and I already share a life. We’ve owned a house together for nearly five years, we’ve built a business together, and I’ve been part of raising her daughter, Payton, since she was nine. Now she’s 18, driving her own car, working full-time — and I still can’t believe how fast that’s happened. All this to say: Jamie and I already are partners. Getting married is just making it “government official” (a little more official than Facebook official 😅). People already call her my wife, and honestly, I’ve been saying it more often too.

I’m excited. Sure, maybe not much will change day-to-day, and that’s fine. We’ve got a good life. We look out for each other. We argue sometimes, but less so in recent years — and when we do, it’s because we care. You don’t fight for things you don’t believe in.

We balance each other in all the right ways. We see the world differently, but together we see more. At 36, I couldn’t have imagined a better partner to marry than Jamie. Marriage won’t change who we are — it’s a continuation of the life we’ve built — but it does mark the start of every year still to come, and I can’t wait.