three.js学习笔记 为模型增添物理效果
2016-06-29 12:53
726 查看
前一篇介绍了物理引擎Physijs,场景中的对象只需要用特定的Physijs对象封装一下便可以在场景中展现物理效果(重力、碰撞检测等)。但Physijs并没有为模型的加载提供一种特定的方法。所以由3Dmax或是Blender等建模软件创建的模型通过传统方式加载到场景中并没有物理效果。
为了使模型具有物理效果这里我使用了一种方法(才疏学浅,仅供参考)。
这里使用的是r71的加载方式,最新的有所不同。
正常加载:
以3Dmax导出的字体模型为例。
源代码:
fork me on github blog: https://chenjy1225.github.io/
为了使模型具有物理效果这里我使用了一种方法(才疏学浅,仅供参考)。
这里使用的是r71的加载方式,最新的有所不同。
正常加载:
var loader = new THREE.OBJMTLLoader(); loader.load('obj/three.obj', 'obj/three.mtl', function(object) { model =object; scene.add(model); }, onProgress, onError);物理场景加载:
var loader = new THREE.OBJMTLLoader(); loader.load('obj/three.obj', 'obj/three.mtl', function(object) { model = object; for (var i = 0; i < model.children.length; i++) { model.children[i].castShadow = true; var ground_material = Physijs.createMaterial( model.children[i].material, 1, 0 ); var mesh = new Physijs.ConcaveMesh( model.children[i].geometry, ground_material, 0 ); scene.add(mesh); } scene.add(model); }, onProgress, onError);在加载的过程中使用模型的几何形状和材质创建一个Physijs对象。将新建的Physijs对象和模型重叠的放置。便可产生阴影、碰撞及重力等多种效果。这里使用的是Physijs.ConcaveMesh,可以对比较复杂的图形进行比较细致的表现。
以3Dmax导出的字体模型为例。
源代码:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>three.js</title> </head> <body> <script type="text/javascript" src="js/three.js"></script> <script type="text/javascript" src="js/Physijs/physi.js"></script> <script src="js/Detector.js"></script> <script type="text/javascript" src="js/dat.gui.min.js"></script> <script type="text/javascript" src="js/stats.min.js"></script> <script type="text/javascript" src="js/OBJLoader.js"></script> <script type="text/javascript" src="js/MTLLoader.js"></script> <script type="text/javascript" src="js/OBJMTLLoader.js"></script> <script> 'use strict'; Physijs.scripts.worker = 'js/Physijs/physijs_worker.js'; Physijs.scripts.ammo = 'ammo.js'; if (!Detector.webgl) Detector.addGetWebGLMessage(); var renderer, scene, camera, light; var geometry, material, mesh, model; var stats = initStats(); function init() { renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setClearColor(0x000000); renderer.setSize(window.innerWidth, window.innerHeight); renderer.shadowMapEnabled = true; scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); camera.lookAt(new THREE.Vector3(-10, 0, -10)); camera.position.set(150, 30, 150); light = new THREE.SpotLight(0xffffff); light.castShadow = true; light.position.set(-100, 100, 100); scene.add(light); var onProgress = function(xhr) { if (xhr.lengthComputable) { var percentComplete = xhr.loaded / xhr.total * 100; console.log(Math.round(percentComplete, 2) + '% downloaded'); } }; var onError = function(xhr) {}; var loader = new THREE.OBJMTLLoader(); loader.load('obj/three.obj', 'obj/three.mtl', function(object) { model = object; model.rotation.x = Math.PI / 180 * 90; for (var i = 0; i < model.children.length; i++) { model.children[i].castShadow = true; var ground_material = Physijs.createMaterial( model.children[i].material, 1, 0 ); var mesh = new Physijs.ConcaveMesh( model.children[i].geometry, ground_material, 0 ); mesh.rotation.x = Math.PI / 180 * 90; scene.add(mesh); } scene.add(model); }, onProgress, onError); creatGround(); document.body.appendChild(renderer.domElement); window.addEventListener('resize', onWindowResize, false); render(); } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } function creatGround() { geometry = new THREE.CubeGeometry(1000, 1, 1000); material = new THREE.MeshBasicMaterial({ color: 0xffffff }); mesh = new THREE.Mesh(geometry, material); mesh.position.set(0, -10, 0); mesh.receiveShadow = true; scene.add(mesh); } function initStats() { var stats = new Stats(); stats.setMode(0); // 0: fps, 1: ms stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; document.body.appendChild(stats.domElement); return stats; } var control = new function() { this.cx = 150; this.cy = 30; this.cz = 150; this.redraw = function() { camera.position.set(control.cx, control.cy, control.cz); } } var gui = new dat.GUI(); gui.add(control, 'cx', -300, 300).onChange(control.redraw); gui.add(control, 'cy', -300, 300).onChange(control.redraw); gui.add(control, 'cz', -300, 300).onChange(control.redraw); var clock = new THREE.Clock(); function render() { var delta = clock.getDelta(); stats.update(); requestAnimationFrame(render); renderer.render(scene, camera); } init(); </script> <style> body { padding: 0; margin: 0; overflow: hidden; } </style> </body> </html>效果图:
fork me on github blog: https://chenjy1225.github.io/
相关文章推荐
- JQuery1——基础($对象,选择器,对象转换)
- Android学习笔记(二九):嵌入浏览器
- Android java 与 javascript互访(相互调用)的方法例子
- JavaScript演示排序算法
- javascript实现10进制转为N进制数
- 最后一次说说闭包
- Ajax
- 2019年开发人员应该学习的8个JavaScript框架
- HTML中的script标签研究
- 对一个分号引发的错误研究
- 异步流程控制:7 行代码学会 co 模块
- ES6 走马观花(ECMAScript2015 新特性)
- JavaScript拆分字符串时产生空字符的原因
- Canvas 在高清屏下绘制图片变模糊的解决方法
- Redux系列02:一个炒鸡简单的react+redux例子
- JavaScript 各种遍历方式详解
- call/apply/bind 的理解与实例分享