diff --git a/src/render/RenderPixi.js b/src/render/RenderPixi.js index 2e546ff..125d093 100644 --- a/src/render/RenderPixi.js +++ b/src/render/RenderPixi.js @@ -25,6 +25,7 @@ var RenderPixi = {}; height: 600, background: '#fafafa', wireframeBackground: '#222', + hasBounds: false, enabled: true, wireframes: true, showSleeping: true, @@ -47,7 +48,19 @@ var RenderPixi = {}; // init pixi render.context = new PIXI.WebGLRenderer(render.options.width, render.options.height, render.canvas, transparent, true); render.canvas = render.context.view; + render.container = new PIXI.DisplayObjectContainer(); render.stage = new PIXI.Stage(); + render.stage.addChild(render.container); + render.bounds = render.bounds || { + min: { + x: 0, + y: 0 + }, + max: { + x: render.options.width, + y: render.options.height + } + }; // caches render.textures = {}; @@ -56,7 +69,7 @@ var RenderPixi = {}; // use a sprite batch for performance render.spriteBatch = new PIXI.SpriteBatch(); - render.stage.addChild(render.spriteBatch); + render.container.addChild(render.spriteBatch); // insert canvas if (Common.isElement(render.element)) { @@ -78,12 +91,12 @@ var RenderPixi = {}; * @param {RenderPixi} render */ RenderPixi.clear = function(render) { - var stage = render.stage, + var container = render.container, spriteBatch = render.spriteBatch; - // clear stage - while (stage.children[0]) { - stage.removeChild(stage.children[0]); + // clear stage container + while (container.children[0]) { + container.removeChild(container.children[0]); } // clear sprite batch @@ -103,8 +116,8 @@ var RenderPixi = {}; if (bgSprite) spriteBatch.addChildAt(bgSprite, 0); - // add sprite batch back into stage - render.stage.addChild(render.spriteBatch); + // add sprite batch back into container + render.container.addChild(render.spriteBatch); // reset background state render.currentBackground = null; @@ -155,9 +168,11 @@ var RenderPixi = {}; world = engine.world, context = render.context, stage = render.stage, + container = render.container, options = render.options, bodies = Composite.allBodies(world), - constraints = Composite.allConstraints(world), + allConstraints = Composite.allConstraints(world), + constraints = [], i; if (options.wireframes) { @@ -166,6 +181,44 @@ var RenderPixi = {}; RenderPixi.setBackground(render, options.background); } + // handle bounds + var boundsWidth = render.bounds.max.x - render.bounds.min.x, + boundsHeight = render.bounds.max.y - render.bounds.min.y, + boundsScaleX = boundsWidth / render.options.width, + boundsScaleY = boundsHeight / render.options.height; + + if (options.hasBounds) { + // Hide bodies that are not in view + for (i = 0; i < bodies.length; i++) { + var body = bodies[i]; + body.render.sprite.visible = Bounds.overlaps(body.bounds, render.bounds); + } + + // filter out constraints that are not in view + for (i = 0; i < allConstraints.length; i++) { + var constraint = allConstraints[i], + bodyA = constraint.bodyA, + bodyB = constraint.bodyB, + pointAWorld = constraint.pointA, + pointBWorld = constraint.pointB; + + if (bodyA) pointAWorld = Vector.add(bodyA.position, constraint.pointA); + if (bodyB) pointBWorld = Vector.add(bodyB.position, constraint.pointB); + + if (!pointAWorld || !pointBWorld) + continue; + + if (Bounds.contains(render.bounds, pointAWorld) || Bounds.contains(render.bounds, pointBWorld)) + constraints.push(constraint); + } + + // transform the view + container.scale.set(1 / boundsScaleX, 1 / boundsScaleY); + container.position.set(-render.bounds.min.x, -render.bounds.min.y); + } else { + constraints = allConstraints; + } + for (i = 0; i < bodies.length; i++) RenderPixi.body(engine, bodies[i]); @@ -188,7 +241,7 @@ var RenderPixi = {}; bodyB = constraint.bodyB, pointA = constraint.pointA, pointB = constraint.pointB, - stage = render.stage, + container = render.container, constraintRender = constraint.render, primitiveId = 'c-' + constraint.id, primitive = render.primitives[primitiveId]; @@ -204,8 +257,8 @@ var RenderPixi = {}; } // add to scene graph if not already there - if (stage.children.indexOf(primitive) === -1) - stage.addChild(primitive); + if (container.children.indexOf(primitive) === -1) + container.addChild(primitive); // render the constraint on every update, since they can change dynamically primitive.clear(); @@ -260,7 +313,7 @@ var RenderPixi = {}; } else { var primitiveId = 'b-' + body.id, primitive = render.primitives[primitiveId], - stage = render.stage; + container = render.container; // initialise body primitive if not existing if (!primitive) { @@ -269,8 +322,8 @@ var RenderPixi = {}; } // add to scene graph if not already there - if (stage.children.indexOf(primitive) === -1) - stage.addChild(primitive); + if (container.children.indexOf(primitive) === -1) + container.addChild(primitive); // update body primitive primitive.position.x = body.position.x;