/** Render the current frame */ private static void render() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(30f, aspect, 1f, 10000000f); float look = anchorL.z * 5; gluLookAt(look, look, anchorL.z, 0, 0, 0, 0, 0, 1); glClearColor(.5f, 0.5f, 0.5f, .5f); // clear the screen glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); { // int systemDimLength = cube.sideLength / 2; // rotate square according to angle glRotatef(angle, 0, 0, 1.0f); // glColor3f(1f, 1f, 1f); // cube.glSurfaceDraw(); /* * Draw the particle in the system */ glColor3f(0.0f, 1.0f, 0.0f); glPointSize(3.0f); /* * glBegin(GL_POINTS); { for (Particle p : system) { * glVertex3f(p.x.x, p.x.y, p.x.z); } } glEnd(); */ /* * Draw the lines */ glLineWidth(2.0f); for (Constraint p : constraints) { glBegin(GL_LINES); { glVertex3f(p.getA().x.x, p.getA().x.y, p.getA().x.z); glVertex3f(p.getB().x.x, p.getB().x.y, p.getB().x.z); } glEnd(); } /* * Shadows, just for effect! */ glColor4f(0, 0, 0, .5f); /* * glBegin(GL_POINTS); { for (Particle p : system) { * glVertex3f(p.x.x, p.x.y, -systemDimLength); } } glEnd(); */ /* * Draw the line shadows */ for (Constraint p : constraints) { glBegin(GL_LINES); { glVertex3f(p.getA().x.x, p.getA().x.y, -0); glVertex3f(p.getB().x.x, p.getB().x.y, -0); } glEnd(); } glBegin(GL_LINES); { glVertex3f(anchorL.x, anchorL.y, -0); glVertex3f(anchorR.x, anchorR.y, -0); } glEnd(); glColor3f(1, 0, 0); /* * Draw the tension line */ glBegin(GL_LINES); { glVertex3f(anchorL.x, anchorL.y, -0); glVertex3f(anchorL.x, anchorL.y, anchorL.z); glVertex3f(anchorL.x, anchorL.y, anchorL.z); glVertex3f(anchorR.x, anchorR.y, anchorR.z); glVertex3f(anchorR.x, anchorR.y, anchorR.z); glVertex3f(anchorR.x, anchorR.y, -0); } glEnd(); } glPopMatrix(); }
/** Do all calculations, handle input, etc. */ private static void logic() { if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) { finished = true; } int dx = Mouse.getDX(), dy = Mouse.getDY(), dz = Mouse.getDWheel(); if (Mouse.isButtonDown(0) && Mouse.isInsideWindow()) { Vector3 d = new Vector3(dx, dy, 0); anchorL = anchorL.sub(d); anchorR = anchorR.sub(d); } if (Mouse.isButtonDown(1) && Mouse.isInsideWindow()) { Vector3 d = new Vector3(0, dy, 0); anchorL = anchorL.sub(d); anchorR = anchorR.add(d); } Vector3 zChange = new Vector3(0, 0, dz / 4); anchorL = anchorL.add(zChange); anchorR = anchorR.add(zChange); /* * Move those particles! */ // Clear force accumulator for (Particle p : system) p.clearForces(); // Accumulate forces for (Particle p : system) p.addForce(gravity); // Integrate for (Particle p : system) NewtonianIntegrators.verlet(p, stepSize); /* * Formal and informal constraint check. */ for (int i = 0; i < integrationIterations; i++) { cloth[0][0][0].x = anchorL; cloth[cloth[0].length / 2][0][0].x = anchorL.add(anchorR).scale(.5f); cloth[cloth[0].length - 1][0][0].x = anchorR; // bounds check float dragFloat = 10; Vector3 zFloor = new Vector3(0, 0, 1); for (Particle p : system) { if (p.x.z <= 0 + 1) { p.x = p.x.add(zFloor); p.xOld = p.x.add(p.xOld.scale(dragFloat)).scale(1f / (dragFloat + 1)); } } // for (Particle p : system) { // if (cube.isWithin(p.x)) { // cube.escape(p); // } // } for (Constraint c : constraints) c.satisfy(); } }