FAO Recruitment agency workers

Hello and good day to any recruitment agency workers who have made their way to my site from the link on my C.V.

Since November 2013 I have been in employment. However, some of the C.V. sites out there may still have me listed as unemployed and still looking for work. Sorry to disappoint you folks but since I’m already employed, I won’t be applying for any jobs you have available.

However at the very least, thank you for considering me as a possible candidate and I do hope you find someone to fill the role as soon as possible.

-Carl Mitchell

Welcome

Welcome.

This site serves as the portfolio of Carl Mitchell.

Here is a contents list specifying the name of the projects and the languages/technologies used for your convenience:

Do note that this is a newly created and continually updated site, so not all of my projects may have been written about just yet. For example,  some C# projects are in the process of being finished and will appear on this site soon. I’ve also recently started using the Unity game engine and hope to have some projects appear in this portfolio in the nearby future.

If you have obtained my C.V and wish to know more about any of the projects, feel free to contact me via the details specified on my C.V.

Procedural World Map Generation (JavaScript, HTML5)

Next in line for JavaScript is an application that can create and draw world maps consisting of several continents.

It is essentially a variant of the fractal Midpoint displacement algorithm and works as so:

For each island:

  • Pick a number of initial points, low numbers like 2 or 3 will form a line shaped or triangle shaped continent and higher numbers will form a circle.
  • Pick a radius, essentially the size of the island
  • Pick an offset, during the tessellation stage, when randomness is added, how much randomness should be used to offset the newly created point?
  • Pick a scale factor, for each level of tessellation the offset needs to be decreased in size and this scale will determine by what % it will decrease (0.5 = 50% for example).
  • With these 4 pieces of data:
    • Generate the initial points using the radius and number of initial points required. For now, the island is simply placed at (0, 0) and generates the points on a circle connect by lines
    • For N levels of tessellation (9 seems to be the most before any more detail added is smaller than 1 pixel):
      • Find the middle of each pair of points
      • Add a random offset to the x and y values, determined by the value set as the “offset” before
      • Add the newly generated point to the list of points
      • Once all points have been subdivided and offset, reduce the offset value by the scale factor

And doing so for M number of islands which each have a position vector that can be used to move them around.

The application also comes with the following features:

  • Regenerate any selected island with new random data without changing the others
  • Reposition any selected island with new x and y coordinates
  • Change any of the following, that will be used the next time an island is regenerated (essentially every variable is changeable):
    • Number of initial points used
    • Radius
    • Offset
    • Scale factor
  • Add new islands to the existing world map, which will also automatically select it as the “currently selected island” when applying changes.
  • Remove selected islands from the existing world map
  • Place all the islands in random positions, large islands may merge into larger islands allowing you to create complex looking continents
  • Choose the draw the islands “number” so when selecting an island with the GUI, you know which one you are modifying
  • Click to select the island you want to change, a circle will be drawn around the current chosen island. Deselect by clicking on the ocean or clicking the Deselect option from the GUI (if you place too many islands and there’s no ocean to click!). Selecting an island will also automatically update the GUI values such as x position, y position and selected island.

The GUI is from the datGUI library.

See this video: I recommend watching in full screen and at a HD resolution if you can in order to see the finer details of the fractal and to also be able to see the GUI properly.

Overall I’m quite pleased with the application but there is one thing I wish I could do with it. At the moment it only shows a blue ocean and green islands, there’s nothing on the islands such as elevation data, river data, etc. Unfortunately since I’m only storing the points of the islands coast and not the points in between, then I would have to go about this application in a very different way if I wanted something on the actual islands. They would have to be split into (and drawn separately as) polygons rather than being outlined and filled in in-place like it is now. Maybe some other day?

As with my other work, if you want to see the source then please contact me via the details on my CV I’ve sent you.

Collision Detection and Resolution Part 2: 3D (JavaScript, HTML5, ThreeJS)

As well as learning JavaScript, I’m also learning how to use the various JavaScript libraries out there. One of the more exciting libraries is the ThreeJS library that allows you to create WebGL applications in JavaScript and use the GPU for rendering to the HTML5 canvas (rather than CPU rendering, also known as Software renderering, which is remarkably slower).

So I decided to create a 3D version of this which in turn is a JavaScript port of this.

Unfortunately, due to Google* Drive’s new “update” under the guise of “making it easier for our users” (read: removing commonly used features in order to save money), I can no longer use it to host my javascript work so I’ll have to use the same method as before: either a video of it in action uploaded onto youtube or a series of pictures. Here’s the video:

