Virtual worlds and virtual reality

I can’t help but to be both excited and concerned about the recent acquisition of Oculus VR by Facebook. Many of the initial reactions were kneejerk, and a bit over the top, but at the same time they should not be written off. Once we get over the feeling of betrayal from backers due to the sense of entitlement for getting the Oculus project off the ground, there is a lot to consider.

I get the sense that people are afraid that Facebook will completely dominate the social VR and virtual worlds segment and leave even less room for smaller companies to make any progress. The facts behind these fears are pretty simple, and well founded. Facebook is an absolute juggernaut of a company. They have the technical prowess as well as the people power and money to pull off just about any engineering project they put their collective mind to. I may not be a fan of the way they make their money, but to write them off is a total mistake. Companies like Facebook, Google, and Amazon have the chops and the resources to pull off virtual reality at massive scale even if they have to start from proverbial scratch.

Working at InWorldz, I know that the limiting factor is not the size of our imaginations, nor a lack of determination or skill, but very simply a lack of people power. We have a lot of goals and vision, but we have to limit our scope to what we can finish in a reasonable amount of time with the staff and contractors we have. If we had more people, I’d have at least 2 more very out of box projects running in development right now. Every day more and more ideas are developed and we have to choose but a small few to work on during the course of a year. As I begin to extend this time out, I realize that I need to continue to work as hard as I can to realize my dreams within the next 10 years and see if I can truly make a difference.

There is a very fine balance between accomplishing a goal as fast as possible and burnout. A VERY fine line.

Facebook on the other hand has infinite resources in comparison to our little company. They can put more people on a single part of a project then I have ever had working on the entirety of the InWorldz source code. They can do the scaling and performance research in parallel with developing the plans for more elaborate uses of the VR tech. They can afford to have a ton of failures on their way to success knowing that time is on their side.

So where is the good in all of this for companies around InWorldz’ current size? The research and ideas behind whatever technologies are developed will undoubtedly be shared over time. In the way that BigTable and Dynamo were the flagships of the NoSQL movement, it is entirely possible that a bunch of new techniques will be developed pertaining to virtual world scaling and rendering. These ideas will be shared because companies need to show that they’re at the top of their game. This helps everyone.

A second, and potentially larger benefit is that right now VR and virtual worlds are still a very niche segment. We just don’t have the user base we need to sustain a lot of successful companies in the space. A big company like Facebook highlighting the various uses of VR and virtual worlds may bring desperately needed attention to our little niche and bring it into its own. Everyone isn’t going to like the Facebook vision of VR, but that leaves room for people to find alternatives they can grab onto.

Facebook also will not conceive of every good idea that comes with a virtual world and virtual reality. More important than the tech is how the tech can be used to enhance people’s lives and/or give them more enjoyment in their day. There is room for everyone to come up with great use cases in the VR/VW space and then use whatever implementation they think best serves the purpose.

My vote on all of this from a virtual worlds perspective? Net positive effect on VWs.

Programming for.. relaxation?

Programming for.. relaxation?

Sometimes after a long 12 hour day of software development I like to sit back, relax, and… do more software development.

I never said I was normal.

I’ve always had a huge interest in embedded and constrained systems. I have an Arduino microcontroller that I’ve done a bunch of projects on to teach myself more about the crossroads between software and hardware. This past halloween I put together a pumpkin powered by a microcontroller, a few LEDs, and an ultrasonic distance sensor. You can see it here, and it is spooky.

On a side note, it just so happens that my desire to learn more about electronics actually brought about the InWorldz InShape project. I was planning on building a motion tracking setup out of some very cheap hardware that would connect to your tablet to send the InShape motion data. Thankfully resident grid monkey Jim Tarber talked me out of building the device and just write an app for smartphones. We really don’t want to become a hardware manufacturing company, but as a virtual worlds company, we will always be looking at the latest hardware to try to make the immersive experience more compelling.

TipCalc

That brings me to the point of this post. A few weeks ago someone I follow on twitter and have met on InWorldz landed a well deserved career with the pebble smartwatch company. @KatharineBerry always has something interesting to say and really seemed to be enjoying the software development she was doing for the pebble devices. So as usual I got curious and I wondered just how capable a device the size of a watch could be nowadays.

