Merge pull request #614 from georgiee/physics-phaser-exporter

Custom PhysicsEditor export & new p2 polygon parsing
This commit is contained in:
Richard Davey 2014-03-21 11:27:13 +00:00
commit f0034008f5
3 changed files with 192 additions and 2 deletions

View file

@ -0,0 +1,65 @@
<exporter>
<name>lime-json</name>
<displayName>Phaser (JSON)</displayName>
<description>Exporter for Phaser, JSON</description>
<version>1.0</version>
<yAxisDirection>down</yAxisDirection>
<physicsEngine>box2d</physicsEngine>
<template>phaser.json</template>
<fileExtension>json</fileExtension>
<anchorPoint>
<enabled>no</enabled>
</anchorPoint>
<origin>
<type>fixed</type>
<relX>0.0</relX>
<relY>1.0</relY>
</origin>
<supportsCircles>yes</supportsCircles>
<body>
</body>
<fixture>
<parameter>
<name>isSensor</name>
<displayName>Is Sensor</displayName>
<description>If set the physial </description>
<type>bool</type>
<default>false</default>
</parameter>
<parameter>
<name>filter_groupIndex</name>
<displayName>Group</displayName>
<description>Collision group.</description>
<shortDescription></shortDescription>
<type>int</type>
<default>0</default>
</parameter>
<parameter>
<name>filter_bitfield</name>
<type>bitfield</type>
<size>16</size>
</parameter>
<parameter>
<name>filter_categoryBits</name>
<displayName>Cat.</displayName>
<description>Collision category</description>
<shortDescription>Collision category</shortDescription>
<type>uint16</type>
<default>1</default>
<bitfield>yes</bitfield>
</parameter>
<parameter>
<name>filter_maskBits</name>
<displayName>Mask</displayName>
<description>Collision mask</description>
<shortDescription>Collision mask</shortDescription>
<type>uint16</type>
<default>65535</default>
<bitfield>yes</bitfield>
</parameter>
</fixture>
</exporter>

View file

@ -0,0 +1,32 @@
{ {% for body in bodies %}
{% if not forloop.first %}, {% endif %}
"{{body.name}}": [
{% for fixture in body.fixtures %}{% if not forloop.first %} ,{% endif %}
{
"isSensor": {{fixture.isSensor}},
"filter": {
"group": {{fixture.filter_groupIndex}},
"categoryBits": {{fixture.filter_categoryBits}},
"maskBits": {{fixture.filter_maskBits}}
},
{% if fixture.isCircle %}
"circle": {
"radius": {{fixture.radius|floatformat:3}},
"position": [
{{fixture.center.x|floatformat:3}},
{{fixture.center.y|floatformat:3}}
]
}
{% else %}
"polygons":[
{% for polygon in fixture.polygons %}{% if not forloop.first %} ,{% endif %}
[ {% for point in polygon %} {% if not forloop.first %}, {% endif %} {{point.x}}, {{point.y}} {% endfor %} ]
{% endfor %}
]
{% endif %}
}
{% endfor %}
]
{% endfor %}
}

View file

@ -1095,6 +1095,100 @@ Phaser.Physics.P2.Body.prototype = {
},
/**
* Reads the shape data from a physics data file stored in the Game.Cache and adds it as a polygon to this Body.
* The shape data format is based on the custom phaser export in
* @method Phaser.Physics.P2.Body#loadPhaserPolygon
* @param {string} key - The key of the Physics Data file as stored in Game.Cache.
* @param {string} object - The key of the object within the Physics data file that you wish to load the shape data from.
*/
addPhaserPolygon: function (key, object) {
var data = this.game.cache.getPhysicsData(key, object);
var createdFixtures = []
//cycle through the fixtures
for (var i = 0; i < data.length; i++)
{
var fixtureData = data[i]
var shapesOfFixture = this.addFixture(fixtureData)
createdFixtures[fixtureData.filter.group] = createdFixtures[fixtureData.filter.group] || []
createdFixtures[fixtureData.filter.group].push(shapesOfFixture)
}
this.data.aabbNeedsUpdate = true;
this.shapeChanged();
return createdFixtures;
},
/**
* Add a polygon fixture. This is used during #loadPhaserPolygon.
*
* @method Phaser.Physics.P2.Body#addPolygonFixture
* @param {string} fixtureData - The data for the fixture.
* It contains: isSensor, filter (collision) and the actual polygon shapes
*/
addFixture: function(fixtureData){
//console.log('addPolygonFixture', fixtureData)
var generatedShapes = []
if (fixtureData.circle){
//a circle has unfortunately no position in p2. pretty useless.
var shape = new p2.Circle(this.world.pxm(fixtureData.circle.radius))
shape.collisionGroup = fixtureData.filter.categoryBits
shape.collisionMask = fixtureData.filter.maskBits
shape.sensor = fixtureData.isSensor
this.data.addShape(shape);
generatedShapes.push(shape)
}else{
polygons = fixtureData.polygons
var cm = p2.vec2.create();
for (var i = 0; i < polygons.length; i++){
shapes = polygons[i]
var vertices = [];
for (var s = 0; s < shapes.length; s += 2)
{
vertices.push([ this.world.pxmi(shapes[s]), this.world.pxmi(shapes[s + 1]) ]);
}
var shape = new p2.Convex(vertices);
// Move all vertices so its center of mass is in the local center of the convex
for (var j = 0; j !== shape.vertices.length; j++)
{
var v = shape.vertices[j];
p2.vec2.sub(v, v, shape.centerOfMass);
}
p2.vec2.scale(cm, shape.centerOfMass, 1);
cm[0] -= this.world.pxmi(this.sprite.width / 2);
cm[1] -= this.world.pxmi(this.sprite.height / 2);
shape.updateTriangles();
shape.updateCenterOfMass();
shape.updateBoundingRadius();
shape.collisionGroup = fixtureData.filter.categoryBits
shape.collisionMask = fixtureData.filter.maskBits
shape.sensor = fixtureData.isSensor
this.data.addShape(shape, cm);
generatedShapes.push(shape)
}
}
return generatedShapes
},
/**
* Reads the shape data from a physics data file stored in the Game.Cache and adds it as a polygon to this Body.
*
@ -1107,8 +1201,8 @@ Phaser.Physics.P2.Body.prototype = {
* @param {boolean|number} [options.removeCollinearPoints=false] - Set to a number (angle threshold value) to remove collinear points, or false to keep all points.
* @return {boolean} True on success, else false.
*/
loadPolygon: function (key, object, options) {
loadPolygon: function (key, object, options) {
var data = this.game.cache.getPhysicsData(key, object);
if (data.length === 1)
@ -1132,7 +1226,6 @@ Phaser.Physics.P2.Body.prototype = {
for (var i = 0; i < data.length; i++)
{
var vertices = [];
for (var s = 0; s < data[i].shape.length; s += 2)
{
vertices.push([ this.world.pxmi(data[i].shape[s]), this.world.pxmi(data[i].shape[s + 1]) ]);