We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexDiscussionExhibition › JBox2D with BoxWrap2D Tutorial
Page Index Toggle Pages: 1
JBox2D with BoxWrap2D Tutorial (Read 11368 times)
JBox2D with BoxWrap2D Tutorial
Jul 7th, 2009, 11:24pm
 
Note: this thread is intended to be a monologue / tutorial, hopefully a kind of reference. To keep information relevant, I suggest to post your (welcomed) remarks in a separate thread: Discussion on the JBox2D with BoxWrap2D Tutorial.

Some months ago I saw a Flash program showing some uses of a 2D physics engine (solid objects) and I was seduced. I searched some Java engines and didn't found many. Later, ewjordan shown JBox2D, his port of Box2D (a C++ library) to Java and its Processing wrapper, BoxWrap2D.

Somehow I postponed discovering of the library, fearing it was complex and time consuming to learn.

But more recently I played some nice Flash games using physics engines (most of them derived from Box2D...) on Kongregate, and I saw renewed interest on the library in Discourse.
I saw that as a good opportunity to jump. And found out it wasn't so hard. Somehow, it is even simpler than doing a simple, typical "ball hitting walls and other balls" sketch in Processing!

At time of starting to write this tutorial, I am hardly more knowledgeable than you... I played a bit with the BoxWrap2D demo, with the shown custom rendering methods, and I read the tutorial for Box2D. It looks manageable so I though I should share my first steps in the hope it will jump start other persons.
I pondered a bit if I should start directly with JBox2D (as I want to use it in other environments) or walk before running and use BoxWrap2D. I chose the latter, partly because of this tutorial... And looking how BoxWrap2D is done is a good learning experience as well.

Enough meta discussion, let's begin!
We first set the scene, making a kind of template we will use every time.

Code:
// Import everything exposed by JBox2D (except the testbed stuff)
import org.jbox2d.common.*;
import org.jbox2d.collision.*;
import org.jbox2d.dynamics.*;
import org.jbox2d.dynamics.joints.*;
import org.jbox2d.dynamics.contacts.*;
// BoxWrap2D
import org.jbox2d.p5.*;

// A reference to the physics engine
Physics physics;

void setup()
{
 // Medium sized scene
 size(640, 480);
 // Physics is computed 60 times per second, so let's draw at same rate
 frameRate(60);
 // Nicer graphisc
 smooth();
 // Set up everything physics
 InitScene();
}

void draw()
{
 // Not much to do here, most drawing is handled by BoxWrap2D
 background(255);
}

void mousePressed()
{
 // Do something interactive, like creating new objects
}

void keyPressed()
{
 // Can be used to reset the sketch, for example
 physics.destroy();
 physics = null;
 InitScene();
}

void InitScene()
{
 // Set up the engine with the sketch's dimensions
 physics = new Physics(this, width, height);
}


If we try and run this sketch... it works! (if you installed correctly the library.) But it is quite boring, there is almost nothing to see... Just a static border around the sketch.

