/**
   * @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;
  }
Esempio n. 2
0
  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();
    // }

  }