import sys, time, math from OpenGL.GL import * from OpenGL.GLU import * from OpenGL.GLUT import * from dmsgl import * camera = OrthoCamera(-25,25, 0,50, -25,25) light = Light() GravityAccel = Vector([0, -9.8, 0]) AirDrag = 1 BounceCoeff = 0.8 class Object: def __init__(self, pos=Vector([0,0,0]), vel=Vector([0,0,0]), mass=1.0, radius=1.0, material=Material()): self.pos = pos self.vel = vel self.mass = mass self.radius = radius self.material = material self.force = Vector([0, 0, 0]) self.mobile = True def draw(self): self.material.apply() glPushMatrix() glTranslatef(self.pos[0], self.pos[1], self.pos[2]) gluSphere(quadric, self.radius, 16, 8) glPopMatrix() self.material.disable() def calculateForce(self): self.force = Vector([0, 0, 0]) self.force += self.mass * GravityAccel self.force -= self.vel * AirDrag def update(self, dt): if self.mobile: acc = self.force / self.mass self.vel += acc * dt self.pos += self.vel * dt if self.pos[1] < 0 and self.vel[1] < 0: self.vel[1] = -self.vel[1] * BounceCoeff class Spring: def __init__(self, obj1, obj2, restLength=-1, k=1): self.obj1 = obj1 self.obj2 = obj2 if restLength >= 0: self.restLength = restLength else: self.restLength = obj1.pos.distance(obj2.pos) self.k = k def draw(self): Color.Red.apply() glBegin(GL_LINES) glVertex3fv(self.obj1.pos) glVertex3fv(self.obj2.pos) glEnd() def calculateForce(self): v = self.obj2.pos - self.obj1.pos displacement = v.length() - self.restLength v.normalize() force = self.k * displacement * v self.obj1.force += force self.obj2.force -= force num = 10 objects = [] for i in range(0,num): objects.append(Object(pos=Vector([i*10.0/num, 30, 0]), mass=10.0, radius=1.0, material=Material(diffuse=Color.Green))) objects[0].mobile = False springs = [] for i in range(0,num-1): springs.append(Spring(objects[i],objects[i+1],k=400)) active = False def draw(): Color.Black.clear() camera.apply() light.apply() for o in objects: o.draw() for s in springs: s.draw() glutSwapBuffers() def keyboard(key, x, y): global active if key == chr(27): sys.exit(0) elif key == ' ': active = not active elif key == 'r': objects[0].mobile = True prevTime = time.time() def update(): global prevTime, active t = time.time() dt = t - prevTime prevTime = t if active: for o in objects: o.calculateForce() for s in springs: s.calculateForce() for o in objects: o.update(dt) glutPostRedisplay() glutInit([]) glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH) glutInitWindowSize(400,400) glutCreateWindow(sys.argv[0]) glutDisplayFunc(draw) glutKeyboardFunc(keyboard) glutIdleFunc(update) glEnable(GL_DEPTH_TEST) quadric = gluNewQuadric() glutMainLoop()