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:
parent
abe379840d
commit
9d0f906fd8
2 changed files with 366 additions and 0 deletions
|
@ -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
365
src/render/RenderPixi.js
Normal 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;
|
||||
};
|
||||
|
||||
})();
|
Loading…
Reference in a new issue