use of artisynth.core.mechmodels.Collidable.Group in project artisynth_core by artisynth.
the class CollisionRenderer method prerender.
public void prerender(CollisionHandler handler, RenderProps props) {
RenderObject ro = new RenderObject();
ro.clearAll();
// constraints
ro.createLineGroup();
// segments
ro.createLineGroup();
// contours
ro.createLineGroup();
// contact info
ro.createPointGroup();
// intersection faces
ro.createTriangleGroup();
// create default dummy normal
ro.addNormal(0, 0, 0);
CollisionBehavior behav = handler.myBehavior;
ContactInfo cinfo = handler.getLastContactInfo();
if (behav.myDrawConstraints) {
ro.lineGroup(CONSTRAINT_GRP);
double nrmlLen = handler.getContactNormalLen();
if (nrmlLen > 0) {
addConstraintRenderInfo(ro, handler.myBilaterals0.values(), nrmlLen);
addConstraintRenderInfo(ro, handler.myBilaterals1.values(), nrmlLen);
addConstraintRenderInfo(ro, handler.myUnilaterals, nrmlLen);
}
}
double normalLen = 0;
if (behav.getDrawContactNormals()) {
normalLen = handler.getContactNormalLen();
}
if (normalLen != 0 && cinfo != null) {
ro.lineGroup(SEGMENT_GRP);
Method method = handler.getMethod();
if (method == Method.CONTOUR_REGION) {
int numc = 0;
for (ContactPlane region : cinfo.getContactPlanes()) {
for (Point3d p : region.points) {
if (numc >= handler.myMaxUnilaterals) {
break;
}
addLineSeg(ro, p, region.normal, normalLen);
}
}
} else if (method != Method.INACTIVE) {
for (ContactConstraint cc : handler.myBilaterals0.values()) {
maybeAddVertexFaceNormal(ro, cc, normalLen);
}
for (ContactConstraint cc : handler.myBilaterals1.values()) {
maybeAddVertexFaceNormal(ro, cc, normalLen);
}
}
}
if (behav.myDrawIntersectionContours && props.getEdgeWidth() > 0 && cinfo != null) {
ro.lineGroup(CONTOUR_GRP);
// offset lines
if (cinfo.getContours() != null) {
for (IntersectionContour contour : cinfo.getContours()) {
int vidx0 = ro.numVertices();
for (IntersectionPoint p : contour) {
ro.addVertex(ro.addPosition((float) p.x, (float) p.y, (float) p.z));
}
int vidx1 = ro.numVertices() - 1;
ro.addLineLoop(vidx0, vidx1);
}
} else if (cinfo.getIntersections() != null) {
// use intersections to render lines
for (TriTriIntersection tsect : cinfo.getIntersections()) {
addLineSeg(ro, tsect.points[0], tsect.points[1]);
}
}
}
if (behav.myDrawIntersectionPoints && cinfo != null) {
if (cinfo.getIntersections() != null) {
for (TriTriIntersection tsect : cinfo.getIntersections()) {
for (Point3d pnt : tsect.points) {
addPoint(ro, pnt);
}
}
}
for (PenetratingPoint cpp : cinfo.getPenetratingPoints(0)) {
if (cpp.distance > 0) {
addPoint(ro, cpp.vertex.getWorldPoint());
}
}
for (PenetratingPoint cpp : cinfo.getPenetratingPoints(1)) {
if (cpp.distance > 0) {
addPoint(ro, cpp.vertex.getWorldPoint());
}
}
if (behav.getMethod() == CollisionBehavior.Method.VERTEX_EDGE_PENETRATION) {
if (cinfo.getEdgeEdgeContacts() != null) {
for (EdgeEdgeContact eec : cinfo.getEdgeEdgeContacts()) {
addPoint(ro, eec.point0);
addPoint(ro, eec.point1);
}
}
}
}
if (behav.myDrawIntersectionFaces && cinfo != null) {
ArrayList<TriTriIntersection> intersections = cinfo.getIntersections();
if (intersections != null) {
buildFaceSegments(ro, handler, intersections);
}
}
RenderObject oldRob = myRob;
myRob = ro;
// if (oldRob != null) {
// oldRob.dispose();
// }
RenderObject rd = null;
if (behav.myDrawPenetrationDepth != -1 && cinfo != null) {
int num = behav.myDrawPenetrationDepth;
Collidable b0 = behav.getCollidable(0);
CollidableBody h0 = handler.getCollidable(0);
if (!(b0 instanceof Group)) {
if (h0 != b0 && h0.getCollidableAncestor() != b0) {
// then we want the *other* collidable body, so switch num
num = (num == 0 ? 1 : 0);
}
}
ArrayList<PenetrationRegion> regions;
ArrayList<PenetratingPoint> points;
if (num == 0) {
regions = cinfo.getRegions(0);
points = cinfo.getPenetratingPoints(0);
} else {
regions = cinfo.getRegions(1);
points = cinfo.getPenetratingPoints(1);
}
if (regions != null && regions.size() > 0) {
rd = createPenetrationRenderObject(handler, points, regions);
}
}
oldRob = myDepthRob;
myDepthRob = rd;
// if (oldRob != null) {
// oldRob.dispose();
// }
}
use of artisynth.core.mechmodels.Collidable.Group in project artisynth_core by artisynth.
the class CollisionManagerTest method pairMatches.
private boolean pairMatches(CollidablePair pair, CollidableBody cb0, CollidableBody cb1) {
Collidable c0 = pair.get(0);
Collidable c1 = pair.get(1);
Collidable an0 = cb0.getCollidableAncestor();
Collidable an1 = cb1.getCollidableAncestor();
if (c1 instanceof Group) {
Group g1 = (Group) c1;
if (an0 == an1 && an0 != null) {
return ((an0 == c0 || cb0 == c0 || cb1 == c0) && g1.includesSelf());
} else {
if (g1.includesRigid()) {
if (isBody(c0)) {
if ((cb0 == c0 && !cb1.isDeformable()) || (cb1 == c0 && !cb0.isDeformable())) {
return true;
}
} else {
if ((an0 == c0 && !cb1.isDeformable()) || (an1 == c0 && !cb0.isDeformable())) {
return true;
}
}
}
if (g1.includesDeformable()) {
if (isBody(c0)) {
if ((cb0 == c0 && cb1.isDeformable()) || (cb1 == c0 && cb0.isDeformable())) {
return true;
}
} else {
if ((an0 == c0 && cb1.isDeformable()) || (an1 == c0 && cb0.isDeformable())) {
return true;
}
}
}
}
return false;
} else {
if (isBody(c0) && isBody(c1)) {
return ((c0 == cb0 && c1 == cb1) || (c0 == cb1 && c1 == cb0));
} else if (isBody(c0)) {
return ((c0 == cb0 && c1 == an1) || (c0 == an1 && c1 == cb0));
} else if (isBody(c1)) {
return ((c0 == an0 && c1 == cb1) || (c0 == an1 && c1 == cb0));
} else {
return ((c0 == an0 && c1 == an1) || (c0 == an1 && c1 == an0));
}
}
}
use of artisynth.core.mechmodels.Collidable.Group in project artisynth_core by artisynth.
the class CollisionManagerTest method testSetDefaults.
// CollisionBehavior getBehavior (String name0, String name1) {
// Collidable col0 = findCollidable(name0);
// Collidable col1 = findCollidable(name1);
// return myMech.getCollisionBehavior (col0, col1);
// }
void testSetDefaults() {
Group[] groups = new Group[] { Collidable.All, Collidable.Rigid, Collidable.Deformable, Collidable.AllBodies, Collidable.Self };
double cnt = 0.0;
for (int i = 0; i < groups.length; i++) {
Group gi = groups[i];
for (int j = 0; j < groups.length; j++) {
Group gj = groups[j];
if (!(gi == Collidable.Self && gj == Collidable.Rigid) && !(gi == Collidable.Rigid && gj == Collidable.Self) && !(gi == Collidable.Self && gj == Collidable.Self)) {
setDefaultBehavior(gi, gj, true, cnt++);
}
}
}
setDefaultBehavior(Collidable.Rigid, Collidable.Rigid, false, 0);
setDefaultBehavior(Collidable.Deformable, Collidable.Rigid, false, 0);
setDefaultBehavior(Collidable.Deformable, Collidable.Deformable, false, 0);
setDefaultBehavior(Collidable.Deformable, Collidable.Self, false, 0);
}
use of artisynth.core.mechmodels.Collidable.Group in project artisynth_core by artisynth.
the class CollisionManagerTest method checkCollisionResponse.
private void checkCollisionResponse(Collidable c0, ArrayList<CollidableBody> cbodies, Collidable c1) {
CollisionResponse resp = myMech.getCollisionResponse(c0, c1);
HashSet<CollisionHandler> expectedHandlers = new HashSet<CollisionHandler>();
HashSet<CollisionHandler> responseHandlers = new HashSet<CollisionHandler>();
Group g1 = null;
if (c1 instanceof Group) {
g1 = (Group) c1;
}
if (c0 == c1 || (g1 != null && g1.includesSelf())) {
// check for self intersection handlers
if (c0.isDeformable() && c0.isCompound()) {
ArrayList<CollidableBody> ibods0 = CollisionManager.getInternallyCollidableBodies(c0);
for (int i = 0; i < ibods0.size(); i++) {
CollidableBody cbi = ibods0.get(i);
for (int j = i + 1; j < ibods0.size(); j++) {
CollidableBody cbj = ibods0.get(j);
CollisionHandler ch = getHandler(cbi, cbj);
if (ch != null) {
expectedHandlers.add(ch);
}
}
}
}
}
if (g1 != null) {
if (g1.includesRigid() || g1.includesDeformable()) {
ArrayList<CollidableBody> ebods0 = CollisionManager.getExternallyCollidableBodies(c0);
for (int i = 0; i < ebods0.size(); i++) {
CollidableBody cbi = ebods0.get(i);
for (int j = 0; j < cbodies.size(); j++) {
CollidableBody cbj = cbodies.get(j);
if (!hasCommonAncestor(cbi, cbj)) {
// filter out internal collisions
if ((g1.includesRigid() && !cbj.isDeformable()) || (g1.includesDeformable() && cbj.isDeformable())) {
CollisionHandler ch = getHandler(cbi, cbj);
if (ch != null) {
expectedHandlers.add(ch);
}
}
}
}
}
}
} else {
if (hasCommonAncestor(c0, c1)) {
// both c0 and c1 must be bodies - just check for internal
// collisions
CollisionHandler ch = getHandler((CollidableBody) c0, (CollidableBody) c1);
if (ch != null) {
expectedHandlers.add(ch);
}
} else {
ArrayList<CollidableBody> ebods0 = CollisionManager.getExternallyCollidableBodies(c0);
ArrayList<CollidableBody> ebods1 = CollisionManager.getExternallyCollidableBodies(c1);
for (int i = 0; i < ebods0.size(); i++) {
CollidableBody cbi = ebods0.get(i);
for (int j = 0; j < ebods1.size(); j++) {
CollidableBody cbj = ebods1.get(j);
if (!hasCommonAncestor(cbi, cbj)) {
CollisionHandler ch = getHandler(cbi, cbj);
if (ch != null) {
expectedHandlers.add(ch);
}
}
}
}
}
}
ArrayList<CollisionHandler> handlers = resp.getHandlers();
responseHandlers.addAll(handlers);
if (handlers.size() != responseHandlers.size()) {
System.out.println("handlers:");
for (CollisionHandler ch : handlers) {
System.out.println(" " + ch.getCollidablePair());
}
throw new TestException("Redundant response handlers detected for " + new CollidablePair(c0, c1));
}
if (!expectedHandlers.equals(responseHandlers)) {
System.out.println("responseHandlers:");
for (CollisionHandler ch : responseHandlers) {
System.out.println(" " + ch.getCollidablePair());
}
System.out.println("expectedHandlers:");
for (CollisionHandler ch : expectedHandlers) {
System.out.println(" " + ch.getCollidablePair());
}
throw new TestException("Response handlers differ from expected handlers for " + new CollidablePair(c0, c1));
}
}
Aggregations