I'm a robot

PhysicsEditor comes with a whole bunch of data formats allowing you to export to many game engines right out of the box - including Cocos2d, Corona SDK, Name, Moai, Gideros, JSON, Flash / AS3 and many others. But sometimes this is not enough.

Maybe you need some extra properties you can assign to a shape or simply need a complete new format to match your needs.

This is where PhysicsEditor's custom exporter comes to help.

What you are going to learn

Anatomy of a Custom Shape Exporter

An exporter consists of 2 files:

The exporters shipped with PhysicsEditor are located inside the application's folder in a folder called exporters.

To add your own exporter you can simply point PhysicsEditor's preferences to a location where you want to keep your custom exporters.

Physics Editor Preferences

exporter.xml

Let's first have a look at the exporter.xml. This file describes the basic information about the exporter itself.

PhysicsEditor scans the exporter directories with each start. If you change the directory location in the preferences or make some changes in the exporter.xml you need to restart PhysicsEditor. If you change the contents template file there is no need for restarting - it is read with each export.

The exporter.xml is - as the name aready says an xml file.

It has 4 main blocks:

Global exporter parameters

Element Type Info
<name> string Identifier for the exporter, must be unique. Otherwise the lastest exporter found for that name will overwrite the others.
<displayName> string This is how the exporter's name is displayed in the combo box in the GUI
<description> string Some information about the exporter
<version> string Exporter version - should be build from digits separated with dots - e.g. 1.0 or 1.0.1
<yAxisDirection> up / down Direction of the yAxis
<physicsEngine> box2d / chipmunk / generic Name of the physics engine used. This currently set the polygon orientation.
<template> string Name of the template file - relative to the exporter.xml
<fileExtension> string File extension used when exporting the data file

Anchor Points

Physics Editor with AnchorPoint in cocos2d exporter

AnchorPoints can be used as the center of a sprite - e.g. for rotation or move operations. When setting the origin to anchorPoint it is also possible to center.

Additional global parameters are anchor points:

Element Type Info
<enabled> yes / no Display and use anchor points for this exporter
<relX> float Relative position of the anchor points x position
<relY> float Relative position of the anchor points y position

Origin

Origin - the 0/0 location of the sprite. This might be set to a fixed position or to the anchor point.

Element Type Info
<type> fixed / anchorPoint Fixed sets a fixed relative position to the sprite's size, anchorPoint uses the AnchorPoint as sprite's center
<relX> float Relative position of the origin x position
<relY> float Relative position of the origin y position

Parameter blocks

There are 3 parameter blocks which can be used to define properties and values on file base, per body and per fixture.

Element Type Info
<global> list of <parameter> The global parameters used for the complete file - e.g. gravity
<body> list of <parameter> Parameters used for an individual body
<fixture> list of <parameter> Parameters used on an individual fixture. Might be multiple sub-fixtures in case the fixture is decomposed into convex parts.

Parameter definitions

In each of the elements <global>, <body> and <fixture> 0 or more parameters can be defined.

Values for all parameters

These elements must be present for all parameters and define their apperance in the GUI.

Element Type Info
<name> string Name of the value (used in the template)
<displayName> string Human readable name of the value (used in the user interface)
<description> string Description of the element used in the tooltip when hovering over the element for some time
<shortDescription> string Short description of the element used in the status bar when hovering over the element
<type> bool, string,float, int, uint16, bitfield Type of the parameter - which adds additional fields
<bitfield> yes, no Connects a value to an existing bit field

bool

<parameter>
    <name>isSensor</name>
    <displayName>Is Sensor</displayName>
    <description>The object only detects collisions but does not collide with any other object </description>
    <shortDescription>Turns the fixture into a sensor</shortDescription>
    <type>bool</type>
    <default>false</default>
</parameter>
Element Type Info
<type> bool Defines a bool input field / Checkbox
<default> false / true The default value

string

<parameter>
    <name>fixture_id</name>
    <displayName>Identifier</displayName>
    <description>Identifier which can be used to identify a fixture during collision detection</description>
    <shortDescription>Identifier for the fixture</shortDescription>
    <type><code>string</code></type>
    <default>fixture123</default>
</parameter>
Element Type Info
<type> string Defines a string input field
<default> string The default value which is used if nothing else is entered

float

