0
0
Fork 0
mirror of https://github.com/liabru/matter-js.git synced 2024-12-26 13:49:01 -05:00

added pixi.js webgl renderer

This commit is contained in:
liabru 2014-03-20 00:46:25 +00:00
parent abe379840d
commit 9d0f906fd8
2 changed files with 366 additions and 0 deletions

View file

@ -31,6 +31,7 @@ Matter.Vector = Vector;
Matter.Vertices = Vertices;
Matter.Gui = Gui;
Matter.Render = Render;
Matter.RenderPixi = RenderPixi;
Matter.Events = Events;
// CommonJS module

365
src/render/RenderPixi.js Normal file
View file

@ -0,0 +1,365 @@
/**
* See [Demo.js](https://github.com/liabru/matter-js/blob/master/demo/js/Demo.js)
* and [DemoMobile.js](https://github.com/liabru/matter-js/blob/master/demo/js/DemoMobile.js) for usage examples.
*
* @class RenderPixi
*/
var RenderPixi = {};
(function() {
/**
* Creates a new Pixi.js WebGL renderer
* @method create
* @param {object} options
* @return {RenderPixi} A new renderer
*/
RenderPixi.create = function(options) {
var defaults = {
controller: RenderPixi,
element: null,
canvas: null,
options: {
width: 800,
height: 600,
background: '#fafafa',
wireframeBackground: '#222',
enabled: true,
wireframes: true,
showSleeping: true,
showDebug: false,
showBroadphase: false,
showBounds: false,
showVelocity: false,
showCollisions: false,
showAxes: false,
showPositions: false,
showAngleIndicator: false,
showIds: false,
showShadows: false
}
};
var render = Common.extend(defaults, options);
// init pixi
render.context = new PIXI.WebGLRenderer(800, 600, render.canvas, false, true);
render.canvas = render.context.view;
render.stage = new PIXI.Stage();
// caches
render.textures = {};
render.sprites = {};
render.primitives = {};
// use a sprite batch for performance
render.spriteBatch = new PIXI.SpriteBatch();
render.stage.addChild(render.spriteBatch);
// insert canvas
if (Common.isElement(render.element)) {
render.element.appendChild(render.canvas);
} else {
Common.log('No "render.element" passed, "render.canvas" was not inserted into document.', 'warn');
}
return render;
};
/**
* Clears the scene graph
* @method clear
* @param {RenderPixi} render
*/
RenderPixi.clear = function(render) {
var stage = render.stage,
spriteBatch = render.spriteBatch;
// clear stage
while (stage.children[0]) {
stage.removeChild(stage.children[0]);
}
// clear sprite batch
while (spriteBatch.children[0]) {
spriteBatch.removeChild(spriteBatch.children[0]);
}
var bgSprite = render.sprites['bg-0'];
// clear caches
render.textures = {};
render.sprites = {};
render.primitives = {};
// set background sprite
render.sprites['bg-0'] = bgSprite;
if (bgSprite)
spriteBatch.addChildAt(bgSprite, 0);
// add sprite batch back into stage
render.stage.addChild(render.spriteBatch);
// reset background state
render.currentBackground = null;
};
/**
* Sets the background of the canvas
* @method setBackground
* @param {RenderPixi} render
* @param {string} background
*/
RenderPixi.setBackground = function(render, background) {
if (render.currentBackground !== background) {
var isColor = background.indexOf && background.indexOf('#') !== -1,
bgSprite = render.sprites['bg-0'];
if (isColor) {
// if solid background color
var color = Common.colorToNumber(background);
render.stage.setBackgroundColor(color);
// remove background sprite if existing
if (bgSprite)
render.spriteBatch.removeChild(bgSprite);
} else {
// initialise background sprite if needed
if (!bgSprite) {
var texture = _getTexture(render, background);
bgSprite = render.sprites['bg-0'] = new PIXI.Sprite(texture);
bgSprite.position.x = 0;
bgSprite.position.y = 0;
render.spriteBatch.addChildAt(bgSprite, 0);
}
}
render.currentBackground = background;
}
};
/**
* Description
* @method world
* @param {engine} engine
*/
RenderPixi.world = function(engine) {
var render = engine.render,
world = engine.world,
context = render.context,
stage = render.stage,
options = render.options,
i;
if (options.wireframes) {
RenderPixi.setBackground(render, options.wireframeBackground);
} else {
RenderPixi.setBackground(render, options.background);
}
for (i = 0; i < world.bodies.length; i++)
RenderPixi.body(engine, world.bodies[i]);
for (i = 0; i < world.constraints.length; i++)
RenderPixi.constraint(engine, world.constraints[i]);
context.render(stage);
};
/**
* Description
* @method constraint
* @param {engine} engine
* @param {constraint} constraint
*/
RenderPixi.constraint = function(engine, constraint) {
var render = engine.render,
bodyA = constraint.bodyA,
bodyB = constraint.bodyB,
pointA = constraint.pointA,
pointB = constraint.pointB,
stage = render.stage,
constraintRender = constraint.render,
primitiveId = 'c-' + constraint.id,
primitive = render.primitives[primitiveId];
// initialise constraint primitive if not existing
if (!primitive)
primitive = render.primitives[primitiveId] = new PIXI.Graphics();
// don't render if constraint does not have two end points
if (!constraintRender.visible || !constraint.pointA || !constraint.pointB) {
primitive.clear();
return;
}
// add to scene graph if not already there
if (stage.children.indexOf(primitive) === -1)
stage.addChild(primitive);
// render the constraint on every update, since they can change dynamically
primitive.clear();
primitive.beginFill(0, 0);
primitive.lineStyle(constraintRender.lineWidth, Common.colorToNumber(constraintRender.strokeStyle), 1);
if (bodyA) {
primitive.moveTo(bodyA.position.x + pointA.x, bodyA.position.y + pointA.y);
} else {
primitive.moveTo(pointA.x, pointA.y);
}
if (bodyB) {
primitive.lineTo(bodyB.position.x + pointB.x, bodyB.position.y + pointB.y);
} else {
primitive.lineTo(pointB.x, pointB.y);
}
primitive.endFill();
};
/**
* Description
* @method body
* @param {engine} engine
* @param {body} body
*/
RenderPixi.body = function(engine, body) {
var render = engine.render,
bodyRender = body.render;
if (!bodyRender.visible)
return;
if (bodyRender.sprite) {
var spriteId = 'b-' + body.id,
sprite = render.sprites[spriteId],
spriteBatch = render.spriteBatch;
// initialise body sprite if not existing
if (!sprite)
sprite = render.sprites[spriteId] = _createBodySprite(render, body);
// add to scene graph if not already there
if (spriteBatch.children.indexOf(sprite) === -1)
spriteBatch.addChild(sprite);
// update body sprite
sprite.position.x = body.position.x;
sprite.position.y = body.position.y;
sprite.rotation = body.angle;
} else {
var primitiveId = 'b-' + body.id,
primitive = render.primitives[primitiveId],
stage = render.stage;
// initialise body primitive if not existing
if (!primitive) {
primitive = render.primitives[primitiveId] = _createBodyPrimitive(render, body);
primitive.initialAngle = body.angle;
}
// add to scene graph if not already there
if (stage.children.indexOf(primitive) === -1)
stage.addChild(primitive);
// update body primitive
primitive.position.x = body.position.x;
primitive.position.y = body.position.y;
primitive.rotation = body.angle - primitive.initialAngle;
}
};
/**
* Creates a body sprite
* @method _createBodySprite
* @private
* @param {RenderPixi} render
* @param {body} body
* @return {PIXI.Sprite} sprite
*/
var _createBodySprite = function(render, body) {
var bodyRender = body.render,
texturePath = bodyRender.sprite.texture,
texture = _getTexture(render, texturePath),
sprite = new PIXI.Sprite(texture);
sprite.anchor.x = 0.5;
sprite.anchor.y = 0.5;
return sprite;
};
/**
* Creates a body primitive
* @method _createBodyPrimitive
* @private
* @param {RenderPixi} render
* @param {body} body
* @return {PIXI.Graphics} graphics
*/
var _createBodyPrimitive = function(render, body) {
var bodyRender = body.render,
options = render.options,
primitive = new PIXI.Graphics();
primitive.clear();
if (!options.wireframes) {
primitive.beginFill(Common.colorToNumber(bodyRender.fillStyle), 1);
primitive.lineStyle(body.render.lineWidth, Common.colorToNumber(bodyRender.strokeStyle), 1);
} else {
primitive.beginFill(0, 0);
primitive.lineStyle(1, Common.colorToNumber('#bbb'), 1);
}
primitive.moveTo(body.vertices[0].x - body.position.x, body.vertices[0].y - body.position.y);
for (var j = 1; j < body.vertices.length; j++) {
primitive.lineTo(body.vertices[j].x - body.position.x, body.vertices[j].y - body.position.y);
}
primitive.lineTo(body.vertices[0].x - body.position.x, body.vertices[0].y - body.position.y);
primitive.endFill();
// angle indicator
if (options.showAngleIndicator || options.showAxes) {
primitive.beginFill(0, 0);
if (options.wireframes) {
primitive.lineStyle(1, Common.colorToNumber('#CD5C5C'), 1);
} else {
primitive.lineStyle(1, Common.colorToNumber(body.render.strokeStyle));
}
primitive.moveTo(0, 0);
primitive.lineTo(((body.vertices[0].x + body.vertices[body.vertices.length-1].x) / 2) - body.position.x,
((body.vertices[0].y + body.vertices[body.vertices.length-1].y) / 2) - body.position.y);
primitive.endFill();
}
return primitive;
};
/**
* Gets the requested texture (a PIXI.Texture) via its path
* @method _getTexture
* @private
* @param {RenderPixi} render
* @param {string} imagePath
* @return {PIXI.Texture} texture
*/
var _getTexture = function(render, imagePath) {
var texture = render.textures[imagePath];
if (!texture)
texture = render.textures[imagePath] = PIXI.Texture.fromImage(imagePath);
return texture;
};
})();