Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Direct Collision Detection (Ebberts Formula)

  • Direct Collision Detection (Ebberts Formula)

    Posted by Erin Shelby on November 1, 2007 at 6:43 pm

    Dan (et al),

    I was wondering how I would tweak the expression you provided on your web site so the collision detection is simply between two objects – not every object in the comp. It’s a pretty dense expression and most my attempts have resulted in errors

    -Erin

    Edit: I should note it’s between two *specific* layers. “collision A”, “collision B”, or something like that.

    Brent Taylor replied 11 years, 4 months ago 4 Members · 7 Replies
  • 7 Replies
  • Dan Ebberts

    November 1, 2007 at 7:07 pm

    This should do it:

    function getMin(a, b, c, d){
    return Math.min(Math.min(a,b),Math.min(c,d));
    }

    function getMax(a, b, c, d){
    return Math.max(Math.max(a,b),Math.max(c,d));
    }

    function getBoundingBox(theLayer){
    bb = [];
    c1 = theLayer.toWorld([0,0]);
    c2 = theLayer.toWorld([theLayer.width,0]);
    c3 = theLayer.toWorld([theLayer.width,theLayer.height]);
    c4 = theLayer.toWorld([0,theLayer.height]);
    bb[0] = getMin(c1[0],c2[0],c3[0],c4[0]);
    bb[1] = getMin(c1[1],c2[1],c3[1],c4[1]);
    bb[2] = getMax(c1[0],c2[0],c3[0],c4[0]);
    bb[3] = getMax(c1[1],c2[1],c3[1],c4[1]);
    return bb;
    }

    function checkLayers(theLayer){
    cUL = [];
    cLR = [];
    L = theLayer;
    if (! L.active) return false;
    BB = getBoundingBox(L);
    UL = [BB[0],BB[1]];
    LR = [BB[2],BB[3]];

    if (!(myLR[1] < UL[1] || LR[1] < myUL[1] || myLR[0] < UL[0] || LR[0] < myUL[0])){ if (myUL[1] < UL[1]) cUL[1]=UL[1] else cUL[1]=myUL[1]; if (myUL[0] < UL[0]) cUL[0]=UL[0] else cUL[0]=myUL[0]; if (myLR[1] < LR[1]) cLR[1]=myLR[1] else cLR[1]=LR[1]; if (myLR[0] < LR[0]) cLR[0]=myLR[0] else cLR[0]=LR[0]; for(i = cUL[0]; i <= cLR[0]; i++){ for (j = cUL[1]; j <= cLR[1]; j++){ if (sampleImage(fromWorld([i,j]))[3] > 0 &&
    L.sampleImage(L.fromWorld([i,j]))[3] > 0){

    return true;
    }
    }
    }
    }
    return false;
    }

    myBB = getBoundingBox(thisLayer);
    myUL = [myBB[0],myBB[1]];
    myLR = [myBB[2],myBB[3]];

    if (checkLayers(thisComp.layer(“other layer”))) 100 else 30

    Dan

  • Carlos Cervantes

    March 7, 2012 at 12:23 am

    Is there a way to create a collision not with the bounding box of two layers but with two meshes from the Puppet Tool Pins?

  • Dan Ebberts

    March 7, 2012 at 6:07 am

    It would be difficult to do that accurately. You should be able though to rig something up where the expression would check to see if specific puppet pins were in contact with non-zero alpha areas of another layer using sampleImage(), but I don’t know if that helps you or not.

    Dan

  • Brent Taylor

    January 15, 2015 at 1:07 am

    I know this is a very old post, but it’s exactly what I’m trying to do so I hope it’s ok.

    I’m using the code Dan supplied in this thread, but I keep getting errors telling me the engine has timed out. Or the program just crashes. The preview window also hangs a lot as I move layers around if the layer with the expression is enabled.

    I have a fairly powerful machine (3.4 GHz quad core with 16 GB of ram and a dedicated video card). Is there something I’m doing wrong? Or does this expression just require monstrous horsepower?

    The only thing I can think of that I might be doing wrong is maybe I’m putting the expression in the wrong place. I’m putting it in the “theLayer” opacity expression slot.

  • Dan Ebberts

    January 15, 2015 at 1:21 am

    It’s definitely an opacity expression and I think it’s the same as the one here:

    https://www.motionscript.com/design-guide/collision.html

    With the all layer space transforms and sampleImage, it’s a fairly cpu-intensive expression. If you have more than a few layers I would guess it will bog down.

    Dan

  • Brent Taylor

    January 15, 2015 at 8:57 pm

    Got it. Thanks for the info! I’m working on making my own alternate version… should be less intense albeit less precise. Let’s see if I can manage to make something new in javascript despite my newbliness. 🙂

  • Brent Taylor

    January 15, 2015 at 10:30 pm

    Well, here is what I came up with. It’s my very first attempt at creating a new javascript expression from scratch, so it might not be very elegant, but it seems to work ok.

    When the “pointer thing” object (roughly) touches the A12 object, the opacity changes.

    The “100” value all over the place determines the threshold for how close the anchor point can get for the collision to count. So it’s not very exact. However, for my purposes, this will do nicely and doesn’t require nearly as much cpu.

    Now if I could just figure out how to get it to affect a slider on another layer at the same time.

    if
    (thisComp.layer("pointer thing").transform.xPosition &lt;= thisComp.layer("A12").transform.xPosition + 100 && thisComp.layer("pointer thing").transform.xPosition >= thisComp.layer("A12").transform.xPosition - 100 && thisComp.layer("pointer thing").transform.yPosition &lt;= thisComp.layer("A12").transform.yPosition + 100 && thisComp.layer("pointer thing").transform.yPosition >= thisComp.layer("A12").transform.yPosition - 100)

    50
    else
    100

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy