200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 使用 Three.js 和 Cannon.js 构建真实 3D 骰子动画

使用 Three.js 和 Cannon.js 构建真实 3D 骰子动画

时间:2018-09-04 04:40:51

相关推荐

使用 Three.js 和 Cannon.js 构建真实 3D 骰子动画

使用 Three.js 和 Cannon.js 构建真实 3D 骰子动画

3D 场景搭建

Cannon.js

设置重力。

this.world.gravity.set(0, 0, -9.8 * 16);

设置骰子地面以及墙体三种材质,并两两设置联系材质。

this.diceBodyMaterial = new CANNON.Material();const deskBodyMaterial = new CANNON.Material();const barrierBodyMaterial = new CANNON.Material();this.world.addContactMaterial(new CANNON.ContactMaterial(deskBodyMaterial, this.diceBodyMaterial, {friction: 0.01,restitution: 0.5,}));this.world.addContactMaterial(new CANNON.ContactMaterial(barrierBodyMaterial, this.diceBodyMaterial, {friction: 0,restitution: 0.5,}));this.world.addContactMaterial(new CANNON.ContactMaterial(this.diceBodyMaterial, this.diceBodyMaterial, {friction: 0,restitution: 0.5,}));

添加地面以及墙体模型

this.world.addBody(new CANNON.Body({mass: 0,shape: new CANNON.Plane(),material: deskBodyMaterial,}));let barrier = new CANNON.Body({mass: 0,shape: new CANNON.Plane(),material: barrierBodyMaterial,})barrier.position.set(0, this.dimentions.height * 0.93, 0);barrier.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), Math.PI / 2);this.world.addBody(barrier);barrier = new CANNON.Body({mass: 0,shape: new CANNON.Plane(),material: barrierBodyMaterial,})barrier.position.set(0, -this.dimentions.height * 0.93, 0);barrier.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2);this.world.addBody(barrier);barrier = new CANNON.Body({mass: 0,shape: new CANNON.Plane(),material: barrierBodyMaterial,})barrier.position.set(this.dimentions.width * 0.93, 0, 0);barrier.quaternion.setFromAxisAngle(new CANNON.Vec3(0, 1, 0), -Math.PI / 2);this.world.addBody(barrier);barrier = new CANNON.Body({mass: 0,shape: new CANNON.Plane(),material: barrierBodyMaterial,})barrier.position.set(-this.dimentions.width * 0.93, 0, 0);barrier.quaternion.setFromAxisAngle(new CANNON.Vec3(0, 1, 0), Math.PI / 2);this.world.addBody(barrier);

Three.js

创建场景

this.scene = new THREE.Scene();

设置环境光源

const light = new THREE.AmbientLight(0xf0f5fb, 0.8);this.scene.add(light);

添加渲染器,初始化抗锯齿与透明功能

this.renderer = new THREE.WebGLRenderer({canvas: this.canvas,antialias: true,alpha: true,});

配置渲染器

this.renderer.shadowMap.enabled = true;this.renderer.shadowMap.type = THREE.PCFShadowMap;this.renderer.setClearColor(0x000000, 0);this.renderer.setPixelRatio(devicePixelRatio);

设置渲染尺寸

this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);

添加相机

const aspect = Math.min(this.canvas.clientWidth / this.dimentions.width, this.canvas.clientHeight / this.dimentions.height);const cameraZ = this.canvas.clientHeight / aspect / Math.tan(10 * Math.PI / 180);if (this.camera) this.scene.remove(this.camera);const y = this.camera ? this.camera.position.y * cameraZ / this.camera.position.z : -10;this.camera = new THREE.PerspectiveCamera(20, this.canvas.clientWidth / this.canvas.clientHeight, 1, cameraZ * 2);this.camera.position.set(0, y, cameraZ);

添加轨道控制器并限制角度

this.control = new OrbitControls(this.camera, this.canvas);this.control.enableDamping = true;this.control.dampingFactor = 0.1;this.control.enableZoom = false;this.control.enablePan = false;this.control.minPolarAngle = Math.PI * 0.5;this.control.maxPolarAngle = Math.PI * 0.9;this.control.minAzimuthAngle = 0;this.control.maxAzimuthAngle = 0;

添加点光源

const longSide = Math.max(this.dimentions.width, this.dimentions.height);if (this.light) this.scene.remove(this.light);this.light = new THREE.SpotLight(0xefdfd5, 2);this.light.position.set(-longSide / 2, longSide / 2, longSide * 2);this.light.target.position.set(0, 0, 0);this.light.distance = longSide * 5;this.light.castShadow = true;this.light.shadow.camera.near = longSide / 10;this.light.shadow.camera.far = longSide * 5;this.light.shadow.camera.fov = 50;this.light.shadow.bias = 0.001;this.light.shadow.mapSize.set(4096, 4096);this.scene.add(this.light);

添加桌面并设置阴影,导入材质

if (this.desk) this.scene.remove(this.desk);const loader = new THREE.TextureLoader();this.desk = new THREE.Mesh(new THREE.PlaneGeometry(this.dimentions.width * 2, this.dimentions.height * 2, 1, 1),new THREE.MeshPhongMaterial({map: loader.load('/assets/model/WoodFineDark.jpg'),reflectivity: 1,specular: 0x222222,shininess: 20,}),);this.desk.receiveShadow = true;this.scene.add(this.desk);

开始渲染

场景初始化完成后即可开始渲染,这里通过requestAnimationFrame递归调用函数进行动画渲染

function render() {component.tick();requestAnimationFrame(render);component.renderer.render(component.scene, component.camera);}

未完待续

骰子模型的导入骰子的运动模型生成(实现可复现运动,多机视觉一致性,力度及方向控制)骰子的点数识别(通过四元数结算实现)骰子点数指定(通过运动模拟实现)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。