When it comes to rendering box2d bodies on the canvas, a common issue arises. Box2d provides us with the center of the body and its angle, while the canvas draws shapes like rectangles from the top-left corner. I encountered this problem but managed to find a solution by following tutorials from Seth Land. Here's the code snippet that helped me address this challenge:
g.ctx.save();
g.ctx.translate(b.GetPosition().x*SCALE, b.GetPosition().y*SCALE);
g.ctx.rotate(b.GetAngle());
g.ctx.translate(-(b.GetPosition().x)*SCALE, -(b.GetPosition().y)*SCALE);
g.ctx.strokeRect(b.GetPosition().x*SCALE-30,b.GetPosition().y*SCALE-5,60,10);
g.ctx.restore();
In the above code, b
represents the body, SCALE
is the canvas-pixel/box2d-meters converter, and 60 and 10 are the dimensions of the rectangle (half dimensions being 30 and 5).
_
The Challenge Ahead
Now, my goal is to render this in three.js. The initial hurdle is that three.js works in 3D while box2d operates in 2D. However, I aim to create a 3D rectangle on top of the existing 2D structure. I want to retain the 2D axis dimensions from box2d and introduce an arbitrary third dimension.
While my project doesn't necessitate 3D physics, I desire to add thickness to these 2D objects in the third dimension. How can I achieve this? My attempts so far have been as follows:
// Top-down perspective
camera.position.set(0,1000,0);
camera.rotation.set(-1.5,0,0);
geometry = new THREE.CubeGeometry(200, 60, 10, 1, 1, 1);
// Obtain b as box2d rectangle
loop(){
mesh.rotation.y = -b.GetAngle();
mesh.position.x = b.GetPosition().x*SCALE;
mesh.position.y = -b.GetPosition().y*SCALE;
}
Regrettably, this approach doesn't replicate the box2d debug draw accurately. The value of -1.5 for camera rotation does not provide the desired 90-degree angle turn (if someone knows the correct value, please share). Additionally, the three.js rectangle fails to align with the movements of box2d, similar to the issues faced with standard canvas before implementing context translations and rotations.
I am hopeful that someone can offer insights into a potential solution. Thank you in advance! :)
EDIT: It appears that someone has already accomplished this feat (requires WebGL on Chrome): http://serv1.aelag.com:8082/threeBox
The second link showcases spheres, so there are no challenges with rotation mapping between box2d and three.js. The first link includes cubes and rectangles, which aligns with what I am aiming to achieve.