UNPKG

cannon

Version:

A lightweight 3D physics engine written in JavaScript.

212 lines (177 loc) 7.87 kB
<!DOCTYPE html> <html> <head> <title>cannon.js - RigidVehicle</title> <meta charset="utf-8"> <link rel="stylesheet" href="css/style.css" type="text/css"/> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> </head> <body> <script src="../build/cannon.js"></script> <script src="../build/cannon.demo.js"></script> <script src="../libs/dat.gui.js"></script> <script src="../libs/Three.js"></script> <script src="../libs/TrackballControls.js"></script> <script src="../libs/Detector.js"></script> <script src="../libs/Stats.js"></script> <script src="../libs/smoothie.js"></script> <script> var demo = new CANNON.Demo(); var mass = 1; var vehicle; demo.addScene("car",function(){ var world = demo.getWorld(); world.gravity.set(0, 0, -30); world.broadphase = new CANNON.SAPBroadphase(world); world.defaultContactMaterial.friction = 0.2; var groundMaterial = new CANNON.Material("groundMaterial"); var wheelMaterial = new CANNON.Material("wheelMaterial"); var wheelGroundContactMaterial = window.wheelGroundContactMaterial = new CANNON.ContactMaterial(wheelMaterial, groundMaterial, { friction: 0.3, restitution: 0, contactEquationStiffness: 1000 }); // We must add the contact materials to the world world.addContactMaterial(wheelGroundContactMaterial); var chassisShape; var centerOfMassAdjust = new CANNON.Vec3(0, 0, -1); chassisShape = new CANNON.Box(new CANNON.Vec3(5, 2, 0.5)); var chassisBody = new CANNON.Body({ mass: 1 }); chassisBody.addShape(chassisShape, centerOfMassAdjust); chassisBody.position.set(0, 0, 0); // Create the vehicle vehicle = new CANNON.RigidVehicle({ chassisBody: chassisBody }); var axisWidth = 7; var wheelShape = new CANNON.Sphere(1.5); var down = new CANNON.Vec3(0, 0, -1); var wheelBody = new CANNON.Body({ mass: mass, material: wheelMaterial }); wheelBody.addShape(wheelShape); vehicle.addWheel({ body: wheelBody, position: new CANNON.Vec3(5, axisWidth/2, 0).vadd(centerOfMassAdjust), axis: new CANNON.Vec3(0, 1, 0), direction: down }); var wheelBody = new CANNON.Body({ mass: mass, material: wheelMaterial }); wheelBody.addShape(wheelShape); vehicle.addWheel({ body: wheelBody, position: new CANNON.Vec3(5, -axisWidth/2, 0).vadd(centerOfMassAdjust), axis: new CANNON.Vec3(0, -1, 0), direction: down }); var wheelBody = new CANNON.Body({ mass: mass, material: wheelMaterial }); wheelBody.addShape(wheelShape); vehicle.addWheel({ body: wheelBody, position: new CANNON.Vec3(-5, axisWidth/2, 0).vadd(centerOfMassAdjust), axis: new CANNON.Vec3(0, 1, 0), direction: down }); var wheelBody = new CANNON.Body({ mass: mass, material: wheelMaterial }); wheelBody.addShape(wheelShape); vehicle.addWheel({ body: wheelBody, position: new CANNON.Vec3(-5, -axisWidth/2, 0).vadd(centerOfMassAdjust), axis: new CANNON.Vec3(0, -1, 0), direction: down }); // Some damping to not spin wheels too fast for(var i=0; i<vehicle.wheelBodies.length; i++){ vehicle.wheelBodies[i].angularDamping = 0.4; } // Constrain wheels var constraints = []; // Add visuals demo.addVisual(vehicle.chassisBody); for(var i=0; i<vehicle.wheelBodies.length; i++){ demo.addVisual(vehicle.wheelBodies[i]); } vehicle.addToWorld(world); if(false){ // Ground var groundShape = new CANNON.Plane(); var ground = new CANNON.Body({ mass: 0, material: groundMaterial }); ground.addShape(groundShape); ground.position.z = -3; world.add(ground); demo.addVisual(ground); } else { var mock = false; var matrix = []; var sizeX = 64, sizeY = sizeX; for (var i = 0; i < sizeX; i++) { matrix.push([]); for (var j = 0; j < sizeY; j++) { var height = Math.sin(i / sizeX * Math.PI * 8) * Math.sin(j / sizeY * Math.PI * 8) * 8 + 8; if(i===0 || i === sizeX-1 || j===0 || j === sizeY-1) height = 10; matrix[i].push(height); } } var hfShape = new CANNON.Heightfield(matrix, { elementSize: 300 / sizeX }); var hfBody; var quat = new CANNON.Quaternion(); var pos = new CANNON.Vec3(-sizeX * hfShape.elementSize / 2, -20, -20); // Use normal hfBody = new CANNON.Body({ mass: 0, material: groundMaterial }); hfBody.addShape(hfShape, new CANNON.Vec3(0,0,-1), new CANNON.Quaternion()); hfBody.position.copy(pos); hfBody.quaternion.copy(quat); if(!mock){ world.add(hfBody); demo.addVisual(hfBody); } if(mock){ for(var i=0; i<sizeX - 1; i++){ for (var j = 0; j < sizeY - 1; j++) { for (var k = 0; k < 2; k++) { hfShape.getConvexTrianglePillar(i, j, !!k); var convexBody = new CANNON.Body({ mass: 0, material: groundMaterial }); convexBody.addShape(hfShape.pillarConvex); hfBody.pointToWorldFrame(hfShape.pillarOffset, convexBody.position); world.add(convexBody); demo.addVisual(convexBody); } } } } } }); demo.start(); document.onkeydown = handler; document.onkeyup = handler; var maxSteerVal = Math.PI / 8; var maxSpeed = 10; var maxForce = 100; function handler(event){ var up = (event.type == 'keyup'); if(!up && event.type !== 'keydown') return; switch(event.keyCode){ case 38: // forward vehicle.setWheelForce(up ? 0 : maxForce, 2); vehicle.setWheelForce(up ? 0 : -maxForce, 3); break; case 40: // backward vehicle.setWheelForce(up ? 0 : -maxForce/2, 2); vehicle.setWheelForce(up ? 0 : maxForce/2, 3); break; case 39: // right vehicle.setSteeringValue(up ? 0 : -maxSteerVal, 0); vehicle.setSteeringValue(up ? 0 : -maxSteerVal, 1); break; case 37: // left vehicle.setSteeringValue(up ? 0 : maxSteerVal, 0); vehicle.setSteeringValue(up ? 0 : maxSteerVal, 1); break; } } </script> </body> </html>