three.js学习笔记 为模型增添物理效果

来源:互联网 发布:散打软件 编辑:程序博客网 时间:2024/06/07 04:05

前一篇介绍了物理引擎Physijs,场景中的对象只需要用特定的Physijs对象封装一下便可以在场景中展现物理效果(重力、碰撞检测等)。但Physijs并没有为模型的加载提供一种特定的方法。所以由3Dmax或是Blender等建模软件创建的模型通过传统方式加载到场景中并没有物理效果。

为了使模型具有物理效果这里我使用了一种方法(才疏学浅,仅供参考)。

这里使用的是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: msstats.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/


0 0