Thursday 25 September 2014

Game Engines Blog 1

So for this week, after getting tloc set up and running I began to look at a couple of samples. I just wanted to get a camera setup and running with a model so I looked specifically at the obj loader sample with the arc ball camera. At first I wasn’t used to the amount of use of inheritance and pointers used in tloc, but I quickly got used to the entity and component concept because I’ve been playing around with the Unity game engine all summer and have made some prototypes using it. I tried changing the positioning and rotation of the camera however it wasn’t behaving properly so I decided to write my own view matrix function which returns a 4 by 4 matrix determining where the camera will look at. This has allowed me to focus the camera on our player object.

math_t::Mat4f GetViewMatrix(const math_t::Vec3f& eye, const math_t::Vec3f& target)
{
       math_t::Vec3f up = math_t::Vec3f(0.0f, 1.0f, 0.0f);
      
       math_t::Vec3f zaxis = math_t::Vec3f(eye - target);
       zaxis.Normalize();
      
       math_t::Vec3f up_cross_zaxis;
       up_cross_zaxis.Cross(up, zaxis);

       math_t::Vec3f xaxis = up_cross_zaxis;
       xaxis.Normalize();

       math_t::Vec3f zaxis_cross_xaxis;
       zaxis_cross_xaxis.Cross(zaxis, xaxis);
       math_t::Vec3f yaxis = zaxis_cross_xaxis;

       float dot_xaxis_eye = xaxis.Dot(eye);
       float dot_yaxis_eye = yaxis.Dot(eye);
       float dot_zaxis_eye = zaxis.Dot(eye);

       math_t::Mat4f viewMatrix(xaxis[0],yaxis[0],zaxis[0], 0,
                                                 xaxis[1],yaxis[1],zaxis[1], 0,
                                                 xaxis[2],yaxis[2],zaxis[2], 0,
                                                 -dot_xaxis_eye, -dot_yaxis_eye, -dot_zaxis_eye, 1);

       return viewMatrix;
}

Next was to rotate the player box and have the camera follow the rotation and face where the player is facing. This was simply done by taking in the player’s rotated angle and calculating the rotation of the camera around the player’s position.

//rorate the entity around the Y axis
void RotateEntity(const core_cs::entity_vptr a_ent, double angle)
{
       math_cs::transform_sptr transform = a_ent->GetComponent<math_cs::Transform>();
       math_cs::Transform::orientation_type orien(transform->GetOrientation());
       //rotating around Y axis test
      
       math_t::Mat3f RotationMatrix((float)cos(angle), 0, (float)sin(angle),
                                                        0, 1, 0,
                                                        (float)-sin(angle), 0, (float)cos(angle));
       transform->SetOrientation(RotationMatrix);
}

I've also added spring physics to the camera so it adds a bit of a delay following the player.


//camera with spring physics (chase camera) for adding delay while following the player
static math_t::Vec3f camVelo(0);
math_t::Vec3f originalPos = transform->GetPosition();
math_t::Vec3f targetPos = newCamPos;

float stiffness = 0.8f;
float damping = 0.15f;
float mass = 0.005f;

math_t::Vec3f stretch = originalPos - newCamPos;
math_t::Vec3f force = -stiffness * stretch - damping * camVelo;

math_t::Vec3f acceleration = force/mass;
camVelo += acceleration * 0.001f;

newCamPos = originalPos + (camVelo * 0.001f);
newCamPos[1] = targetPos[1];