canvas = {
const timeStep = 1 / 60;
const velocityIterations = 8;
const positionIterations = 3;
const maxVertices = 1 << 16;
const renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xFFFFFF);
renderer.setSize(width, height);
renderer.setPixelRatio(devicePixelRatio);
invalidation.then(() => renderer.dispose());
const geometry = new THREE.BufferGeometry();
geometry.addAttribute("position", new THREE.BufferAttribute(new Float32Array(maxVertices * 3), 3));
geometry.addAttribute("color", new THREE.BufferAttribute(new Float32Array(maxVertices * 3), 3));
const positions = geometry.attributes.position.array;
const colors = geometry.attributes.color.array;
const buffer = new THREE.LineSegments(geometry, new THREE.LineBasicMaterial({vertexColors: THREE.VertexColors}));
const particleVertices = [];
const particleResolution = 8;
let currentVertex = 0;
initCircleVertices(particleVertices, particleResolution);
const camera = new THREE.PerspectiveCamera(70, width / height, 1, 1000);
camera.position.x = 0;
camera.position.y = 1;
camera.position.z = 2.5;
camera.lookAt(0, 1, 0);
const scene = new THREE.Scene();
scene.add(buffer);
function insertLine(x1, y1, x2, y2) {
let i = currentVertex;
let threeI = i * 3;
positions[threeI] = x1;
positions[threeI + 1] = y1;
positions[threeI + 2] = 0;
i++;
threeI = i * 3;
positions[threeI] = x2;
positions[threeI + 1] = y2;
positions[threeI + 2] = 0;
currentVertex += 2;
}
function insertParticleVertices(radius, x, y) {
const vertices = particleVertices;
for (let i = 0; i < particleResolution; ++i) {
const i4 = i * 4;
const x1 = vertices[i4] * radius + x;
const y1 = vertices[i4 + 1] * radius + y;
const x2 = vertices[i4 + 2] * radius + x;
const y2 = vertices[i4 + 3] * radius + y;
insertLine(x1, y1, x2, y2);
}
}
function initCircleVertices(v, resolution) {
const size = 2 * Math.PI / resolution;
for (let i = 0; i < resolution; ++i) {
const s1 = i * size;
const s2 = (i + 1) * size;
v.push(Math.cos(s1), Math.sin(s1), Math.cos(s2), Math.sin(s2));
}
}
function transformAndInsert(v1, v2, transform) {
const tv1 = new b2.Vec2();
const tv2 = new b2.Vec2();
b2.Vec2.Mul(tv1, transform, v1);
b2.Vec2.Mul(tv2, transform, v2);
insertLine(tv1.x, tv1.y, tv2.x, tv2.y);
}
function transformVerticesAndInsert(vertices, transform) {
for (let i = 1, n = vertices.length; i < n; i++) {
transformAndInsert(vertices[i - 1], vertices[i], transform);
}
}
function drawPolygonShape(shape, transform) {
const i = currentVertex * 3;
transformVerticesAndInsert(shape.vertices, transform, 0, 0, 0);
const j = (currentVertex - 1) * 3;
insertLine(positions[j], positions[j + 1], positions[i], positions[i + 1]);
}
function drawParticleSystem(system) {
const particles = system.GetPositionBuffer();
for (let i = 0, n = particles.length; i < n; i += 2) {
insertParticleVertices(system.radius / 2, particles[i], particles[i + 1], 3);
}
}
function draw() {
const world = machine.world;
currentVertex = 0;
for (let i = 0, n = world.bodies.length; i < n; i++) {
const body = world.bodies[i];
const transform = body.GetTransform();
for (let j = 0, m = body.fixtures.length; j < m; j++) {
drawPolygonShape(body.fixtures[j].shape, transform);
}
}
for (var i = 0, n = world.particleSystems.length; i < n; i++) {
drawParticleSystem(world.particleSystems[i]);
}
buffer.geometry.attributes.position.needsUpdate = true;
// buffer.geometry.attributes.color.needsUpdate = true;
renderer.render(scene, camera);
}
for (let time = 0; true; time += timeStep) {
machine.world.Step(timeStep, velocityIterations, positionIterations);
machine.joint.SetMotorSpeed(Math.cos(time) / 3 - machine.joint.GetJointAngle());
draw();
yield renderer.domElement;
}
}