美文网首页
three.js笔记

three.js笔记

作者: 马川敉 | 来源:发表于2019-03-26 10:00 被阅读0次

three.js

专业名词

场景(Scene)、相机(camera)和渲染器(WebGLRenderer)
render(scene, camera);

光源(light), 平行光, 点光源, 聚光光源

物体(object): 矢量(Vector3),形状(geometry),材质(material)

PerspectiveCamera(透视摄像机)。视野角度(FOV),长宽比(aspect ratio),远剪切面,近剪切面

网格(mesh)

Line(geometry, material);
scene.add(line);

左手坐标系

library

library name function describe
three.js Three.js引擎
Detector.js 探测器 检测当前浏览器是否支持或者开启了WEBGL
Stats.js JavaScript性能监控器 监测动画效果
OrbitControls.js 鼠标控制旋转的js
WindowResize.js 处理窗口大小调整 在调整窗口的大小时更新渲染和相机
TransformControls.js 鼠标操控物体移动、缩放、旋转的控件(物体操作工具)
EditorControls.js 鼠标操控场景视角(即场景Camera位置),模拟实现平移整个场景的控件(场景控制工具)
dat.gui.js 用于创建菜单栏 提供场景中的各个参数编辑功能(调试场景利器)

资料

  1. 保存视角场景等到数据库

总结

  1. 鼠标拾取,光线投射

代码片段

THREEx.WindowResize(renderer, camera);  // 处理窗口大小调整。

controls = new THREE.OrbitControls( camera, renderer.domElement );  // 鼠标控制旋转

添加二维网格

var gridHelper = new THREE.GridHelper(1000, 20);
scene.add(gridHelper);

绘制三维网格

var gridXZ = new THREE.GridHelper(80, 10, 0xEED5B7, 0xEED5B7);
gridXZ.position.set( 80,0,80 );
this.mesh.add(gridXZ);
var gridXY = new THREE.GridHelper(80, 10, 0xEED5B7, 0xEED5B7);
gridXY.position.set( 80,80,0 );
gridXY.rotation.x = Math.PI/2;
this.mesh.add(gridXY);
var gridYZ = new THREE.GridHelper(80, 10, 0xEED5B7, 0xEED5B7);
gridYZ.position.set( 0,80,80 );
gridYZ.rotation.z = Math.PI/2;
this.mesh.add(gridYZ);

绘制直线

var linematerial = new THREE.LineBasicMaterial( { vertexColors: THREE.VertexColors, linewidth: 1.3} );
var color1 = new THREE.Color( 0x000000 ), color2 = new THREE.Color( 0x000000 );
var p1 = new THREE.Vector3( 0, 0, 0 );
var p2 = new THREE.Vector3( 0, 0, 160 );
var geometry = new THREE.Geometry();
geometry.vertices.push(p1);
geometry.vertices.push(p2);
geometry.colors.push( color1, color2 );
var line = new THREE.Line( geometry, linematerial, THREE.LinePieces );
this.mesh.add(line);

添加物体

this.mesh = new THREE.Object3D();//忘了强调,这句话要放在所有的this.mesh.add()之前
var geometry = new THREE.SphereGeometry( 0.3, 32, 16 );
var material = new THREE.MeshLambertMaterial( { color: 0x00ff00 } );
meshpoint = new THREE.Mesh( geometry, material );
meshpoint.position.set(40,40,40);
this.mesh.add(meshpoint);

根据浏览器大小调整渲染器大小

window.addEventListener('resize', onWindowResize, false);

function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize(window.innerWidth, window.innerHeight);

}

开启鼠标控制

需要引入鼠标控制插件

// <script src="js/controls/OrbitControls.js"></script>

const controls = new THREE.OrbitControls(camera, renderer.domElement)
controls.enableDamping = true;   // 开启阻尼
controls.dampingFactor = 0.25;
controls.rotateSpeed = 0.35;
// 设置 '鼠标控制' 是否生效, 默认为生效
// controls.enabled = false;

