Friday, February 27, 2015

Interpolating between Positions and Radii

Having completed the technology to fill in the space between spheres, the next step is to build the systems to let the spheres move and change size!

If you think back to the original project idea, you'll remember we intend to implement an interface through which to make shapes comprised of spheres, where the user can set keyframes for sounds, colors, sizes, and positions!

So, to begin the process Amier used the Blueprint interface to make a "man".

It was simple to do - in the Event Blueprint section of the previously mentioned Caplet Collection collection, OnEventBeginPlay (called when the game starts) is triggered, and I call our "add caplet" function several times with parameters that describe the man.

To allow movement, I began by making an array of vectors (which are used by UE4 to represent any 3 dimensional float) that will represent the positions of the object, and to scale the Caplet I made an array of floats.
Then, inside the Caplet object I added two functions and modified an existing one (scale):

Interp

This is called by the Caplet Collection in tick for each Caplet. It takes in the delta time since the last tick, and keeps track of a floating point variable called 'time'. Time is incremented by delta time, and if it is greater than 1 the current indices in the position and scale arrays are incremented, and time set to 0. The indices are also kept within their bounds here as well.
Finally, Move and Scale are called.

Interp's Implementation


Move
This is called by Interp. It is relatively simple, but made ugly by the blueprint's constraints with regards to branching statements. The algorithm checks if the current position index is greater than the Positions Array's length - 1.
If so, simply set the current position to the current index (since the index starts at 0, and is guaranteed to have a value of at most array length-1). If not, that means interpolation must occur between the current index and the next index.

So, how to lerp between two points mathematically? Just for fun I wanted to derive it myself, without "cheating" and looking at notes/books/internet.
At first, I came up with this:
float Lerp(float a, float b, float t)
{ return (b-a)*t + a; }

While it took about 5 seconds to come up with and implement, unfortunately this was not safe for floating points, which I realized after my precision flew out the window. I quickly switched to one a bit more safe:
float Lerp(float a, float b, float t)
{ return (1-t)*a + t*b; }

To apply this to vectors, you need to perform it per each component between the two vectors.
So, I achieved the interpolated position between two vectors and some time t in [0,1] and the code looks like this.

At this point, you need to consider the edge case where the index is at the last position - there needs to be support to allow smooth interpolation from the end of the array to the beginning. I placed another branch to check if the current index is the final one and if so, lerp to the initial member of the array.

I want the user to be able to add more positions relative the the caplet collection object, and the blueprint functions to set position are limited to adding offsets (not good for interpolating cause they compound, unless you subtract the difference from the new interpolated value and the previous one and offset by that much, which gets complex). So using functions that set the actor's location in world space, I interpolate all the positions using the relative space, and offset by the position of the root Caplet Collection's world position, achieving a correct final result.

The final method.



Scale
Scale used to be a function called when the Caplet was created to force its set radius to match the rendered one, and as such had relative offsets/scales which would compound if called each frame. So, I reworked it and using the same algorithms I applied in Move, I achieved an interpolating radius.

Scale's Implementation


Click here for a quick video of it in action!


Wednesday, February 11, 2015

Caplets

What Next?

In order to make an editor for the user to create their own shapes, we needed to make some sort of object comprised of smaller ones. We decided the best way to do it was to take spheres, and connect them with tubes, like in this photo. Using a name suggested by Professor Jarek, we'll call them Caplets.

To implement it, we started with the basics: how to make a tube or "skin" between spheres? By finding the planes tangent to both spheres, we can draw triangles and fill out the space, like this.

MATH

Summoning my old high school geometry skills and Processing, I was able to build a quick test.
The secret was using spherical coordinates: By drawing some quick lines, I was able to solve for Theta, and using spherical coords means we have all the information we need.

Solving for Theta

Converting that to xyz coords gives a vector (let's call it R) that points to from the center of a sphere to the point where the tangent plane intersects. By normalizing and multiplying by the radius of a sphere, and then adding it to the center's position you get the point of intersection. By incrementing Phi you can get the next point on each sphere, and the rest is history.

There was a large snag though: the formula I used is only valid in two dimensions, or when both spheres share the same Z and Y values. To fix this, calculate the vector formed by subtracting the two sphere's centers, and use that vector as a basis to form a rotation matrix. Transforming the calculated R's of each triangle with this before adding to their respective centers adjusts for this and fixes everything. 

Implementation!

In order to implement it into UE4, I began by looking into ways to draw custom geometry like quads or triangles. After seeing a lot of disheartening forum posts saying it was either impossible due to UE4's architecture or I would need to extend their geometrical primitive class and implement it myself, I found hints of a Plug-In by Epic themselves that does this. I found it and it works like a charm.

Now, to support all the things we want it to I did a lot of architect-ing. I made an object called Caplet Collection, and a Caplet object.  The Caplet Collection has a function that allows it to add Caplets as components using another as a parent if desired, and an Edge list that keeps track of the connections/order. Every update, it iterates through the Edge list and draws the Caplets.

The final blueprint Part 1 Part 2

Next post will be me combining the work down on the caplet spheres with the sound/collision work done on the SphereBP we've been using up till now, and hopefully initial work on a working editor!

Saturday, February 7, 2015

A Different kind of Tone



Today was yet another Saturday working on Sphericles. Our previous (and really first productive meeting) was mainly getting things physically set up  and introducing the basic functionality of UE4 - especially the flow charts.

Getting to work today, now that I had known how to manage things better, was a lot less painful and a lot more fun. Now that we had a crude rudimentary model of, well, a crude rudimentary model of what we wanted, it was time to start applying what I learned by messing around in UE4 to help create what Sphericles is supposed to do.

Last week, chime sounds were played on contact with the spheres, but we want something a bit more dynamic than chimes. The idea is to get different kinds of tones to play for different kinds of spheres. At first, I tried to see if we could just change the pitch of some standard tone, but this didn't really lead to much distinction as I had hoped. I tried also to see if there would be any luck in procedurally constructing sounds from within UE4. No luck. I just decided, at that point, that the easiest solution would be to produce all notes as their own tones and mix and match notes to create chords from within a UE4 Sound Cue. Generating tones in Audacity, I was able to recreate all 12 the notes centered around A440Hz:

C, C-sharp, D, E-flat, E, F, F-sharp, G, G-sharp, A, B-flat, and B

Finally, I assigned an audio cue to randomly mix two tones to produce a chord to play for each sphere. Attenuation was assigned so that sound volume depends on distance from the audio source.

Sunday, February 1, 2015

Checking in with Graphics and Gameplay Work, 2/1/15

I gave myself some projects to better understand UE4's shader system.
They call them Materials, and are applied to meshes through a drop-down
menu. Using a flow-chart-like interface you can take inputs like normals
 and positions and apply mathematical operations to them, and then
output them.

Flow Chart

It ends up looking like this.

I told the sphere objects to randomly choose from some of my other
test-materials, and when they spawn randomly around the environment they
choose a random material at creation, which which ends up looking like this.

I also added collision between the player and the physical mesh, so
touching it will delete it. Later I'll add the option for effects/sound
to play when it is destroyed.

Amier also added lots and lots of gameplay related work - he'll post about it soon :)