@@ -46,7 +46,9 @@ var Render = {};
4646 showPositions : false ,
4747 showAngleIndicator : false ,
4848 showIds : false ,
49- showShadows : false
49+ showShadows : false ,
50+ showVertexNumbers : false ,
51+ showConvexHulls : false
5052 }
5153 } ;
5254
@@ -177,6 +179,9 @@ var Render = {};
177179 // fully featured rendering of bodies
178180 Render . bodies ( engine , bodies , context ) ;
179181 } else {
182+ if ( options . showConvexHulls )
183+ Render . bodyConvexHulls ( engine , bodies , context ) ;
184+
180185 // optimised method for wireframes only
181186 Render . bodyWireframes ( engine , bodies , context ) ;
182187 }
@@ -199,6 +204,9 @@ var Render = {};
199204 if ( options . showCollisions )
200205 Render . collisions ( engine , engine . pairs . list , context ) ;
201206
207+ if ( options . showVertexNumbers )
208+ Render . vertexNumbers ( engine , bodies , context ) ;
209+
202210 Render . constraints ( constraints , context ) ;
203211
204212 if ( options . showBroadphase && engine . broadphase . controller === Grid )
@@ -372,69 +380,75 @@ var Render = {};
372380 var c = context ,
373381 render = engine . render ,
374382 options = render . options ,
383+ body ,
384+ part ,
375385 i ;
376386
377387 for ( i = 0 ; i < bodies . length ; i ++ ) {
378- var body = bodies [ i ] ;
388+ body = bodies [ i ] ;
379389
380390 if ( ! body . render . visible )
381391 continue ;
382392
383- if ( body . render . sprite && body . render . sprite . texture && ! options . wireframes ) {
384- // body sprite
385- var sprite = body . render . sprite ,
386- texture = _getTexture ( render , sprite . texture ) ;
393+ // handle compound parts
394+ for ( k = body . parts . length > 1 ? 1 : 0 ; k < body . parts . length ; k ++ ) {
395+ part = body . parts [ k ] ;
396+
397+ if ( part . render . sprite && part . render . sprite . texture && ! options . wireframes ) {
398+ // part sprite
399+ var sprite = part . render . sprite ,
400+ texture = _getTexture ( render , sprite . texture ) ;
387401
388- if ( options . showSleeping && body . isSleeping )
389- c . globalAlpha = 0.5 ;
402+ if ( options . showSleeping && part . isSleeping )
403+ c . globalAlpha = 0.5 ;
390404
391- c . translate ( body . position . x , body . position . y ) ;
392- c . rotate ( body . angle ) ;
405+ c . translate ( part . position . x , part . position . y ) ;
406+ c . rotate ( part . angle ) ;
393407
394- c . drawImage ( texture , texture . width * - 0.5 * sprite . xScale , texture . height * - 0.5 * sprite . yScale ,
395- texture . width * sprite . xScale , texture . height * sprite . yScale ) ;
408+ c . drawImage ( texture , texture . width * - 0.5 * sprite . xScale , texture . height * - 0.5 * sprite . yScale ,
409+ texture . width * sprite . xScale , texture . height * sprite . yScale ) ;
396410
397- // revert translation, hopefully faster than save / restore
398- c . rotate ( - body . angle ) ;
399- c . translate ( - body . position . x , - body . position . y ) ;
411+ // revert translation, hopefully faster than save / restore
412+ c . rotate ( - part . angle ) ;
413+ c . translate ( - part . position . x , - part . position . y ) ;
400414
401- if ( options . showSleeping && body . isSleeping )
402- c . globalAlpha = 1 ;
403- } else {
404- // body polygon
405- if ( body . circleRadius ) {
406- c . beginPath ( ) ;
407- c . arc ( body . position . x , body . position . y , body . circleRadius , 0 , 2 * Math . PI ) ;
415+ if ( options . showSleeping && part . isSleeping )
416+ c . globalAlpha = 1 ;
408417 } else {
409- c . beginPath ( ) ;
410- c . moveTo ( body . vertices [ 0 ] . x , body . vertices [ 0 ] . y ) ;
411- for ( var j = 1 ; j < body . vertices . length ; j ++ ) {
412- c . lineTo ( body . vertices [ j ] . x , body . vertices [ j ] . y ) ;
418+ // part polygon
419+ if ( part . circleRadius ) {
420+ c . beginPath ( ) ;
421+ c . arc ( part . position . x , part . position . y , part . circleRadius , 0 , 2 * Math . PI ) ;
422+ } else {
423+ c . beginPath ( ) ;
424+ c . moveTo ( part . vertices [ 0 ] . x , part . vertices [ 0 ] . y ) ;
425+ for ( var j = 1 ; j < part . vertices . length ; j ++ ) {
426+ c . lineTo ( part . vertices [ j ] . x , part . vertices [ j ] . y ) ;
427+ }
428+ c . closePath ( ) ;
413429 }
414- c . closePath ( ) ;
415- }
416430
417- if ( ! options . wireframes ) {
418- if ( options . showSleeping && body . isSleeping ) {
419- c . fillStyle = Common . shadeColor ( body . render . fillStyle , 50 ) ;
431+ if ( ! options . wireframes ) {
432+ if ( options . showSleeping && part . isSleeping ) {
433+ c . fillStyle = Common . shadeColor ( part . render . fillStyle , 50 ) ;
434+ } else {
435+ c . fillStyle = part . render . fillStyle ;
436+ }
437+
438+ c . lineWidth = part . render . lineWidth ;
439+ c . strokeStyle = part . render . strokeStyle ;
440+ c . fill ( ) ;
441+ c . stroke ( ) ;
420442 } else {
421- c . fillStyle = body . render . fillStyle ;
443+ c . lineWidth = 1 ;
444+ c . strokeStyle = '#bbb' ;
445+ if ( options . showSleeping && part . isSleeping )
446+ c . strokeStyle = 'rgba(255,255,255,0.2)' ;
447+ c . stroke ( ) ;
422448 }
423-
424- c . lineWidth = body . render . lineWidth ;
425- c . strokeStyle = body . render . strokeStyle ;
426- c . fill ( ) ;
427- c . stroke ( ) ;
428- } else {
429- c . lineWidth = 1 ;
430- c . strokeStyle = '#bbb' ;
431- if ( options . showSleeping && body . isSleeping )
432- c . strokeStyle = 'rgba(255,255,255,0.2)' ;
433- c . stroke ( ) ;
434449 }
435450 }
436451 }
437-
438452 } ;
439453
440454 /**
@@ -447,65 +461,101 @@ var Render = {};
447461 */
448462 Render . bodyWireframes = function ( engine , bodies , context ) {
449463 var c = context ,
464+ body ,
465+ part ,
450466 i ,
451467 j ,
452468 k ;
453469
454470 c . beginPath ( ) ;
455471
472+ // render all bodies
456473 for ( i = 0 ; i < bodies . length ; i ++ ) {
457- var body = bodies [ i ] ;
474+ body = bodies [ i ] ;
458475
459- if ( ! body . render . visible || body . parts . length === 1 )
476+ if ( ! body . render . visible )
460477 continue ;
461478
462- c . moveTo ( body . vertices [ 0 ] . x , body . vertices [ 0 ] . y ) ;
479+ // handle compound parts
480+ for ( k = body . parts . length > 1 ? 1 : 0 ; k < body . parts . length ; k ++ ) {
481+ part = body . parts [ k ] ;
463482
464- for ( j = 1 ; j < body . vertices . length ; j ++ ) {
465- c . lineTo ( body . vertices [ j ] . x , body . vertices [ j ] . y ) ;
483+ c . moveTo ( part . vertices [ 0 ] . x , part . vertices [ 0 ] . y ) ;
484+
485+ for ( j = 1 ; j < part . vertices . length ; j ++ ) {
486+ c . lineTo ( part . vertices [ j ] . x , part . vertices [ j ] . y ) ;
487+ }
488+
489+ c . lineTo ( part . vertices [ 0 ] . x , part . vertices [ 0 ] . y ) ;
466490 }
467-
468- c . lineTo ( body . vertices [ 0 ] . x , body . vertices [ 0 ] . y ) ;
469491 }
470492
471493 c . lineWidth = 1 ;
472- c . strokeStyle = '#9E9277 ' ;
494+ c . strokeStyle = '#bbb ' ;
473495 c . stroke ( ) ;
496+ } ;
474497
475- for ( i = 0 ; i < bodies . length ; i ++ ) {
476- var body = bodies [ i ] ;
477- for ( j = 0 ; j < body . vertices . length ; j ++ ) {
478- c . fillStyle = 'yellow' ;
479- c . fillText ( j , body . vertices [ j ] . x , body . vertices [ j ] . y + 10 ) ;
480- }
481- }
498+ /**
499+ * Optimised method for drawing body convex hull wireframes in one pass
500+ * @private
501+ * @method bodyWireframes
502+ * @param {engine } engine
503+ * @param {body[] } bodies
504+ * @param {RenderingContext } context
505+ */
506+ Render . bodyConvexHulls = function ( engine , bodies , context ) {
507+ var c = context ,
508+ body ,
509+ part ,
510+ i ,
511+ j ,
512+ k ;
482513
483514 c . beginPath ( ) ;
484515
516+ // render convex hulls
485517 for ( i = 0 ; i < bodies . length ; i ++ ) {
486- var body = bodies [ i ] ;
518+ body = bodies [ i ] ;
487519
488- if ( ! body . render . visible )
520+ if ( ! body . render . visible || body . parts . length === 1 )
489521 continue ;
490522
491- for ( k = body . parts . length > 1 ? 1 : 0 ; k < body . parts . length ; k ++ ) {
492- var part = body . parts [ k ] ;
493-
494- c . moveTo ( part . vertices [ 0 ] . x , part . vertices [ 0 ] . y ) ;
523+ c . moveTo ( body . vertices [ 0 ] . x , body . vertices [ 0 ] . y ) ;
495524
496- for ( j = 1 ; j < part . vertices . length ; j ++ ) {
497- c . lineTo ( part . vertices [ j ] . x , part . vertices [ j ] . y ) ;
498- }
499-
500- c . lineTo ( part . vertices [ 0 ] . x , part . vertices [ 0 ] . y ) ;
525+ for ( j = 1 ; j < body . vertices . length ; j ++ ) {
526+ c . lineTo ( body . vertices [ j ] . x , body . vertices [ j ] . y ) ;
501527 }
528+
529+ c . lineTo ( body . vertices [ 0 ] . x , body . vertices [ 0 ] . y ) ;
502530 }
503531
504532 c . lineWidth = 1 ;
505- c . strokeStyle = '#bbb ' ;
533+ c . strokeStyle = 'rgba(255,255,255,0.2) ' ;
506534 c . stroke ( ) ;
507535 } ;
508536
537+ /**
538+ * Renders body vertex numbers.
539+ * @private
540+ * @method vertexNumbers
541+ * @param {engine } engine
542+ * @param {body[] } bodies
543+ * @param {RenderingContext } context
544+ */
545+ Render . vertexNumbers = function ( engine , bodies , context ) {
546+ var c = context ,
547+ i ,
548+ j ;
549+
550+ for ( i = 0 ; i < bodies . length ; i ++ ) {
551+ var body = bodies [ i ] ;
552+ for ( j = 0 ; j < body . vertices . length ; j ++ ) {
553+ c . fillStyle = 'yellow' ;
554+ c . fillText ( j , body . vertices [ j ] . x , body . vertices [ j ] . y + 10 ) ;
555+ }
556+ }
557+ } ;
558+
509559 /**
510560 * Draws body bounds
511561 * @private
0 commit comments