/// //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))); } }
/// //Updates a force state by applying the defined force to the GObject // //Parameters: // GO: A pointer to the game object to apply the force to // state: A pointer to the state updating the attached object void State_Force_Update(GObject* GO, State* state) { struct State_Force_Members* members = (struct State_Force_Members*)state->members; RigidBody_ApplyForce(GO->body, members->force, members->radius); }
/// //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); } } }
/// //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); } }