void wdHandleCollision(World* W) { CollisionInfo Info; Node* it = lstFirst(&W->Polygons); Node* it2; //On met à FALSE tous les collide while(!nodeEnd(it)) { polySetCollided((Polygon*)nodeGetData(it), FALSE); it=nodeGetNext(it); } it = lstFirst(&W->Polygons); while(!nodeEnd(it)) { List LExtracted = gridGetPolygonList(&W->CollisionGrid, (Polygon*) nodeGetData(it)); it2 = lstFirst(&LExtracted); while(!nodeEnd(it2)) { if(!polyHasCollided((Polygon*)nodeGetData(it2)))//it != it2) { Info = polyCollide( (Polygon*) nodeGetData(it), (Polygon*) nodeGetData(it2)); if(Info.P1 != NULL) /* Il y a collision */ polyHandleCollision(Info); } it2 = nodeGetNext(it2); } lstFree(&LExtracted); polySetCollided((Polygon*)nodeGetData(it), TRUE); it = nodeGetNext(it); } }
void wdDraw(World* W, void (*vxDraw)(Vertex* V, float R, float G, float B, float A), void (*elDraw)(Elastic* E), void (*rdDraw)(Rigid* R), void (*polyDraw) (Polygon* P)) { Node* it; if(vxDraw != NULL) { it = lstFirst(&W->Vertices); while(!nodeEnd(it)) { if(vxIsFixed((Vertex*) nodeGetData(it))) (*vxDraw)((Vertex*) nodeGetData(it), 1.f, 0.f, 0.f, 0.3f); else (*vxDraw)((Vertex*) nodeGetData(it), 0.f, 1.f, 0.f, 0.3f); it = nodeGetNext(it); } } if(elDraw != NULL) { it = lstFirst(&W->Elastics); while(!nodeEnd(it)) { (*elDraw) ((Elastic*) nodeGetData(it)); it = nodeGetNext(it); } } if(rdDraw != NULL) { it = lstFirst(&W->Rigids); while(!nodeEnd(it)) { (*rdDraw) ((Rigid*) nodeGetData(it)); it = nodeGetNext(it); } } if(polyDraw != NULL) { it = lstFirst(&W->Polygons); while(!nodeEnd(it)) { (*polyDraw) ((Polygon*) nodeGetData(it)); it = nodeGetNext(it); } } }
void wdApplyForce(World* W, Vec2 Force) { Node* it = lstFirst(&W->Vertices); while(!nodeEnd(it)) vxApplyForce((Vertex*) nodeGetData(it), Force, 1.f), it = nodeGetNext(it); }
Polygon* newPolygonL(List L) { unsigned int i = 0, nbVx = lstCount(&L); Polygon* newPoly = (Polygon*) malloc(sizeof(Polygon)); Node* it = lstFirst(&L); /*Initialisation des Dynamic Arrays */ newPoly->Rigids = da(); newPoly->Vertices = da(); newPoly->InternalRigids = da(); daReserve(&newPoly->Rigids, nbVx); daReserve(&newPoly->Vertices, nbVx); newPoly->Center = NULL; newPoly->Fixed = FALSE; newPoly->GridPos.Valid = FALSE; newPoly->Collided = FALSE; /* Ajoute les Vertices */ while(!nodeEnd(it)) { daAdd(&newPoly->Vertices, (Vertex*) nodeGetData(it)); it = nodeGetNext(it); } /* Construit les limites, i.e. Créé un nouveau Rigid à partir de deux Vertices de la liste et la distance les séparant, puis l'ajoute à la liste */ for(i = 0; i < nbVx; i++) daAdd(&newPoly->Rigids, newRigid((Vertex*)daGet(&newPoly->Vertices, i), (Vertex*)daGet(&newPoly->Vertices, (i+1)%nbVx), vec2Length(vec2Sub(vxGetPosition((Vertex*)daGet(&newPoly->Vertices, i)), vxGetPosition((Vertex*)daGet(&newPoly->Vertices, (i+1)%nbVx)))))); return newPoly; }
void wdLimitVextexPosition(World* W) { Vec2 curPos; Vec2 newPos; Node* it = lstFirst(&W->Vertices); while(!nodeEnd(it)) { /* Garde le Vertex dans les limites du monde */ curPos = vxGetPosition((Vertex*) nodeGetData(it)); if(curPos.x > W->Width) newPos.x = W->Width; else if(curPos.x < 0.f) newPos.x = 0.f; else newPos.x = curPos.x; if(curPos.y > W->Height) newPos.y = W->Height; else if(curPos.y < 0.f) newPos.y = 0.f; else newPos.y = curPos.y; //printf("new pos : %f, %f ; curpos: %f, %f\n", newPos.x, newPos.y, curPos.x, curPos.y); if (curPos.y != newPos.y || curPos.x != newPos.x) vxSetPosition((Vertex*) nodeGetData(it), newPos); if (curPos.y != newPos.y || curPos.x != newPos.x) vxSetPosition((Vertex*) nodeGetData(it), newPos); it = nodeGetNext(it); } }
void wdAddVxFromList(World* W, List L) { Node* it = lstFirst(&L); while(!nodeEnd(it)) { wdAddVertex(W, (Vertex*) nodeGetData(it)); it = nodeGetNext(it); } }
void wdResolveElastic(World* W) { Node* it = lstFirst(&W->Elastics); while(!nodeEnd(it)) { elResolve((Elastic*) nodeGetData(it)); it = nodeGetNext(it); } }
void wdResolveRigid(World* W) { Node* it = lstFirst(&W->Rigids); /* Parcoure les contraintes orphelines */ while(!nodeEnd(it)) { rdResolve( (Rigid*) nodeGetData(it)); it = nodeGetNext(it); } /* Parcoure les Polygons */ it = lstFirst(&W->Polygons); while(!nodeEnd(it)) { polyResolve((Polygon*) nodeGetData(it)); it = nodeGetNext(it); } }
void wdUpdateGrid(World *W, Bool Force) { Node* it = lstFirst(&W->Polygons); while(!nodeEnd(it)) { if (Force || !polyIsFixed((Polygon*)nodeGetData(it))) gridUpdatePolygonPositionByBB(&W->CollisionGrid, (Polygon*)nodeGetData(it)); it=nodeGetNext(it); } }
Object* cpyObject(Object* O) { List CT; lstInit(&CT); Node* it = lstFirst(&O->CoordTex); while(!nodeEnd(it)) { Vec2* CoordTex = newVec2(); vec2Cp(CoordTex, *((Vec2*) nodeGetData(it))); lstAdd(&CT, CoordTex); it = nodeGetNext(it); } return newObject(cpyPolygon(O->Shape), O->Tex, CT); }
void wdResetGrid(World* W) { gridFree(&W->CollisionGrid); float CellSize=128.f; gridInit(&W->CollisionGrid, W->Width/CellSize+1, W->Height/CellSize+1); gridSetCellSize(&W->CollisionGrid, CellSize); Node* it = lstFirst(&W->Polygons); while(!nodeEnd(it)) { gridAddPolygonByBB(&W->CollisionGrid, (Polygon*)nodeGetData(it)); it=nodeGetNext(it); } }
Polygon* wdGetNearestPoly(World* W, float X, float Y) { Polygon *tmpPoly; List* LExtracted = gridGetPositionList(&W->CollisionGrid, X, Y); Node* it = lstFirst(LExtracted); while(!nodeEnd(it)) { tmpPoly = (Polygon*) nodeGetData(it); if (polyIsInside(tmpPoly, vec2(X, Y))) return tmpPoly; it = nodeGetNext(it); } return NULL; }
Polygon* wdFindPolygon(World *W, Vertex* V) { Node* it; Polygon* P; it = lstFirst(&W->Polygons); while(!nodeEnd(it)) { P = (Polygon*)nodeGetData(it); unsigned int vxnb = polyGetVxCount(P), i; for (i=0; i<vxnb; i++) { if (polyGetVertex(P, i) == V) return P; } it = nodeGetNext(it); } return NULL; }
Elastic* wdGetNearestElastic(World* W, float X, float Y) { float Dist = 30.f*30.f, tmpDist; Elastic *Nearest = NULL; Node* it; Vec2 M = vec2(X, Y); it = wdGetElasticIt(W); while(!nodeEnd(it)) { tmpDist =elGetSquaredDistanceToPoint((Elastic*)nodeGetData(it), M); if(Dist > tmpDist) { Dist = tmpDist; Nearest = (Elastic*)nodeGetData(it); } it = nodeGetNext(it); } return Nearest; }
Rigid* wdGetNearestRigid(World* W, float X, float Y) { float Dist = 30.f*30.f, tmpDist; Rigid *Nearest = NULL; Node* it; Vec2 M = vec2(X, Y); it = wdGetRigidIt(W); while(!nodeEnd(it)) { tmpDist =rdGetSquaredDistanceToPoint((Rigid*)nodeGetData(it), M); if(Dist > tmpDist) { Dist = tmpDist; Nearest = (Rigid*)nodeGetData(it); } it = nodeGetNext(it); } return Nearest; }
Vertex* wdGetNearest(World* W, float X, float Y) { if (lstEmpty(&W->Vertices)) return NULL; float Dist = powf(40.f, 2.f), tmpDist; Vertex* Nearest = NULL; Node* it = lstFirst(&W->Vertices); while(!nodeEnd(it)) { Vec2 VPos = vxGetPosition((Vertex*) nodeGetData(it)); Vec2 V = vec2(X - VPos.x, Y - VPos.y); tmpDist = vec2SqLength(V); if (tmpDist < Dist) { Dist = tmpDist; Nearest = (Vertex*) nodeGetData(it); } it = nodeGetNext(it); } return Nearest; }
int main() { struct lnode *head, *tail, *node; char buf[2]; /* list starts empty */ head = tail = NULL; for (char c = 'a'; c < 'z'; c++) { /* add this letter, as a word, to the list */ buf[0] = c; buf[1] = '\0'; newNode(&head, &tail, buf, 1); } /* we don't like the letter 'f' */ node = getNode(&head, &tail, "f", 1); if (node == NULL) { fprintf(stderr, "We forgot f???\n"); printf("node %p\n",getNode(&head, &tail, "f", 1)); } else { deleteNode(&head, &tail, node); } /* now let's print every node */ for (node = head; node != NULL; node = nodeGetNext(node)) { /* increment its count */ nodeIncCount(node); /* then show it */ printf("%s: %d %d\n", nodeGetWord(node), nodeGetLine(node), nodeGetCount(node)); } /* get rid of our list */ deleteList(&head, &tail); // printf("%d\n", deleteList(&head,&tail)); return 0; }
void plPhysics(Player* P, World* W) { /* Mise à jour spécifique de Player */ P->RdUStatus = P->RdRStatus = P->RdDStatus = P->RdLStatus = P->VxURStatus = P->VxULStatus = P->VxDLStatus = P->VxDRStatus = nullCollisionInfo(); polyResolve(plGetShape(P)); //for (i=0; i<10; i++) polyResolve(P->BodyPolygons[i]); for (int i=0; i<12; i++) { vxResolve(P->vxBodyParts[i], 0.5f, 0.5f); rdResolve(P->BodyRigids[i]); } float dif = vxGetPosition(P->VxDL).x - vxGetOldPos(P->VxDL).x; if (dif >= 0.f && ABS(dif) > 0.2f) P->Dir = DIR_RIGHT; else P->Dir = DIR_LEFT; List LExtracted = gridGetPolygonList(&W->CollisionGrid, P->Shape); Node* it; CollisionInfo Info; P->State = PL_NOSTATE; P->Normal = vec2(0.f, 0.f); it = lstFirst(&LExtracted); while(!nodeEnd(it)) { Info = polyCollide(plGetShape(P), (Polygon*) nodeGetData(it)); if(Info.P1 != NULL) { //printf("Collision\n"); if (Info.Edge == plGetRdD(P)) { P->GroundAngle = vec2Angle(Info.Normal)-M_PI_2; P->Normal = vec2Prod(Info.Normal, -1.f); P->State = P->State | PL_HAS_SUPPORT; if(P->Normal.y < -0.5f) P->State = P->State | PL_ON_GROUND; } else if(Info.V == plGetVxDL(P) || Info.V == plGetVxDR(P)) { P->GroundAngle = vec2Angle(Info.Normal)-M_PI_2; P->Normal = Info.Normal; P->State = P->State | PL_HAS_SUPPORT; if(P->Normal.y < -0.5f) P->State = P->State | PL_ON_GROUND; } /* Test des propriétés de la collision */ if(Info.Edge == plGetRdU(P)) P->RdUStatus = Info; else if(Info.Edge == plGetRdR(P)) P->RdRStatus = Info; else if(Info.Edge == plGetRdD(P)) P->RdDStatus = Info; else if(Info.Edge == plGetRdL(P)) P->RdLStatus = Info; if(Info.V == plGetVxUL(P)) P->VxULStatus = Info; else if(Info.V == plGetVxUR(P)) P->VxURStatus = Info; else if(Info.V == plGetVxDR(P)) P->VxDRStatus = Info; else if(Info.V == plGetVxDL(P)) P->VxDLStatus = Info; polyHandleCollision(Info); } it = nodeGetNext(it); } lstFree(&LExtracted); }