//************************************************************************************* //************************************************************************************* BOOL IsObjectVertexInValidPosition(EERIE_3DOBJ * obj, long kk, long flags, long source) { EERIEPOLY * back_ep = CheckInPolyPrecis(obj->pbox->vert[kk].pos.x, obj->pbox->vert[kk].pos.y, obj->pbox->vert[kk].pos.z); if (!back_ep) { EERIE_3D posi; Vector_Copy(&posi, &obj->pbox->vert[kk].pos); posi.y -= 30.f; CUR_COLLISION_MATERIAL = MATERIAL_STONE; return FALSE; } if (!(flags & 1)) { EERIE_SPHERE sphere; EERIE_3D * pos = &obj->pbox->vert[kk].pos; sphere.origin.x = pos->x; sphere.origin.y = pos->y; sphere.origin.z = pos->z; sphere.radius = 8.f; if (ARX_INTERACTIVE_CheckCollision(obj, kk, source)) { CUR_COLLISION_MATERIAL = 11; return FALSE; } } return TRUE; }
/** * Eliminate the columns corresponding to a list of eliminated parameters. * @param M the constraints matrix whose columns are to be removed * @param nbVars an offset to be added to the ranks of the variables to be * removed * @param elimParms the list of ranks of the variables to be removed * @param newM (output) the matrix without the removed columns */ void Constraints_removeElimCols(Matrix * M, unsigned int nbVars, unsigned int *elimParms, Matrix ** newM) { unsigned int i, j, k; if (elimParms[0]==0) { Matrix_clone(M, newM); return; } if ((*newM)==NULL) { (*newM) = Matrix_Alloc(M->NbRows, M->NbColumns - elimParms[0]); } else { assert ((*newM)->NbColumns==M->NbColumns - elimParms[0]); } for (i=0; i< M->NbRows; i++) { value_assign((*newM)->p[i][0], M->p[i][0]); /* kind of cstr */ k=0; Vector_Copy(&(M->p[i][1]), &((*newM)->p[i][1]), nbVars); for (j=0; j< M->NbColumns-2-nbVars; j++) { if (j!=elimParms[k+1]) { value_assign((*newM)->p[i][j-k+nbVars+1], M->p[i][j+nbVars+1]); } else { k++; } } value_assign((*newM)->p[i][(*newM)->NbColumns-1], M->p[i][M->NbColumns-1]); /* cst part */ } } /* Constraints_removeElimCols */
/// //Initializes a new force state // //Parameters: // state: A pointer to the state to initialize as a force state // force: A pointer to a vector to copy as the force this state will apply // radius: A pointer to a vector to copy as the radius this state will apply the force at void State_Force_Initialize(State* state, Vector* force, Vector* radius) { struct State_Force_Members* members = (struct State_Force_Members*)malloc(sizeof(struct State_Force_Members)); state->members = (State_Members)members; members->force = Vector_Allocate(); Vector_Initialize(members->force, 3); Vector_Copy(members->force, force); members->radius = Vector_Allocate(); Vector_Initialize(members->radius, 3); Vector_Copy(members->radius, radius); state->State_Members_Free = State_Force_Free; state->State_Update = State_Force_Update; }
static Matrix *Polyhedron2standard_form(Polyhedron *P, Matrix **T) { int i, j; int rows; unsigned dim = P->Dimension; Matrix *M2; Matrix *H, *U; Matrix M; assert(P->NbEq == 0); Polyhedron_Remove_Positivity_Constraint(P); for (i = 0; i < P->NbConstraints; ++i) assert(value_zero_p(P->Constraint[i][1+dim])); Polyhedron_Matrix_View(P, &M, P->NbConstraints); H = standard_constraints(&M, 0, &rows, &U); *T = homogenize(U); Matrix_Free(U); M2 = Matrix_Alloc(rows, 2+dim+rows); for (i = dim; i < H->NbRows; ++i) { Vector_Copy(H->p[i], M2->p[i-dim]+1, dim); value_set_si(M2->p[i-dim][1+i], -1); } for (i = 0, j = H->NbRows-dim; i < dim; ++i) { if (First_Non_Zero(H->p[i], i) == -1) continue; Vector_Oppose(H->p[i], M2->p[j]+1, dim); value_set_si(M2->p[j][1+j+dim], 1); ++j; } Matrix_Free(H); return M2; }
/// //Allows the parkour controller to vertically wallrun // //Parameters: // obj: A pointer to the object attached to the parkourController state // state: The parkourController state updating the object static void State_ParkourController_VerticalWallrun(GObject* obj, State* state) { //Get the members of this state struct State_ParkourController_Members* members = (struct State_ParkourController_Members*)state->members; Vector impulse; Vector_INIT_ON_STACK(impulse, 3); impulse.components[1] = members->jumpMag; RigidBody_ApplyImpulse(obj->body, &impulse, &Vector_ZERO); //Cap max upward speed if(obj->body->velocity->components[1] > members->maxVelocity) { obj->body->velocity->components[1] = members->maxVelocity; } if(obj->body->velocity->components[0] != 0.0f || obj->body->velocity->components[2]) { Vector_Copy(&impulse, &Vector_ZERO); impulse.components[0] -= obj->body->velocity->components[0]; impulse.components[2] -= obj->body->velocity->components[2]; RigidBody_ApplyImpulse(obj->body, &impulse, &Vector_ZERO); } }
//----------------------------------------------------------------------------- void CMagicMissile::Create(EERIE_3D aeSrc, EERIE_3D angles) { int i; EERIE_3D s, e; SetDuration(ulDuration); SetAngle(angles.b); Vector_Copy(&this->angles, &angles); eCurPos.x = eSrc.x = aeSrc.x; eCurPos.y = eSrc.y = aeSrc.y; eCurPos.z = eSrc.z = aeSrc.z; fSize = 1; bDone = true; s.x = eSrc.x; s.y = eSrc.y; s.z = eSrc.z; e.x = eSrc.x; e.y = eSrc.y; e.z = eSrc.z; i = 0; i = 40; e.x -= fBetaRadSin * 50 * i; e.y += sin(DEG2RAD(MAKEANGLE(this->angles.a))) * 50 * i; e.z += fBetaRadCos * 50 * i; pathways[0].sx = eSrc.x; pathways[0].sy = eSrc.y; pathways[0].sz = eSrc.z; pathways[5].sx = e.x; pathways[5].sy = e.y; pathways[5].sz = e.z; Split(pathways, 0, 5, 50, 0.5f); for (i = 0; i < 6; i++) { if (pathways[i].sy >= eSrc.y + 150) { pathways[i].sy = eSrc.y + 150; } } fTrail = 0; iLength = 50; fOneOnLength = 1.0f / (float) iLength; iBezierPrecision = BEZIERPrecision; fOneOnBezierPrecision = 1.0f / (float) iBezierPrecision; bExplo = false; bMove = true; ARX_SOUND_PlaySFX(SND_SPELL_MM_CREATE, &eCurPos); ARX_SOUND_PlaySFX(SND_SPELL_MM_LAUNCH, &eCurPos); snd_loop = ARX_SOUND_PlaySFX(SND_SPELL_MM_LOOP, &eCurPos, 1.0F, ARX_SOUND_PLAY_LOOPED); }
static Polyhedron *partition2polyhedron(Matrix *A, struct barvinok_options *options) { int i; unsigned nvar, nparam; Matrix *M; Polyhedron *P; nvar = A->NbColumns; nparam = A->NbRows; M = Matrix_Alloc(nvar + nparam, 1 + nvar + nparam + 1); assert(M); for (i = 0; i < nparam; ++i) { Vector_Copy(A->p[i], M->p[i] + 1, nvar); value_set_si(M->p[i][1 + nvar + i], -1); } for (i = 0; i < nvar; ++i) { value_set_si(M->p[nparam + i][0], 1); value_set_si(M->p[nparam + i][1 + i], 1); } P = Constraints2Polyhedron(M, options->MaxRays); Matrix_Free(M); return P; }
/// //Lets the runner jump off of a wall // obj: A pointer to the object // state: A pointer to the runner controller state which is allowing the object to wall jump void State_RunnerController_WallJump(GObject* obj, State* state) { //Get the members of this state struct State_RunnerController_Members* members = (struct State_RunnerController_Members*)state->members; Vector impulse; Vector_INIT_ON_STACK(impulse, 3); Vector_Copy(&impulse, members->wallNormal); Vector_Scale(&impulse, members->jumpMag * 2); RigidBody_ApplyImpulse(obj->body, &impulse, &Vector_ZERO); Vector_Copy(&impulse, &Vector_E2); Vector_Scale(&impulse, members->jumpMag); RigidBody_ApplyImpulse(obj->body, &impulse, &Vector_ZERO); }
/* Return * T 0 * 0 1 */ static Matrix *homogenize(Matrix *T) { int i; Matrix *H = Matrix_Alloc(T->NbRows+1, T->NbColumns+1); for (i = 0; i < T->NbRows; ++i) Vector_Copy(T->p[i], H->p[i], T->NbColumns); value_set_si(H->p[T->NbRows][T->NbColumns], 1); return H; }
//************************************************************************************* //************************************************************************************* BOOL IsObjectVertexCollidingPoly(EERIE_3DOBJ * obj, EERIEPOLY * ep, long k, long * validd) { EERIE_3D pol[3]; Vector_Copy(&pol[0], (EERIE_3D *)&ep->v[0]); Vector_Copy(&pol[1], (EERIE_3D *)&ep->v[1]); Vector_Copy(&pol[2], (EERIE_3D *)&ep->v[2]); float mul = 1.3f; pol[0].x = (pol[0].x - ep->center.x) * mul + ep->center.x; pol[0].y = (pol[0].y - ep->center.y) * mul + ep->center.y; pol[0].z = (pol[0].z - ep->center.z) * mul + ep->center.z; if (ep->type & POLY_QUAD) { if (IsObjectVertexCollidingTriangle(obj, (EERIE_3D *)&pol, k, validd)) return TRUE; Vector_Copy(&pol[0], (EERIE_3D *)&ep->v[2]); Vector_Copy(&pol[1], (EERIE_3D *)&ep->v[3]); Vector_Copy(&pol[2], (EERIE_3D *)&ep->v[0]); if (IsObjectVertexCollidingTriangle(obj, (EERIE_3D *)&pol, k, validd)) return TRUE; return FALSE; } if (IsObjectVertexCollidingTriangle(obj, (EERIE_3D *)&pol, k, validd)) return TRUE; return FALSE; }
//************************************************************************************* //************************************************************************************* void ARX_FOGS_RenderAll(LPDIRECT3DDEVICE7 m_pd3dDevice) { EERIE_3D angle; Vector_Init(&angle); SETALPHABLEND(m_pd3dDevice, FALSE); for (long i = 0; i < MAX_FOG; i++) { if (fogs[i].exist) { if (fogobj) DrawEERIEInter(m_pd3dDevice, fogobj, &angle, &fogs[i].pos, NULL); Vector_Copy(&fogs[i].bboxmin, &BBOXMIN); Vector_Copy(&fogs[i].bboxmax, &BBOXMAX); if (fogs[i].special & FOG_DIRECTIONAL) { EERIE_3D orgn, dest; orgn.x = fogs[i].pos.x; orgn.y = fogs[i].pos.y; orgn.z = fogs[i].pos.z; dest.x = orgn.x + fogs[i].move.x * 50.f; dest.y = orgn.y + fogs[i].move.y * 50.f; dest.z = orgn.z + fogs[i].move.z * 50.f; EERIEDraw3DLine(m_pd3dDevice, &orgn, &dest, EERIECOLOR_WHITE); } if (fogs[i].selected) { EERIEDraw2DLine(m_pd3dDevice, fogs[i].bboxmin.x, fogs[i].bboxmin.y, fogs[i].bboxmax.x, fogs[i].bboxmin.y, 0.01f, EERIECOLOR_YELLOW); EERIEDraw2DLine(m_pd3dDevice, fogs[i].bboxmax.x, fogs[i].bboxmin.y, fogs[i].bboxmax.x, fogs[i].bboxmax.y, 0.01f, EERIECOLOR_YELLOW); EERIEDraw2DLine(m_pd3dDevice, fogs[i].bboxmax.x, fogs[i].bboxmax.y, fogs[i].bboxmin.x, fogs[i].bboxmax.y, 0.01f, EERIECOLOR_YELLOW); EERIEDraw2DLine(m_pd3dDevice, fogs[i].bboxmin.x, fogs[i].bboxmax.y, fogs[i].bboxmin.x, fogs[i].bboxmin.y, 0.01f, EERIECOLOR_YELLOW); } } } }
/// //Lets the ParkourController vault over a wall // //Parameters: // obj: A pointer to the object attached to the ParkourController state // state: void State_ParkourController_WallVault(GObject* obj, State* state) { //Get the members of this state struct State_ParkourController_Members* members = (struct State_ParkourController_Members*)state->members; Vector impulse; Vector_INIT_ON_STACK(impulse, 3); Vector_Copy(&impulse, members->wallNormal); Vector_Scale(&impulse, -members->maxVelocity); RigidBody_ApplyImpulse(obj->body, &impulse, &Vector_ZERO); }
struct trace *Trace_HullTrace(struct trace *trace, struct hull *hull, vec3_t start, vec3_t end) { int check; struct trace_local tl; struct trace *lt; if (hull == NULL) return NULL; if (trace == NULL) lt = calloc(1, sizeof(*lt)); else { lt = trace; memset(trace, 0, sizeof(*trace)); } if (lt == NULL) return NULL; memset(&tl, 0, sizeof(*&tl)); tl.trace = lt; lt->fraction = 1; lt->startsolid = false; Vector_Copy(lt->endpos, end); tl.hull = hull; check = Trace_RecursiveHullTrace(&tl, hull->firstclipnode, 0, 1, start, end); if (check == TR_SOLID) { lt->startsolid = lt->allsolid = true; Vector_Copy(lt->endpos, start); } return lt; }
/// //Lets the runner vault off of a wall // obj: A pointer to the object // state: A pointer to the runner controller state which is allowing the object to wall vault void State_RunnerController_WallVault(GObject* obj, State* state) { //Get the members of this state struct State_RunnerController_Members* members = (struct State_RunnerController_Members*)state->members; Vector impulse; Vector_INIT_ON_STACK(impulse, 3); Vector_Copy(&impulse, members->wallNormal); float mag = obj->body->velocity->components[1]; Vector_Scale(&impulse, -mag * 1.0f); RigidBody_ApplyImpulse(obj->body, &impulse, &Vector_ZERO); Vector_Copy(&impulse, &Vector_E2); obj->body->velocity->components[1] = 0; Vector_Scale(&impulse, members->jumpMag); RigidBody_ApplyImpulse(obj->body, &impulse, &Vector_ZERO); }
/// //Initializes the scene within the engine. //This must be done after all engine components are initialized. void InitializeScene(void) { /// //Camera controller simulation GObject* cam = GObject_Allocate(); GObject_Initialize(cam); State* state = State_Allocate(); cam->body = RigidBody_Allocate(); RigidBody_Initialize(cam->body, cam->frameOfReference, 1.0f); cam->body->coefficientOfRestitution = 0.1f; cam->collider = Collider_Allocate(); AABBCollider_Initialize(cam->collider, 2.5f, 3.0f, 2.5f, &Vector_ZERO); State_ParkourController_Initialize(state, 7.0f, 10.0f, 0.05f, 50.0f, 0.1f); GObject_AddState(cam,state); ObjectManager_AddObject(cam); //Create floor GObject* block = GObject_Allocate(); GObject_Initialize(block); block->mesh = AssetManager_LookupMesh("Cube"); block->collider = Collider_Allocate(); AABBCollider_Initialize(block->collider, 2.0f, 2.0f, 2.0f, &Vector_ZERO); block->body = RigidBody_Allocate(); RigidBody_Initialize(block->body, block->frameOfReference, 0.0f); block->body->freezeTranslation = block->body->freezeRotation = 1; block->body->dynamicFriction = block->body->staticFriction = 0.1f; block->body->rollingResistance = 0.25f; Vector v; Vector_INIT_ON_STACK(v, 3); v.components[0] = v.components[2] = 40.0f; v.components[1] = 1.0f; GObject_Scale(block, &v); Vector_Copy(&v, &Vector_ZERO); v.components[1] = -10.0f; GObject_Translate(block, &v); ObjectManager_AddObject(block); //Create sphere block = GObject_Allocate(); GObject_Initialize(block); block->mesh = AssetManager_LookupMesh("Sphere"); block->material = Material_Allocate(); Material_Initialize(block->material, AssetManager_LookupTexture("Earth")); //*Matrix_Index(block->material->colorMatrix, 2, 2) = 0.0f; //*Matrix_Index(block->material->colorMatrix, 1, 1) = 0.0f; block->collider = Collider_Allocate(); SphereCollider_Initialize(block->collider, 1.0f); block->body = RigidBody_Allocate(); RigidBody_Initialize(block->body, block->frameOfReference, 0.0f); block->body->dynamicFriction = block->body->staticFriction = 1.0f; block->body->coefficientOfRestitution = 0.9f; Vector_Copy(&v, &Vector_ZERO); v.components[0] = -3.0f; v.components[1] = 5.0f; v.components[2] = -10.0f; GObject_Translate(block, &v); Vector_Copy(&v, &Vector_ZERO); v.components[0] = v.components[1] = v.components[2] = 10.0f; GObject_Scale(block, &v); ObjectManager_AddObject(block); //Set gravity Vector* gravity = Vector_Allocate(); Vector_Initialize(gravity, 3); gravity->components[1] = -9.81f; PhysicsManager_AddGlobalAcceleration(gravity); }
void right_hermite(Matrix *A,Matrix **Hp,Matrix **Up,Matrix **Qp) { Matrix *H, *Q, *U; int i, j, nr, nc, rank; Value tmp; /* Computes form: A = QH , UA = H */ nc = A->NbColumns; nr = A->NbRows; /* H = A */ *Hp = H = Matrix_Alloc(nr,nc); if (!H) { errormsg1("DomRightHermite", "outofmem", "out of memory space"); return; } /* Initialize all the 'Value' variables */ value_init(tmp); Vector_Copy(A->p_Init,H->p_Init,nr*nc); /* U = I */ if (Up) { *Up = U = Matrix_Alloc(nr, nr); if (!U) { errormsg1("DomRightHermite", "outofmem", "out of memory space"); value_clear(tmp); return; } Vector_Set(U->p_Init,0,nr*nr); /* zero's */ for(i=0;i<nr;i++) /* with diagonal of 1's */ value_set_si(U->p[i][i],1); } else U = (Matrix *)0; /* Q = I */ /* Actually I compute Q transpose... its easier */ if (Qp) { *Qp = Q = Matrix_Alloc(nr,nr); if (!Q) { errormsg1("DomRightHermite", "outofmem", "out of memory space"); value_clear(tmp); return; } Vector_Set(Q->p_Init,0,nr*nr); /* zero's */ for (i=0;i<nr;i++) /* with diagonal of 1's */ value_set_si(Q->p[i][i],1); } else Q = (Matrix *)0; rank = hermite(H,U,Q); /* Q is returned transposed */ /* Transpose Q */ if (Q) { for (i=0; i<nr; i++) { for (j=i+1; j<nr; j++) { value_assign(tmp,Q->p[i][j]); value_assign(Q->p[i][j],Q->p[j][i] ); value_assign(Q->p[j][i],tmp); } } } value_clear(tmp); return; } /* right_hermite */
/// //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); } } }
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; }
//----------------------------------------------------------------------------- float CMagicMissile::Render(LPDIRECT3DDEVICE7 m_pd3dDevice) { int i = 0; EERIE_3D lastpos, newpos; EERIE_3D v; EERIE_3D stiteangle; EERIE_3D stitepos; EERIE_3D stitescale; EERIE_RGB stitecolor; EERIE_3D av; if (ulCurrentTime >= ulDuration) { return 0.f; } // Set Appropriate Renderstates ------------------------------------------- SETCULL(m_pd3dDevice, D3DCULL_NONE); SETZWRITE(m_pd3dDevice, FALSE); m_pd3dDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE); m_pd3dDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE); SETALPHABLEND(m_pd3dDevice, TRUE); // Set Texture ------------------------------------------------------------ if (tex_mm && tex_mm->m_pddsSurface) { if ((spells[spellinstance].caster == 0) && (cur_mr == 3)) SETTC(m_pd3dDevice, NULL); else SETTC(m_pd3dDevice, tex_mm); } // ------------------------------------------------------------------------ if (bMove) { fTrail = (ulCurrentTime * fOneOnDuration) * (iBezierPrecision + 2) * 5; } lastpos.x = pathways[0].sx; lastpos.y = pathways[0].sy; lastpos.z = pathways[0].sz; Vector_Copy(&newpos, &lastpos); for (i = 0; i < 5; i++) { int kp = i; int kpprec = (i > 0) ? kp - 1 : kp ; int kpsuiv = kp + 1 ; int kpsuivsuiv = (i < (5 - 2)) ? kpsuiv + 1 : kpsuiv; for (int toto = 1; toto < iBezierPrecision; toto++) { if (fTrail < i * iBezierPrecision + toto) break; float t = toto * fOneOnBezierPrecision; float t1 = t; float t2 = t1 * t1 ; float t3 = t2 * t1 ; float f0 = 2.f * t3 - 3.f * t2 + 1.f ; float f1 = -2.f * t3 + 3.f * t2 ; float f2 = t3 - 2.f * t2 + t1 ; float f3 = t3 - t2 ; float val = pathways[kpsuiv].sx; float p0 = 0.5f * (val - pathways[kpprec].sx) ; float p1 = 0.5f * (pathways[kpsuivsuiv].sx - pathways[kp].sx) ; v.x = f0 * pathways[kp].sx + f1 * val + f2 * p0 + f3 * p1 ; val = pathways[kpsuiv].sy ; p0 = 0.5f * (val - pathways[kpprec].sy) ; p1 = 0.5f * (pathways[kpsuivsuiv].sy - pathways[kp].sy) ; v.y = f0 * pathways[kp].sy + f1 * val + f2 * p0 + f3 * p1 ; val = pathways[kpsuiv].sz ; p0 = 0.5f * (val - pathways[kpprec].sz) ; p1 = 0.5f * (pathways[kpsuivsuiv].sz - pathways[kp].sz) ; v.z = f0 * pathways[kp].sz + f1 * val + f2 * p0 + f3 * p1 ; Vector_Copy(&newpos, &v); if (!((fTrail - (i * iBezierPrecision + toto)) > iLength)) { float c; if (fTrail < iLength) { c = 1.0f - ((fTrail - (i * iBezierPrecision + toto)) / fTrail); } else { c = 1.0f - ((fTrail - (i * iBezierPrecision + toto)) / (float)iLength); } float fsize = c; float alpha = c - 0.2f; if (alpha < 0.2f) alpha = 0.2f; c += frand2() * 0.1f; if (c < 0) c = 0; else if (c > 1) c = 1; int color = D3DRGB(c * fColor[0] * alpha, c * fColor[1] * alpha, c * fColor[2] * alpha); if (fsize < 0.5f) fsize = fsize * 2 * 3; else fsize = (1.0f - fsize + 0.5f) * 2 * (3 * 0.5f); float fs = fsize * 6 + rnd() * 0.3f; float fe = fsize * 6 + rnd() * 0.3f; Draw3DLineTex(m_pd3dDevice, lastpos, newpos, color, fs, fe); } EERIE_3D temp_vector; Vector_Copy(&temp_vector, &lastpos); Vector_Copy(&lastpos, &newpos); Vector_Copy(&newpos, &temp_vector); } } av.x = newpos.x - lastpos.x; av.y = newpos.y - lastpos.y; av.z = newpos.z - lastpos.z; float bubu = GetAngle(av.x, av.z, 0, 0); float bubu1 = GetAngle(av.x, av.y, 0, 0); Vector_Copy(&stitepos, &lastpos); stiteangle.b = -RAD2DEG(bubu); stiteangle.a = 0; stiteangle.g = -(RAD2DEG(bubu1)); if (av.x < 0) stiteangle.g -= 90; if (av.x > 0) stiteangle.g += 90; if (stiteangle.g < 0) stiteangle.g += 360.0f; if ((spells[spellinstance].caster == 0) && (cur_mr == 3)) { stitecolor.r = 1.f; stitecolor.g = 0.f; stitecolor.b = 0.2f; } else { stitecolor.r = 0.3f; stitecolor.g = 0.3f; stitecolor.b = 0.5f; } Vector_Init(&stitescale, 1, 1, 1); { if ((smissile)) DrawEERIEObjEx(m_pd3dDevice, smissile, &stiteangle, &stitepos, &stitescale, &stitecolor); } Vector_Copy(&eCurPos, &lastpos); return 1 - 0.5f * rnd(); }
/// //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(¤tNormal, current->minimumTranslationVector); //Make sure the normal is pointing toward this object if(current->obj1 != obj) { Vector_Scale(¤tNormal, -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, ¤tNormal); //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, ¤tNormal); break; } else if(dotProduct > 0.0f) { members->horizontalRunning = 1; //Set the wall normal of state Vector_Copy(members->wallNormal, ¤tNormal); } } 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); } }
/* Compute integer hull of truncated linear cone C, i.e., of C with * the origin removed. * Here, we do this by first computing the Hilbert basis of C * and then discarding elements from this basis that are rational * overconvex combinations of other elements in the basis. */ Matrix *Cone_Hilbert_Integer_Hull(Polyhedron *C, struct barvinok_options *options) { int i, j, k; Matrix *hilbert = Cone_Hilbert_Basis(C, options->MaxRays); Matrix *rays, *hull; unsigned dim = C->Dimension; Value tmp; unsigned MaxRays = options->MaxRays; /* When checking for redundant points below, we want to * check if there are any _rational_ solutions. */ POL_UNSET(options->MaxRays, POL_INTEGER); POL_ENSURE_VERTICES(C); rays = Matrix_Alloc(C->NbRays-1, C->Dimension); for (i = 0, j = 0; i < C->NbRays; ++i) { if (value_notzero_p(C->Ray[i][1+C->Dimension])) continue; Vector_Copy(C->Ray[i]+1, rays->p[j++], C->Dimension); } /* We only sort the pointers into the big Value array */ qsort(rays->p, rays->NbRows, sizeof(Value *), lex_cmp); qsort(hilbert->p, hilbert->NbRows, sizeof(Value *), lex_cmp); /* Remove rays from Hilbert basis */ for (i = 0, j = 0, k = 0; i < hilbert->NbRows && j < rays->NbRows; ++i) { if (Vector_Equal(hilbert->p[i], rays->p[j], C->Dimension)) ++j; else hilbert->p[k++] = hilbert->p[i]; } hilbert->NbRows = k; /* Now remove points that are overconvex combinations of other points */ value_init(tmp); for (i = 0; hilbert->NbRows > 1 && i < hilbert->NbRows; ++i) { Matrix *LP; Vector *obj; int nray = rays->NbRows; int npoint = hilbert->NbRows; enum lp_result result; LP = Matrix_Alloc(dim + 1 + nray + (npoint-1), 2 + nray + (npoint-1)); for (j = 0; j < dim; ++j) { for (k = 0; k < nray; ++k) value_assign(LP->p[j][k+1], rays->p[k][j]); for (k = 0; k < npoint; ++k) { if (k == i) value_oppose(LP->p[j][1+nray+npoint-1], hilbert->p[k][j]); else value_assign(LP->p[j][1+nray+k-(k>i)], hilbert->p[k][j]); } } value_set_si(LP->p[dim][0], 1); for (k = 0; k < nray+npoint-1; ++k) value_set_si(LP->p[dim][1+k], 1); value_set_si(LP->p[dim][LP->NbColumns-1], -1); for (k = 0; k < LP->NbColumns-2; ++k) { value_set_si(LP->p[dim+1+k][0], 1); value_set_si(LP->p[dim+1+k][1+k], 1); } /* Somewhat arbitrary objective function. */ obj = Vector_Alloc(LP->NbColumns-1); value_set_si(obj->p[0], 1); value_set_si(obj->p[obj->Size-1], 1); result = constraints_opt(LP, obj->p, obj->p[0], lp_min, &tmp, options); /* If the LP is not empty, the point can be discarded */ if (result != lp_empty) { hilbert->NbRows--; if (i < hilbert->NbRows) hilbert->p[i] = hilbert->p[hilbert->NbRows]; --i; } Matrix_Free(LP); Vector_Free(obj); } value_clear(tmp); hull = Matrix_Alloc(rays->NbRows + hilbert->NbRows, dim+1); for (i = 0; i < rays->NbRows; ++i) { Vector_Copy(rays->p[i], hull->p[i], dim); value_set_si(hull->p[i][dim], 1); } for (i = 0; i < hilbert->NbRows; ++i) { Vector_Copy(hilbert->p[i], hull->p[rays->NbRows+i], dim); value_set_si(hull->p[rays->NbRows+i][dim], 1); } Matrix_Free(rays); Matrix_Free(hilbert); options->MaxRays = MaxRays; return hull; }
int main(int argc, char **argv) { isl_ctx *ctx; int i, nbPol, nbVec, nbMat, func, j, n; Polyhedron *A, *B, *C, *D, *E, *F, *G; char s[128]; struct barvinok_options *options = barvinok_options_new_with_defaults(); argc = barvinok_options_parse(options, argc, argv, ISL_ARG_ALL); ctx = isl_ctx_alloc_with_options(&barvinok_options_args, options); nbPol = nbVec = nbMat = 0; fgets(s, 128, stdin); while ((*s=='#') || ((sscanf(s, "D %d", &nbPol) < 1) && (sscanf(s, "V %d", &nbVec) < 1) && (sscanf(s, "M %d", &nbMat) < 1))) fgets(s, 128, stdin); for (i = 0; i < nbPol; ++i) { Matrix *M = Matrix_Read(); A = Constraints2Polyhedron(M, options->MaxRays); Matrix_Free(M); fgets(s, 128, stdin); while ((*s=='#') || (sscanf(s, "F %d", &func)<1)) fgets(s, 128, stdin); switch(func) { case 0: { Value cb, ck; value_init(cb); value_init(ck); fgets(s, 128, stdin); /* workaround for apparent bug in older gmps */ *strchr(s, '\n') = '\0'; while ((*s=='#') || (value_read(ck, s) != 0)) { fgets(s, 128, stdin); /* workaround for apparent bug in older gmps */ *strchr(s, '\n') = '\0'; } barvinok_count_with_options(A, &cb, options); if (value_ne(cb, ck)) return -1; value_clear(cb); value_clear(ck); break; } case 1: Polyhedron_Print(stdout, P_VALUE_FMT, A); B = Polyhedron_Polar(A, options->MaxRays); Polyhedron_Print(stdout, P_VALUE_FMT, B); C = Polyhedron_Polar(B, options->MaxRays); Polyhedron_Print(stdout, P_VALUE_FMT, C); Polyhedron_Free(C); Polyhedron_Free(B); break; case 2: Polyhedron_Print(stdout, P_VALUE_FMT, A); for (j = 0; j < A->NbRays; ++j) { B = supporting_cone(A, j); Polyhedron_Print(stdout, P_VALUE_FMT, B); Polyhedron_Free(B); } break; case 3: Polyhedron_Print(stdout, P_VALUE_FMT, A); C = B = NULL; barvinok_decompose(A,&B,&C); puts("Pos:"); Polyhedron_Print(stdout, P_VALUE_FMT, B); puts("Neg:"); Polyhedron_Print(stdout, P_VALUE_FMT, C); Domain_Free(B); Domain_Free(C); break; case 4: { Value cm, cb; struct tms tms_before, tms_between, tms_after; value_init(cm); value_init(cb); Polyhedron_Print(stdout, P_VALUE_FMT, A); times(&tms_before); manual_count(A, &cm); times(&tms_between); barvinok_count(A, &cb, 100); times(&tms_after); printf("manual: "); value_print(stdout, P_VALUE_FMT, cm); puts(""); time_diff(&tms_before, &tms_between); printf("Barvinok: "); value_print(stdout, P_VALUE_FMT, cb); puts(""); time_diff(&tms_between, &tms_after); value_clear(cm); value_clear(cb); break; } case 5: Polyhedron_Print(stdout, P_VALUE_FMT, A); B = triangulate_cone(A, 100); Polyhedron_Print(stdout, P_VALUE_FMT, B); check_triangulization(A, B); Domain_Free(B); break; case 6: Polyhedron_Print(stdout, P_VALUE_FMT, A); B = remove_equalities(A, options->MaxRays); Polyhedron_Print(stdout, P_VALUE_FMT, B); Polyhedron_Free(B); break; case 8: { evalue *EP; Matrix *M = Matrix_Read(); const char **param_name; C = Constraints2Polyhedron(M, options->MaxRays); Matrix_Free(M); Polyhedron_Print(stdout, P_VALUE_FMT, A); Polyhedron_Print(stdout, P_VALUE_FMT, C); EP = barvinok_enumerate_with_options(A, C, options); param_name = Read_ParamNames(stdin, C->Dimension); print_evalue(stdout, EP, (const char**)param_name); evalue_free(EP); Polyhedron_Free(C); } case 9: Polyhedron_Print(stdout, P_VALUE_FMT, A); Polyhedron_Polarize(A); C = B = NULL; barvinok_decompose(A,&B,&C); for (D = B; D; D = D->next) Polyhedron_Polarize(D); for (D = C; D; D = D->next) Polyhedron_Polarize(D); puts("Pos:"); Polyhedron_Print(stdout, P_VALUE_FMT, B); puts("Neg:"); Polyhedron_Print(stdout, P_VALUE_FMT, C); Domain_Free(B); Domain_Free(C); break; case 10: { evalue *EP; Value cb, ck; value_init(cb); value_init(ck); fgets(s, 128, stdin); sscanf(s, "%d", &n); for (j = 0; j < n; ++j) { Polyhedron *P; M = Matrix_Read(); P = Constraints2Polyhedron(M, options->MaxRays); Matrix_Free(M); A = DomainConcat(P, A); } fgets(s, 128, stdin); /* workaround for apparent bug in older gmps */ *strchr(s, '\n') = '\0'; while ((*s=='#') || (value_read(ck, s) != 0)) { fgets(s, 128, stdin); /* workaround for apparent bug in older gmps */ *strchr(s, '\n') = '\0'; } C = Universe_Polyhedron(0); EP = barvinok_enumerate_union(A, C, options->MaxRays); value_set_double(cb, compute_evalue(EP, &ck)+.25); if (value_ne(cb, ck)) return -1; Domain_Free(C); value_clear(cb); value_clear(ck); evalue_free(EP); break; } case 11: { isl_space *dim; isl_basic_set *bset; isl_pw_qpolynomial *expected, *computed; unsigned nparam; expected = isl_pw_qpolynomial_read_from_file(ctx, stdin); nparam = isl_pw_qpolynomial_dim(expected, isl_dim_param); dim = isl_space_set_alloc(ctx, nparam, A->Dimension - nparam); bset = isl_basic_set_new_from_polylib(A, dim); computed = isl_basic_set_lattice_width(bset); computed = isl_pw_qpolynomial_sub(computed, expected); if (!isl_pw_qpolynomial_is_zero(computed)) return -1; isl_pw_qpolynomial_free(computed); break; } case 12: { Vector *sample; int has_sample; fgets(s, 128, stdin); sscanf(s, "%d", &has_sample); sample = Polyhedron_Sample(A, options); if (!sample && has_sample) return -1; if (sample && !has_sample) return -1; if (sample && !in_domain(A, sample->p)) return -1; Vector_Free(sample); } } Domain_Free(A); } for (i = 0; i < nbVec; ++i) { int ok; Vector *V = Vector_Read(); Matrix *M = Matrix_Alloc(V->Size, V->Size); Vector_Copy(V->p, M->p[0], V->Size); ok = unimodular_complete(M, 1); assert(ok); Matrix_Print(stdout, P_VALUE_FMT, M); Matrix_Free(M); Vector_Free(V); } for (i = 0; i < nbMat; ++i) { Matrix *U, *V, *S; Matrix *M = Matrix_Read(); Smith(M, &U, &V, &S); Matrix_Print(stdout, P_VALUE_FMT, U); Matrix_Print(stdout, P_VALUE_FMT, V); Matrix_Print(stdout, P_VALUE_FMT, S); Matrix_Free(M); Matrix_Free(U); Matrix_Free(V); Matrix_Free(S); } isl_ctx_free(ctx); return 0; }
/** Removes the equalities that involve only parameters, by eliminating some * parameters in the polyhedron's constraints and in the context.<p> * <b>Updates M and Ctxt.</b> * @param M1 the polyhedron's constraints * @param Ctxt1 the constraints of the polyhedron's context * @param renderSpace tells if the returned equalities must be expressed in the * parameters space (renderSpace=0) or in the combined var/parms space * (renderSpace = 1) * @param elimParms the list of parameters that have been removed: an array * whose 1st element is the number of elements in the list. (returned) * @return the system of equalities that involve only parameters. */ Matrix * Constraints_Remove_parm_eqs(Matrix ** M1, Matrix ** Ctxt1, int renderSpace, unsigned int ** elimParms) { int i, j, k, nbEqsParms =0; int nbEqsM, nbEqsCtxt, allZeros, nbTautoM = 0, nbTautoCtxt = 0; Matrix * M = (*M1); Matrix * Ctxt = (*Ctxt1); int nbVars = M->NbColumns-Ctxt->NbColumns; Matrix * Eqs; Matrix * EqsMTmp; /* 1- build the equality matrix(ces) */ nbEqsM = 0; for (i=0; i< M->NbRows; i++) { k = First_Non_Zero(M->p[i], M->NbColumns); /* if it is a tautology, count it as such */ if (k==-1) { nbTautoM++; } else { /* if it only involves parameters, count it */ if (k>= nbVars+1) nbEqsM++; } } nbEqsCtxt = 0; for (i=0; i< Ctxt->NbRows; i++) { if (value_zero_p(Ctxt->p[i][0])) { if (First_Non_Zero(Ctxt->p[i], Ctxt->NbColumns)==-1) { nbTautoCtxt++; } else { nbEqsCtxt ++; } } } nbEqsParms = nbEqsM + nbEqsCtxt; /* nothing to do in this case */ if (nbEqsParms+nbTautoM+nbTautoCtxt==0) { (*elimParms) = (unsigned int*) malloc(sizeof(int)); (*elimParms)[0] = 0; if (renderSpace==0) { return Matrix_Alloc(0,Ctxt->NbColumns); } else { return Matrix_Alloc(0,M->NbColumns); } } Eqs= Matrix_Alloc(nbEqsParms, Ctxt->NbColumns); EqsMTmp= Matrix_Alloc(nbEqsParms, M->NbColumns); /* copy equalities from the context */ k = 0; for (i=0; i< Ctxt->NbRows; i++) { if (value_zero_p(Ctxt->p[i][0]) && First_Non_Zero(Ctxt->p[i], Ctxt->NbColumns)!=-1) { Vector_Copy(Ctxt->p[i], Eqs->p[k], Ctxt->NbColumns); Vector_Copy(Ctxt->p[i]+1, EqsMTmp->p[k]+nbVars+1, Ctxt->NbColumns-1); k++; } } for (i=0; i< M->NbRows; i++) { j=First_Non_Zero(M->p[i], M->NbColumns); /* copy equalities that involve only parameters from M */ if (j>=nbVars+1) { Vector_Copy(M->p[i]+nbVars+1, Eqs->p[k]+1, Ctxt->NbColumns-1); Vector_Copy(M->p[i]+nbVars+1, EqsMTmp->p[k]+nbVars+1, Ctxt->NbColumns-1); /* mark these equalities for removal */ value_set_si(M->p[i][0], 2); k++; } /* mark the all-zero equalities for removal */ if (j==-1) { value_set_si(M->p[i][0], 2); } } /* 2- eliminate parameters until all equalities are used or until we find a contradiction (overconstrained system) */ (*elimParms) = (unsigned int *) malloc((Eqs->NbRows+1) * sizeof(int)); (*elimParms)[0] = 0; allZeros = 0; for (i=0; i< Eqs->NbRows; i++) { /* find a variable that can be eliminated */ k = First_Non_Zero(Eqs->p[i], Eqs->NbColumns); if (k!=-1) { /* nothing special to do for tautologies */ /* if there is a contradiction, return empty matrices */ if (k==Eqs->NbColumns-1) { printf("Contradiction in %dth row of Eqs: ",k); show_matrix(Eqs); Matrix_Free(Eqs); Matrix_Free(EqsMTmp); (*M1) = Matrix_Alloc(0, M->NbColumns); Matrix_Free(M); (*Ctxt1) = Matrix_Alloc(0,Ctxt->NbColumns); Matrix_Free(Ctxt); free(*elimParms); (*elimParms) = (unsigned int *) malloc(sizeof(int)); (*elimParms)[0] = 0; if (renderSpace==1) { return Matrix_Alloc(0,(*M1)->NbColumns); } else { return Matrix_Alloc(0,(*Ctxt1)->NbColumns); } } /* if we have something we can eliminate, do it in 3 places: Eqs, Ctxt, and M */ else { k--; /* k is the rank of the variable, now */ (*elimParms)[0]++; (*elimParms)[(*elimParms[0])]=k; for (j=0; j< Eqs->NbRows; j++) { if (i!=j) { eliminate_var_with_constr(Eqs, i, Eqs, j, k); eliminate_var_with_constr(EqsMTmp, i, EqsMTmp, j, k+nbVars); } } for (j=0; j< Ctxt->NbRows; j++) { if (value_notzero_p(Ctxt->p[i][0])) { eliminate_var_with_constr(Eqs, i, Ctxt, j, k); } } for (j=0; j< M->NbRows; j++) { if (value_cmp_si(M->p[i][0], 2)) { eliminate_var_with_constr(EqsMTmp, i, M, j, k+nbVars); } } } } /* if (k==-1): count the tautologies in Eqs to remove them later */ else { allZeros++; } } /* elimParms may have been overallocated. Now we know how many parms have been eliminated so we can reallocate the right amount of memory. */ if (!realloc((*elimParms), ((*elimParms)[0]+1)*sizeof(int))) { fprintf(stderr, "Constraints_Remove_parm_eqs > cannot realloc()"); } Matrix_Free(EqsMTmp); /* 3- remove the "bad" equalities from the input matrices and copy the equalities involving only parameters */ EqsMTmp = Matrix_Alloc(M->NbRows-nbEqsM-nbTautoM, M->NbColumns); k=0; for (i=0; i< M->NbRows; i++) { if (value_cmp_si(M->p[i][0], 2)) { Vector_Copy(M->p[i], EqsMTmp->p[k], M->NbColumns); k++; } } Matrix_Free(M); (*M1) = EqsMTmp; EqsMTmp = Matrix_Alloc(Ctxt->NbRows-nbEqsCtxt-nbTautoCtxt, Ctxt->NbColumns); k=0; for (i=0; i< Ctxt->NbRows; i++) { if (value_notzero_p(Ctxt->p[i][0])) { Vector_Copy(Ctxt->p[i], EqsMTmp->p[k], Ctxt->NbColumns); k++; } } Matrix_Free(Ctxt); (*Ctxt1) = EqsMTmp; if (renderSpace==0) {/* renderSpace=0: equalities in the parameter space */ EqsMTmp = Matrix_Alloc(Eqs->NbRows-allZeros, Eqs->NbColumns); k=0; for (i=0; i<Eqs->NbRows; i++) { if (First_Non_Zero(Eqs->p[i], Eqs->NbColumns)!=-1) { Vector_Copy(Eqs->p[i], EqsMTmp->p[k], Eqs->NbColumns); k++; } } } else {/* renderSpace=1: equalities rendered in the combined space */ EqsMTmp = Matrix_Alloc(Eqs->NbRows-allZeros, (*M1)->NbColumns); k=0; for (i=0; i<Eqs->NbRows; i++) { if (First_Non_Zero(Eqs->p[i], Eqs->NbColumns)!=-1) { Vector_Copy(Eqs->p[i], &(EqsMTmp->p[k][nbVars]), Eqs->NbColumns); k++; } } } Matrix_Free(Eqs); Eqs = EqsMTmp; return Eqs; } /* Constraints_Remove_parm_eqs */
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; } } }
//************************************************************************************* // Checks is a triangle of a physical object is colliding a triangle //************************************************************************************* BOOL IsObjectVertexCollidingTriangle(EERIE_3DOBJ * obj, EERIE_3D * verts, long k, long * validd) { EERIE_TRI t1, t2; BOOL ret = FALSE; memcpy(&t2, verts, sizeof(EERIE_3D) * 3); PHYSVERT * vert = obj->pbox->vert; EERIE_3D center; center.x = (verts[0].x + verts[1].x + verts[2].x) * DIV3; center.y = (verts[0].y + verts[1].y + verts[2].y) * DIV3; center.z = (verts[0].z + verts[1].z + verts[2].z) * DIV3; float rad = EEDistance3D(¢er, &verts[0]); if (k == -1) { long nn = 0; for (; nn < obj->pbox->nb_physvert; nn++) { if (EEDistance3D(¢er, &vert[nn].pos) <= __max(60, rad + 25)) { nn = 1000; } } if (nn < 1000) return FALSE; } else { if (EEDistance3D(¢er, &vert[k].pos) > rad + 25) return FALSE; } //TOP if ((k == -1) || (k == 1) || (k == 2) || (k == 3)) { Vector_Copy(&t1.v[0], &vert[1].pos); Vector_Copy(&t1.v[1], &vert[2].pos); Vector_Copy(&t1.v[2], &vert[3].pos); PHYS_COLLIDER = 1; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[1] = 0; validd[2] = 0; validd[3] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #if FULLTESTS==TRUE if ((k == -1) || (k == 1) || (k == 4) || (k == 3)) { Vector_Copy(&t1.v[0], &vert[3].pos); Vector_Copy(&t1.v[1], &vert[4].pos); Vector_Copy(&t1.v[2], &vert[1].pos); PHYS_COLLIDER = 1; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[1] = 0; validd[3] = 0; validd[4] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #endif //BOTTOM if ((k == -1) || (k == 9) || (k == 10) || (k == 12)) { Vector_Copy(&t1.v[0], &vert[10].pos); Vector_Copy(&t1.v[1], &vert[9].pos); Vector_Copy(&t1.v[2], &vert[11].pos); PHYS_COLLIDER = 9; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[0] = 0; validd[10] = 0; validd[12] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #if FULLTESTS==TRUE if ((k == -1) || (k == 10) || (k == 11) || (k == 12)) { Vector_Copy(&t1.v[0], &vert[9].pos); Vector_Copy(&t1.v[1], &vert[12].pos); Vector_Copy(&t1.v[2], &vert[11].pos); PHYS_COLLIDER = 10; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[10] = 0; validd[11] = 0; validd[12] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #endif //UP/FRONT if ((k == -1) || (k == 1) || (k == 4) || (k == 5)) { Vector_Copy(&t1.v[0], &vert[1].pos); Vector_Copy(&t1.v[1], &vert[4].pos); Vector_Copy(&t1.v[2], &vert[5].pos); PHYS_COLLIDER = 4; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[1] = 0; validd[4] = 0; validd[5] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #if FULLTESTS==TRUE if ((k == -1) || (k == 4) || (k == 5) || (k == 8)) { Vector_Copy(&t1.v[0], &vert[4].pos); Vector_Copy(&t1.v[1], &vert[8].pos); Vector_Copy(&t1.v[2], &vert[5].pos); PHYS_COLLIDER = 5; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[4] = 0; validd[5] = 0; validd[8] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #endif //DOWN/FRONT if ((k == -1) || (k == 5) || (k == 8) || (k == 9)) { Vector_Copy(&t1.v[0], &vert[5].pos); Vector_Copy(&t1.v[1], &vert[8].pos); Vector_Copy(&t1.v[2], &vert[9].pos); PHYS_COLLIDER = 8; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[5] = 0; validd[8] = 0; validd[9] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #if FULLTESTS==TRUE if ((k == -1) || (k == 8) || (k == 12) || (k == 9)) { Vector_Copy(&t1.v[0], &vert[8].pos); Vector_Copy(&t1.v[1], &vert[12].pos); Vector_Copy(&t1.v[2], &vert[9].pos); PHYS_COLLIDER = 12; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[8] = 0; validd[12] = 0; validd[9] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #endif //UP/BACK if ((k == -1) || (k == 3) || (k == 2) || (k == 7)) { Vector_Copy(&t1.v[0], &vert[3].pos); Vector_Copy(&t1.v[1], &vert[2].pos); Vector_Copy(&t1.v[2], &vert[7].pos); PHYS_COLLIDER = 3; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[3] = 0; validd[2] = 0; validd[7] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #if FULLTESTS==TRUE if ((k == -1) || (k == 2) || (k == 6) || (k == 7)) { Vector_Copy(&t1.v[0], &vert[2].pos); Vector_Copy(&t1.v[1], &vert[6].pos); Vector_Copy(&t1.v[2], &vert[7].pos); PHYS_COLLIDER = 2; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[2] = 0; validd[6] = 0; validd[7] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #endif //DOWN/BACK if ((k == -1) || (k == 7) || (k == 6) || (k == 11)) { Vector_Copy(&t1.v[0], &vert[7].pos); Vector_Copy(&t1.v[1], &vert[6].pos); Vector_Copy(&t1.v[2], &vert[11].pos); PHYS_COLLIDER = 7; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[6] = 0; validd[7] = 0; validd[11] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #if FULLTESTS==TRUE if ((k == -1) || (k == 6) || (k == 10) || (k == 11)) { Vector_Copy(&t1.v[0], &vert[6].pos); Vector_Copy(&t1.v[1], &vert[10].pos); Vector_Copy(&t1.v[2], &vert[11].pos); PHYS_COLLIDER = 6; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[6] = 0; validd[10] = 0; validd[11] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #endif //UP/LEFT if ((k == -1) || (k == 1) || (k == 2) || (k == 6)) { Vector_Copy(&t1.v[0], &vert[6].pos); Vector_Copy(&t1.v[1], &vert[2].pos); Vector_Copy(&t1.v[2], &vert[1].pos); PHYS_COLLIDER = 2; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[1] = 0; validd[2] = 0; validd[6] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #if FULLTESTS==TRUE if ((k == -1) || (k == 1) || (k == 5) || (k == 6)) { Vector_Copy(&t1.v[0], &vert[1].pos); Vector_Copy(&t1.v[1], &vert[5].pos); Vector_Copy(&t1.v[2], &vert[6].pos); PHYS_COLLIDER = 5; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[1] = 0; validd[5] = 0; validd[6] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #endif //DOWN/LEFT if ((k == -1) || (k == 10) || (k == 6) || (k == 5)) { Vector_Copy(&t1.v[0], &vert[10].pos); Vector_Copy(&t1.v[1], &vert[6].pos); Vector_Copy(&t1.v[2], &vert[5].pos); PHYS_COLLIDER = 6; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[10] = 0; validd[6] = 0; validd[5] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #if FULLTESTS==TRUE if ((k == -1) || (k == 5) || (k == 9) || (k == 10)) { Vector_Copy(&t1.v[0], &vert[5].pos); Vector_Copy(&t1.v[1], &vert[9].pos); Vector_Copy(&t1.v[2], &vert[10].pos); PHYS_COLLIDER = 5; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[5] = 0; validd[9] = 0; validd[10] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #endif //UP/RIGHT if ((k == -1) || (k == 4) || (k == 3) || (k == 7)) { Vector_Copy(&t1.v[0], &vert[4].pos); Vector_Copy(&t1.v[1], &vert[3].pos); Vector_Copy(&t1.v[2], &vert[7].pos); PHYS_COLLIDER = 4; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[3] = 0; validd[4] = 0; validd[7] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #if FULLTESTS==TRUE if ((k == -1) || (k == 7) || (k == 8) || (k == 4)) { Vector_Copy(&t1.v[0], &vert[7].pos); Vector_Copy(&t1.v[1], &vert[8].pos); Vector_Copy(&t1.v[2], &vert[4].pos); PHYS_COLLIDER = 7; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[4] = 0; validd[7] = 0; validd[8] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #endif //DOWN/RIGHT if ((k == -1) || (k == 8) || (k == 7) || (k == 11)) { Vector_Copy(&t1.v[0], &vert[8].pos); Vector_Copy(&t1.v[1], &vert[7].pos); Vector_Copy(&t1.v[2], &vert[11].pos); PHYS_COLLIDER = 8; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[7] = 0; validd[8] = 0; validd[11] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #if FULLTESTS==TRUE if ((k == -1) || (k == 11) || (k == 12) || (k == 8)) { Vector_Copy(&t1.v[0], &vert[11].pos); Vector_Copy(&t1.v[1], &vert[12].pos); Vector_Copy(&t1.v[2], &vert[8].pos); PHYS_COLLIDER = 11; if (Triangles_Intersect(&t1, &t2)) { if (validd) { validd[8] = 0; validd[11] = 0; validd[12] = 0; ret = TRUE; } else return TRUE; }//MAKE_COLL_TEST } #endif return ret; }