void JelloMesh::Update(double dt, const World& world, const vec3& externalForces) { m_externalForces = externalForces; CheckForCollisions(m_vparticles, world); ComputeForces(m_vparticles); ResolveContacts(m_vparticles); ResolveCollisions(m_vparticles); switch (m_integrationType) { case EULER: EulerIntegrate(dt); break; case MIDPOINT: MidPointIntegrate(dt); break; case RK4: RK4Integrate(dt); break; } }
void CPhysEnv::Simulate(float DeltaTime, BOOL running) { float CurrentTime = 0.0f; float TargetTime = DeltaTime; tParticle *tempSys; int collisionState; while(CurrentTime < DeltaTime) { if (running) { ComputeForces(m_CurrentSys); // IN ORDER TO MAKE THINGS RUN FASTER, I HAVE THIS LITTLE TRICK // IF THE SYSTEM IS DOING A BINARY SEARCH FOR THE COLLISION POINT, // I FORCE EULER'S METHOD ON IT. OTHERWISE, LET THE USER CHOOSE. // THIS DOESN'T SEEM TO EFFECT STABILITY EITHER WAY if (m_CollisionRootFinding) { EulerIntegrate(TargetTime-CurrentTime); } else { switch (m_IntegratorType) { case EULER_INTEGRATOR: EulerIntegrate(TargetTime-CurrentTime); break; case MIDPOINT_INTEGRATOR: MidPointIntegrate(TargetTime-CurrentTime); break; case HEUN_INTEGRATOR: HeunIntegrate(TargetTime-CurrentTime); break; case RK4_INTEGRATOR: RK4Integrate(TargetTime-CurrentTime); break; case RK4_ADAPTIVE_INTEGRATOR: RK4AdaptiveIntegrate(TargetTime-CurrentTime); break; case FEHLBERG: FehlbergIntegrate(TargetTime-CurrentTime); break; } } } collisionState = CheckForCollisions(m_TargetSys); if(collisionState == PENETRATING) { // TELL THE SYSTEM I AM LOOKING FOR A COLLISION SO IT WILL USE EULER m_CollisionRootFinding = TRUE; // we simulated too far, so subdivide time and try again TargetTime = (CurrentTime + TargetTime) / 2.0f; // blow up if we aren't moving forward each step, which is // probably caused by interpenetration at the frame start assert(fabs(TargetTime - CurrentTime) > EPSILON); } else { // either colliding or clear if(collisionState == COLLIDING) { int Counter = 0; do { ResolveCollisions(m_TargetSys); Counter++; } while((CheckForCollisions(m_TargetSys) == COLLIDING) && (Counter < 100)); assert(Counter < 100); m_CollisionRootFinding = FALSE; // FOUND THE COLLISION POINT } // we made a successful step, so swap configurations // to "save" the data for the next step CurrentTime = TargetTime; TargetTime = DeltaTime; // SWAP MY TWO PARTICLE SYSTEM BUFFERS SO I CAN DO IT AGAIN tempSys = m_CurrentSys; m_CurrentSys = m_TargetSys; m_TargetSys = tempSys; } } }
void timeStep(int step) { // animation code goes here // This function is called for each frame of animation double t = (double) (frame - startFrame) / (endFrame - startFrame); for (int i=0; i<NUM_PARTICLES; i++) { if (pos[i][1] <= -20 || pos[i][1] >= 16.5 || pos[i][0] <= -4 || pos[i][0] >= 5) { mass[i] = 1.0; sizes[i] = (((float)rand()/RAND_MAX))/3; maxsizes[i] = sizes[i] + .3; pos[i][0] = 0.0; pos[i][1] = 0.0; pos[i][2] = 0.0; vel[i][2] = 0.0; if (sizes[i] > .2) { vel[i][0] = ((((float)rand()/RAND_MAX)*2)-1)*3 + 3; vel[i][1] = ((((float)rand()/RAND_MAX)*2))*15 + 6; } else if (sizes[i] > .1) { vel[i][0] = ((((float)rand()/RAND_MAX)*2)-1)*2 + 2; vel[i][1] = ((((float)rand()/RAND_MAX)*2))*15 + 4; } else { vel[i][0] = ((((float)rand()/RAND_MAX)*2)-1)*1; vel[i][1] = ((((float)rand()/RAND_MAX)*2))*5 + 2; } acc[i][0] = 0.0; acc[i][1] = 0.0; acc[i][2] = 0.0; force[i][0] = 0.0; force[i][1] = 0.0; force[i][2] = 0.0; colors[i][0] = 0.0; colors[i][1] = (rand()%100)*.01 - .5; colors[i][2] = (rand()%100)*.01 + .5; } } for (int j=0; j<NUM_PARTICLES; j++) { if (sizes[j] <= maxsizes[j]) { sizes[j] += .02; } } // do the particle system stuff sumForces(); EulerIntegrate(t); if (frame == endFrame) increment = -1; else if (frame == startFrame) increment = 1; frame = frame + increment; display(); glutTimerFunc(10,timeStep, 0); }
void MoveRect(CollisionManager* manager, RigidBody* body, Rect rect, V3 deltaP, float deltaT) { V3 velocity; V3 offset = EulerIntegrate(deltaP, body->v, deltaT); float epsilon = 0.001f; VectorAdd(&velocity, RVector3Scale(deltaP, deltaT)); //Check For Collisions for(int it = 0; it < 4; ++it) { Contact contacts[5]; int contact_count = 0; float t = 1.0f; if( VectorLength(offset) ) { V3 point; int result = 0; int bytes = 0; u32 size = 0; int count = 0; char* shapes = manager->shapes; while(bytes < manager->used) { u32* t_shapes = (u32*)(shapes++); size = *t_shapes; if(size == RECT_SIZE) { Rect* r = (Rect*)(shapes + bytes); result = TestRectRect(rect, *r, &point); if(result) { Contact c = {}; c.p1 = ClosestPointOnRect(body->c, *r); c.p2 = ClosestPointOnRect(c.p1, rect); V3 dist = RVector3Sub(c.p1, c.p2); float tHit = Max(0.0f, VectorLength(dist) / VectorLength(offset) - epsilon); if(tHit < t) t = tHit; c.t = tHit; //c.d = CalculateClosingV(body->c, body->v, , ); Rect minkowski_rect = *r; VectorAdd(&minkowski_rect.d, rect.d); c.normal = GetRectNormal(minkowski_rect, body->c); contacts[contact_count++] = c; } } else if(size == SPHERE_SIZE) { Sphere* s = (Sphere*)(shapes + bytes); result = TestSphereRect(*s, rect, &point); if(result) { //TO DO: Create Contact } } else if(size == CAPSULE_SIZE) { Capsule* cap = (Capsule*)(shapes + bytes); result = TestCapsuleRect(*cap, rect); if(result) { } } else { //GJK } bytes += size; ++count; }//End of Entities //Calculate New Positions and Velocities VectorAdd(&body->c, RVector3Scale(offset, t)); if(t == 1.0f) break; { int contact = 0; while(contact < contact_count) { Contact* c = &contacts[contact++]; V3 normal = c->normal; V3 v = body->v; float contact_speed = Dot(normal, v); float dot = Dot(v, normal); VectorScalarMult(&normal, dot); VectorSubtract(&body->v, v, normal); normal = c->normal; dot = Dot(offset, normal); VectorScalarMult(&normal, dot); VectorSubtract(&offset, offset, normal); } } } else { break; } }//End of Iteration }
MSLVector Model3DRigid::Integrate(const MSLVector &x, const MSLVector &u, const double &h) { return EulerIntegrate(x,u,h); }
void timeStep(int step) { // animation code goes here // This function is called for each frame of animation double t = (double) (frame - startFrame) / (endFrame - startFrame); //translate player 2 if(keys[0]==true) { if (lockflag2 == 0 && playerflag == true) { t2trans[0] -= 0.3; if(t2trans[0] < 4) { t2trans[0] += 0.3; } } } if(keys[1] == true) { if (lockflag2 == 0 && playerflag == true) { t2trans[0]+= 0.3; if(t2trans[0] > 18) { t2trans[0] -= 0.3; } } } //rotate player 2 if(keys[2] == true) { if (lockflag2 == 0 && playerflag == true) { t2rotate -= 2; ang2 += 2; //print player 2's angle printf("\b");//backspaces on char printf("\r");//return to beginning of line printf("%d", ang2); if(t2rotate < -108) { t2rotate += 2; ang2 -= 2; } } } if(keys[3]==true) { if (lockflag2 == 0 && playerflag == true) { t2rotate += 2; ang2 -= 2; //print player 2's angle printf("\b");//backspaces on char printf("\r");//return to beginning of line printf("%d", ang2); if(t2rotate > -24) { t2rotate -= 2; ang2 += 2; } } } //translate player 1 if(keys[4]==true) { if (lockflag == 0 && playerflag == false) { t1trans[0] -= 0.3; if(t1trans[0] < -18) { t1trans[0] +=0.3; } } } if(keys[5] == true) { if (lockflag == 0 && playerflag == false) { t1trans[0] += 0.3; if(t1trans[0] > -4) { t1trans[0] -=0.3; } } } //rotate player 1 if(keys[6] == true) { if (lockflag == 0 && playerflag == false) { t1rotate += 1; ang1 += 1; //print player 1's angle printf("\b");//backspaces on char printf("\r");//return to beginning of line printf("%d", ang1); if(t1rotate > 228) { t1rotate -= 1; ang1 -= 1; } } } if(keys[7]==true) { if (lockflag == 0 && playerflag == false) { t1rotate -= 1; ang1 -= 1; //print player 1's angle printf("\b");//backspaces on char printf("\r");//return to beginning of line printf("%d", ang1); if(t1rotate < 140) { t1rotate += 1; ang1 += 1; } } } if (keys[8] == true) { if (lockflag == 0 && playerflag == false) { //powerct += 1; if (tcount-initpow >= .5) { //powerct = 100; endpow = .5; } else { //print player 1's power printf("\b");//backspaces on char printf("\r");//return to beginning of line //printf("%d", powerct); printf("%.0f", (tcount-initpow)*200); } } } if (keys[9] == true) { if (lockflag2 == 0 && playerflag == true) { //powerct2 += 1; if (tcount2-initpow2 >= .5) { // powerct2 = 100; endpow2 = .5; } else { //print player 2's power printf("\b");//backspaces on char printf("\r");//return to beginning of line //printf("%d", powerct2); printf("%.0f", (tcount2-initpow2)*200); } } } sheet1trans[1] = 3 + t * (3 - (8)); int i; if (lockflag == 1 && playerflag == false) { for (i=0; i<NUM_PARTICLES; i++) { //printf("pos[i][1]: %f\n", pos[i][1]); //printf("sheet[1]: %f\n", sheet1trans[1]); //printf("dif Y: %f\n", abs(pos[i][1] - sheet1trans[1])); //printf("dif X: %f\n", abs(pos[i][0] - sheet1trans[0])); if (((abs(pos[i][1] - sheet1trans[1]) < 5) && (abs(pos[i][0] - sheet1trans[0]) < .4))) { //printf("\nHIT SCREEN\n"); mass[i] = 1.0; vel[i][0] *= -1; hitflag = 0; stopflag1 = 1; } else if (pos[i][1] < -1 || (pos[i][0] < -20) || (pos[i][0] > 20)) { playerflag = true; printf("\nPLAYER 2's TURN\n"); mass[i] = 1.0; //pos[i][0] = 0.0; //pos[i][1] = 0.0; //pos[i][2] = 0.0; acc[i][0] = 0.0; acc[i][1] = 0.0; acc[i][2] = 0.0; force[i][0] = 0.0; force[i][1] = 0.0; force[i][2] = 0.0; bulletflag1 = 0; lockflag = 0; hitflag = 0; stopflag1 = 1; } } } if (lockflag2 == 1 && playerflag == true) { for (i=0; i<NUM_PARTICLES; i++) { if ((abs(pos2[i][1] - sheet1trans[1]) < 5) && (abs(pos2[i][0] - sheet1trans[0]) < .4)) { mass2[i] = 1.0; vel2[i][0] *= -1; hitflag2 = 0; stopflag2 = 1; } else if (pos2[i][1] < -1 || (pos2[i][0] > 20)|| (pos2[i][0] < -20)) { playerflag = false; printf("\nPLAYER 1's TURN\n"); mass2[i] = 1.0; acc2[i][0] = 0.0; acc2[i][1] = 0.0; acc2[i][2] = 0.0; force2[i][0] = 0.0; force2[i][1] = 0.0; force2[i][2] = 0.0; bulletflag2 = 0; lockflag2 = 0; hitflag2 = 0; stopflag2 = 1; } } } if (lockflag == 1 && playerflag == false) { sumForces(); EulerIntegrate(); } if (lockflag2 == 1 && playerflag == true) { sumForces2(); EulerIntegrate2(); } if (frame == endFrame) increment = -1; else if (frame == startFrame) increment = 1; frame = frame + increment; tcount += .01; tcount2 += .01; //printf("tcount = %f\n", tcount); display(); glutTimerFunc(50,timeStep, 0); }