PierrotLL

Nape 1009 reproducible (haxe)

Nov 30th, 2017
512
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package;
  2.  
  3. import flash.display.Sprite;
  4. import flash.events.Event;
  5. import flash.text.TextField;
  6. import flash.utils.JSON;
  7. import flash.utils.Object;
  8. import haxe.Timer;
  9. import nape.Config;
  10. import nape.callbacks.CbType;
  11. import nape.callbacks.InteractionType;
  12. import nape.callbacks.PreCallback;
  13. import nape.callbacks.PreFlag;
  14. import nape.callbacks.PreListener;
  15. import nape.phys.Body;
  16. import nape.phys.BodyList;
  17. import nape.phys.BodyType;
  18. import nape.phys.Material;
  19. import nape.shape.Circle;
  20. import nape.shape.Polygon;
  21. import nape.shape.Shape;
  22. import nape.space.Space;
  23. import nape.util.BitmapDebug;
  24.  
  25. class Main extends Sprite {
  26.    
  27.     /**
  28.      * README
  29.      * There is two ways to use this sample:
  30.      * - To quickly reproduce the error: call play(json) with one of the jsons given as examples.
  31.      * - To find a new case: comment play(json) and uncomment bruteforce() then be very patient until it displays a json in red. (sometimes more than 50000 iterations are needed)
  32.      * Do not call play(json) AND bruteforce() in the same instance.
  33.      *
  34.      * The preCollisionListener seems to be essential to get the error, even if it always returns ACCEPT.
  35.      *
  36.      * The crash is from zpp_nape/Space.cx line 2251: callbackset.remove_arb(arb);
  37.      * It is a TypeError #1009 (callbackset is null).
  38.      * It seems to always happen on a very slow collision, when some bodies overlap in the initial state.
  39.      */
  40.    
  41.     var space:Space;
  42.     var balls:Array<Body>;
  43.    
  44.     var state:Object;
  45.     var iterations:Int;
  46.    
  47.    
  48.     function new() {
  49.         super();
  50.         if (stage != null) init(null);
  51.         else addEventListener(Event.ADDED_TO_STAGE, init);
  52.     }
  53.    
  54.     function init(e:Event) {
  55.         removeEventListener(Event.ADDED_TO_STAGE, init);
  56.        
  57.         Config.linearSleepThreshold = 300 * 0.2;
  58.         Config.angularSleepThreshold = 100 * 0.4;
  59.        
  60.         space = createSpace();
  61.        
  62.         var field:Body = createField();
  63.         field.space = space;
  64.        
  65.         balls = new Array<Body>();
  66.         for (i in 0...10) {
  67.             balls[i] = createBall();
  68.             balls[i].space = space;
  69.         }
  70.        
  71.         /*
  72.          * Each json describe one case that makes nape crash
  73.          */
  74.        
  75.         /* AS3 with nape-dev.swc or nape-release.swc from napephys.com */
  76.         //var json:Object = {"balls":[{"r": -3.156528096282359, "x":462.2162040323019, "dy": -5.1896775057228925, "y":131.62446077913046, "dx":999.9865335330205}, {"r": -5.267932761744512, "x":343.6876875348389, "dy": -457.88791750451605, "y":414.27104007452726, "dx":889.0099296427331}, {"r":10.122915831505384, "x":122.46028548106551, "dy": -397.7241442465419, "y":429.7891780734062, "dx":917.5050436282932}, {"r": -1.7963113573382579, "x":484.34904934838414, "dy":962.1575397603133, "y":446.90443333238363, "dx":272.49379567685776}, {"r":6.134388216932091, "x":566.8670255690813, "dy": -924.1050666040219, "y":106.13426957279444, "dx": -382.138490441327}, {"r":3.7768165707699577, "x":685.1834611967206, "dy": -178.74010382284067, "y":439.2476936802268, "dx": -983.89632344338}, {"r": -0.6322812194278491, "x":631.6975560970604, "dy": -999.4881483239193, "y":240.43079614639282, "dx":31.991270059550207}, {"r":11.680096533966307, "x":489.84701903536916, "dy": -985.9390682201955, "y":416.1373497918248, "dx": -167.10521762378556}, {"r": -3.4340166680066133, "x":608.1786840222776, "dy": -228.72212909138187, "y":316.1457637324929, "dx": -973.49175017763}, {"r": -0.6969883272643331, "x":220.29011901468039, "dy": -213.2234088407065, "y":262.8941785544157, "dx":977.0034687360885}]};
  77.         //var json:Object = {"balls":[{"r":2.304954084555204,"dy":500.537749476724,"x":547.007760591805,"y":259.75943449884653,"dx":865.7147112928001},{"r":8.088982974357869,"dy":-962.0263189633062,"x":565.9635991789401,"y":225.4328766837716,"dx":272.9567028338216},{"r":3.0866010187846147,"dy":-767.3748407255088,"x":124.52481277287006,"y":497.5758083164692,"dx":641.1987631160092},{"r":-1.0848035447305087,"dy":-53.664278723848355,"x":160.42164023965597,"y":211.59836277365685,"dx":-998.5590344035995},{"r":10.42561051099377,"dy":-551.9065529686793,"x":374.8824402689934,"y":442.34102480113506,"dx":833.9059639972786},{"r":2.952367705188305,"dy":820.4765433256946,"x":411.82099217548966,"y":479.4938759878278,"dx":571.6801919362954},{"r":0.9324079656657958,"dy":-476.8062899506552,"x":573.981655947864,"y":121.27740476280451,"dx":-879.0083969243365},{"r":10.63930998816048,"dy":836.9045238846372,"x":336.5966519340873,"y":355.2835015580058,"dx":547.3488996073972},{"r":-0.7172337646709215,"dy":864.3553314794212,"x":279.87469462677836,"y":345.0612550601363,"dx":502.88155756907594},{"r":-0.2921149876017557,"dy":-509.9306906430794,"x":279.1422327980399,"y":481.0675488784909,"dx":-860.2154908743926}]};
  78.         //var json:Object = {"balls":[{"r":-0.6747614463169533,"dy":317.54634209645695,"x":130.14394538477063,"y":296.2216179817915,"dx":-948.2427540567658},{"r":8.158060570437016,"dy":-791.7863630553991,"x":426.2916679494083,"y":190.5905159190297,"dx":610.79812972823},{"r":-6.219030883941777,"dy":765.6887073971993,"x":374.8432073742151,"y":140.81931747496128,"dx":643.2113209236961},{"r":6.1072291223096435,"dy":808.5924706026161,"x":451.28654846921563,"y":475.62004663050175,"dx":588.36911584885},{"r":9.4009070992979,"dy":-556.3703267198126,"x":549.3600419722497,"y":346.18493784219027,"dx":830.9344496082041},{"r":6.811587619153979,"dy":313.0142280040542,"x":673.1301883235574,"y":473.5712569206953,"dx":949.7484367278663},{"r":-0.47474721960728683,"dy":-878.8746477057213,"x":160.73340568691492,"y":328.1808281317353,"dx":477.05277865257676},{"r":6.124891022981558,"dy":703.8825649807046,"x":538.7657119892538,"y":212.52992171794176,"dx":710.3163624162013},{"r":7.420271756377211,"dy":-487.1252801733692,"x":268.8964016735554,"y":328.4786669537425,"dx":873.3321025909999},{"r":4.229908275492413,"dy":-971.8425986030944,"x":448.76833418384194,"y":399.97291527688503,"dx":-235.63099019523023}]};
  79.         //var json:Object = {"balls":[{"r":11.223716572686193,"dy":891.2212267204964,"x":256.763063184917,"y":377.6177240535617,"dx":453.56887574304926},{"r":-3.251533126994658,"dy":-706.4366655058992,"x":360.82773292437196,"y":415.98646976053715,"dx":707.776262408472},{"r":-3.702958088187698,"dy":857.0360871793217,"x":620.6580780446529,"y":196.0784088820219,"dx":-515.256387900585},{"r":3.6798378207243267,"dy":-683.7836427642802,"x":382.37734641879797,"y":309.2748336493969,"dx":-729.6848154429495},{"r":0.5843887252218014,"dy":-98.408860959845,"x":464.29445473477244,"y":308.15525613725185,"dx":-995.1460677129694},{"r":7.170918443547993,"dy":-297.6251343384354,"x":543.0872270837426,"y":447.9411441832781,"dx":-954.6828161279683},{"r":6.797702460941407,"dy":810.8829184248893,"x":218.26762836426497,"y":472.6870821788907,"dx":-585.2084180928485},{"r":-4.751269592009655,"dy":490.83829792857006,"x":629.1461830027401,"y":303.79466488957405,"dx":871.2506902646243},{"r":-1.5131191342740316,"dy":321.74602584775624,"x":524.3183753453195,"y":332.4558276683092,"dx":946.826010865341},{"r":1.100517520240663,"dy":460.0385247108853,"x":115.91202924028039,"y":234.47336666285992,"dx":887.8989558400393}]};
  80.        
  81.         /* Haxe with nape 2.0.20 from haxelib (also crashes in AS3 with self-build nape-release-2.0.20.swc) */
  82.         var json:Object = {"balls":[{"r":12.510891459178243, "dx": -125.90689683682967, "x":294.8822371661663, "y":214.13405239582062, "dy":992.0420622780669}, {"r":7.809591052585731, "dx":592.8236784079118, "x":497.09897404536605, "y":465.5042951926589, "dy":805.3322831719295}, {"r": -5.83355820793757, "dx": -968.8109568592889, "x":327.84602576866746, "y":430.99390529096127, "dy": -247.8009884350523}, {"r":7.905704963498769, "dx":688.0244466057911, "x":343.6834901571274, "y":428.53208538144827, "dy":725.6875091062234}, {"r":3.141439459734368, "dx": -221.3440292212329, "x":489.5091576501727, "y":415.28559159487486, "dy": -975.1957858441094}, {"r":7.5085219413345, "dx":220.02215415022596, "x":372.4642732180655, "y":397.8513905778527, "dy": -975.4948752725943}, {"r": -5.797343647478622, "dx":316.64666290604777, "x":676.6619213856757, "y":237.54338398575783, "dy": -948.5435629798263}, {"r":12.394488899184388, "dx":987.0094761703454, "x":348.0925536714494, "y":431.52794260531664, "dy":160.6620488788202}, {"r":8.43956271057679, "dx": -949.4537783619918, "x":120.36441238597035, "y":121.07095532119274, "dy":313.9068695555066}, {"r":9.111144937472208, "dx":875.2132885498985, "x":637.3177004046738, "y":108.46717916429043, "dy":483.73722158385954}]};
  83.         //var json:Object = {"balls":[{"r":12.510891459178243,"dx":-125.90689683682967,"x":294.8822371661663,"y":214.13405239582062,"dy":992.0420622780669},{"r":7.809591052585731,"dx":592.8236784079118,"x":497.09897404536605,"y":465.5042951926589,"dy":805.3322831719295},{"r":-5.83355820793757,"dx":-968.8109568592889,"x":327.84602576866746,"y":430.99390529096127,"dy":-247.8009884350523},{"r":7.905704963498769,"dx":688.0244466057911,"x":343.6834901571274,"y":428.53208538144827,"dy":725.6875091062234},{"r":3.141439459734368,"dx":-221.3440292212329,"x":489.5091576501727,"y":415.28559159487486,"dy":-975.1957858441094},{"r":7.5085219413345,"dx":220.02215415022596,"x":372.4642732180655,"y":397.8513905778527,"dy":-975.4948752725943},{"r":-5.797343647478622,"dx":316.64666290604777,"x":676.6619213856757,"y":237.54338398575783,"dy":-948.5435629798263},{"r":12.394488899184388,"dx":987.0094761703454,"x":348.0925536714494,"y":431.52794260531664,"dy":160.6620488788202},{"r":8.43956271057679,"dx":-949.4537783619918,"x":120.36441238597035,"y":121.07095532119274,"dy":313.9068695555066},{"r":9.111144937472208,"dx":875.2132885498985,"x":637.3177004046738,"y":108.46717916429043,"dy":483.73722158385954}]};
  84.         //var json:Object = {"balls":[{"r":1.715299413082748,"x":646.9439085572958,"dx":-982.9024086918445,"y":448.87818917632103,"dy":184.12727931452858},{"r":0.15720247039960233,"x":240.8002683892846,"dx":221.59650677657768,"y":217.9318282753229,"dy":-975.1384456498565},{"r":1.0393383300532528,"x":609.6032074652612,"dx":601.1028557559986,"y":484.18885096907616,"dy":799.1716691687607},{"r":2.0531504921991526,"x":279.49916161596775,"dx":-919.3278313777674,"y":166.01293999701738,"dy":393.4924884343427},{"r":3.766813014058811,"x":597.1395275555551,"dx":-331.2455908302468,"y":299.5803773403168,"dy":-943.5445715786407},{"r":3.418674686231491,"x":686.2579471431673,"dx":876.766249298559,"y":262.03186213970184,"dy":480.9167745992407},{"r":2.9069704167233046,"x":225.76720546931028,"dx":159.74117771373304,"y":204.62767910212278,"dy":-987.15893155187},{"r":0.0011162416045147451,"x":360.61766454949975,"dx":-181.53909222860557,"y":400.4634788259864,"dy":983.3837287614707},{"r":3.2987872096025868,"x":224.49092408642173,"dx":-887.7377363095985,"y":199.2192141711712,"dy":-460.3495536349632},{"r":5.189076023513413,"x":608.2989612594247,"dx":-403.5892654771892,"y":127.91087795048952,"dy":-914.9402738931011}]};
  85.        
  86.         play(json);
  87.        
  88.        
  89.         /*
  90.          * Method used ot find a new test case.
  91.          * To use, comment "play(json)" and uncomment "bruteforce()"
  92.          * It runs iterations in background until the error happens,
  93.          * then displays the initial state needed to reproduce the case with play().
  94.          * Some cases found with bruteforce() doesn't make nape crash again in play(), don't know why.
  95.          */
  96.         //bruteforce();
  97.     }
  98.    
  99.     function play(state:Object) {
  100.         applyState(state);
  101.         testOverlap();
  102.         var debug:BitmapDebug = new BitmapDebug(stage.stageWidth, stage.stageHeight);
  103.         addChild(debug.display);
  104.         addEventListener(Event.ENTER_FRAME, function(e:Event) {
  105.             space.step(0.016);
  106.             debug.clear();
  107.             debug.draw(space);
  108.             debug.flush();
  109.         });
  110.     }
  111.    
  112.     function bruteforce() {
  113.         var start:Float = Timer.stamp();
  114.         while (Timer.stamp() - start < 1) {
  115.             if (isSleeping()) {
  116.                 state = randomState();
  117.                 applyState(state);
  118.                 iterations++;
  119.             }
  120.             try {
  121.                 space.step(0.016);
  122.             } catch (e:Dynamic) {
  123.                 print(JSON.stringify(state), 0xff0000);
  124.                 return;
  125.             }
  126.         }
  127.         print(iterations + "");
  128.         Timer.delay(bruteforce, 0);
  129.     }
  130.    
  131.    
  132.    
  133.     function createSpace() : Space {
  134.         var space:Space = new Space();
  135.         space.worldAngularDrag = 50 * 0.015;
  136.         // preCollisionListener always return ACCEPT, but is essentiel to makes nape crash.
  137.         // Without this useless listener, nape doesn't crash.
  138.         space.listeners.add(new PreListener(InteractionType.COLLISION, CbType.ANY_BODY, CbType.ANY_BODY, preCollisionListener, 0, true));
  139.         return space;
  140.     }
  141.    
  142.     function createField() : Body {
  143.         var w:Int = 800;
  144.         var h:Int = 600;
  145.         var t:Int = 50;
  146.         var material:Material = new Material();
  147.         material.elasticity = 1;
  148.         material.density = 50;
  149.         var body:Body = new Body(BodyType.STATIC);
  150.         body.shapes.add(new Polygon(Polygon.rect(0, 0, w, t), material));
  151.         body.shapes.add(new Polygon(Polygon.rect(0, h - t, w, t), material));
  152.         body.shapes.add(new Polygon(Polygon.rect(0, t, t, h - 2 * t), material));
  153.         body.shapes.add(new Polygon(Polygon.rect(w - t, t, t, h - 2 * t), material));
  154.         var fluid:Shape = new Polygon(Polygon.rect(0, 0, w, h));
  155.         fluid.fluidEnabled = true;
  156.         fluid.fluidProperties.viscosity = 0.57;
  157.         body.shapes.add(fluid);
  158.         return body;
  159.     }
  160.    
  161.     var nextBallId:Int;
  162.     function createBall() : Body {
  163.         var material:Material = new Material();
  164.         material.elasticity = 1;
  165.         material.density = 5;
  166.         var body:Body = new Body(BodyType.DYNAMIC);
  167.         body.isBullet = true;
  168.         body.shapes.add(new Circle(40, null, material));
  169.         body.userData.id = nextBallId++;
  170.         return body;
  171.     }
  172.    
  173.     function isSleeping() : Bool {
  174.         return space.liveBodies.length == 0;
  175.     }
  176.    
  177.     function preCollisionListener(c:PreCallback) : PreFlag {
  178.         return PreFlag.ACCEPT;
  179.     }
  180.    
  181.     function randomState() : Object {
  182.         var state:Object = {balls:[]};
  183.         for (i in 0 ... balls.length) {
  184.             state.balls[i] = {};
  185.             state.balls[i].x = Math.random() * (800 - 200) + 100;
  186.             state.balls[i].y = Math.random() * (600 - 200) + 100;
  187.             state.balls[i].r = Math.random() * Math.PI * 2;
  188.             state.balls[i].dx = 1000 * Math.cos(balls[i].rotation);
  189.             state.balls[i].dy = 1000 * Math.sin(balls[i].rotation);
  190.         }
  191.         return state;
  192.     }
  193.    
  194.     function applyState(state:Object) {
  195.         for (i in 0 ... balls.length) {
  196.             balls[i].position.x = state.balls[i].x;
  197.             balls[i].position.y = state.balls[i].y;
  198.             balls[i].rotation   = state.balls[i].r;
  199.             balls[i].velocity.x = state.balls[i].dx;
  200.             balls[i].velocity.y = state.balls[i].dy;
  201.         }
  202.     }
  203.    
  204.     function testOverlap() {
  205.         for (i in 0 ... balls.length) {
  206.             var list:BodyList = space.bodiesInBody(balls[i]);
  207.             for (j in 0 ... list.length) {
  208.                 if (list.at(j) != balls[i] && list.at(j).userData.id != null) {
  209.                     flash.Lib.trace(balls[i].userData.id + " overlaps " + list.at(j).userData.id);
  210.                 }
  211.             }
  212.         }
  213.     }
  214.    
  215.     var textfield:TextField;
  216.     function print(text:String, ?color:Int = 0) {
  217.         if (textfield == null) {
  218.             textfield = new TextField();
  219.             textfield.width = stage.stageWidth;
  220.             textfield.height = stage.stageHeight;
  221.             textfield.wordWrap = true;
  222.             addChild(textfield);
  223.         }
  224.         textfield.text = text;
  225.         textfield.textColor = color;
  226.     }
  227.  
  228.     static function main() {
  229.         flash.Lib.current.addChild(new Main());
  230.     }
  231.    
  232. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×