What is it doing? Actually quite a number of things. It defines a camera position (used for zooms or pans), defines the limits of the simulation and the world where the objects will live, define defaults settings for new objects: density (weight per volume, or rather surface here), restitution (if objects are elastic or not), friction (are they smooth or rough) and some other parameters like gravity (close of Earth's one).
And lastly, it creates a big hollow box around the sketch, to avoid loosing the falling objects.

So let's add some objects there, to see them falling on the ground.

I add a CreateObjects(); call at the end of setup() and create this function:
Code:
void CreateObjects()
{
 // A round object in the middle of the scene (center coordinates, radius)
 physics.createCircle(width / 2.0, height / 2.0, 50.0);
 // And two rectangles not far (coordinates of top-left, and bottom-right corners)
 physics.createRect(
     width / 2.0 - 150, height / 2.0 - 50,
     width / 2.0 - 75, height / 2.0 + 50
 );
 physics.createRect(
     width / 2.0 + 75, height / 2.0 - 40,
     width / 2.0 + 175, height / 2.0 + 40
 );
}


Ah, I see the objects, but they don't fall... At least, we can see how circles are done (by default): as a polygon, with a line to see them rolling.
OK, actually, the objects were created without density, they weight nothing so they can't fall!
Such weightless object are drawn in green.
I will just add physics.setDensity(1.0); after the physics creation in InitScene(), so that all objects created later will get this value.

Cool, they fall to the ground. They are gray and change color (violet) when they find a stable position (no more updates to position).
Let's add a polygon object, that's the third (and last) kind of object we can create with BoxWrap2D.

 physics.createPolygon(
     hw - 150, hh - 100,
     hw, hh - 150,
     hw + 150, hh - 100
 );


(I defined hw and hh as half width and half height, faster to type and more readable.)
Mmm, the triangle doesn't move and is green. I see: "Ordered clockwise in screen coordinates (which becomes counterclockwise in world coordinates)." and "if your objects are showing up as static objects instead of dynamic ones, and are not colliding correctly, you have probably not met the clockwise ordering requirement". OK, but it is defined clockwise (unless I got my mental model wrong...). Just try the reverse order:

 physics.createPolygon(
     hw + 150, hh - 100,
     hw, hh - 150,
     hw - 150, hh - 100
 );


It works nicely. Looks like the information is wrong there, unless I miss something.

That's all for the first lesson, we will make our objects more dynamic in the next one!
JBox2D with BoxWrap2D Tutorial - Part 2
Reply #1 - Jul 8th, 2009, 4:55am
 
In the previous lesson, we made some objects and saw them falling.
Nice, but quickly boring... Smiley
Let see where we stopped, so we can make the sketch to evolve to something more dynamic.

Code:
// Import everything exposed by JBox2D (except the testbed stuff)
import org.jbox2d.common.*;
import org.jbox2d.collision.*;
import org.jbox2d.dynamics.*;
import org.jbox2d.dynamics.joints.*;
import org.jbox2d.dynamics.contacts.*;
// BoxWrap2D
import org.jbox2d.p5.*;

// A reference to the physics engine
Physics physics;

void setup()
{
// Medium sized scene
size(640, 480);
// Physics is computed 60 times per second, so let's draw at same rate
frameRate(60);
// Nicer graphisc
smooth();

// Set up everything physics
InitScene();
// And add object to the scene
CreateObjects();
}

void draw()
{
// Not much to do here, most drawing is handled by BoxWrap2D
background(255);
}

void keyPressed()
{
// Can be used to reset the sketch, for example
physics.destroy();
physics = null;
InitScene();
CreateObjects();
}

void InitScene()
{
// Set up the engine with the sketch's dimensions
physics = new Physics(this, width, height);
physics.setDensity(1.0);
}

void CreateObjects()
{
// Middle of the world
float hw = width / 2.0;
float hh = height / 2.0;

// A round object in the middle of the scene (center coordinates, radius)
physics.createCircle(hw, hh, 50.0);
// And two rectangles not far (coordinates of top-left, and bottom-right corners)
physics.createRect(
hw - 150, hh - 50,
hw - 75, hh + 50
);
physics.createRect(
hw + 75, hh - 40,
hw + 175, hh + 40
);
// A polygon, defined by a list of vertices
physics.createPolygon(
hw + 150, hh - 100,
hw, hh - 150,
hw - 150, hh - 100
);
}


We can add fixed obstacles: as we saw, they just need to have a density of 0, eg. by defining them before the setDensity, or by changing it on the fly:

Code:
void InitScene()
{
// Set up the engine with the sketch's dimensions
physics = new Physics(this, width, height);
// Add fixed obstacles, of density 0.0
physics.createCircle(width / 5, height / 5, 10.0);
physics.createCircle(4 * width / 5, height / 5, 10.0);
physics.createCircle(width / 5, 4 * height / 5, 10.0);
physics.createCircle(4 * width / 5, 4 * height / 5, 10.0);
// And set the density for the other objects
physics.setDensity(1.0);
}


Now, we can give an initial velocity (speed) to the objects, to make them flying across the scene...
We need to get the result of the createXxx methods, and change their settings.
Beware! The velocity vector is expressed as a point relative to the center of mass of the object. But, like most methods not wrapped by BoxWrap2D, the coordinates are expressed in world units, where the origin is at the bottom-left of the scene (y is upward, which makes sense for a physics simulation).

Code:
void CreateObjects()
{
// Middle of the world
float hw = width / 2.0;
float hh = height / 2.0;

// A round object in the middle of the scene (center coordinates, radius)
Body circle = physics.createCircle(hw, hh, 50.0);
// Make it rotating (value in radian/second)
circle.setAngularVelocity(3.0);
// And two rectangles not far (coordinates of top-left, and bottom-right corners)
Body rect1 = physics.createRect(
hw - 150, hh - 50,
hw - 75, hh + 50
);
// Small vector: slow
Vec2 v1 = new Vec2(-10.0, 0.0); // To the left
rect1.setLinearVelocity(v1);

Body rect2 = physics.createRect(
hw + 75, hh - 40,
hw + 175, hh + 40
);
// Bigger: fast
Vec2 v2 = new Vec2(20.0, 50.0); // Toward top-right
rect2.setLinearVelocity(v2);

// A polygon, defined by a list of vertices
Body triangle = physics.createPolygon(
hw + 150, hh - 100,
hw, hh - 150,
hw - 150, hh - 100
);
Vec2 v3 = new Vec2(5.0, 30.0); // Go a little high
triangle.setLinearVelocity(v3);
}


Yeah, that's more lively! Smiley Hit a key to see the scene again.

Now, let's do something interactively. Like in the BoxWrap2D demo, we will create a random moving circle on mouse click. I spice it a bit by making these "balls" super-rebounding.

Code:
void mousePressed()
{
// Do something interactive, like creating new objects
float r = physics.getRestitution();
physics.setRestitution(0.9); // Make them super-rebounding
Body randomBody = physics.createCircle(mouseX, mouseY, random(5.0, 15.0));
Vec2 vel = new Vec2(random(-30.0, 30.0), random(-30.0, 30.0));
randomBody.setLinearVelocity(vel);
physics.setRestitution(r); // Restore
}


Lastly, I will display the position of the circle, as an example of on-screen display and position tracking. The trick here is also to transform the position we get from the body, which is in world units, to screen units.

I declare:
Body circle; (and of course remove the Body declaration from CreateObjects)
I add:
 PFont f = loadFont("Verdana-12.vlw");
 textFont(f);

to setup.
And I change draw():
Code:
void draw()
{
// Not much to do here, most drawing is handled by BoxWrap2D
background(255);
// Show position of circle
Vec2 posW = circle.getPosition();
Vec2 posS = physics.worldToScreen(posW);
String position = String.format("Pos: %.2f, %.2f", posS.x, posS.y);
text(position, 10, 20);
}


That's all. Next time, we will make more complex compound shapes with joints.
Re: JBox2D with BoxWrap2D Tutorial
Reply #2 - Jul 8th, 2009, 8:33am
 
A remark on performance: I use, out of habit, the default renderer (JAVA2D). In the previous versions of BoxWrap2D, the P3D renderer used by the demo gave some strange result. In the latest version it is OK, so I compared the performances.
For this, I measured the time needed for the circle to stop. I added a linear velocity to it to avoid the slow drift in the above sketch:
 circle.setAngularVelocity(3.0);
 Vec2 vc = new Vec2(-30.0, 0.0); // To the left
 circle.setLinearVelocity(vc);

and at the end of CreateObjects() I added a time sample:
 timeStart = millis(); bShown = false;
where I define the variables before setup():
boolean bShown; long timeStart;
At the end of draw(), I just add:
 if (circle.isSleeping() && !bShown)
 {
   println(millis() - timeStart);
   bShown = true;
 }

Thus, when the circle stops moving (isSleeping() call), I show the time since the start of movement.

Results:
JAVA2D: 12515 / 12078 / 12406 -- 12406 / 12406 / 12500
P2D: 9890 / 9609 / 9360 -- 8985 / 8828 / 8312
P3D: 12546 / 11891 / 11906 -- 8938 / 8469 / 8219
OPENGL: 6407 / 6203 / 6203 -- 5157 / 4968 / 4969
All this to render 374 frames, whatever the mode. I measure always 3 times (using the reset scene feature) to get a mean time. The second set of numbers, after --, is measured with smooth() commented out.

So we get respectively: 30, 39, 31 and 60 frames per second with smooth, and 30, 43, 44 and 74 FPS without.
Only OpenGL is able to keep up with the world calculation rate... For a very simple scene. I am a bit surprised to see a frame rate higher than the requested one for OpenGL...

I tested that on a rather old and slow computer... You might find different results (more or less difference, depending on computer power and graphics card power...). You are welcome to share your results... in the other thread! Smiley

NOTE: you can find the full code of the final sketches of each lesson (perhaps slightly changed) at my Processing Launchpad repository.
JBox2D with BoxWrap2D Tutorial - Part 3
Reply #3 - Jul 10th, 2009, 3:23pm
 
I will report joint study to next lesson...
I saw an advice to avoid using setXxxVelocity on bodies, as this is quite artificial, not fitting in a physics world (although it has its uses and well, it is useful for a quick demo...).
Why? Because you set the speed out of the blues, without taking in account inertia and such.
And there are three functions to do that in a more physics way, applying torque (for rotation), impulse (a sudden strike) or force (more designed for continuous or relatively long period application).

At the same time, I show how to pick a shape with mouse, how to draw custom decoration over the scene, and how to use these forces, of course.

We will start with the same base than the second lesson, with usual imports and a setup() loading a font. Curiously, on another old computer I use, the text displayed in draw() is shown only in Java2D mode...

We will start by creating the scene and the objects. To spice a bit the scene, I make a number of fixed plots:
Code:
// Reference to the world as we need it for more advanced stuff...
World world;

void InitScene()
{
// Set up the engine with the sketch's dimensions
physics = new Physics(this, width, height);
world = physics.getWorld();
// Add some fixed obstacles, of density 0.0
for (int ic = 0, margin = 50; ic < 10; ic++)
{
physics.createCircle(
random(margin, width - margin),
random(margin, height - margin), 10.0);
}
// And set the density for the other objects
physics.setDensity(1.0);
}


And I add a bunch of small objects over the usual ones (and some others):
Code:
void CreateObjects()
{
// Middle of the world
float hw = width / 2.0;
float hh = height / 2.0;

for (int p = 20; p < width - 20; p += 7)
{
physics.createRect(p, 25, p + 5, 30);
}

physics.createCircle(hw, hh, 50.0);
physics.createRect(hw - 150, hh - 50, hw - 75, hh + 50);
physics.createRect(hw + 75, hh - 40, hw + 175, hh + 40);
physics.createPolygon(
hw + 120, hh - 80,
hw + 150, hh - 100,
hw, hh - 150,
hw - 150, hh - 100,
hw - 120, hh - 80
);
// Some smaller, more rebunding objects
physics.setRestitution(0.9);
physics.createCircle(hw - 75, hh - 75, 20.0);
physics.createRect(50, 50, 100, 100);
physics.setRestitution(0.7);
physics.createCircle(hw + 75, hh + 75, 20.0);
physics.createRect(width - 50, 50, width - 100, 100);
}


To find which shape is under the mouse (or any given point), we use a trick: Box2D allows to check of a given bounding box (AABB = Axis Aligned Bounding Box) intersects a shape, so we make a very small box around the point of interest, and list all shapes intersecting it. If none is found, we are on the scene. If it is a shape belonging to a static body, we skip it (in general, we want to pick something else than the background).
Otherwise, we double-check the shape encloses the point (in case we are not lucky and landed just on the edge) and if OK, we return the first found body (which should be the only one as the bodies rarely overlap).
Code:
// Idea taken from source seen at The Stem > Box2D Joints #2 - Revolute Joints <http://blog.thestem.ca/archives/102>
Body GetBodyAtPoint(float x, float y)
{
// Create a small box at mouse point
Vec2 v = physics.screenToWorld(x, y);
AABB aabb = new AABB(new Vec2(v.x - 0.001, v.y - 0.001), new Vec2(v.x + 0.001, v.y + 0.001));
// Look at the shapes intersecting this box (max.: 10)
org.jbox2d.collision.Shape[] shapes = world.query(aabb, 10);
if (shapes == null)
return null; // No body there...
for (int is = 0; is < shapes.length; is++)
{
org.jbox2d.collision.Shape s = shapes[is];
if (!s.m_body.isStatic()) // Don't pick static shapes
{
// Ensure it is really at this point
if (s.testPoint(s.m_body.getXForm(), v))
return s.m_body; // Return the first body found
}
}
return null;
}


We capture the click in mouseReleased(), and exploit the information in draw():
Code:
// Latest touched object
Body movedBody;
// Get the position where the mouse is pressed
float pressMouseX = -1, pressMouseY = -1;
void mousePressed()
{
pressMouseX = mouseX;
pressMouseY = mouseY;
}

// When released, we see if it is on a non-static body
void mouseReleased()
{
movedBody = GetBodyAtPoint(mouseX, mouseY);
pressMouseX = pressMouseY = -1;
}

// Information on interaction (used shown later)
String information = "";

void draw()
{
background(255);
// Show position of latest touched object
if (movedBody != null)
{
Vec2 posW = movedBody.getPosition();
Vec2 posS = physics.worldToScreen(posW);
String position = String.format("Pos: %.2f, %.2f - %s", posS.x, posS.y, information);
text(position, 10, 20);
}
// We visualize the drag scope
if (pressMouseX >= 0)
{
stroke(#FF8800);
line(pressMouseX, pressMouseY, mouseX, mouseY);
}
}


Mmm, long message, continuing on next one...
Re: JBox2D with BoxWrap2D Tutorial
Reply #4 - Jul 10th, 2009, 3:24pm
 
Now, as promised, we can do three kinds of action, we chose it with a press of a key:
Code:

void keyPressed()
{
 switch (key)
 {
 case 'r':
 case 'R':
   // Reset the sketch
   physics.destroy();
   physics = null;
   InitScene();
   CreateObjects();
   break;
 case 't':
 case 'T':
   interactionKind = 'T';
   break;
 case 'f':
 case 'F':
   interactionKind = 'F';
   break;
 case 'i':
 case 'I':
   interactionKind = 'I';
   break;
 default: // Ignore...
 }
}


And we apply the chosen action:
Code:
// Code of interaction to apply
char interactionKind = 'T';

// When released, we see if it is on a non-static body
// and if so, we apply the currently chosen action
void mouseReleased()
{
 movedBody = GetBodyAtPoint(mouseX, mouseY);
 if (movedBody != null)
 {
   // We apply force or impulse where we click
   Vec2 point = new Vec2(mouseX, mouseY);
   float mass = movedBody.m_mass;
   float dX = mouseX - pressMouseX;
   float dY = mouseY - pressMouseY;
   switch (interactionKind)
   {
   case 'T':
float torque = (dX * dX + dY * dY) * (dX < 0 ? 1 : -1);
information = String.format("Torque: %.0f * %.1f", torque, mass);
movedBody.applyTorque(torque * mass);
break;
   case 'F':
Vec2 force = new Vec2(dX / 10, dY / 10);
information = String.format("Force: %s * %.1f", force, mass);
movedBody.applyForce(force.mul(mass), point);
break;
   case 'I':
Vec2 impulse = new Vec2(dX / 100, dY / 100);
information = String.format("Impulse: %s * %.1f", impulse, mass);
movedBody.applyImpulse(impulse.mul(mass), point);
break;
   }
 }
 pressMouseX = pressMouseY = -1;
}


We use the distance between the mouse press and the mouse release (displayed as a line when you drag the mouse), as a parameter to the action given on the object where we release the mouse (if any).
Torque is a torsion effort, it makes the object to rotate around its center of mass. It is expressed in N.m, Newton x meters, we make it proportional to the mass of the body to expect moving it effectively. It is not uncommon to have ranges in the thousands.
Force is a linear effort, expressed in Newtons, also proportional to mass. The magnitude of the force is expressed as a vector, the longer, the stronger the force. It is applied on a point and thus can make the body to rotate.
An impulse is actually just a strong force applied in a very short time (a Box2D time unit), making the body literaly to jump. The force is supposed to be used over several time units, eg. to make an object to float or to stick on a wall. The impulse is more to give a starting move to an object. More explanations on the difference can be found at the Box2D Forums: ApplyImpulse vs. ApplyForce.

Next time, I promise we will see compound shapes and joints.

Remember: you can find the whole code on the Launchpad repository (see 3rd message).
JBox2D with BoxWrap2D Tutorial - Part 3 - A
Reply #5 - Jul 14th, 2009, 11:08am
 
OK, for this lesson, I take the source from the third one, as it offers a bit of interactive tools to play with.
I just remove the random obstacles from InitScene, and rewrite CreateObjects. Actually, I will create a CreateXxxObject function per kind of joint, and replace the interaction kind selection by keyboard by a joint kind selection, which resets the world with a set of objects testing the various possibilities of the joints.
I also use a bigger world: 800x500 and defines globally the middle of the world (HW, HH).
In mouseReleased() I only apply an impulse.
As said, in keyPressed, I choose the demo:
Code:
void keyPressed()
{
// Reset the sketch
physics.destroy();
physics = null;
InitScene();
println(key);
switch (key)
{
case 'd':
case 'D': // Distance
CreateDistanceObjects();
break;
case 'r':
case 'R': // Revolution
CreateRevoluteObjects();
break;
case 'p':
case 'P': // Prismatic
CreatePrismaticObjects();
break;
case 'g':
case 'G': // Gear
CreateGearObjects();
break;
case 'y':
case 'Y': // Pulley
CreatePulleyObjects();
break;
default: // Ignore...
}
}


It appears that testing the various parameters leads to quite long code, so I will split this lesson into several parts (one per joint), partly to make them more edible, partly to fit within forum limits...

Without futher ado, here it the code for the distance joints. I hope the abundant comments will help understanding how they work. Don't hesitate to tweak the values and see how they change the behavior.
Code:
// A distance joint constrains two points on two bodies
// to remain at a fixed distance from each other. You can view
// this as a massless, rigid rod.
// -> That's what is said in the JBox2D source but the distance might vary,
// although there is a tendency to reach this defined distance.
void CreateDistanceObjects()
{
// Set some fixed objects (handles)
physics.setDensity(0.0);
Body hl = physics.createCircle(70.0, 50.0, 10.0);
Body hr = physics.createCircle(width - 70.0, 50.0, 10.0);

int C_NB = 7;
Body[] hc = new Body[C_NB];
for (int i = 0; i < C_NB; i++)
{
hc[i] = physics.createCircle(170 + 75.0 * i, 50.0, 10.0);
}

// And some moving ones
physics.setDensity(1.0);
Body hangingL = physics.createRect(90.0, 150.0, 110.0, 200.0);
Body hangingR = physics.createRect(width - 50.0, 150.0, width - 30.0, 200.0);

Body[] hangC = new Body[C_NB];
for (int i = 0; i < C_NB; i++)
{
hangC[i] = physics.createRect(190 + 75.0 * i, 150.0, 210 + 75.0 * i, 200.0);
}

// The "manual way", If you need to attach somewhere else than at the centers
// Create a distance (stick) joint between two bodies that holds the specified points at a constant distance
// body1, body2, xa, ya, xb, yb
Vec2 hlp = physics.worldToScreen(hl.getPosition());
Vec2 hangingLp = physics.worldToScreen(hangingL.getPosition());
physics.createDistanceJoint(hl, hangingL,
hlp.x, hlp.y, hangingLp.x - 5.0, hangingLp.y - 20.0);

// A simpler way, joining the centers of mass of the bodies
// By default, it is stiff: frequency and damping ratio are zero
JointUtils.createDistanceJoint(hr, hangingR);

// Trying to do something more elastic
DistanceJoint[] dj = new DistanceJoint[C_NB];
for (int i = 0; i < C_NB; i++)
{
dj[i] = JointUtils.createDistanceJoint(hc[i], hangC[i]);
}
// A high frequence makes the hanging object to stabilize faster
dj[0].setFrequency(0.2);
// A low damping ration makes the amplitude of the movement bigger
dj[0].setDampingRatio(0.1);

// (No accessor) Gives some margin to extend
dj[1].m_length *= 2.0;
// Same parameters, for comparison
dj[1].setFrequency(0.2);
dj[1].setDampingRatio(0.1);

// High frequency
dj[2].m_length *= 2.0;
dj[2].setFrequency(1.0);
dj[2].setDampingRatio(0.1);

// Stiffer
dj[3].m_length *= 2.0;
dj[3].setFrequency(0.2);
dj[3].setDampingRatio(0.5);

// Very high frequency with low damping:
// It moves a lot but stops occillating quickly
dj[4].m_length *= 2.0;
dj[4].setFrequency(10.0);
dj[4].setDampingRatio(0.01);

// Smaller extent
dj[5].m_length *= 0.7;
// Same parameters, for comparison
dj[5].setFrequency(0.2);
dj[5].setDampingRatio(0.1);

// With a very low frequency, it doesn't even have time to go up!
dj[6].setFrequency(0.08);
dj[6].setDampingRatio(0.1);

// Tight joints. With no room to extend, I supposed it would make
// a rigid body but the engine makes the shapes to overlap...
Body tb1, tb2, tb3;
tb1 = physics.createRect(20.0, 220.0, 100.0, 240.0);
tb2 = physics.createRect(50.0, 240.0, 70.0, 320.0);
tb3 = physics.createRect(70.0, 260.0, 150.0, 300.0);
JointUtils.createDistanceJoint(tb1, tb2);
JointUtils.createDistanceJoint(tb2, tb3);

// Looser joints
Body lb1, lb2;
lb1 = physics.createRect(200.0, 300.0, 250.0, 350.0);
lb2 = physics.createCircle(300.0, 350.0, 30.0);
JointUtils.createDistanceJoint(lb1, lb2);

// Even looser joints!
Body elb1, elb2;
elb1 = physics.createRect(width - 70.0, 300.0, width - 20.0, 350.0);
elb2 = physics.createCircle(width - 120.0, 250.0, 30.0);
DistanceJoint ldj = JointUtils.createDistanceJoint(elb1, elb2);
ldj.setFrequency(0.2);
ldj.setDampingRatio(0.1);
}


See full source on the Launchpad site.
Next: Prismatic Joint
Re: JBox2D with BoxWrap2D Tutorial
Reply #6 - Mar 2nd, 2010, 7:40am
 
Off-Topic replies have been moved to this Topic.
Page Index Toggle Pages: 1