Jackhammer rescue scene

Discuss scenes and videos made with Algodoo.

Jackhammer rescue scene

Postby Kilinich » Sat Dec 08, 2012 8:33 pm

The idea of that scene come to my mind with "readable" feature, but then I try it - implementation looks impossible.
It takes about a half a year to test and think how it can be done and about a month to build and code.

So I believe it's my most epic and complicates scripted scene at this moment :mrgreen:

Rating: rated 8.1
Filesize: 383.07 kB
Comments: 11
Ratings: 12
download
Dream of Algodoo as game development engine...
User avatar
Kilinich
[Best bug reporter 2010]
 
Posts: 2098
Joined: Mon Aug 31, 2009 8:27 pm
Location: South Russia

Re: Jackhammer rescue scene

Postby Kilinich » Sat Dec 08, 2012 8:41 pm

Key function here is scene.my.breakPolygon(geom, hitPos, hitVectior, hitDepth, particleCollideSet)
Polygon must have _breakable=true property to be breakable.

Usage:
create circle and set onCollide = {scene.my.breakPolygon(e.other,e.pos,-e.normal,1,2)}
draw big polygon (~10m size) and drop a circle on it.

Whole code:
Code: Select all
scene.my.breakPolygon := (geom, hitPos, hitVect, hitDepth, partCS) => {
  geom._breakable ? {
    xFor := (n1, n2, code) => {n2 > n1 ? {m := (n1 + n2) / 2; xFor(n1, m, code); xFor(m + 1, n2, code)} : {code(n1)}};
    deTrans := (cos_a, sin_a, gpos, c) => {[c(0) * cos_a - c(1) * sin_a, c(1) * cos_a + c(0) * sin_a]+ gpos};
    proj := (n,v) => {n(0)*v(1) - n(1)*v(0)};
    dl := (v) => {v(0)*v(0)+v(1)*v(1)};
    geomRead := readable(geom);
    geomSurf := geomRead.surfaces(0);
    cos_a := math.cos(geom.angle);
    sin_a := math.sin(geom.angle);
    np := hitPos - geom.pos;
    hitPos_ :=  [np(0) * cos_a + np(1) * sin_a, np(1) * cos_a - np(0) * sin_a];
    hitVect_ := -[hitVect(0) * cos_a + hitVect(1) * sin_a, hitVect(1) * cos_a - hitVect(0) * sin_a];
    vertCount := string.length(geomSurf);
    perpArray := [proj(hitVect_, geomSurf(0) - hitPos_)];
    posit := math.toInt(perpArray(0) > 0);
    nodeArray := [];
    xFor (1, vertCount, (i) => {
       perpArray = perpArray ++ [proj(hitVect_, geomSurf(i%vertCount) - hitPos_)];
       posit_i := math.toint(perpArray(i%vertCount) > 0);
       posit_i == posit ? {}:{
          l1 := dl(geomSurf(i-1) - hitPos_);
          l2 := dl(geomSurf(i%vertCount) - hitPos_);
          l1 < l2 ? {nodeArray = nodeArray ++ [[l1,i-1]]} : {nodeArray = nodeArray ++ [[l2,i%vertCount]]};
          posit = posit_i;
       }
    });
    intCount := string.length(nodeArray);
    nodeArray = scene.my.qSortTable(nodeArray, intCount ,0);
    dl(geomSurf(nodeArray(1)(1)) - hitPos_) < hitDepth*2 ? {
      a := nodeArray(0)(1);
      b := nodeArray(1)(1);
      c := a > b ? (a - b) : (b - a);
      c < 4 ? {
        b > a ? {
          a = (a -1 +vertCount)%vertCount;
          b = (b +1 +vertCount)%vertCount
        } : {
          a = (a +1 +vertCount)%vertCount;
          b = (b -1 +vertCount)%vertCount
        }
      } : {                 
        (vertCount - c) < 4 ? {
          a > b ? {
            a = (a -1 +vertCount)%vertCount;
            b = (b +1 +vertCount)%vertCount
          } : {
            a = (a +1 +vertCount)%vertCount;
            b = (b -1 +vertCount)%vertCount
          }
        } : {}
      };
      a <= b ? {
         partSurf := [];
         partSize := 0;
         xFor(a, b, (i) => {
           partSurf = partSurf ++ [deTrans(cos_a, sin_a, geom.pos, geomSurf(i))];
           pa_i = perpArray(i);
           partSize = partSize + pa_i*pa_i
         });
         l := string.length(partSurf);
         big := partSize/l > scene.my.big;
         scene.my.clonePoly(geom, partSurf, big ? geom.collideSet : partCS, big, big? [0,0] : hitVect, !big);
         partSurf = [];
         partSize = 0;
         xFor(b, a+vertCount, (i) => {
           partSurf = partSurf ++ [deTrans(cos_a, sin_a, geom.pos, geomSurf(i%vertCount))];
           pa_i = perpArray(i%vertCount);
           partSize = partSize + pa_i*pa_i
         });
         l = string.length(partSurf);
         big = partSize/l > scene.my.big;
         scene.my.clonePoly(geom, partSurf, big ? geom.collideSet : partCS, big, big? [0,0] : hitVect, !big);
      }:{
         partSurf := [];
         partSize := 0;
         xFor(b, a, (i) => {
           partSurf = partSurf ++ [deTrans(cos_a, sin_a, geom.pos, geomSurf(i))];
           pa_i = perpArray(i);
           partSize = partSize + pa_i*pa_i
         });
         l := string.length(partSurf);
         big := partSize/l > scene.my.big;
         scene.my.clonePoly(geom, partSurf, big ? geom.collideSet : partCS, big, big? [0,0] : hitVect, !big);
         partSurf = [];
         partSize = 0;
         xFor(a, b+vertCount, (i) => {
           partSurf = partSurf ++ [deTrans(cos_a, sin_a, geom.pos, geomSurf(i%vertCount))];
           pa_i = perpArray(i%vertCount);
           partSize = partSize + pa_i*pa_i                                                                   
         });
         l = string.length(partSurf);
         big = partSize/l > scene.my.big;
         scene.my.clonePoly(geom, partSurf, big ? geom.collideSet : partCS, big, big? [0,0] : hitVect, !big);
      };
      Scene.RemoveEntity(geom);
    }:{
      a := nodeArray(0)(1);
      cp := hitPos-hitVect*hitDepth;
      partSurf := [cp];
      scene.my.xFor (a+1, a+vertCount-1, (i) => {partSurf = partSurf ++ [detrans(cos_a, sin_a, geom.pos, geomSurf(i%vertCount))]});
      scene.my.clonePoly(geom, partSurf, geom.collideSet, true, [0,0], false);
      partSurf=[cp,deTrans(cos_a, sin_a, geom.pos, geomSurf(a)),deTrans(cos_a, sin_a, geom.pos, geomSurf((a+1)%vertCount))];
      scene.my.clonePoly(geom, partSurf, partCS, false, hitVect * 5, true);
      partSurf=[cp,deTrans(cos_a, sin_a, geom.pos, geomSurf(a)),deTrans(cos_a, sin_a, geom.pos, geomSurf((a-1+vertCount)%vertCount))];
      scene.my.clonePoly(geom, partSurf, partCS, false, hitVect * 7, true);
      Scene.RemoveEntity(geom)
    }
  } : {}
};