It turns out the watch is very capable. Utilizing a bluetooth link to your smartphone, the watch can transfer data and act as a quick wrist-flip conduit to your information. Without taking your phone out of your pocket you can see who is calling you, switch to the next track while listening to music and read incoming text messages.

Being me though, I was more interested in what I could make the watch do than what the watch could do for me. So I took a few hours to go through and learn about the pebble platform. The 2.0 SDK is straightforward without too many gotchas, and it was pretty easy to utilize the UI elements to provide a decent interface. After running through some docs, I wrote my first app. Pebble TipCalc. A watch app where you put in the total for a restaurant bill and the percentage you would like to tip and it returns the tip amount and bill total.

Since the first version, I’ve updated the app to utilize fixed point math (even with the small amounts and totals, I was seeing annoying accuracy problems with floating point) and enabled a more intuitive input of the the bill amount. It was a nice weekend distraction for when my brain was fried from too much VR work. I’m hoping to be able to somehow incorporate the device into future InWorldz projects.

Now you know what programmer types do “for fun”.

Learning to float

Every day I learn more and more about myself. I analyze the events of my life and try to make sense of it. I try to see the patterns in the chaos. I choose the directions I want to go in. I do my best to blaze a trail that will lead to success, happiness, and wellbeing for those that are directly and indirectly linked to my work.

We all have responsibilities and burdens to bear in our lives. We carry on, we do the best that we can to resolve issues and problems that arise. We try to keep people around us happy, trying hard to keep our dreams moving forward. Where things get difficult to deal with is when we are bombarded every waking hour with the consequences of these responsibilities. Where every phone call, every email, and every discussion is laden with more choices and more paths into the unknown.

When you’re trying to blaze a trail, there will be many times in your life where you won’t hear much other than the negatives about what you’re doing, or not doing good enough, fast enough, or thorough enough. When things are working out well for those around you, they will tend to just be content and continue forward with their own plans utilizing your work to help them along. So mostly, when you hear about something, you’re going to hear what others perceive you are not doing right. You’re going to hear this from your family, from your friends, and in the business case, you’re going to hear this from your customers. The wider the trail you choose to cut in your life, the greater the opportunity for disappointment. You’re already pushing as hard as you can, sometimes too hard, and it’s not going to feel good enough.

This can be taxing. It saps your life force in ways that are difficult to describe. We’ve all felt it before. It is the origin of not wanting to get out of bed. It is the origin of feeling tired after you’ve gotten enough sleep. It is the origin of avoiding people you love. We deal with this in different ways, some better than others. Some of us deal with it by not dealing with it and just pressing on, ignoring the feeling and moving forward until suddenly we just cant anymore. Burn out.

But burning out is not an answer. It will do more harm than good. You pushed on until you couldn’t anymore and now it will take you twice as long to recover. You will do twice as much damage to your personal relationships and your own wellbeing. You need to learn a better way to deal with this before it gets out of hand.

I spoke to a friend of mine about this recently, and she eloquently termed properly dealing with these constant bombardments as “learning to float”. The bombardments are like quick sand. They will never stop. They do not always contain problems in them that can be solved, maybe none can be solved immediately, and not always problems that you can solve alone. The more you fight against it, the further you sink until they feel like they’re burying you. The only thing you can do is give yourself some time to float. Disconnect for a while. Break away from the bombardment long enough to reconnect with life and to realize you are a very small piece in a large and ever changing puzzle.

This is a lesson I am trying hard to learn, to take these small chunks of time that I need between the dawn and the dusk and brush off the day that I may analyze everything from a clear perspective, unburdened by baggage. I will learn to do this in the same way I learned all about letting go of fear, but hopefully not in such a drastic way…  That’s another story for another time.

Peace and happiness to you all. Let’s learn to float down the river together.

Here’s looking at you

I recently had to rewrite an LSL function that wasn’t working properly for InWorldz. This involved a bit of vector math and then finally throwing in the creation and use of a rotation quaternion. Since I know that quaternion rotations and the math behind translations between coordinate spaces can seem like voodoo to someone just getting started with games and 3d environments, I figured I’d write this post trying to explain a few of the important topics that were demonstrated while I was implementing the function.

