網格變形是基本的網格操作,所有的網格操作都需要進行網格變形,它是透過改變網格點的vertex座標位置,來達成使用者預想的幾何形狀結果。
首先在Viewer宣告一個mouseDownAction用來存放編輯動作。
this.mouseDownAction = {};
接著在Viewer加入setMouseDown函數,並且串接一個 action 引數用來接受外來的動作。
Viewer.prototype.setMouseDown = function (action) {
var self = this;
self.mouseDownAction = action;
};
然後在 onMouseDown 函數中加入呼叫函數。
self.mouseDownAction(self);
再創建一個 Editor.js 模組化內容如下。
import * as THREE from 'three';
var Editor = function (container) {
};
Editor.prototype.mouseDown = function (viewer) {
var self = this;
//Do Something
};
module.exports = Editor;
最後在 index.js 宣告並綁定 Editor.js 模組。
var editor = new Editor();
viewer.setMouseDown(editor.mouseDown);
首先在Editor中的 mouseDown 函數作一些宣告縮短取得資料的語法。
var intersected = viewer.intersects[0];
var geometry = intersected.object.geometry;
var topology = intersected.object.topology;
接著拿到面的法向量以用來當作要變形的方向,並根據先前學到的取得三角網格面與面上三個vertex的id。
var normal = intersected.face.normal;
var face = geometry.faces[intersected.faceIndex];
var point = [face.a, face.b, face.c];
然後分別對每個點的x、y、z都乘上法向量以及強度係數,並進行點座標的更新,同時要注意的是拓樸也需要跟著一起更新。
for (var v = 0; v < point.length; v++) {
var vid = point[v];
var x = geometry.vertices[vid].x + normal.x * 2;
var y = geometry.vertices[vid].y + normal.y * 2;
var z = geometry.vertices[vid].z + normal.z * 2;
geometry.vertices[vid] = new THREE.Vector3(x, y, z);
topology.vertex[vid].vector3 = new THREE.Vector3(x, y, z);
}
最後通知Three.js網格更新與物件更新,完成的效果如下圖。
geometry.verticesNeedUpdate = true;
geometry.elementsNeedUpdate = true;
簡單的網格變形
https://github.com/QQBoxy/threecad/blob/master/client/example12/Viewer.js
本次介紹了如何移動網格點,但是目前還沒有進行法向量的更新,所以網格只會一直往同一個方向前進,現在這隻小程式已經開始有一些CAD軟體的影子了,大家都學會了嗎?