protected boolean recoverFromPenetration(CollisionWorld collisionWorld) {
    boolean penetration = false;

    collisionWorld
        .getDispatcher()
        .dispatchAllCollisionPairs(
            ghostObject.getOverlappingPairCache(),
            collisionWorld.getDispatchInfo(),
            collisionWorld.getDispatcher());

    currentPosition.set(ghostObject.getWorldTransform(new Transform()).origin);

    double maxPen = 0.0f;
    for (int i = 0; i < ghostObject.getOverlappingPairCache().getNumOverlappingPairs(); i++) {
      manifoldArray.clear();

      BroadphasePair collisionPair =
          ghostObject.getOverlappingPairCache().getOverlappingPairArray().getQuick(i);

      if (collisionPair.algorithm != null) {
        collisionPair.algorithm.getAllContactManifolds(manifoldArray);
      }

      for (int j = 0; j < manifoldArray.size(); j++) {
        PersistentManifold manifold = manifoldArray.getQuick(j);
        double directionSign = manifold.getBody0() == ghostObject ? -1.0f : 1.0f;
        for (int p = 0; p < manifold.getNumContacts(); p++) {
          ManifoldPoint pt = manifold.getContactPoint(p);

          double dist = pt.getDistance();
          if (dist < 0.0f) {
            if (dist < maxPen) {
              maxPen = dist;
              touchingNormal.set(pt.normalWorldOnB); // ??
              touchingNormal.scale(directionSign);
            }

            currentPosition.scaleAdd(
                directionSign * dist * 0.2f, pt.normalWorldOnB, currentPosition);

            penetration = true;
          } else {
            // printf("touching %f\n", dist);
          }
        }

        // manifold->clearManifold();
      }
    }

    Transform newTrans = ghostObject.getWorldTransform(new Transform());
    newTrans.origin.set(currentPosition);
    ghostObject.setWorldTransform(newTrans);
    // printf("m_touchingNormal =
    // %f,%f,%f\n",m_touchingNormal[0],m_touchingNormal[1],m_touchingNormal[2]);

    // System.out.println("recoverFromPenetration "+penetration+" "+touchingNormal);

    return penetration;
  }
    @Override
    public boolean needsCollision(BroadphaseProxy proxy0) {
      // don't collide with itself
      if (proxy0.clientObject == me) {
        return false;
      }

      // don't do CCD when the collision filters are not matching
      if (!super.needsCollision(proxy0)) {
        return false;
      }

      CollisionObject otherObj = (CollisionObject) proxy0.clientObject;

      // call needsResponse, see http://code.google.com/p/bullet/issues/detail?id=179
      if (dispatcher.needsResponse(me, otherObj)) {
        // don't do CCD when there are already contact points (touching contact/penetration)
        ObjectArrayList<PersistentManifold> manifoldArray =
            new ObjectArrayList<PersistentManifold>();
        BroadphasePair collisionPair = pairCache.findPair(me.getBroadphaseHandle(), proxy0);
        if (collisionPair != null) {
          if (collisionPair.algorithm != null) {
            // manifoldArray.resize(0);
            collisionPair.algorithm.getAllContactManifolds(manifoldArray);
            for (int j = 0; j < manifoldArray.size(); j++) {
              PersistentManifold manifold = manifoldArray.getQuick(j);
              if (manifold.getNumContacts() > 0) {
                return false;
              }
            }
          }
        }
      }
      return true;
    }
示例#3
0
  void updateServerElements() {
    for (RigidBody rb : rigidBodies) {
      ServerElement element = rigidBodyToServerElement.get(rb);
      if (rb != null && rb.getMotionState() != null) {
        rb.getMotionState().getWorldTransform(tmpTrans);
        element.setTransform(tmpTrans);
      }
      if (!rb.isActive()) {
        rb.activate();
      }
      // log.debug(" "+element.getPosition());
    }

    for (Integer id : serverGameArea.getGameState().getDynamicElements().keySet()) {
      ServerElement elem = serverGameArea.getGameState().getDynamicElements().get(id);
      elem.getCollidees().clear();
    }

    Integer nbManifold = dynamicsWorld.getDispatcher().getNumManifolds();
    for (Integer i = 0; i < nbManifold; i++) {
      PersistentManifold pm = dynamicsWorld.getDispatcher().getManifoldByIndexInternal(i);
      RigidBody rb0 = (RigidBody) pm.getBody0();
      RigidBody rb1 = (RigidBody) pm.getBody1();

      ServerElement elem0 = rigidBodyToServerElement.get(rb0);
      ServerElement elem1 = rigidBodyToServerElement.get(rb1);

      if ((elem0 instanceof ServerBullet) || (elem1 instanceof ServerBullet)) {
        log.info("coll " + elem0 + " " + elem1);
      }

      elem0.addCollidee(elem1);
      elem1.addCollidee(elem0);
    }
  }
示例#4
0
  public float reactionForce() {
    float force = 0;
    int totalContacts = 0;

    for (PersistentManifold m : contactManifolds) {

      int numContacts = m.getNumContacts();
      totalContacts += numContacts;

      for (int i = 0; i < numContacts; ++i) {
        ManifoldPoint p = m.getContactPoint(i);
        force += p.appliedImpulse;
      }
    }

    return totalContacts != 0 ? force / totalContacts : 0;
  }
  @Override
  public void debugDrawWorld() {
    if (getDebugDrawer() != null
        && (getDebugDrawer().getDebugMode() & DebugDrawModes.DRAW_CONTACT_POINTS) != 0) {
      int numManifolds = getDispatcher().getNumManifolds();
      Vector3f color = Stack.alloc(Vector3f.class);
      color.set(0f, 0f, 0f);
      for (int i = 0; i < numManifolds; i++) {
        PersistentManifold contactManifold = getDispatcher().getManifoldByIndexInternal(i);
        // btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
        // btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());

        int numContacts = contactManifold.getNumContacts();
        for (int j = 0; j < numContacts; j++) {
          ManifoldPoint cp = contactManifold.getContactPoint(j);
          getDebugDrawer()
              .drawContactPoint(
                  cp.positionWorldOnB,
                  cp.normalWorldOnB,
                  cp.getDistance(),
                  cp.getLifeTime(),
                  color);
        }
      }
    }

    if (getDebugDrawer() != null
        && (getDebugDrawer().getDebugMode()
                & (DebugDrawModes.DRAW_WIREFRAME | DebugDrawModes.DRAW_AABB))
            != 0) {
      int i;

      Transform tmpTrans = Stack.alloc(Transform.class);
      Vector3f minAabb = Stack.alloc(Vector3f.class);
      Vector3f maxAabb = Stack.alloc(Vector3f.class);
      Vector3f colorvec = Stack.alloc(Vector3f.class);

      // todo: iterate over awake simulation islands!
      for (i = 0; i < collisionObjects.size(); i++) {
        CollisionObject colObj = collisionObjects.getQuick(i);
        if (getDebugDrawer() != null
            && (getDebugDrawer().getDebugMode() & DebugDrawModes.DRAW_WIREFRAME) != 0) {
          Vector3f color = Stack.alloc(Vector3f.class);
          color.set(255f, 255f, 255f);
          switch (colObj.getActivationState()) {
            case CollisionObject.ACTIVE_TAG:
              color.set(255f, 255f, 255f);
              break;
            case CollisionObject.ISLAND_SLEEPING:
              color.set(0f, 255f, 0f);
              break;
            case CollisionObject.WANTS_DEACTIVATION:
              color.set(0f, 255f, 255f);
              break;
            case CollisionObject.DISABLE_DEACTIVATION:
              color.set(255f, 0f, 0f);
              break;
            case CollisionObject.DISABLE_SIMULATION:
              color.set(255f, 255f, 0f);
              break;
            default:
              {
                color.set(255f, 0f, 0f);
              }
          }

          debugDrawObject(colObj.getWorldTransform(tmpTrans), colObj.getCollisionShape(), color);
        }
        if (debugDrawer != null && (debugDrawer.getDebugMode() & DebugDrawModes.DRAW_AABB) != 0) {
          colorvec.set(1f, 0f, 0f);
          colObj.getCollisionShape().getAabb(colObj.getWorldTransform(tmpTrans), minAabb, maxAabb);
          debugDrawer.drawAabb(minAabb, maxAabb, colorvec);
        }
      }

      Vector3f wheelColor = Stack.alloc(Vector3f.class);
      Vector3f wheelPosWS = Stack.alloc(Vector3f.class);
      Vector3f axle = Stack.alloc(Vector3f.class);
      Vector3f tmp = Stack.alloc(Vector3f.class);

      for (i = 0; i < vehicles.size(); i++) {
        for (int v = 0; v < vehicles.getQuick(i).getNumWheels(); v++) {
          wheelColor.set(0, 255, 255);
          if (vehicles.getQuick(i).getWheelInfo(v).raycastInfo.isInContact) {
            wheelColor.set(0, 0, 255);
          } else {
            wheelColor.set(255, 0, 255);
          }

          wheelPosWS.set(vehicles.getQuick(i).getWheelInfo(v).worldTransform.origin);

          axle.set(
              vehicles
                  .getQuick(i)
                  .getWheelInfo(v)
                  .worldTransform
                  .basis
                  .getElement(0, vehicles.getQuick(i).getRightAxis()),
              vehicles
                  .getQuick(i)
                  .getWheelInfo(v)
                  .worldTransform
                  .basis
                  .getElement(1, vehicles.getQuick(i).getRightAxis()),
              vehicles
                  .getQuick(i)
                  .getWheelInfo(v)
                  .worldTransform
                  .basis
                  .getElement(2, vehicles.getQuick(i).getRightAxis()));

          // m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_wheelAxleWS
          // debug wheels (cylinders)
          tmp.add(wheelPosWS, axle);
          debugDrawer.drawLine(wheelPosWS, tmp, wheelColor);
          debugDrawer.drawLine(
              wheelPosWS,
              vehicles.getQuick(i).getWheelInfo(v).raycastInfo.contactPointWS,
              wheelColor);
        }
      }

      if (getDebugDrawer() != null && getDebugDrawer().getDebugMode() != 0) {
        for (i = 0; i < actions.size(); i++) {
          actions.getQuick(i).debugDraw(debugDrawer);
        }
      }
    }
  }