convexParticle method

bool convexParticle(
  1. ConvexPolyhedron sj,
  2. Particle si,
  3. Vec3 xj,
  4. Vec3 xi,
  5. Quaternion qj,
  6. Quaternion qi,
  7. Body bj,
  8. Body bi, [
  9. Shape? rsi,
  10. Shape? rsj,
  11. bool justTest = false,
])

Implementation

bool convexParticle(
  ConvexPolyhedron sj,
  Particle si,
  Vec3 xj,
  Vec3 xi,
  Quaternion qj,
  Quaternion qi,
  Body bj,
  Body bi,
  [
    Shape? rsi,
    Shape? rsj,
    bool justTest = false
]){
  int penetratedFaceIndex = -1;
  final penetratedFaceNormal = _convexParticlePenetratedFaceNormal;
  final worldPenetrationVec = _convexParticleWorldPenetrationVec;
  double? minPenetration;
  //int numDetectedFaces = 0;

  // Convert particle position xi to local coords in the convex
  final local = _convexParticleLocal;
  final cqj = Quaternion();
  local.copy(xi);
  local.vsub(xj, local); // Convert position to relative the convex origin
  qj.conjugate(cqj);
  cqj.vmult(local, local);

  if (sj.pointIsInside(local)) {
    //if (true|| sj.worldVerticesNeedsUpdate) {
      sj.computeWorldVertices(xj, qj);
    //}
    if (sj.worldFaceNormalsNeedsUpdate) {
      sj.computeWorldFaceNormals(qj);
    }

    // For each world polygon in the polyhedra
    for (int i = 0, nfaces = sj.faces.length; i != nfaces; i++) {
      // Construct world face vertices
      final verts = sj.worldVertices[sj.faces[i][0]];
      final normal = sj.worldFaceNormals[i];
      final convexParticleVertexToParticle = Vec3();
      // Check how much the particle penetrates the polygon plane.
      xi.vsub(verts, convexParticleVertexToParticle);
      final penetration = -normal.dot(convexParticleVertexToParticle);
      if (minPenetration == null || penetration.abs() < minPenetration.abs()) {
        if (justTest) {
          return true;
        }

        minPenetration = penetration;
        penetratedFaceIndex = i;
        penetratedFaceNormal.copy(normal);
        //numDetectedFaces++;
      }
    }

    if (penetratedFaceIndex != -1) {
      // Setup contact
      var r = createContactEquation(bi, bj, si, sj, rsi, rsj);
      penetratedFaceNormal.scale(minPenetration!, worldPenetrationVec);
      // rj is the particle position projected to the face
      worldPenetrationVec.vadd(xi, worldPenetrationVec);
      worldPenetrationVec.vsub(xj, worldPenetrationVec);
      r.rj.copy(worldPenetrationVec);
      //final projectedToFace = xi.vsub(xj).vadd(worldPenetrationVec);
      //projectedToFace.copy(r.rj);

      //qj.vmult(r.rj,r.rj);
      penetratedFaceNormal.negate(r.ni); // Contact normal
      r.ri.set(0, 0, 0); // Center of particle

      // Make relative to bodies
      r.ri.vadd(xi, r.ri);
      r.ri.vsub(bi.position, r.ri);
      r.rj.vadd(xj, r.rj);
      r.rj.vsub(bj.position, r.rj);

      result.add(r);
      createFrictionEquationsFromContact(r, frictionResult);
    }
    else {
      //print('Point found inside convex, but did not find penetrating face!');
    }
  }
  return false;
}