Я хочу сделать браузерную VR-игру с использованием Three.js и Ammo.js для физики и твердых тел. Голова vr и контроллеры настроены, модели загружены, но пули не будут стрелять из пистолета, как я хочу. Когда я попытался сделать то же самое, используя только Three.js без жестких тел в сцене, я использовал «vector.applyQuaternion» из документации Three.js, и это сработало, пули были выпущены сверху пистолета. Проблема в том, что я не нашел ничего похожего для использования кода ammo.js
без использования кода ammo.js
... function handleController( controller ) {
if ( controller1.userData.isSelecting ) {
bullet1.position.set( controller1.position.x , controller1.position.y + 0.018 , controller1.position.z -0.01);
bullet1.userData.velocity.x = 0;
bullet1.userData.velocity.y = 10;
bullet1.userData.velocity.z = 10;
bullet1.userData.velocity.applyQuaternion( controller1.quaternion );
scene.add(bullet1);
}
if ( controller2.userData.isSelecting ) {
bullet2.position.set( controller2.position.x , controller2.position.y + 0.018 , controller2.position.z -0.01 );
bullet2.userData.velocity.x = 0;
bullet2.userData.velocity.y = 10;
bullet2.userData.velocity.z = 10;
bullet2.userData.velocity.applyQuaternion( controller2.quaternion );
scene.add(bullet2);
}
} ...
function render() {
handleController( controller1 );
handleController( controller2 );
var delta = clock.getDelta()
bullet1.position.x -= bullet1.userData.velocity.x * delta;
bullet1.position.y -= bullet1.userData.velocity.y * delta;
bullet1.position.z -= bullet1.userData.velocity.z * delta;
bullet2.position.x -= bullet2.userData.velocity.x * delta;
bullet2.position.y -= bullet2.userData.velocity.y * delta;
bullet2.position.z -= bullet2.userData.velocity.z * delta;
renderer.render( scene, camera );
}
с ammo.js
function createBullet1RigidBody( threeObject, physicsShape, mass ) {
//threeObject.position.copy( pos );
//threeObject.quaternion.copy( quat1 );
quat1.set( controller1.position.x, controller1.position.y , controller1.position.z , Math.PI/2 );
pos1 = new THREE.Vector3 ( controller1.position.x, controller1.position.y , controller1.position.z );
var transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin( new Ammo.btVector3( controller1.position.x, controller1.position.y, controller1.position.z -0.5) );
transform.setRotation( new Ammo.btQuaternion( quat1.x, quat1.y, quat1.z, quat1.w ) );
var motionState = new Ammo.btDefaultMotionState( transform );
var localInertia = new Ammo.btVector3( 0, 0, 0 );
physicsShape.calculateLocalInertia( mass, localInertia );
var rbInfo = new Ammo.btRigidBodyConstructionInfo( mass, motionState, physicsShape, localInertia );
var body1 = new Ammo.btRigidBody( rbInfo );
threeObject.userData.physicsBody = body1;
scene.add( threeObject );
if ( mass > 0 ) {
bullet1Bodies.push( threeObject );
// Disable deactivation
body1.setActivationState( 4 );
}
physicsWorld.addRigidBody( body1 );
return body1;
}
function createBullet2RigidBody( threeObject, physicsShape, mass ) {
//threeObject.position.copy( pos );
//threeObject.quaternion.copy( quat2 );
var transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin( new Ammo.btVector3( controller2.position.x, controller2.position.y, controller2.position.z -0.5 ) );
transform.setRotation( new Ammo.btQuaternion( quat.x, quat.y, quat.z, quat.w ) );
var motionState = new Ammo.btDefaultMotionState( transform );
var localInertia = new Ammo.btVector3( 0, 0, 0 );
physicsShape.calculateLocalInertia( mass, localInertia );
var rbInfo = new Ammo.btRigidBodyConstructionInfo( mass, motionState, physicsShape, localInertia );
var body2 = new Ammo.btRigidBody( rbInfo );
threeObject.userData.physicsBody = body2;
scene.add( threeObject );
if ( mass > 0 ) {
bullet2Bodies.push( threeObject );
// Disable deactivation
body2.setActivationState( 4 );
}
physicsWorld.addRigidBody( body2 );
return body2;
}
...
function handleController( controller ) {
if ( controller1.userData.isSelecting ) {
var bullet1Mass = 0.1;
var bullet1Radius = 0.6;
var bullet1 = new THREE.Mesh( geometry_bullet, new THREE.MeshLambertMaterial( { color: 0x2661b9 } ) );
var bullet1Shape = new Ammo.btSphereShape ( bullet1Radius );
bullet1Shape.setMargin ( margin );
var bullet1_body = createBullet1RigidBody( bullet1, bullet1Shape, bullet1Mass, bullet1Radius );
//bullet1.position.set( pos1.x, pos1.y, pos1.z );
bullet1.userData.physicsBody.setFriction( 0 );
bullet1_body.setLinearVelocity( new Ammo.btVector3( 100, 100, 100 , controller1.quaternion) );
}
if ( controller2.userData.isSelecting ) {
var bullet2Mass = 0.1;
var bullet2Radius = 0.6;
var bullet2 = new THREE.Mesh( geometry_bullet, new THREE.MeshLambertMaterial( { color: 0xee2f2f } ) );
var bullet2Shape = new Ammo.btSphereShape ( bullet2Radius );
var pos2 = new THREE.Vector3 ( controller2.position.x, controller2.position.y + 10, controller2.position.z +10 );
bullet2Shape.setMargin ( margin );
//quat2.set( 0,0,0,1 );
var bullet2_body = createBullet2RigidBody( bullet2, bullet2Shape, bullet2Mass, bullet2Radius, pos2, quat2 );
//var pos2 = bullet2.position.set( controller2.position.x, controller2.position.y, controller2.position.z -0.1 );
bullet2.userData.physicsBody.setFriction( 0 );
bullet2_body.setLinearVelocity( new Ammo.btVector3( 0, 0, controller2.position.z *100 ) );
//bullet2.userData.physicsBody.applyQuaternion(controller2.quaternion);
}
}
В результате пули созданы, но они движутся только по оси Z. Скорость пули2 изменяется, если я перемещаю контроллер по оси x, а пули движутся только по оси z. Пули bullet1 следуют за движением по оси x, y, z, но не за вращением контроллера. "Bullet2.userData.physicsBody.applyQuaternion (controller2.quaternion);"строка является комментарием, если я удаляю бары, я получаю эту ошибку «Ошибка типа: bullet2.userData.physicsBody.applyQuaternion не является функцией». Я ожидал сделать то же самое, что и в предыдущем примере, без боеприпасов (userData.velocity.applyQuaternion), но в ammo.js нет LinearVelocity, я могу использовать только getLinearVelocity и setLinearVelocity.