Scene.my.xFor := (n1, n2, code)=>{
    n2 > n1 ? {
        m := (n1 + n2) / 2;
        scene.my.xFor(n1, m, code);
        scene.my.xFor(m + 1, n2, code)
    } : {code(n1)}
};

scene.my.fadeGeom := (geom) => {
  geom.collideSet = 0;
  geom.vel = [0,0];
  geom.angvel = 0;
  geom.color = eval("{"+geom.color+" * [1,1,1,"+(sim.time + 1)+" - sim.time]}");
  geom.density = eval("{sim.time < "+(sim.time+1)+" ? +inf : 0}");
};

scene.my.big = 0.25;

Scene.my.tmTrans := (tm, ang, shift) => {
  sin_a := math.sin(ang); cos_a := math.cos(ang);
  m1 := [[tm(0),tm(1)], [tm(3),tm(4)]]; m2 := [[cos_a, sin_a], [-sin_a, cos_a]];
  mx := [[m1(0)(0)*m2(0)(0) + m1(0)(1)*m2(1)(0), m1(0)(0)*m2(0)(1) + m1(0)(1)*m2(1)(1)],
         [m1(1)(0)*m2(0)(0) + m1(1)(1)*m2(1)(0), m1(1)(0)*m2(0)(1) + m1(1)(1)*m2(1)(1)]];
  sx := [shift(0)*mx(0)(0) + shift(1)*mx(0)(1), shift(0)*mx(1)(0) + shift(1)*mx(1)(1)];
  [mx(0)(0), mx(0)(1), tm(2)+sx(0), mx(1)(0), mx(1)(1), tm(5)+sx(1), tm(6), tm(7), tm(8)]
};

