Write a function that applies a blendshape and animation to an actor on screen and then outputs the world coordinates of a given actor's mesh vertex at a specific moment in time.
Set the time desired via input or playing/pausing the animation w/ play button. Select the muted-yellow "ghost vertices". The vertex's world position is displayed in the bottom left of the canvas.
Being brand new to ThreeJS enhanced the difficulty of this first task. I started off just following the provided examples on threejs.org & pouring over documentation to understand it's methods of operation. While the task itself was trivial to complete with a basic input method for the given vertex (such as its index), I wanted to utilize a fluid solution using interactive points for selecting vertices. I had trouble setting up these interactive vertices to follow the blend shape I had provided. I then realized that it was due to my implementation of the shader material that was provided by this example on interactive points (Github repo here).
This inadvertantly had the side effect of producing static vertices that would be easier to track in continous play mode, so they are the main form of selection. For this task, I have provided some pseudocode in the next section to shed some light on the inner workings of my algorithm.
Note: This code is a simplified version of the logic that is used for the above implementation. Its focus is to inform the reader of the main logic that drives the solution and performs the task. As such, component definitions are missing and the code snippet will likely error if compiled with no modification.
Write a function to determine if two actors are facing each other (can't use ray tracing).
Use trigonometry and quaternions to see if vector matches the negative of the other actors vector.
After the red actor is randomly rotated, you can immediately check
if the actor's are facing each other within the viewing angle provided.
This viewing angle can be set by the user in units of degrees (°).
If the blue actor is within the red's actor viewing range, then
the output on the lower right will confirm that the actor' are facing.
In other terms, if the angle between the facing directions of the red &
blue actors (w/ blues direction negated) is smaller than the provided viewing angle, then
a positive result is output for "Is Facing?".
If they are not, then the red actor is randomly rotated and the ouput
will inform the users that the actors are not facing each other.
Note: The difference between angles is referring to the red actors prior rotation,
& is not a reflection of the difference for the actors' rotations currently
on screen (Unless he was not rotated due to finding a sastisfactory angle).
With my solid foundation working with vectors, the solution for this problem was found almost immediately. The real challenge came with setting up my random rotations with my implementation of a FBX loader. As I was still familarizing myself with ThreeJS, I had misunderstood the documentation on how to transform and rotate objects. I eventually identified my misunderstanding using the Google Chrome dev enviroment & classic logging techniques, and implemented the correct behavior. With the solution working, I spent some time to understand loading an object with a custom material to enhance presentation, alongside implementing the user inferace.
Assuming two actors in a scene, write a function to find a bone on actor 1 that is closest to a given bone on actor 2.
Use branching search & bone positions to compare distances. There is no need to check for existence of actor 2.
Select the target bone on the purple actor via the drop-down menu. Then simply click 'Find Bone' & the closest bone's name will be displayed in the bottom right corner. You can also click 'Randomize' to transform the rotation of the orange actor for better results.
This one proved to be the most challenging task of them all. Having experience working with setting up skeletons for my games in blender (Referred to as 'Armatures' in blender's terminology), I knew that the structure started with a root bone and branched out other bones in a tree structure. Yet I was again setback by not knowing the ThreeJS architecture thoroughly enough. This time it was difficulties loading the bone tree structure properly, but this was eventually solved using the techniques mentioned above. So with my bone structure now loading properly, I implemented a recursive function to search through all of the bones and compare the distances to the target bone. It will then return the bone who's distance to the target bone was the smallest.
While I was aware that these task could have been completed within my language of choice, I wanted to familarize myself with the tools & frameworks expected of me on the job. So I decided to delve into a complete solution for these tasks using ThreeJS. This is certainly more than what was expected for the challenge, since I wanted to show my ability to craft solutions given your past experiences working with junior software engineers. My timeframe for completion leaves alot to be desired, and citing my personal setbacks only serves to excuse the delay. If your interested in knowing more about my other responsibilities that delayed my response, please feel free to ask.
What I can report is that, at time of writing (06/29/2023 @ 00:26 PT), this page in total took roughly 40 hours to complete according to my WakaTime tracker. This consisted of roughly 30 hrs of coding in Javascript, 6 & 1/2 hrs of HTML, 1 & 1/2 hrs of CSS, and 1 hr in Blender. Breaking this down in time per tasks, I logged 17 hours in the .js file for task 1, w/ an estimated 3 hours in related files, and 5-8 hours researching & debugging. For task 2, I only logged 5.25 hours in the .js file, an estimated 1.5-2.5 hrs in related files, and 3-6 hours researching & debugging. For task 3, I logged 4 hours in the .js file, an estimated 3-5 hours in related files, and 4-7 hours researching & debugging. Evaluate the screenshots from WakaTime below, taking note that about 1 hour of work on the 15th will be cutoff due to the free version's history only spanning two weeks.
All task logic finished on 06/25/2023 @ 10:46pm PT with < 30 hours logged coding.
I would say a fair estimate of time spent on research and untracked debugging lies in the range of 15-25 more hours.