Questions

  1. OBJLoader.js和OBJLoader2.js的区别
  2. 光源拖动

存档

  1. mesh对象的前三个属性position,rotation和scale有三种设置方法。
  2. 使用CylinderBufferGeometry创建顶底大小不一致的圆台

资料

  1. 漫步视角 + 碰撞监测
  2. 墙体我使用了BoxGeometry,墙体上的窗户的洞、门洞,我们可以使用ThreeBSP库中差集函数来进行模型相减来实现。, ThreeBPS
  3. BPS使用示例
  4. 开门动画使用Tween.js
  5. 计算机图形学中三维数学的一些基础知识,主要包括2D、3D笛卡尔坐标系,向量、矩阵的数学和几何意义以及公式。
  6. three.js源码注解

碰撞监测思路

  1. movingCube中心点是否和其他物体重合
  2. movingCube的中心点是否在其他物体内部
  3. movingCube的中心点到合个顶点的射线是否和其他物体有交点, 且交点是否小于中心点到定点的距离
let overlap = false;
// collision(collisionArray, object, camera, transformControls);

/**
    *  功能:检测 movingCube 是否与数组 collideMeshList 中的元素发生了碰撞
    * 
    */
const originPoint = movingCube.position.clone();

for (var vertexIndex = 0; vertexIndex < movingCube.geometry.vertices.length; vertexIndex++) {
    // 顶点原始坐标
    // .clone(); 复制坐标
    const localVertex = movingCube.geometry.vertices[vertexIndex].clone();
    // 顶点经过变换后的坐标
    // .applyMatrix4 ( m : Matrix4 ) 将该向量乘以四阶矩阵m(第四个维度隐式地为1),并按视角划分
    const globalVertex = localVertex.applyMatrix4(movingCube.matrix);
    // 获得由中心指向顶点的向量,  
    // .sub ( v : Vector3 ) 从该向量减去向量v。
    const directionVector = globalVertex.sub(movingCube.position);
    // console.log('中心指向定点的向量', collideMeshList.length);
    // v3.push(directionVector);
    // 将方向向量初始化
    // .normalize () 将该向量转换为单位向量(unit vector), 也就是说,将该向量的方向设置为和原向量相同,但是其长度(length)为1。
    const ray = new THREE.Raycaster(originPoint, directionVector.clone().normalize());
    // 检测射线与多个物体的相交情况
    const collisionResults = ray.intersectObjects(collideMeshList);
    // if (collisionResults.length > 1) {
    //  console.log('在一条线上', collisionResults);
    // }
    // 如果返回结果不为空,且交点与射线起点的距离小于物体中心至顶点的距离,则发生了碰撞
    if (collisionResults.length > 0 && collisionResults[0].distance < directionVector.length()) {
        // const object = transformControls.object;
        // var x, y, x;
        // if (!overlap) {
        overlap = true;
        // const position = object.position;
        //  x = position.x;
        //  y = position.y;
        //  z = position.z;
        // } else {
        // console.log(x, y, z);
        // console.log('重叠');
        break;

        //  object.position.set(x, y, z);
        // }
    } else {
        // console.log('没有重叠');
        // overlap = false;
    }
}
if (overlap) {
    console.log('重叠');
} else {
    console.log('不重叠');
    const mesh = enti_map.get(name);
    const mp = movingCube.position;
    mesh.position.set(mp.value, mp.value, mp.value);
}
// const curve = new THREE.CatmullRomCurve3(v3);
// const line = curve.getPoints(50);
// const geometry_line = new THREE.BufferGeometry().setFromPoints(line);
// const material = new THREE.MeshBasicMaterial({
//  color: 4500442
// });
// const mesh = new THREE.Line(geometry_line, material);
// scene.add(mesh);

相关文章

网友评论

      本文标题:three.js笔记

      本文链接:https://www.haomeiwen.com/subject/ugiwvqtx.html