///
//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;
				}
			}
		}
	}
}
Exemple #2
0
static void PVS_Add(struct map *map, struct pvs *pvs, struct node *node)
{
	int i;
	float d;
	struct plane *plane;
	unsigned char *lpvs;

	while(1)
	{
		if (node->contents < 0)
		{
			if (node->contents != CONTENTS_SOLID)
			{
				lpvs = LEAF_PVS(map, (struct leaf *)node);
				for (i=0; i<pvs->bytes; i++)
					pvs->pvs [i] |= lpvs[i];
			}
			return;
		}

		plane = node->plane;
		d = Vector_DotProduct(pvs->origin, plane->normal) - plane->dist;
		if (d>8)
			node = node->children[0];
		else if (d<-8)
			node = node->children[1];
		else
		{
			PVS_Add(map, pvs, node->children[0]);
			node = node->children[1];
		}
	}
}
//*************************************************************************************
// Apply spring force on two physical vertexes
//*************************************************************************************
void ApplySpring(EERIE_3DOBJ * obj, long k, long l, float PHYSICS_constant, float PHYSICS_Damp)
{
	EERIE_3D deltaP, deltaV, springforce;
	PHYSVERT * pv_k = &obj->pbox->vert[k];
	PHYSVERT * pv_l = &obj->pbox->vert[l];
	float Dterm, Hterm;

	float restlength = TRUEEEDistance3D(&obj->pbox->vert[k].initpos, &obj->pbox->vert[l].initpos);
	//Computes Spring Magnitude
	deltaP.x = pv_k->pos.x - pv_l->pos.x;		// Vector distance
	deltaP.y = pv_k->pos.y - pv_l->pos.y;		// Vector distance
	deltaP.z = pv_k->pos.z - pv_l->pos.z;		// Vector distance
	float dist = (float)TRUEsqrt(deltaP.x * deltaP.x + deltaP.y * deltaP.y + deltaP.z * deltaP.z); // Magnitude of delta
	float divdist = 1.f / dist;
	Hterm = (dist - restlength) * PHYSICS_constant;

	deltaV.x = pv_k->velocity.x - pv_l->velocity.x;
	deltaV.y = pv_k->velocity.y - pv_l->velocity.y;
	deltaV.z = pv_k->velocity.z - pv_l->velocity.z;		// Delta Velocity Vector
	Dterm = (Vector_DotProduct(&deltaV, &deltaP) * PHYSICS_Damp) * divdist; // Damping Term
	Dterm = (-(Hterm + Dterm));
	divdist *= Dterm;
	springforce.x = deltaP.x * divdist;	// Normalize Distance Vector
	springforce.y = deltaP.y * divdist;	// & Calc Force
	springforce.z = deltaP.z * divdist;

	pv_k->force.x += springforce.x;	// + force on particle 1
	pv_k->force.y += springforce.y;
	pv_k->force.z += springforce.z;

	pv_l->force.x -= springforce.x;	// - force on particle 2
	pv_l->force.y -= springforce.y;
	pv_l->force.z -= springforce.z;
}
Exemple #4
0
void Matrix_Apply(const Matrix *m,const Vector *b,Vector *a)
{
uint r;

	assert( a && b && m );
	assert( a->length == b->length && a->length == m->dimension );
	assert( a != b );

	for(r=0;r<m->dimension;r++)
	{
		a->element[r] = Vector_DotProduct(b,m->rows[r]);
	}
}
///
//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);
		}
	}
}
Exemple #7
0
int Trace_RecursiveHullTrace(struct trace_local *tl, int num, float p1f, float p2f, const vec3_t p1, const vec3_t p2)
{
	struct plane *plane;
	float t1, t2, frac, midf;
	struct clipnode *node;
	int i, nearside, check, oldcheck;
	vec3_t mid;

	struct hull *hull = tl->hull;
	struct trace *trace = tl->trace;

	while (1)
	{
		if (num < 0)
		{
			tl->leafs_count++;
			if (num == CONTENTS_SOLID)
			{
				if (tl->leafs_count == 1)
					trace->startsolid = true;
				return TR_SOLID;
			}
			else
			{
				if (num == CONTENTS_EMPTY)
					trace->inopen = true;
				else
					trace->inwater = true;
				return TR_EMPTY;
			}
		}

		node = hull->clipnodes + num;

		plane = hull->planes + node->planenum;

		//printf("t_rht: %p %p %i %i %f ", node, plane, node->planenum, plane->type, plane->dist);
		//PRINT_VEC(plane->normal);

		if (plane->type < 3)
		{
			t1 = p1[plane->type] - plane->dist;
			t2 = p2[plane->type] - plane->dist;
			//printf("t_rht 1: t1, t2, plane->dist %f %f %f\n", t1, t2, plane->dist);
		}
		else
		{
			t1 = Vector_DotProduct(plane->normal, p1) - plane->dist;
			t2 = Vector_DotProduct(plane->normal, p2) - plane->dist;
			//printf("t_rht 2: t1, t2, plane->dist %f %f %f\n", t1, t2, plane->dist);
		}

		if (t1 >= 0 && t2 >= 0)
		{
			num = node->children[0];
			continue;
		}

		if (t1 < 0 && t2 < 0)
		{
			num = node->children[1];
			continue;
		}

		frac = t1 / (t1 - t2);
		frac = bound(0, frac, 1);
		midf = p1f + (p2f - p1f) * frac;

		for (i=0; i<3; i++)
			mid[i] = p1[i] + frac * (p2[i] - p1[i]);

		nearside = (t1 < t2) ? 1 : 0;
		//printf("doing trace 1 %f %f\n", frac, midf);
		check = Trace_RecursiveHullTrace(tl, node->children[nearside], p1f, midf, p1, mid);
		if (check == TR_BLOCKED)
		{
			return check;
		}

		if (check == TR_SOLID && (trace->inopen  || trace->inwater))
		{
			return check;
		}
		oldcheck = check;

		//printf("doing trace 2\n");
		check = Trace_RecursiveHullTrace(tl, node->children[1 - nearside], midf, p2f, mid, p2);
		if (check == TR_EMPTY || check == TR_BLOCKED)
		{
			return check;
		}

		if (oldcheck != TR_EMPTY)
		{
			return check;
		}

		if (!nearside)
		{
			Vector_Copy(trace->plane.normal, plane->normal);
			trace->plane.dist = plane->dist;
		}
		else
		{
			Vector_Negate(trace->plane.normal, plane->normal);
			trace->plane.dist = -plane->dist;
		}

		if (t1 < t2)
			frac = (t1 + DIST_EPSILON) / (t1 - t2);
		else
			frac = (t1 - DIST_EPSILON) / (t1 - t2);

		frac = bound(0, frac, 1);

		midf = p1f + (p2f - p1f) * frac;

		for (i=0; i<3; i++)
			mid[i] = p1[i] + frac * (p2[i] - p1[i]);

		trace->fraction = midf;

		//printf("fraction: %f\n", midf);

		Vector_Copy(trace->endpos, mid);

		return TR_BLOCKED;
	}
#warning maybe return smth else here
	return TR_BLOCKED;
}
Exemple #8
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);
    }
}
Exemple #9
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);


}