Scene.my.qSortTable := (array, size, key)=>{
  size == 2 ? {array(0)(key) < array(1)(key) ? array : [array(1), array(0)]} : {
    size > 2 ? {
        b := size / 2; low := []; high := [];
        scene.my.xfor(0, b-1, (i)=>{array(i)(key) > array(b)(key) ? {high = high ++ [array(i)]} : {low = low ++ [array(i)]}});
        scene.my.xfor(b + 1, size-1, (i)=>{array(i)(key) > array(b)(key) ? {high = high ++ [array(i)]} : {low = low ++ [array(i)]}});
        lowCount := string.length(low); highCount := string.length(high);
        (lowCount > 1 ? Scene.my.QSortTable(low, lowCount, key) : low) ++ [array(b)] ++ (highcount > 1 ? Scene.my.QSortTable(high, highCount, key) : high)
    } : array
  }
};

scene.my.trans := (geom, c) => {                 
  nc := c - geom.pos;
  cos_a := math.cos(geom.angle);
  sin_a := math.sin(geom.angle);
  [nc(0) * cos_a + nc(1) * sin_a, nc(1) * cos_a - nc(0) * sin_a];
};

scene.my.pcc := 50;

scene.my.clonePoly := (poly, newSurf, newCS, br, nvel, particle) => {
  p := scene.addPolygon({
    vel := poly.vel + nvel;
    angvel := poly.angvel;
    _breakable := br;
    surfaces := [newSurf];
    collideWater := poly.collideWater;
    color := poly.color;
    friction := poly.friction;
    restitution := poly.restitution;
    zDepth := poly.zDepth;
    drawBorder := poly.drawBorder;
    density := poly.density;
    texture := poly.texture;
    textureClamped := poly.textureClamped;
    collideSet := newCS;
    _pcc := scene.my.pcc;
    onCollide := particle ? (e) => {e.this._pcc = e.this._pcc - 1; e.this._pcc < 0 ? {scene.my.fadeGeom(e.this)}:{}} : (e) => {};
  });
  p.textureMatrix = scene.my.tmTrans(poly.textureMatrix, poly.angle, p.pos - poly.pos);
};
Dream of Algodoo as game development engine...
User avatar
Kilinich
[Best bug reporter 2010]
 
Posts: 2098
Joined: Mon Aug 31, 2009 8:27 pm
Location: South Russia

Re: Jackhammer rescue scene

Postby faytree » Sun Dec 09, 2012 9:44 am

outrageously awesome! :thumbup: very fun like a challenge in a real world! .Why you didn't say that the crane (y'know the thing that holds the drill)follows the mouse in desc .Thatsd why i always lose!.

fantastic! :clap:
waiting for semester break to come...
User avatar
faytree
 
Posts: 947
Joined: Mon Nov 05, 2012 1:37 pm
Location: Selangor, Malaysia


Return to Scenes

Who is online

Users browsing this forum: No registered users and 6 guests

cron