Skip to main content

2 posts tagged with "scripting"

View All Tags

· One min read
Physion

A new (BodyNode) property was recently added in Physion.

Its name: Gravity Scale (gravityScale).

As the name suggests, the gravityScale property of a body can be used to "scale" the gravitational attraction applied to it. In other words, the gravityScale allows you to specify a different gravity for each body.

By default, the value of this new property is 1.0 meaning that the Scene's gravity will be applied to the body. If you change this value to say 0.5 then only half of the Scene's gravitational force will be applied to the body. If you want to make a body float (i.e ignore gravity) you can set a gravity scale of 0. To make a balloon-like body you can set its gravityScale to a negative number.

In the video below you can see the gravity scale in action:

Note that the minimum value of this property is -1 and its maximum value is +1.

Using this new property and some minimal scripting, the user can easily create gravity pads which are very useful in marble races and other similar simulations.

· 4 min read
Physion

Recently, a feature request was made in Physion's Discord Server: "Add the ability to visualize the trajectory of an object". This functionality was already implemented in the old version of Physion as you can see in the video below:

Unfortunately (and for the time being) the web version of Physion doesn't natively support tracers. The goods news is that we can implement the tracer functionality using scripting.

The Tracer Script

We're going to create a NodeScript (i.e. a script that gets attached to a Node) to implement the tracer functionality.

Let's start with the constructor:

 class Tracer {

constructor(node) {
this.node = node;
this.initialized = false;

this.trajectory = [];
this.maxTrajectorySize = 100;

if (typeof physion !== "undefined") {
this.graphics = physion.utils.createGraphics();
this.lineStyle = physion.utils.createLineStyle(0);
this.fillStyle = physion.utils.createFillStyle(0xff0000);
}

this.tracerRadius = 0.1;
}

// ..

}

In the constructor we initialize the data members of the class that we're going to use:

Data memberDescription
nodeA reference to the node that this script is attached to (passed as argument in the constructor).
initializedBoolean switch to help us perform a "one-off" initialization (see below).
trajectoryThe trajectory array which is going to hold the positions (x, y) of our node as the simulation runs.
maxTrajectorySizeThe maximum length of the trajectory array. The bigger this value is the bigger the trace will be.
graphicsThis is the 'canvas' where the trace will be drawn.
lineStyleThe line style to be used when drawing the tracer (line width of 0 pixels, i.e. don't draw outline)
fillStyleThe fill style to be used when drawing the tracer (red color)
tracerRadiusThe radius of the circles used when drawing the tracer.

The update() method of the script is shown below:

update(delta) {
if (!this.initialized) {
this.initialized = true;
const scene = this.node.findSceneNode();
if (scene) {
scene.layers.foreground.addChild(this.graphics);
}
}

this.updateTrajectory();
this.drawTracer();
}

First, we use our initialized data member to perform a 'one-off' initialization task: Add our graphics to the foreground layer of the scene (that our node belongs to). In order to retrieve the scene that our node belongs to, we use the findscenenode method.

After initialization is performed, the script keeps repeating the following:

  • Updates the trajectory array
  • Draws the tracer

The updateTrajectory() method is responsible to update our trajectory array in each update. It does that by pushing the latest position of our node to the array. It also makes sure that this array doesn't grow infinetely: If the size of the trajectory array gets bigger than maxTrajectorySize then old positions will get removed.

updateTrajectory() {
this.trajectory.push(this.node.getPosition());
while (this.trajectory.length > this.maxTrajectorySize) {
this.trajectory.shift();
}
}

Finally we call the drawTrajectory helper which will use the trajectory array to draw a series of circles thus visualizing the trajectory of our node:

drawTracer() {
if (this.graphics && this.fillStyle) {
this.graphics.clear();
this.trajectory.forEach((point, i) => {
this.fillStyle.alpha = (i + 1) / this.trajectory.length;
physion.utils.drawStyledCircle(this.graphics, point.x, point.y, this.tracerRadius, this.lineStyle, this.fillStyle);
});
}
}

Using the Tracer Script

The Tracer script is available in the Assets Browser. To use it simply drag and drop the script onto the node to create the tracer for.

You can also see the tracer script in action in this sample scene.

Future Work

  • Add the ability to trace any point on an object (and not just its center as presented in this solution).
  • Add a TracerNode (and the corresponding UI) to allow creating tracers natively (i.e. without a custom script)
  • More customization (e.g. gradient color)