///
//Translates the RenderingManager's camera according to keyboard input
//
//Parameters:
//	GO: The game object this state is attached to
//	state: the First Person Camera State updating the gameObject
void State_FirstPersonCamera_Translate(GObject* GO, State* state)
{
	Camera* cam = RenderingManager_GetRenderingBuffer().camera;

	if(InputManager_GetInputBuffer().mouseLock)
	{
		Vector netMvmtVec;
		Vector partialMvmtVec;
		Vector_INIT_ON_STACK(netMvmtVec, 3);
		Vector_INIT_ON_STACK(partialMvmtVec, 3);


		if (InputManager_IsKeyDown('w'))
		{
			//Get "back" Vector
			Matrix_SliceRow(&partialMvmtVec, cam->rotationMatrix, 2, 0, 3);
			//Subtract "back" Vector from netMvmtVec
			Vector_Decrement(&netMvmtVec, &partialMvmtVec);
			//Or in one step but less pretty... Faster though. I think I want readable here for now though.
			//Vector_DecrementArray(netMvmtVec.components, Matrix_Index(cam->rotationMatrix, 2, 0), 3);
		}
		if (InputManager_IsKeyDown('s'))
		{
			//Get "back" Vector
			Matrix_SliceRow(&partialMvmtVec, cam->rotationMatrix, 2, 0, 3);
			//Add "back" Vector to netMvmtVec
			Vector_Increment(&netMvmtVec, &partialMvmtVec);
		}
		if (InputManager_IsKeyDown('a'))
		{
			//Get "Right" Vector
			Matrix_SliceRow(&partialMvmtVec, cam->rotationMatrix, 0, 0, 3);
			//Subtract "Right" Vector From netMvmtVec
			Vector_Decrement(&netMvmtVec, &partialMvmtVec);
		}
		if (InputManager_IsKeyDown('d'))
		{
			//Get "Right" Vector
			Matrix_SliceRow(&partialMvmtVec, cam->rotationMatrix, 0, 0, 3);
			//Add "Right" Vector to netMvmtVec
			Vector_Increment(&netMvmtVec, &partialMvmtVec);
		}

		float dt = TimeManager_GetDeltaSec();

		if (Vector_GetMag(&netMvmtVec) > 0.0f && dt > 0.0f)
		{
			Vector_Normalize(&netMvmtVec);
			Vector_Scale(&netMvmtVec, state->members->movementSpeed * dt);

			Camera_Translate(cam, &netMvmtVec);
		}
	}

}
///
//Rotates the runner controller
//	obj: A pointer to the game object to rotate
//	state: A pointer to the runner controller rotating the object
void State_RunnerController_Rotate(GObject* obj, State* state)
{
	// create a camera object
	Camera* cam = RenderingManager_GetRenderingBuffer()->camera;

	//Grab the state members
	struct State_RunnerController_Members* members = (struct State_RunnerController_Members*)state->members;

	// if player's mouse is locked
	if(InputManager_GetInputBuffer().mouseLock)
	{

		int deltaMouseX = (InputManager_GetInputBuffer().mousePosition[0] - InputManager_GetInputBuffer().previousMousePosition[0]);
		int deltaMouseY = (InputManager_GetInputBuffer().mousePosition[1] - InputManager_GetInputBuffer().previousMousePosition[1]);

		Vector* axis = Vector_Allocate();
		Vector_Initialize(axis,3);

		if(deltaMouseX != 0)
		{
			axis->components[1] = 1.0f;
			// rotate the camera
			Camera_ChangeYaw(cam, members->angularVelocity * deltaMouseX);
			axis->components[1] = 0.0f;
		}

		if (deltaMouseY != 0)
		{
			Vector forwardVector;
			Vector_INIT_ON_STACK(forwardVector, 3);
			Matrix_SliceRow(&forwardVector, cam->rotationMatrix, 2, 0, 3);

			// Keep camera from overextending it's boundaries.
			if (deltaMouseY > 0)
			{
				if (Vector_DotProduct(&forwardVector, &Vector_E2) < 0.7f)
				{
					axis->components[0] = 1.0f;
					Camera_ChangePitch(cam, members->angularVelocity * deltaMouseY);
					axis->components[0] = 0.0f;
				}
			}
			else if (deltaMouseY < 0)
			{
				if (Vector_DotProduct(&forwardVector, &Vector_E2) > -0.7f)
				{
					axis->components[0] = 1.0f;
					Camera_ChangePitch(cam, members->angularVelocity * deltaMouseY);
					axis->components[0] = 0.0f;
				}
			}
		}
	}
}
///
//Accelerates the runner controller
//
//PArameters:
//	obj: A pointer to the game object to accelerate
//	state: A pointer to rhe runner controller state which is accelerating this object
void State_RunnerController_Accelerate(GObject* obj, State* state)
{
	//Grab the state members
	struct State_RunnerController_Members* members = (struct State_RunnerController_Members*)state->members;

	//Grab the forward vector from the camera
	Camera* cam = RenderingManager_GetRenderingBuffer()->camera;

	Vector forward;
	Vector_INIT_ON_STACK(forward, 3);

	Matrix_SliceRow(&forward, cam->rotationMatrix, 2, 0, 3);

	//Project the forward vector onto the XY Plane
	Vector perp;
	Vector_INIT_ON_STACK(perp, 3);

	Vector_GetProjection(&perp, &forward, &Vector_E2);
	Vector_Decrement(&forward, &perp);

	//Scale the vector to the acceleration
	Vector_Normalize(&forward);
	Vector_Scale(&forward, -members->acceleration);



	//Only apply the impulse if the velocity is less than the max speed
	if(Vector_GetMag(obj->body->velocity) - fabs(Vector_DotProduct(obj->body->velocity, &Vector_E2)) < members->maxVelocity)
	{
		//Apply the impulse
		RigidBody_ApplyForce(obj->body, &forward, &Vector_ZERO);
	}
	else
	{
		printf("Value:\t%f\n", Vector_GetMag(obj->body->velocity) - fabs(Vector_DotProduct(obj->body->velocity, &Vector_E2)));
	}
}
///
//Allows the runner controller to wallrun if necessary conditions are met
//
//Parameters:
//	obj: A pointer to the object which is running on walls
//	state: A pointer to the runner controller state which is allowing the object to wallrun
void State_RunnerController_Wallrun(GObject* obj, State* state)
{
	//Get the members of this state
	struct State_RunnerController_Members* members = (struct State_RunnerController_Members*)state->members;


	//Get the first collision this object is involved in
	Collision* first = (Collision*)obj->collider->currentCollisions->head->data;

	//If we are not wallrunning yet
	if(members->horizontalRunning == 0 && members->verticalRunning == 0)
	{
		//Make sure this is a wall
		if(first->minimumTranslationVector->components[0] != 0.0 || first->minimumTranslationVector->components[2] != 0.0f)
		{
			//Save the normal
			Vector_Copy(members->wallNormal, first->minimumTranslationVector);

			if(first->obj1 != obj)
			{
				Vector_Scale(members->wallNormal, -1.0f);
			}

			//Determine what kind of wallrun is occurring
			//First get the forward vector of the camera
			Camera* cam = RenderingManager_GetRenderingBuffer()->camera;

			Vector forward;
			Vector_INIT_ON_STACK(forward, 3);

			Matrix_SliceRow(&forward, cam->rotationMatrix, 2, 0, 3);

			//Project the forward vector onto the XY Plane
			Vector perp;
			Vector_INIT_ON_STACK(perp, 3);

			Vector_GetProjection(&perp, &forward, &Vector_E2);
			Vector_Decrement(&forward, &perp);

			Vector_Normalize(&forward);

			//Get dot product of forward vector and collision normal
			float dotProd = fabs(Vector_DotProduct(&forward, first->minimumTranslationVector));
			//If the dot product is closer to 0 we are horizontal running, else we are vertical running
			if(dotProd < 0.75)
			{
				members->horizontalRunning = 1;
			}
			else
			{
				members->verticalRunning = 1;

			}
		}
	}

	//If we are horizontal running
	if(members->horizontalRunning == 1)
	{
		printf("Horizontal Wallrunnin\n");

		//combat the force of gravity
		Vector antiGravity;
		Vector_INIT_ON_STACK(antiGravity, 3);
		antiGravity.components[1] = 9.81f;
		RigidBody_ApplyForce(obj->body, &antiGravity, &Vector_ZERO);

		//Zero downward velocity
		if(obj->body->velocity->components[1] < 0.0f)
		{
			Vector_Copy(&antiGravity, &Vector_ZERO);
			antiGravity.components[1] = -obj->body->velocity->components[1];
			RigidBody_ApplyImpulse(obj->body, &antiGravity, &Vector_ZERO);
		}


		State_RunnerController_Accelerate(obj, state);


	}
	else if(members->verticalRunning == 1)
	{
		printf("Vertical Wallrunnin\n");


		//combat the force of gravity
		Vector antiGravity;
		Vector_INIT_ON_STACK(antiGravity, 3);
		Vector_Copy(&antiGravity, &Vector_E2);


		//go up!
		Vector_Scale(&antiGravity, 9.81);
		RigidBody_ApplyForce(obj->body, &antiGravity, &Vector_ZERO);

		//If we aren't jumping too fast yet
		if(Vector_DotProduct(obj->body->velocity, &Vector_E2) < members->maxVelocity)
		{
			Vector_Copy(&antiGravity, &Vector_E2);
			Vector_Scale(&antiGravity, members->acceleration);
			RigidBody_ApplyForce(obj->body, &antiGravity, &Vector_ZERO);
		}
	}
}
Example #5
0
void State_ParkourController_Shoot(GObject* obj, State* state)
{
    //Get the members of the state
    struct State_ParkourController_Members* members = (struct State_ParkourController_Members*)state->members;

    //Get a reference to the camera
    Camera* cam = RenderingManager_GetRenderingBuffer()->camera;


    if(InputManager_GetInputBuffer().mouseLock)
    {
        //IF we can shoot again
        if(members->shootTimer >= members->shootCooldown)
        {
            //Get the forward vector of the camera
            Vector direction;
            Vector_INIT_ON_STACK(direction, 3);

            Matrix_SliceRow(&direction, cam->rotationMatrix, 2, 0, 3);
            Vector_Scale(&direction, -1.0f);

            //Create the bullet object
            GObject* bullet = GObject_Allocate();
            GObject_Initialize(bullet);

            //Set the appearance
            bullet->mesh = AssetManager_LookupMesh("Cube");
            //bullet->texture = AssetManager_LookupTexture("White");
            bullet->material = Material_Allocate();
            Material_Initialize(bullet->material, AssetManager_LookupTexture("Jacob"));
            //*Matrix_Index(bullet->material->colorMatrix, 1, 1) = 0.0f;
            //*Matrix_Index(bullet->material->colorMatrix, 2, 2) = 0.0f;

            //Create ridgid body
            bullet->body = RigidBody_Allocate();
            RigidBody_Initialize(bullet->body, bullet->frameOfReference, 1.0f);
            bullet->body->coefficientOfRestitution = 0.2f;
            bullet->body->rollingResistance = 0.2f;
            bullet->body->staticFriction = 0.4f;
            bullet->body->dynamicFriction = 0.2f;

            //Create collider
            bullet->collider = Collider_Allocate();
            ConvexHullCollider_Initialize(bullet->collider);
            ConvexHullCollider_MakeRectangularCollider(bullet->collider->data->convexHullData, 2.0f, 2.0f, 2.0f);

            //Position bullet
            Vector transform;
            Vector_INIT_ON_STACK(transform, 3);

            Vector_GetScalarProduct(&transform, &direction, 2.8243f);
            Vector_Increment(&transform, obj->frameOfReference->position);
            GObject_Translate(bullet, &transform);

            Vector_Copy(&transform, &Vector_ZERO);
            transform.components[2] = 1.0f;
            GObject_Rotate(bullet, &transform, 3.14159f);

            //Scale bullet
            Vector_Copy(&transform, &Vector_ZERO);
            transform.components[0] = transform.components[1] = transform.components[2] = 0.5f;
            GObject_Scale(bullet, &transform);

            //Apply impulse
            Vector_Scale(&direction, 25.0f);
            RigidBody_ApplyImpulse(bullet->body, &direction, &Vector_ZERO);

            //Add the remove state
            State* state = State_Allocate();
            State_Remove_Initialize(state, 7.0f);
            GObject_AddState(bullet, state);

            //Add the bullet to the world
            ObjectManager_AddObject(bullet);

            //Set shoot timer to 0
            members->shootTimer = 0.0f;
        }
    }
}
Example #6
0
///
//Allows the parkour controller to run up a wall
//
//Parameters:
//	obj: A pointer to the object attached to the parkourController state
//	state: The parkourController state updating the object
static void State_ParkourController_Wallrun(GObject* obj, State* state)
{
    //Get the members of this state
    struct State_ParkourController_Members* members = (struct State_ParkourController_Members*)state->members;

    //If we are not vertical wallrunning yet
    if(members->verticalRunning == 0 && members->horizontalRunning == 0)
    {
        //Loop through the list of collisions this object was involved in
        struct LinkedList_Node* currentNode = obj->collider->currentCollisions->head;
        while(currentNode != NULL)
        {
            //Get the current collision
            struct Collision* current = (struct Collision*)currentNode->data;

            //Make sure this collision is with a wall
            //TODO: Epsilon check!!!
            if(current->minimumTranslationVector->components[0] != 0.0f || current->minimumTranslationVector->components[2] != 0.0f)
            {
                //Make a copy of the collision normal in case of manipulation
                Vector currentNormal;
                Vector_INIT_ON_STACK(currentNormal, 3);
                Vector_Copy(&currentNormal, current->minimumTranslationVector);

                //Make sure the normal is pointing toward this object
                if(current->obj1 != obj)
                {
                    Vector_Scale(&currentNormal, -1.0f);
                }


                //Next we must determine what kind of wallrun is happening
                //Start by getting for forward vector of the camera
                Camera* cam = RenderingManager_GetRenderingBuffer()->camera;

                Vector forward;
                Vector_INIT_ON_STACK(forward, 3);

                Matrix_SliceRow(&forward, cam->rotationMatrix, 2, 0, 3);

                //Project the forward vector onto the XY plane
                Vector perp;
                Vector_INIT_ON_STACK(perp, 3);

                Vector_GetProjection(&perp, &forward, &Vector_E2);
                Vector_Decrement(&forward, &perp);

                Vector_Normalize(&forward);

                //Get the dot product of the forward vector and collision normal
                float dotProduct = Vector_DotProduct(&forward, &currentNormal);

                //If the dot product is closer to 1, we are starting to vertically wallrun
                if(dotProduct > 0.75f)
                {
                    members->verticalRunning = 1;
                    //Vertical wall running always has higher precedence than horizontal wall running
                    members->horizontalRunning = 0;
                    //SEt the wall normal of state
                    Vector_Copy(members->wallNormal, &currentNormal);
                    break;
                }
                else if(dotProduct > 0.0f)
                {
                    members->horizontalRunning = 1;
                    //Set the wall normal of state
                    Vector_Copy(members->wallNormal, &currentNormal);
                }
            }
            currentNode = currentNode->next;
        }
    }

    //If we are vertical wall running
    if(members->verticalRunning)
    {

        State_ParkourController_VerticalWallrun(obj, state);

    }
    //else If we are horizontal wall running
    else if(members->horizontalRunning)
    {
        State_ParkourController_HorizontalWallrun(obj, state);
    }
}
Example #7
0
///
//Allows the parkour controller to horizontally wallrun
//
//Parameters:
//	obj: A pointer to the object attached to the parkourController state
//	state: The parkourController state updating the object
static void State_ParkourController_HorizontalWallrun(GObject* obj, State* state)
{
    printf("Horizontal\n");

    //Get the members of this state
    struct State_ParkourController_Members* members = (struct State_ParkourController_Members*)state->members;

    //Zero downward velocity
    if(obj->body->velocity->components[1] < 0.0f)
    {
        Vector impulse;
        Vector_INIT_ON_STACK(impulse, 3);
        impulse.components[1] = -obj->body->velocity->components[1];
        RigidBody_ApplyImpulse(obj->body, &impulse, &Vector_ZERO);
    }

    //Accelerate along wall
    //Get the projection of the forward vector onto the wall's plane

    //Start by getting for forward vector of the camera
    Camera* cam = RenderingManager_GetRenderingBuffer()->camera;

    Vector forward;
    Vector_INIT_ON_STACK(forward, 3);

    Matrix_SliceRow(&forward, cam->rotationMatrix, 2, 0, 3);
    //Forward of camera is back of object...
    Vector_Scale(&forward, -1.0f);

    //Project the forward vector onto the wall plane
    Vector perp;
    Vector_INIT_ON_STACK(perp, 3);

    Vector_GetProjection(&perp, &forward, members->wallNormal);
    Vector_Decrement(&forward, &perp);

    //Set the Y component to 0 to get horizontal vector along wall!
    forward.components[1] = 0.0f;

    Vector_Normalize(&forward);

    //MAke sure the velocity in this direction is not too much
    float magVelAlongWall = Vector_DotProduct(&forward, obj->body->velocity);

    if(magVelAlongWall < members->maxVelocity)
    {
        RigidBody_ApplyImpulse(obj->body, &forward, &Vector_ZERO);
    }

    //Apply a cohesive force to the wall to make sure you do not fall off
    float mag = Vector_DotProduct(obj->body->velocity, members->wallNormal);

    Vector cohesive;
    Vector_INIT_ON_STACK(cohesive, 3);

    if(mag > FLT_EPSILON)
    {
        Vector_GetScalarProduct(&cohesive, members->wallNormal, -mag);

    }
    else if(mag < FLT_EPSILON)
    {
        Vector_GetScalarProduct(&cohesive, members->wallNormal, mag);
    }
    RigidBody_ApplyImpulse(obj->body, &cohesive, members->wallNormal);


}
Example #8
0
///
//Accelerates a gameobject to the degree defined by the state
//
//PArameters:
//	obj: The gameobject to accelerate
//	state: The ParkourController state attached to the game object
static void State_ParkourController_Accelerate(GObject* obj, State* state)
{
    //Grab the state members
    struct State_ParkourController_Members* members = (struct State_ParkourController_Members*)state->members;

    //Grab the camera
    Camera* cam = RenderingManager_GetRenderingBuffer()->camera;

    //Determine the direction of acceleration
    Vector netForce;
    Vector_INIT_ON_STACK(netForce, 3);
    Vector direction;
    Vector_INIT_ON_STACK(direction, 3);
    if(InputManager_IsKeyDown('w'))
    {
        //Get forward vector of camera
        Matrix_SliceRow(&direction, cam->rotationMatrix, 2, 0, 3);
        //Project onto XY Plane
        Vector perp;
        Vector_INIT_ON_STACK(perp, 3);

        Vector_GetProjection(&perp, &direction, &Vector_E2);
        Vector_Decrement(&direction, &perp);

        //Add vector to netForce
        //Since this is the cameras "forward vector" we must add the negative of it.
        //BEcause forward is the negative Z axis
        Vector_Decrement(&netForce, &direction);
    }
    if(InputManager_IsKeyDown('s'))
    {
        //Get back vector of camera
        //Get forward vector of camera
        Matrix_SliceRow(&direction, cam->rotationMatrix, 2, 0, 3);
        //Project onto XY Plane
        Vector perp;
        Vector_INIT_ON_STACK(perp, 3);

        Vector_GetProjection(&perp, &direction, &Vector_E2);
        Vector_Decrement(&direction, &perp);

        //Add vector to netForce
        //Since this is the cameras "forward vector" we must add the negative of it.
        //BEcause forward is the negative Z axis
        Vector_Increment(&netForce, &direction);
    }
    if(InputManager_IsKeyDown('d'))
    {
        //Get forward vector of camera
        Matrix_SliceRow(&direction, cam->rotationMatrix, 0, 0, 3);
        //Project onto XY Plane
        Vector perp;
        Vector_INIT_ON_STACK(perp, 3);

        Vector_GetProjection(&perp, &direction, &Vector_E2);
        Vector_Decrement(&direction, &perp);

        //Add vector to netForce
        //Since this is the cameras "forward vector" we must add the negative of it.
        //BEcause forward is the negative Z axis
        Vector_Increment(&netForce, &direction);
    }
    if(InputManager_IsKeyDown('a'))
    {
        //Get forward vector of camera
        Matrix_SliceRow(&direction, cam->rotationMatrix, 0, 0, 3);
        //Project onto XY Plane
        Vector perp;
        Vector_INIT_ON_STACK(perp, 3);

        Vector_GetProjection(&perp, &direction, &Vector_E2);
        Vector_Decrement(&direction, &perp);

        //Add vector to netForce
        //Since this is the cameras "forward vector" we must add the negative of it.
        //BEcause forward is the negative Z axis
        Vector_Decrement(&netForce, &direction);
    }

    //Scale netforce to the acceleration magnitude
    Vector_Normalize(&netForce);
    Vector_Scale(&netForce, members->acceleration);

    //Only apply impulse if velocity is less than max speed
    if(Vector_GetMag(obj->body->velocity) < members->maxVelocity)
    {
        //Apply the impulse
        RigidBody_ApplyForce(obj->body, &netForce, &Vector_ZERO);
    }
    else
    {
        //Limit velocity
        Vector_Normalize(obj->body->velocity);
        Vector_Scale(obj->body->velocity, members->maxVelocity);
    }
}
// Create an object in front of the character and fire
// Parameters:
//	GO: The object getting passed in, in this case the character
//	State: Needed to grab members
void State_CharacterController_ShootBullet(GObject* GO, State* state)
{
	//Get members
	struct State_CharacterController_Members* members = (struct State_CharacterController_Members*)state->members;

	// Camera local
	Camera* cam = RenderingManager_GetRenderingBuffer()->camera;
	// Gets the time per second
	float dt = TimeManager_GetDeltaSec();
	members->timer += dt;

	if(InputManager_GetInputBuffer().mouseLock)
	{
		// Create a net movement vector
		Vector direction;
		Vector_INIT_ON_STACK(direction, 3);
		if (InputManager_IsMouseButtonPressed(0) && members->timer >= members->coolDown)
		{
			//Get "forward" Vector
			Matrix_SliceRow(&direction, cam->rotationMatrix, 2, 0, 3);
			Vector_Scale(&direction,-1.0f);

			// Create the bullet object
			GObject* bullet = GObject_Allocate();
			GObject_Initialize(bullet);

			//bullet->mesh = AssetManager_LookupMesh("Sphere");
			bullet->mesh = AssetManager_LookupMesh("Arrow");
			bullet->texture = AssetManager_LookupTexture("Arrow");


			bullet->body = RigidBody_Allocate();
			RigidBody_Initialize(bullet->body, bullet->frameOfReference, 0.45f);
			bullet->body->coefficientOfRestitution = 0.2f;

			bullet->collider = Collider_Allocate();
			ConvexHullCollider_Initialize(bullet->collider);
			ConvexHullCollider_MakeRectangularCollider(bullet->collider->data->convexHullData, 0.1f, 2.0f, 0.1f);
			//AABBCollider_Initialize(bullet->collider, 2.0f, 2.0f, 2.0f, &Vector_ZERO);

			//Lay arrow flat
			GObject_Rotate(bullet, &Vector_E1, -3.14159f / 2.0f);

			//Construct a rotation matrix to orient bullet
			Matrix rot;
			Matrix_INIT_ON_STACK(rot, 3, 3);
			//Grab 4,4 minor to get 3x3 rotation matrix of camera
			Matrix_GetMinor(&rot, cam->rotationMatrix, 3, 3);
			//Transpose it to get correct direction
			Matrix_Transpose(&rot);
			//Rotate the bullet
			Matrix_TransformMatrix(&rot, bullet->frameOfReference->rotation);
			Matrix_TransformMatrix(&rot, bullet->body->frame->rotation);


			Vector vector;
			Vector_INIT_ON_STACK(vector,3);
			vector.components[0] = 0.9f;
			vector.components[1] = 1.0f;
			vector.components[2] = 0.9f;
			GObject_Scale(bullet, &vector);

			Vector translation;
			Vector_INIT_ON_STACK(translation, 3);
			Vector_GetScalarProduct(&translation, &direction, 2.82843);
			GObject_Translate(bullet, GO->frameOfReference->position);
			GObject_Translate(bullet, &translation);

			Vector_Scale(&direction, 25.0f);

			//Vector_Increment(bullet->body->velocity,&direction);
			RigidBody_ApplyImpulse(bullet->body,&direction,&Vector_ZERO);

			//Add remove state
			State* state = State_Allocate();
			State_Remove_Initialize(state, 5.0f);
			GObject_AddState(bullet, state);

			ObjectManager_AddObject(bullet);

			members->timer = 0;
		}
	}
}
// translate the character and his bounding box.
// Parameters:
//   GO: The game object this state is attached to (Used for translating the bounding box)
//   state: The first person camera state updating the gameObject
void State_CharacterController_Translate(GObject* GO, State* state)
{
	Camera* cam = RenderingManager_GetRenderingBuffer()->camera;
	//Get members
	struct State_CharacterController_Members* members = (struct State_CharacterController_Members*)state->members;

	if(InputManager_GetInputBuffer().mouseLock)
	{

		// Gets the time per second
		float dt = TimeManager_GetDeltaSec();
		Vector netMvmtVec;
		Vector partialMvmtVec;
		Vector_INIT_ON_STACK(netMvmtVec, 3);
		Vector_INIT_ON_STACK(partialMvmtVec, 3);


		if (InputManager_IsKeyDown('w'))
		{
			//Get "back" Vector
			Matrix_SliceRow(&partialMvmtVec, cam->rotationMatrix, 2, 0, 3);
			//Subtract "back" Vector from netMvmtVec
			Vector_Decrement(&netMvmtVec, &partialMvmtVec);
			//Or in one step but less pretty... Faster though. I think I want readable here for now though.
			//Vector_DecrementArray(netMvmtVec.components, Matrix_Index(cam->rotationMatrix, 2, 0), 3);
		}
		if (InputManager_IsKeyDown('s'))
		{
			//Get "back" Vector
			Matrix_SliceRow(&partialMvmtVec, cam->rotationMatrix, 2, 0, 3);
			//Add "back" Vector to netMvmtVec
			Vector_Increment(&netMvmtVec, &partialMvmtVec);
		}
		if (InputManager_IsKeyDown('a'))
		{
			//Get "Right" Vector
			Matrix_SliceRow(&partialMvmtVec, cam->rotationMatrix, 0, 0, 3);
			//Subtract "Right" Vector From netMvmtVec
			Vector_Decrement(&netMvmtVec, &partialMvmtVec);
		}
		if (InputManager_IsKeyDown('d'))
		{
			//Get "Right" Vector
			Matrix_SliceRow(&partialMvmtVec, cam->rotationMatrix, 0, 0, 3);
			//Add "Right" Vector to netMvmtVec
			Vector_Increment(&netMvmtVec, &partialMvmtVec);
		}


		if (Vector_GetMag(&netMvmtVec) > 0.0f)
		{
			// Get the projection and keep player grounded
			Vector perpMvmtVec;
			Vector_INIT_ON_STACK(perpMvmtVec, 3);
			Vector_GetProjection(&perpMvmtVec, &netMvmtVec, &Vector_E2);
			Vector_Decrement(&netMvmtVec, &perpMvmtVec);

			// Normalize vector and scale
			Vector_Normalize(&netMvmtVec);
			Vector_Scale(&netMvmtVec, members->movementSpeed);

			//Apply Impulse
			RigidBody_ApplyImpulse(GO->body, &netMvmtVec, &Vector_ZERO);


		}

	}

	// If vector is going too fast, the maxspeed will keep it from going faster, by scaling it by maxspeed.
	if(Vector_GetMag(GO->body->velocity) >= members->maxSpeed)
	{
		Vector_Normalize(GO->body->velocity);
		Vector_Scale(GO->body->velocity,members->maxSpeed);
	}

	// Set position of Camera to the body
	Camera_SetPosition(cam,GO->body->frame->position);
}