I was tasked to implement a function to take an object’s local +Z axis and point it at another object somewhere in world space. This kind of action is very intuitive to us as human beings. When you want to point at something you simply look in the direction of the object and align your arm, hand, and finger to aim at the target. Our brains perform all the calculations for us, masking the complexity of this seemingly simple action.

Finding the angle between two points can be visualized like the drawing below. We want to rotate A’s forward direction to aim at point B. What’s that? I hear you saying that A is just a point, it has no forward direction. This is true technically, we have to make one up for the object, or determine within our environment which of the object’s local axes is considered forward for pointing. It turns out that in the case I was working, the +Z axis was chosen arbitrarily to be the forward pointing axis for the object. You can see this added to our drawing below. The arrow is now pointing +Z.

A w/z axis forward

Now the picture of what we’re really trying to do should be clearer. We simply want to make that arrow point at the other object. We can think of this two ways. We can either take our current rotation and apply a difference to spin our object from where it is to where we want it to be, or we can forget that we have a current rotation entirely and set our rotation to point at the object. I’m going to look at this in the second way and just figure out if we were pointing to the global forward +Z axis what would be the required rotation to point us at the object.

The first thing we need to do is find the vector that points from A to B. This can be easily done by subtracting the vectors B – A. You can see the new vector pointing from A to B, and that there is an angle between them that we need to find.

Direction A to B

You might notice that subtracting A from B means that A is now located at the origin and B is now some offset from the origin. This is a good way to look at the problem to try to determine what to do next.

A and B at A origin

Now we need to determine the angle between the forward vector A and the point B. We do this using the vector dot product which returns the cosine of the angle between A and B. Remember that since we’re working with A being the new origin, our forward vector is simply the unit vector +Z. Pseudo code below.

Vector3 A, B; //see the drawings

//get the directional vector between A and B
//another way to look at this is that we're moving B
//so that its origin is at A
Vector3 targetAtNewOrigin = B - A;

Vector3 forward = Vector3.UnitZ; // <0,0,1>

//get the cosine of the angle between the forward vector and the target B
//which has been moved so that it is relative to A as the new origin
float angle = Vector3.Dot(forward, targetAtNewOrigin.Normalize());

Now we have an angle to work with, but there is an important thing to note about what gets returned from the dot product. If Vector3.Dot() returns 1 or larger, it means that the target object is on the specified forward axis. If Vector3.Dot() returns -1 or less, it means that the target object is exactly 180 degrees off our forward axis, behind us. We handle these cases specially.

Quaternion finalRotation;
if (angle > 0.999999) {
    // easy case. we want our final rotation to match 
    // a zero rotation in global space.
    // object is at our +Z
    finalRotation = Quaternion.Identity;
}

if (angle < -0.999999) {
    // second special case. our final rotation should
    // be facing -Z. rotate 180 deg on any axis except
    // Z
    finalRotation = Quaternion.FromAxisAngle(Vector3.UnitX, PI);
}

Note that we’re building a rotation quaternion from an axis/angle representation. In the second case, this rotation could be 180 degrees on either the X or Y axis to point us away from +Z pointing down -Z. To build a quaternion rotation from an axis/angle representation, we need to know how a rotation quaternion is defined. This function is built into most quaternion implementations, but can be summarized as:

quat.x = axis.x * sin(angle/2)
quat.y = axis.y * sin(angle/2)
quat.z = axis.z * sin(angle/2)
quat.w = cos(angle/2)

So we have both the case when the object is exactly in front of us or exactly behind us taken care of. What about when the object is somewhere in between?

We can use the vector cross product to obtain an axis of rotation that is perpendicular to our forward facing direction and the new direction. Imagine in the drawing below the axis found by the cross product going up and down into the screen and using it like a spindle to spin/rotate from A to B.

Rotate A to B at A origin

Using this axis and the angle we have obtained, we can get a final rotation that will put A’s forward axis facing the point at B.

// remember that the angle returned from 
// Vector3.Dot() is actually the cosine of the 
// desired angle. We use Acos to get the 
// true angle in radians
angle = Math.Acos(angle);

// this obtains the rotational axis in the drawing
Vector3 axis = Vector3.Cross(forward, targetAtNewOrigin).Normalize();

// this is our final rotation to set on A to point its forward
// axis to the object
finalRotation = Quaternion.FromAxisAngle(axis, angle);

A.rotation = finalRotation;

And now I’m lookin’ at you!