<parameter>
    <name>density</name>
    <displayName>Density</displayName>
    <description>Density of the fixture, results in the mass if multiplied with the fixture's ares</description>
    <shortDescription>Density of the fixture</shortDescription>
    <type>float</type>
    <min>-1000</min>
    <max>1000</max>
    <default>2.0</default>
</parameter>
Element Type Info
<type> float Defines a float input field
<default> float The default value
<min> float Minimum value
<max> float Maximum value

int / uint16

<parameter>
    <name>filter_groupIndex</name>
    <displayName>Group</displayName>
    <description>Collision group - object which have collision enabled need to be in the same collision group</description>
    <shortDescription>The collision group</shortDescription>
    <type>int</type>
    <default>0</default>
</parameter>
Element Type Info
<type> int Defines a int input field
<default> int The default value

BitField

The bit field is a more complicated structure and might get a better XML representation some day.

It works quite simple for now. First you need to define a biefield parameter which holds the other values. The values themselves get an additional field <bitfield>yes</bitfield> which connects them to the bit field.

Make sure to match the size of the values to the <size> value in the bitfield definition.

<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>
Element Type Info
<type> bitfield Defines a bitfield input
<size> int The number of bits usually 16 or 32

Data structure

Top level objects

Value Description
global Contains all generic parameters defined in <global>
bodies Contains all bodies as body objects

Body

A body object holds all the bodies defined in PhysicsEditor. Here's a table of the built in values. Values defined in the <body> section of the exporter.xml are added to the object.

Value Description
anchorPointRel.x Anchorpoint's x coordinate relative to the sprite's size.
anchorPointRel.y Anchorpoint's y coordinate relative to the sprite's size.
anchorPointAbs.x Anchorpoint's x coordinate in pixels.
anchorPointAbs.y Anchorpoint's y coordinate in pixels.
body.size.width The body's width in pixels. Same as sprite width.
body.size.height The body's height in pixels. Same as sprite width.
body.fixtures List of body's fixture objects.

Fixture

A fixture object holds all the fixtures defined in a body. Here's a table of the built in values. Values defined in the <fixture> section of the exporter.xml are added to the object.

Value Description
type Type of the fixture POLYGON or CIRCLE
isCircle Convenience function to check if the fixture is a circle

Circle-Fixture

These additional values are available inside circle fixtures.

Value Description
fixture.radius The radius of the shape in pixels
fixture.center.x Circle's center coordinate, x value
fixture.center.y Circle's center coordinate, y value

Polygon-Fixture

These additional values are available inside polygon fixtures.

Value Description
fixture.hull All points as a single polygon object - may be concave. Order of the points depends on the physics engine set in the exporter.xml
fixture.polygons List of convex polygon objects after convex decomposition.

Polygon

A polygon is a list of point objects:

Value Description
x x coordinate of a vertex in pixels
y y coordinate of a vertex in pixels

The Template

I am using the GrantLee template system, which is close to Django templates. The basics are available from the GrantLee's documentation.

A good starting point is the plain text exporter which is part of PhysicsEditor's distribution - since it contains all variables and features.

Referencing values

You can access 2 types of values

Values are surrounded by {{ and }}

Sub values are separated by ..

You might use | after the value itself to use filters for changing the value itself. Please have a look a the GrantLee's documentation for more details about that.

Template Output Remark
gravity={{global.gravity}};
gravity=9.800000;
This uses the gravity property from the global object and insers it into the template. (Gravity is a custom property.)
gravity={{global.gravity|floatformat:3}};
gravity=9.800;
Same as above with shortening the float value to 3 digits.

Control-Structure: if

{% if condition %} ... {% else %} ... {% endif %}

Control-Structure: for

{% for object in objectList %} ... {% endfor %}

Mixed example

This example prints a list of coordinates, separating each block with a , but not adding a comma before the first element of the list:

{% for point in fixture.hull %} {% if not forloop.first %}, {% endif %}({{point.x}}, {{point.y}}) {% endfor %}

Conclusion

This is a lot of hard stuff here - but if you have a closer look at the exporters included in the PhysicsEditor application folder you might get started quite fast.

The flexible GUI system allows you to fully customize the user interface according to your needs. Simply adding properties just as you need them.

You can enhance or define any format with the template based exporter - giving you the full control over your physics shapes.

Andreas Löw Join the CodeAndWeb Newsletter (privacy policy)
I'm a robot