CannonJS地板。让球粘在地上
CannonJS floor. Make a ball stick to the ground
新手问题:我正在尝试将一个球丢到地板上并让它粘在那里甚至滚过一个平面。现在它穿过飞机。我不确定我在哪里犯了错误或者我做错了什么。
var world, timeStep=1/60, scene, renderer, camera,
icosahedronBody, sphereShape, groundShape,
ground, groundBody, groundShape;
// CONSTANTS
var GRID_HELPER_SIZE = 40,
GRID_HELPER_STEP = 2,
MASS = 5;
initThree();
initCannon();
animate();
function initCannon() {
world = new CANNON.World();
world.broadphase = new CANNON.NaiveBroadphase();
sphereShape = new CANNON.Sphere();
groundShape = new CANNON.Plane();
icosahedronBody = new CANNON.Body({
mass: MASS,
});
groundBody = new CANNON.Body({
mass: 0, // mass == 0 makes the body static
});
world.solver.iterations = 10;
world.gravity.set(0,-9.8,0);
world.defaultContactMaterial.contactEquationStiffness = 1e9;
world.defaultContactMaterial.contactEquationRegularizationTime = 4;
icosahedronBody.addShape(sphereShape);
icosahedronBody.position.set(0,50,0)
icosahedronBody.linearDamping = 0.5;
world.addBody(icosahedronBody);
groundBody.addShape(groundShape);
groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(0,1,0),-Math.PI/2);
world.addBody(groundBody);
var ballContact = new CANNON.ContactMaterial( groundBody, icosahedronBody, 0.0, 0.0);
world.addContactMaterial(ballContact);
}
function initThree(){
// INITIALIZE CANVAS
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
var light = new THREE.AmbientLight( 0x404040 ),
directionalLight = new THREE.DirectionalLight( 0xffffff ),
gridHelper = new THREE.GridHelper( GRID_HELPER_SIZE, GRID_HELPER_STEP );
renderer.setSize( window.innerWidth - 100 , window.innerHeight - 100 );
renderer.setClearColor( 0x757575 );
document.body.appendChild( renderer.domElement );
camera.position.set(1,25,100); // camera position to x , y , z
camera.lookAt( new THREE.Vector3() )
directionalLight.position.set( 1, 0.75, 0.5 ).normalize();
// INITIAL CANVAS
scene.add( directionalLight );
scene.add( light );
scene.add( camera );
scene.add( gridHelper );
// MATERIALS
var icoGeometry = new THREE.IcosahedronGeometry(10, 1),
icoMaterial = new THREE.MeshLambertMaterial( {color: 0xff0000} );
icosahedron = new THREE.Mesh( icoGeometry, icoMaterial );
var groundGeometry = new THREE.BoxGeometry(100 , 1, 100),
groundMaterial = new THREE.MeshLambertMaterial( {color: 0xcccccc} );
ground = new THREE.Mesh( groundGeometry, groundMaterial );
ground.receiveShadow = true;
// ADD OBJECTS TO SCENE
scene.add( icosahedron );
scene.add( ground );
}
function animate() {
requestAnimationFrame( animate );
updatePhysics();
render();
}
function updatePhysics() {
// Step the physics world
world.step(timeStep);
// Copy coordinates from Cannon.js to Three.js
icosahedron.position.copy(icosahedronBody.position);
icosahedron.quaternion.copy(icosahedronBody.quaternion);
ground.position.copy(groundBody.position);
ground.quaternion.copy(groundBody.quaternion);
}
function render() {
renderer.render( scene, camera );
}
您的 CANNON.Plane
方向似乎有误。默认情况下,它的法线指向Z方向,所以你需要将它沿正X轴旋转-90度,使其法线指向正Y方向(使用right hand rule):
groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1,0,0),-Math.PI/2);
其次,您必须使 BoxGeometry 匹配。确保它沿 Z 轴变薄。
var groundGeometry = new THREE.BoxGeometry(100, 100, 1),
我还注意到 THREE.IcosahedronGeometry
的半径是 10,而 CANNON.Sphere
的半径是 1 (the default)。将其半径设置为 10 以匹配 three.js 几何形状:
sphereShape = new CANNON.Sphere(10);
替换这三行,您的模拟看起来应该是这样。祝你好运!
新手问题:我正在尝试将一个球丢到地板上并让它粘在那里甚至滚过一个平面。现在它穿过飞机。我不确定我在哪里犯了错误或者我做错了什么。
var world, timeStep=1/60, scene, renderer, camera,
icosahedronBody, sphereShape, groundShape,
ground, groundBody, groundShape;
// CONSTANTS
var GRID_HELPER_SIZE = 40,
GRID_HELPER_STEP = 2,
MASS = 5;
initThree();
initCannon();
animate();
function initCannon() {
world = new CANNON.World();
world.broadphase = new CANNON.NaiveBroadphase();
sphereShape = new CANNON.Sphere();
groundShape = new CANNON.Plane();
icosahedronBody = new CANNON.Body({
mass: MASS,
});
groundBody = new CANNON.Body({
mass: 0, // mass == 0 makes the body static
});
world.solver.iterations = 10;
world.gravity.set(0,-9.8,0);
world.defaultContactMaterial.contactEquationStiffness = 1e9;
world.defaultContactMaterial.contactEquationRegularizationTime = 4;
icosahedronBody.addShape(sphereShape);
icosahedronBody.position.set(0,50,0)
icosahedronBody.linearDamping = 0.5;
world.addBody(icosahedronBody);
groundBody.addShape(groundShape);
groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(0,1,0),-Math.PI/2);
world.addBody(groundBody);
var ballContact = new CANNON.ContactMaterial( groundBody, icosahedronBody, 0.0, 0.0);
world.addContactMaterial(ballContact);
}
function initThree(){
// INITIALIZE CANVAS
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
var light = new THREE.AmbientLight( 0x404040 ),
directionalLight = new THREE.DirectionalLight( 0xffffff ),
gridHelper = new THREE.GridHelper( GRID_HELPER_SIZE, GRID_HELPER_STEP );
renderer.setSize( window.innerWidth - 100 , window.innerHeight - 100 );
renderer.setClearColor( 0x757575 );
document.body.appendChild( renderer.domElement );
camera.position.set(1,25,100); // camera position to x , y , z
camera.lookAt( new THREE.Vector3() )
directionalLight.position.set( 1, 0.75, 0.5 ).normalize();
// INITIAL CANVAS
scene.add( directionalLight );
scene.add( light );
scene.add( camera );
scene.add( gridHelper );
// MATERIALS
var icoGeometry = new THREE.IcosahedronGeometry(10, 1),
icoMaterial = new THREE.MeshLambertMaterial( {color: 0xff0000} );
icosahedron = new THREE.Mesh( icoGeometry, icoMaterial );
var groundGeometry = new THREE.BoxGeometry(100 , 1, 100),
groundMaterial = new THREE.MeshLambertMaterial( {color: 0xcccccc} );
ground = new THREE.Mesh( groundGeometry, groundMaterial );
ground.receiveShadow = true;
// ADD OBJECTS TO SCENE
scene.add( icosahedron );
scene.add( ground );
}
function animate() {
requestAnimationFrame( animate );
updatePhysics();
render();
}
function updatePhysics() {
// Step the physics world
world.step(timeStep);
// Copy coordinates from Cannon.js to Three.js
icosahedron.position.copy(icosahedronBody.position);
icosahedron.quaternion.copy(icosahedronBody.quaternion);
ground.position.copy(groundBody.position);
ground.quaternion.copy(groundBody.quaternion);
}
function render() {
renderer.render( scene, camera );
}
您的 CANNON.Plane
方向似乎有误。默认情况下,它的法线指向Z方向,所以你需要将它沿正X轴旋转-90度,使其法线指向正Y方向(使用right hand rule):
groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1,0,0),-Math.PI/2);
其次,您必须使 BoxGeometry 匹配。确保它沿 Z 轴变薄。
var groundGeometry = new THREE.BoxGeometry(100, 100, 1),
我还注意到 THREE.IcosahedronGeometry
的半径是 10,而 CANNON.Sphere
的半径是 1 (the default)。将其半径设置为 10 以匹配 three.js 几何形状:
sphereShape = new CANNON.Sphere(10);
替换这三行,您的模拟看起来应该是这样。祝你好运!