Custom exporter

How to add custom output formats to PhysicsEditor:

An exporter consists of 2 files

  • exporter.xml - the description of the exporter itself
  • template.txt - a template file containing the file layout

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.

PhysicsEditor 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 already says - an xml file.

It has 4 main blocks:

  • Global exporter settings - settings for the exporter itself
  • Global parameters - settings for all bodies - e.g. gravity
  • Body parameters - settings for one body - e.g. body name, type, ...
  • Fixture parameters - settings for a single fixture - e.g. bounce rate of the head

Example:

<?xml version="1.0"?>
<exporter>

    <!-- exporter settings -->
    <name>cocos2d-x</name>
    <displayName>Cocos2d-x</displayName>
    <description>Exporter for Cocos2d-x</description>
    <version>1.0</version>
    <yAxisDirection>up</yAxisDirection>
    <physicsEngine>chipmunk</physicsEngine>
    <template>cocos2d-x.plist</template>
    <fileExtension>plist</fileExtension>
    <anchorPoint>
        <enabled>yes</enabled>
        <relX>0.5</relX>
        <relY>0.5</relY>
    </anchorPoint>
    <origin>
        <type>fixed</type>
        <relX>0.5</relX>
        <relY>0.5</relY>
    </origin>

    <global>
        <!-- global parameters -->
    </global>

    <body>
        <!-- body parameters -->
        <parameter>
            <name>is_dynamic</name>
            <displayName>Dynamic body</displayName>
            <description>A non-dynamic body is immovable such as a wall or the ground.</description>
            <type>bool</type>
            <default>true</default>
        </parameter>
        ...
    </body>

    <fixture>
        <!-- fixture parameters -->
        <parameter>
            <name>density</name>
            <displayName>Density</displayName>
            <description>Density of the physics shape.</description>
            <type>float</type>
            <default>1.0</default>
        </parameter>
        ...
    </fixture>
</exporter>

Global exporter parameters

ElementTypeInfo
<name>stringIdentifier for the exporter, must be unique. Otherwise the lastest exporter found for that name will overwrite the others.
<displayName>stringThis is how the exporter's name is displayed in the combo box in the GUI
<description>stringSome information about the exporter
<version>stringExporter 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>stringName of the template file - relative to the exporter.xml
<fileExtension>stringFile extension used when exporting the data file

Anchor Points

PhysicsEditor editing AnchorPoint/PivotPoint 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:

ElementTypeInfo
<enabled>"yes" | "no"Display and use anchor points for this exporter
<relX>floatRelative position of the anchor points x position
<relY>floatRelative 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.

ElementTypeInfo
<type>"fixed" | "anchorPoint"Fixed sets a fixed relative position to the sprite's size, anchorPoint uses the AnchorPoint as sprite's center
<relX>floatRelative position of the origin x position
<relY>floatRelative 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.

ElementTypeInfo
<global><parameter>[]The global parameters used for the complete file - e.g. gravity
<body><parameter>[]Parameters used for an individual body
<fixture><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&gt; and <fixture&gt; zero or more parameters can be defined.

Values for all parameters

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

ElementTypeInfo
<name>stringName of the value (used in the template)
<displayName>stringHuman readable name of the value (used in the user interface)
<description>stringDescription of the element used in the tooltip when hovering over the element for some time
<shortDescription>stringShort 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

ElementTypeInfo
<type>boolDefines a bool input field / Checkbox
<default>"false" | "true"The default value
PhysicsEditor with custom bool parameter
A bool parameter rendered in the PhysicsEditor UI.
<parameter>
    <name>isSensor</name>
    <displayName>Is Sensor</displayName>
    <description>The object only detects collisions without colliding</description>
    <shortDescription>Turns the fixture into a sensor</shortDescription>
    <type>bool</type>
    <default>false</default>
</parameter>

string

ElementTypeInfo
<type>stringDefines a string input field
<default>stringThe default value which is used if nothing else is entered
PhysicsEditor with custom string parameter
A string parameter rendered in the PhysicsEditor UI.
<parameter>
    <name>fixture_id</name>
    <displayName>Identifier</displayName>
    <description>Identify a fixture during collision detection</description>
    <shortDescription>Identifier for the fixture</shortDescription>
    <type><code>string</code></type>
    <default>fixture123</default>