If you can, watch it full screen in HD. Also, youtube only shows videos at 30fps as of Aug 2014 which is a shame :( so the video won’t look as smooth as it actually runs.

As with all my work, if you want the original source, please contact me via the details on my CV and also state your name as I will only send to companies I have applied to.

It has the same problems as the 2D version in that I just place the cubes randomly so they might be intersecting from the word go, so give them a few frames to resolve any interpenetration.

Collision Detection & Resolution PORT (JavaScript, HTML5)

(Finally, I get some time to program some of my own stuff — my first bit of spare time in months)

If you asked me a year ago if I liked JavaScript, I would’ve said no but the thing is, I had never really learnt it. There was a single module in my bachelor’s degree (a second year module called Web Server Programming, I think) that had us writing a small amount of JavaScript. But that’s all the JavaScript I knew.

Similarly, if you ask others if they like JS, a seemingly large amount of people will say no too.

For me at least, I was wrong about JS.

I had noticed a large number of companies asking for it so I decided to learn it and to be honest, I actually kind of like it. There are plenty of pitfalls to be sure just as any language but there’s also a lot of really nice features that I like. Closure is absurdly useful and the fact that almost everything, even functions, are first class objects is very cool. I think when people say they dislike JS they mostly mean they dislike the DOM.

So after learning a bit of JS, I decided to port one of my previous projects, specifically the collision detection and resolution from here.

It turns out you need a paid account to host html/js/css/etc. on wordpress so it’s hosted on my google drive account. Hopefully this link actually works:

Click here to view the demo in your browser

There are some things to note however:

  • The physics detection is definitely working but the physics resolution seems to be slightly buggy under certain conditions. Sometimes the boxes turn red (collision detected) but don’t seem to move apart from each other (collision not resolved). I think it’s because the boxes all have 0 acceleration (any velocity change is done as an immediate impulse) and 0 relative acceleration is causing some small amount of imprecision.
  • When the program runs, it just places the boxes in random positions so it’s likely that some boxes will be overlapping from the very beginning, give it a few frames to correct itself!
  • Finally, the source code is minified, you can still technically read it but it’s difficult to do so. If you want the non-minified version that has comments and whitespace, please contact me either by email or phone as listed on my C.V. and please state who you are representing as I will only give out code to those who I have applied to

I want to do more stuff in JavaScript and I think the new JS program I do will be something interactive and something to do with fractals! Perhaps a world map generator? Eventually.

SQL Database for a make believe game (SQL Server, T-SQL)

This project involved making a database that a potential video game could use (or may use in the future).

Below is a short summary of the T-SQL features that were used:

  • Transactions for in-game purchases which also used error handling
  • After-Triggers to add purchases to an audit file
  • Views to hide sensitive data (such as player addresses) but show other data such as high scores
  • InsteadOf-Triggers to stop inserts/updates/deletions using the above view
  • Tables in 3rd Normalised form as industry standard
  • Relationships and constraints between each table such as primary keys, foreign keys, unique constraints, default constraints, check constraints etc. to make sure there is correct data integrity
  • Stored procedures to automate the process of purchasing items and update player profiles (incrementing their score, etc.)
  • User defined functions, both scalar and table, for processing player data and calculating derived data such as score per day
  • Old style defaults and rules – I would prefer to use the newer check constraints and default constraints however I’ve heard some companies refuse to update their SQL server version and hence there are some out there having to use these older ways so it was best to learn them as well.
  • Indexes – to speed up searches. An example: there is a unique clustered index on each table (since there are primary keys on each table) and a non-unique non-clustered index on the player table for the players score, which appears often in searches.
  • Subqueries to help with some searches
  • Joins – inner and outer, used whenever I needed data from more than one table.

If there’s anything missing on the list and it’s easier to use than at least one of the items on the list, then you can safely assume it has been used at some point. For example, I wouldn’t mention the use of aggregate functions since they are common but rest assured they have been used multiple times.

Media:

Media will be added soon

Code is available by request to the companies I have applied for. Please contact me by email, land-line phone or mobile phone using the details on the C.V. I sent you.

Fractional (or Fractal) Brownian Motion Generator

A small, mostly background working, application that generates Fractional Brownian Motion signal data. Uses Perlin noise as a basis function since it’s nice and quick. Parameters can be set to change the generated data:

  • Octaves – the number of times the Perlin noise is applied to each point
  • Lacunarity – Essentially what you multiply the signal frequency by and what you divide the signal amplitude by for each octave
  • Spread – How close the noise values are. Larger spread produces a smoother but flatter surface. However, a higher scale can reduce flatness.
  • Scale – uniform multiplication of the resultant values to increase/reduce flatness.
  • Byte array – if ticked, will return integer values between 0 and 255. If not, float values between 0 and 1 multiplied by the scale will be used.
  • Filename – the name of the output file.
  • Size – The square size of the signal data. A size of, say, 128 will generate a 128*128 signal data. The size has to be square but many fractal noise generators only work (or work best with) squares anyhow and other things that you might use alongside this data, such as textures, also work best when square.

The output is simply a text (.txt) file that is easily to read in for any language and contains the size used and the signal data itself.

A common use for this is for height maps and terrain generation.

It uses the CPU to generate the signal values but as my Masters Dissertation showed, using the GPU is far faster by many magnitudes.

Media:

The main menu

The main menu

The output results. In the example of terrain generation, these values are the y-value in each terrain vertex position, un-scaled.

The output results. In the example of terrain generation, these values are the y-value in each terrain vertex position, un-scaled.

Code is available by request to the companies I have applied for. Please contact me by email, land-line phone or mobile phone using the details on the C.V. I sent you.

Terrain Generation, Character Motion & Strategic Path Planning on the PS3 (C++)

Features:

  • PS3 Programming using the PhyreEngine game engine.
  • Diamond-Square terrain generation algorithm
  • Ability to read in and display height maps
  • Basic skeletal structure and human motion using scene graphs and joints (revolute and prismatic)
  • Strategic path planning- A* with a heuristic taking other information into account such as the gradient of the terrain to plan out the best path

Description:

This project looked into creating applications for the PS3 using the PhyreEngine game engine. It was split into three parts: terrain generation, human motion and strategic path planning.

For terrain generation the project can generate terrain itself using the diamond square algorithm or it can read in a heightmap of pre-generated values. For human motion I used a scene graph and joints to form a primitive skeleton that could walk and run across the terrain. For strategic path planning I used the industry standard A* but with a heuristic that takes into account the gradient of the surrounding terrain. Across a steep hill might technically be the shortest path but it would take long in terms of time!

Media:

Unfortunately I do not have any pictures of this program running. Unlike most of the reports for the other modules, this project’s report did not require any pictures so none were taken. At the time it completely skipped over my head that I might need pictures of it in the future so it’s entirely my fault. To run the program (and hence get pictures of it) requires either a development kit PS3 (the “Tool” PS3) or a PC with the PhyreEngine installed, neither of which are available to the public so I can’t get any pictures.

However, here are a few code snippets and as always the full code is available for viewing to companies I have applied for.

//Update takes game time and not delta time, uses it to update the oscillatory motion of the joints.
void PhyreHumanoid::update(float time)
{
       float amp = (getMotionSpeed() / info.periodScale);
       amp = min(amp, info.maxMotionAmp); //clamp amplitude to range
       //rot is used for shoulders and hip joints, it is allowed to rotate forward *and* backward
       float rot =  amp * info.ampScale * cos(getMotionSpeed() * info.periodScale * time);
       //elbRot is used for elbows and knees, it can only rotate backwards, like actual knees and elbows
       float elbRot = amp * info.ampScale * abs(cos(getMotionSpeed() * info.periodScale *
time));
 
       //Turn into circular motion
       Vector3 rotate(rot * (float)PD_PI,0.0f, 0.0f);
       Vector3 elbRotate(elbRot * (float)PD_PI, 0.0f, 0.0f);
       //Apply motion to joints
       SetJointRotations(rotate, elbRotate);
}
 
//Diamond square algorithm
//The 4 seeds determine the initial height of the 4 corners
//Range determines how much the height changes at each iteration.
void TerrainGenerator::createDiamondSquareFractalTerrain(float seed0, float seed1, float
seed2, float seed3, float range, float heightScale)
{
       scale = heightScale;
       srand((unsigned)time(0));
 
       data[0][0] = seed0;
       data[0][numVertexRows-1] = seed1;
       data[numVertexColumns-1][0] = seed2;
       data[numVertexColumns-1][numVertexRows-1] = seed3;
 
       for(int sLength = numVertexColumns – 1; sLength >= 2; sLength /= 2)
       {
              int hLength = sLength / 2;
 
              //Square step
              for(int col = 0; col < numVertexColumns – 1; col += sLength)
              {
                     for(int row = 0; row < numVertexRows – 1; row += sLength)
                     {
                           float average = data[col][row] + data[col+sLength][row] + data[col][row+sLength] + data[col+sLength][row+sLength];
                            average *= 0.25f;
 
                           data[col+hLength][row+hLength] = average + (-range + rand()
* (range – (-range)) / RAND_MAX);
                     }
              }
 
              //Diamond step
              for(int col = 0; col < numVertexColumns; col += hLength)
              {
                     for(int row = (col+hLength)%sLength; row < numVertexRows; row += sLength)
                     {
                           float average = data[(col-hLength+(numVertexColumns-
1))%(numVertexColumns-1)][row] + data[(col+hLength)%(numVertexColumns-1)][row] + data[col]
[(row+hLength)%(numVertexRows-1)] + data[col][(row-hLength+(numVertexRows-
1))%(numVertexRows-1)];
                           average *= 0.25f;
 
                           data[col][row] = average + ((-range) + rand() * (range -
(-range)) / RAND_MAX);
                     }
              }
              range *= 0.5f;
       }
 
       float smallestOffset = getSmallestHeight();
       float largestOffset = getHighestHeight();
 
       for(int i = 0; i < numVertexColumns; ++i)
       {
              for(int j = 0; j < numVertexRows; ++j)
              {
                     data[i][j] = data[i][j]/255.0f * scale + fabsf(largestOffset +
smallestOffset);
              }
       }
}
 
bool TerrainPathPlanner::AStarSearch()
{
       TerrainNode* node = grid->GetStartNode();
 
       while(node != grid->GetEndNode())
       {
              //Used to calculate which neighbours need to be considered
              int sX = max(node->GetX() – 1, 0);
              int sZ = max(0, node->GetZ() – 1);
              int eX = min(grid->GetNumCols() – 1, node->GetX() + 1);
              int eZ= min(grid->GetNumCols() – 1, node->GetZ() + 1);
 
              for(int x = sX; x <= eX; ++x)
              {
                     for(int z = sZ; z <= eZ; ++z)
                     {
                           TerrainNode* testNode = grid->GetNode(x, z);
                           //The latter tests stop the entity from travelling through
two unwalkable nodes diagonally. i.e. like so:
                           /*
                           |o| | | |
                           | |o|x| |
                           | |x|o| |
                           | | | |o|
 
                           The “x” tiles show unwalkable tiles but without the tests
in the next if statement we would generate a path like shown above
                           (denoted by the “o”s) where it has gone through diagonally
through the two unwalkables since afterall the node diagonal to the
                           current node is walkable. However if the two x’s
represented a wall, the path would go through the wall and obviously you wouldn’t
                           want that, so the latter tests in the next if statement
stop the above scenario from ever happening.
                           */
                           if(testNode == node || !(testNode->IsWalkable()) || !grid-
>GetNode(node->GetX(), testNode->GetZ())->IsWalkable() || !grid->GetNode(testNode->GetX(),
node->GetZ())->IsWalkable())
                           {
                                  continue;
                           }
 
                           float cost = straightCost;
                           if(!(node->GetX() == testNode->GetX() || node->GetZ() ==
testNode->GetZ()))
                           {
                                  cost = diagonalCost;
                           }
 
                           float g = node->g() + cost;
                           float h = CalculateHeuristic(testNode, node);
                           float f = g + h;
 
                           if(InClosed(testNode) || InOpen(testNode))
                           {
                                  if(testNode->f() > f)
                                  {
                                         testNode->SetParent(node);
                                         testNode->SetF(f);
                                         testNode->SetG(g);
                                         testNode->SetH(h);
                                  }
                           }
                           else
                           {
                                  testNode->SetParent(node);
                                  testNode->SetF(f);
                                  testNode->SetG(g);
                                  testNode->SetH(h);
                                  openList.push_back(testNode);
                           }
                     }
              }
              closedList.push_back(node);
 
              //If the open list ever ends up empty at this point, then there is no such
path available from start to target position.
              if(static_cast<int>(openList.size()) == 0)
              {
                     return false;
              }
              //Sort in order of smallest f using the Comparator created in the header
 
file
              std::sort(openList.begin(), openList.end(), fCompare);
              node = openList.back(); //use the node with the smallest current f value
              openList.pop_back();
       }
       //If we reach here, we have a path! so create the path and return true
       CreatePath();
       return true;
}

As with practically all my projects, this one earned a 1st.

Code is available by request to the companies I have applied for. Please contact me by email, land-line phone or mobile phone using the details on the C.V. I sent you.