Я работаю над небольшой три. js сценой , в которой я хочу вести машину по дороге. Беда в том, что моя машина переворачивает каждый кадр, вместо того, чтобы кататься на шинах:
Кто-нибудь знает, как я могу сделать свою машину? катиться с пушкой. js? Любые указатели были бы чрезвычайно полезны. Ради сохранения вот моя грубая сцена:
var carBody,
floorBody,
pressed = {},
rotation = 0,
clock = new THREE.Clock(),
loader = new THREE.TextureLoader(),
container = document.querySelector('body'),
w = container.clientWidth,
h = container.clientHeight,
scene = new THREE.Scene(),
camera = new THREE.PerspectiveCamera(75, w/h, 0.1, 100000),
controls = new THREE.TrackballControls(camera, container),
renderConfig = {antialias: true, alpha: true},
renderer = new THREE.WebGLRenderer(renderConfig);
controls.target = new THREE.Vector3(0, 0, 0.75);
controls.panSpeed = 0.4;
camera.position.set(0,80,-4900);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(w, h);
container.appendChild(renderer.domElement);
window.addEventListener('resize', function() {
w = container.clientWidth;
h = container.clientHeight;
camera.aspect = w/h;
camera.updateProjectionMatrix();
renderer.setSize(w, h);
})
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
if (car && carBody && carBody.position) {
moveCar();
updatePhysics();
moveCamera();
//controls.update();
}
}
function getPlane(img, w, h, wrap) {
var texture = loader.load(img);
if (wrap) {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(10, 10);
}
var material = new THREE.MeshBasicMaterial({
map: texture,
side: THREE.DoubleSide,
});
var geometry = new THREE.PlaneGeometry(w, h, 10, 10);
return new THREE.Mesh(geometry, material);
}
function getSides() {
var d = 300;
var group = new THREE.Group();
for (var i=0; i<2; i++) {
var plane = getPlane('asphalt.jpg', 10000, 200, true);
plane.position.y = 100;
plane.rotation.set(Math.PI/2, -Math.PI/2, Math.PI/2);
plane.position.x = i == 0 ? -d : d;
group.add(plane);
}
return group;
}
function getSky() {
var directions = ['right', 'left', 'top', 'bottom', 'front', 'back'];
var geometry = new THREE.BoxGeometry(50000, 50000, 50000);
var materialArray = [];
for (var i=0; i<6; i++)
materialArray.push( new THREE.MeshBasicMaterial({
map: loader.load(directions[i] + '.bmp'),
side: THREE.BackSide
}));
return new THREE.Mesh( geometry, materialArray );
}
function getCar() {
var mtlLoader = new THREE.MTLLoader();
mtlLoader.load('car.mtl', function(mat) {
mat.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(mat);
objLoader.load('car.obj', function(obj) {
window.car = obj;
car.scale.set(0.1, 0.1, 0.1);
obj.position.set(0, 0, -4800);
scene.add(obj);
})
})
}
function getPhysics() {
world = new CANNON.World();
world.gravity.set(0, -100, 0); // earth = -9.82 m/s
world.broadphase = new CANNON.NaiveBroadphase();
world.broadphase.useBoundingBoxes = true;
var solver = new CANNON.GSSolver();
solver.iterations = 7;
solver.tolerance = 0.1;
world.solver = solver;
world.quatNormalizeSkip = 0;
world.quatNormalizeFast = false;
world.defaultContactMaterial.contactEquationStiffness = 1e9;
world.defaultContactMaterial.contactEquationRelaxation = 4;
return world;
}
function addPhysics() {
var m = getPhysicsMaterial();
carBody = new CANNON.Body({
mass: 10,
material: m,
shape: new CANNON.Sphere(30),
linearDamping: 0.6,
angularDamping: 0.8,
position: new CANNON.Vec3(0, 30, -4900)
});
world.addBody(carBody);
// floor
var q = floor.quaternion;
var floorBody = new CANNON.Body({
mass: 0, // mass = 0 makes the body static
material: m,
shape: new CANNON.Plane(),
quaternion: new CANNON.Quaternion(-q._x, q._y, q._z, q._w)
});
world.addBody(floorBody);
}
function getPhysicsMaterial() {
var m = new CANNON.Material('slipperyMaterial');
var c = new CANNON.ContactMaterial(m, m, {
friction: 0.3,
restitution: 0.3,
})
world.addContactMaterial(c);
return m;
}
function moveCar() {
var delta = clock.getDelta(); // seconds
var moveDistance = 2000 * delta; // n pixels per second
// set roll sensitivity
var sensitivity = 1.5;
var rotateAngle = Math.PI / 2 * delta * sensitivity;
// determine the direction to travel
var p = carBody.position;
var dir = new THREE.Vector3(p.x, p.y, p.z);
dir.sub(camera.position).normalize(); // vector b/w camera and car
if (pressed['W'] || pressed['ARROWUP']) {
carBody.velocity.x += moveDistance * dir.x;
carBody.velocity.z += moveDistance * dir.z;
}
if (pressed['S'] || pressed['ARROWDOWN']) {
carBody.velocity.x -= moveDistance * dir.x;
carBody.velocity.z -= moveDistance * dir.z;
}
if (pressed['A'] || pressed['ARROWLEFT']) {
rotation += rotateAngle;
}
if (pressed['D'] || pressed['ARROWRIGHT']) {
rotation -= rotateAngle;
}
if (pressed[' ']) {
carBody.velocity.y = 10;
}
}
function updatePhysics() {
world.step(1/60);
car.position.copy(carBody.position);
car.quaternion.copy(carBody.quaternion);
}
function moveCamera() {
var rotZ = Math.cos(rotation);
var rotX = Math.sin(rotation);
var distance = 100;
camera.position.x = carBody.position.x - (distance * rotX);
camera.position.y = carBody.position.y + 20;
camera.position.z = carBody.position.z - (distance * rotZ);
camera.lookAt(car.position);
}
window.addEventListener('keydown', function(e) {
pressed[e.key.toUpperCase()] = true;
})
window.addEventListener('keyup', function(e) {
pressed[e.key.toUpperCase()] = false;
})
/**
* Add elems
**/
var light = new THREE.HemisphereLight(0xffffbb, 0x080820, 1);
scene.add(light);
var geometry = new THREE.PlaneGeometry(10000, 10000);
var material = new THREE.MeshBasicMaterial();
var floor = new THREE.Mesh(geometry, material);
floor.rotation.x = Math.PI / 2;
scene.add(floor);
var street = getPlane('asphalt.jpg', 10000, 1000, true);
street.rotation.x = Math.PI/2;
street.rotation.z = Math.PI/2;
scene.add(street);
var sides = getSides();
scene.add(sides);
var sky = getSky();
scene.add(sky);
var car = getCar();
var world = getPhysics();
addPhysics();
render();
html,
body {
width: 100%;
height: 100%;
background: #aaa;
}
body {
margin: 0;
overflow: hidden;
}
canvas {
width: 100%;
height: 100%;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/cannon.js/0.6.2/cannon.js'></script>
<script src='https://raw.githack.com/mrdoob/three.js/master/examples/js/loaders/ObjLoader.js'></script>
<script src='https://raw.githack.com/mrdoob/three.js/master/examples/js/loaders/MTLLoader.js'></script>
<script src='https://raw.githack.com/mrdoob/three.js/master/examples/js/controls/TrackballControls.js'></script>