</parameter>

float

ElementTypeInfo
<type>floatDefines a float input field
<default>floatThe default value
<min>floatMinimum value
<max>floatMaximum value
PhysicsEditor with custom float parameter
A float parameter rendered in the PhysicsEditor UI.
<parameter>
    <name>density</name>
    <displayName>Density</displayName>
    <description>
        Density of the fixture, results in the mass if multiplied with the fixture's area
    </description>
    <shortDescription>Density of the fixture</shortDescription>
    <type>float</type>
    <min>-1000</min>
    <max>1000</max>
    <default>2.0</default>
</parameter>

int / uint16

ElementTypeInfo
<type>intDefines a int input field
<default>intThe default value
PhysicsEditor with custom int parameter
An int parameter rendered in the PhysicsEditor UI.
<parameter>
    <name>filter_groupIndex</name>
    <displayName>Group</displayName>
    <description>
        Collision group - objects 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>

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 bitfield 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.

ElementTypeInfo
<type>"bitfield"Defines a bitfield input
<size>intThe number of bits usually 16 or 32
PhysicsEditor with custom bitfield parameter
An bitfield parameter rendered in the PhysicsEditor UI.

This block creates the basic bit field:

<parameter>
    <name>filter_bitfield</name>
    <type>bitfield</type>
    <size>16</size>
</parameter>

This block adds a variable for the collision category and attaches it to the bit field.

<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>

This block adds another variable for the collision mask:

<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>

The Template

I am using the GrantLee template system, which is close to Django templates. The basics are available from the TexturePacker & PhysicsEditor Template Language. A good starting point is the plain text exporter which is part of PhysicsEditor's distribution - since it contains all variables and features.

The template gets its data through the data structure described below.

Referencing values

You can access 2 types of values

  • Build in values
  • Values that are added through parameters in exporter.xml

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 at TexturePacker & PhysicsEditor Template Language for more details about that.

TemplateOutputRemark
g={{global.gravity}};g=9.800000;

This uses the gravity property from the global object and inserts it into the template. (Gravity is a custom property.)

g={{global.gravity|floatformat:3}};g=9.800;

Same as above with shortening the float value to 3 digits.

Control structures

Control-Structure: if

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

Renders the first block if the condition is true, the second if it's false.

Example:

dynamic = {% if body.is_dynamic %}true{% else %}false{% endif %};

Control-Structure: for

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

Loops over a list of elements in the data structure.

The variable forloop.first is true if the loop is in the first cycle.

Example:

{% for body in bodies %}
    {{body.name}}
{% 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 %}

Data structure

Top level objects

ValueTypeDescription
global

Contains all generic parameters defined in <global>

bodiesBody

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.

ValueTypeDescription
anchorPointRelPoint

Anchorpoint's coordinates relative to the sprite's size.

anchorPointAbsPoint

Anchorpoint's coordinate in pixels.

sizeSize

The body's size in pixels. Same as sprite width.

fixtures

Fixture[]

List of body's Fixture objects.

Fixture

A fixture object holds all the fixtures defined in a body. Values defined in the <fixture> section of the exporter.xml are added to the object.

Circle-Fixture

These additional values are available inside circle fixtures.

ValueTypeDescription
type

"CIRCLE"

Type of the fixture

isCircletrue

Convenience function to check if the fixture is a circle

radiusfloat

The radius of the shape in pixels

centerPoint

Circle's center coordinate

Polygon-Fixture

These additional values are available inside polygon fixtures.

ValueDescription
type

"POLYGON"

Type of the fixture

isCirclefalse

Convenience function to check if the fixture is a circle

hullPolygon

All points as a single Polygon object - may be concave. Order of the points depends on the physics engine set in the exporter.xml

polygons

Polygon[]

List of convex Polygon objects after convex decomposition.

Polygon

A polygon is a list of Point objects.

Point

ValueDescription
x

x coordinate of a vertex in pixels

y

y coordinate of a vertex in pixels

Size

ValueDescription
width

width of the object in pixels

height

height of the object in pixels