/** * @param f - fixture that is affected * @return true if force was applied, false otherwise. */ private boolean ApplyToFixture(Fixture f) { float shapeDensity = mUseDensity ? f.getDensity() : mFluidDensity; // don't bother with buoyancy on sensors or fixtures with no density if (f.isSensor() || (shapeDensity == 0)) { return false; } Body body = f.getBody(); mAreac.set(Vector2.Zero); mMassc.set(Vector2.Zero); float area = 0; // Get shape for displacement area calculations Shape shape = f.getShape(); mSC.set(Vector2.Zero); float sarea; switch (shape.getType()) { case Circle: sarea = B2ShapeExtensions.ComputeSubmergedArea( (CircleShape) shape, mSurfaceNormal, mSurfaceHeight, body.getTransform(), mSC); break; case Chain: sarea = B2ShapeExtensions.ComputeSubmergedArea( (ChainShape) shape, mSurfaceNormal, mSurfaceHeight, body.getTransform(), mSC); break; case Edge: sarea = B2ShapeExtensions.ComputeSubmergedArea( (EdgeShape) shape, mSurfaceNormal, mSurfaceHeight, body.getTransform(), mSC); break; case Polygon: sarea = B2ShapeExtensions.ComputeSubmergedArea( (PolygonShape) shape, mSurfaceNormal, mSurfaceHeight, body.getTransform(), mSC); break; default: sarea = 0; break; } area += sarea; mAreac.x += sarea * mSC.x; mAreac.y += sarea * mSC.y; float mass = sarea * shapeDensity; mMassc.x += sarea * mSC.x * shapeDensity; mMassc.y += sarea * mSC.y * shapeDensity; mAreac.x /= area; mAreac.y /= area; mMassc.x /= mass; mMassc.y /= mass; if (area < Float.MIN_VALUE) { return false; } if (DEBUG_BUOYANCY) { // Run debug w/HCR to see the effects of different fluid densities / linear drag mFluidDensity = 2f; mLinearDrag = 5; mAngularDrag = 2; } // buoyancy force. mTmp.set(mGravity).scl(-mFluidDensity * area); body.applyForce(mTmp, mMassc, true); // multiply by -density to invert gravity // linear drag. mTmp.set( body.getLinearVelocityFromWorldPoint(mAreac).sub(mFluidVelocity).mul(-mLinearDrag * area)); body.applyForce(mTmp, mAreac, true); // angular drag. float bodyMass = body.getMass(); if (bodyMass < 1) // prevent a huge torque from being generated... { bodyMass = 1; } float torque = -body.getInertia() / bodyMass * area * body.getAngularVelocity() * mAngularDrag; body.applyTorque(torque, true); return true; }
public void draw(Matrix4 mat) { if (!body.isActive()) { return; } Transform transform = body.getTransform(); texture.bind(); shader.begin(); shader.setUniformMatrix("u_projectionViewMatrix", mat); for (FixtureData data : fixtureData) { data.updateData(transform); data.mesh.render(shader, GL20.GL_TRIANGLE_FAN, 0, data.vertices.length); } shader.end(); // chain.getVertex(0, v0); // transform.mul(v0); // chain.getVertex(1, v1); // transform.mul(v1); // chain.getVertex(2, v2); // transform.mul(v2); // chain.getVertex(3, v3); // transform.mul(v3); // mesh.setVertices(new float[] { -5f, -5f, 0, 0, 1, // bottom left // 5f, -5f, 0, 1, 1, // bottom right // 5f, 5f, 0, 1, 0, // top right // -5f, 5f, 0, 0, 0 }); // top left // // mesh.setVertices(new float[] { v0.x, v0.y, 0, 0, 1, // bottom left // v1.x, v1.y, 0, 1, 1, // bottom right // v2.x, v2.y, 0, 1, 0, // top right // v3.x, v3.y, 0, 0, 0 }); // top left // System.out.println("--"); // Vector2 before = new Vector2(); // Vector2 current = new Vector2(); // Vector2 after = new Vector2(); // for (int i = 0; i < meshes.length; i++) { // Fixture fixture = body.getFixtureList().get(i); // PolygonShape poly = (PolygonShape) fixture.getShape(); // // for (int j = 0; j < meshesData[i].length; j += 6) { // int polyIndex = j / 6; // poly.getVertex(polyIndex, current); // // // if (scale) { // // poly.getVertex(polyIndex == 0 ? poly.getVertexCount() - 1 : // polyIndex - 1, before); // // poly.getVertex(polyIndex == poly.getVertexCount() - 1 ? 0 : // polyIndex + 1, after); // // // // Vector2D vec1 = new Vector2D(new Point2D(after.x, after.y), new // Point2D(current.x, current.y)); // // Vector2D vec2 = new Vector2D(new Point2D(before.x, before.y), new // Point2D(current.x, current.y)); // // // // double a1 = vec1.getAngle(); // // double a2 = vec2.getAngle(); // // double diff = a1 - a2; // // double angle = (a1 + a2) / 2.0; // // // // if (diff > 0) { // // angle -= Math.PI; // // } // // // // System.out.println("angle1 " + a1 * 180 / Math.PI); // // System.out.println("angle2 " + a2 * 180 / Math.PI); // // System.out.println("diff " + diff * 180 / Math.PI); // // System.out.println("center " + angle * 180 / Math.PI); // // // // Vector2D sum = new Vector2D(Math.cos(angle) * 0.2, Math.sin(angle) * // 0.2); // // sum.normalize(); // // // // sum = sum.times(0.2); // // // // Vector2 newPoint = new Vector2(current.x + (float) sum.getX(), // current.y + (float) sum.getY()); // // // // transform.mul(newPoint); // // // // transform.mul(current); // // // // // poly.getVertex(polyIndex, newPoint); // // // newPoint.mul(1.2f); // // // transform.mul(newPoint); // // // // // batch.begin(); // // // batch.draw(texture, current.x * 20 + 200, current.y * 20 + 200); // // // batch.draw(texture2, newPoint.x * 20 + 200, newPoint.y * 20 + // 200); // // // batch.end(); // // } // // transform.mul(current); // // meshesData[i][j] = current.x; // meshesData[i][j + 1] = current.y; // meshesData[i][j + 2] = 0; // // meshesData[i][j + 3] = colors[(color + i) % colors.length]; // // meshesData[i][j + 4] = (float) Math.random(); // meshesData[i][j + 5] = (float) Math.random(); // } // // // render // meshes[i].setVertices(meshesData[i]); // // shader.begin(); // shader.setUniformMatrix("u_projectionViewMatrix", mat); // texture.bind(); // meshes[i].render(shader, GL20.GL_TRIANGLE_FAN, 0, // poly.getVertexCount()); // shader.end(); // } }