在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/HTML/ three.js 使用geometry.merge() 優(yōu)化

three.js 使用geometry.merge() 優(yōu)化

第一段是原本畫網(wǎng)格的代碼 第二段我使用geometry.merge()方法的代碼 不知道哪里寫錯了 不報錯 也出不來 請前輩指教

function initObject() {
                //1.在x軸上定義兩個點p1 p2
                var geometry = new THREE.Geometry();
                geometry.vertices.push(new THREE.Vector3(-500, 0, 0));
                geometry.vertices.push(new THREE.Vector3(500, 0, 0));
                //2.主要在于這里的算法,從右、下角開始畫
                for (var i = 0; i <= 20; i++) {
                    //畫橫線
                    var line = new THREE.Line(geometry, new THREE.LineBasicMaterial({ color: 0x000000, opacity: 0.2 }));
                    line.position.z = (i * 50) - 500;
                    scene.add(line);


                    var line = new THREE.Line(geometry, new THREE.LineBasicMaterial({ color: 0x000000, opacity: 0.2 }));
                    line.position.x = (i * 50) - 500;
                    line.rotation.y = 90 * Math.PI / 180;   //轉(zhuǎn)90度
                    scene.add(line);

                }
            }
function initObject() {  
                var geometry = new THREE.Geometry();  
                var allLine=new THREE.Geometry();
                geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) );  
                geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) ); 
                for ( var i = 0; i <= 20; i ++ ) { 
                    var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
                    line.position.z = ( i * 50 ) - 500;  
                    allLine.merge(line.geometry,line.matrix) 
                    var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
                    line.position.x = ( i * 50 ) - 500;  
                    line.rotation.y = 90 * Math.PI / 180;  
                    allLine.merge(line.geometry,line.matrix)
                }  
                allLineMesh=new THREE.Mesh(allLine,new THREE.MeshBasicMaterial({color:0x000000,side:THREE.DoubleSide}))
                scene.add( allLineMesh );  
            }  
回答
編輯回答
陌璃

(1) 要使用正確的對象類型

這里不能用Mesh,因為這里geometry的點數(shù)不滿足Mesh的規(guī)范,圖形是渲染不出來的,Mesh是由小三角面構(gòu)成,頂點數(shù)必須是3的倍數(shù)。所以,這里應(yīng)該用THREE.Line

將:

allLineMesh=new THREE.Mesh(allLine,new THREE.MeshBasicMaterial({color:0x000000,side:THREE.DoubleSide}))

改成:

allLineMesh=new THREE.Line(allLine,new THREE.MeshBasicMaterial({color:0x000000,side:THREE.DoubleSide}))

你會發(fā)現(xiàn)有圖像出來了,但只有一條直線,下面講這個問題。

(2)對對象使用變換之后,要手動更新對象變換矩陣

在three.js中,考慮到性能,框架在做變換的時候不會自動更新變換矩陣(其實還有很多東西都不會自動更新,可以參考文檔里面定義的xxxNeedsUpdate,computeXXX,updateXXX之類的屬性),所以,如果你對對象做了變換之后要用到對象的矩陣,那么你首先需要更新對象的變換矩陣,可以使用Object3D.updateMatrix()方法。

所以,像下面這種寫法是不能看到geometry有任何改變的:

var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
line.position.z = ( i * 50 ) - 500; // 這里做了變換,但是沒更新變換矩陣
allLine.merge(line.geometry,line.matrix)//使用原始的變換矩陣,于是對象的變換并沒有應(yīng)用到geometry上

可以改成:

var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
line.position.z = ( i * 50 ) - 500;
line.updateMatrix(); // 加了這句
allLine.merge(line.geometry,line.matrix)

現(xiàn)在可以看到圖像了,但是你會發(fā)現(xiàn)圖像很奇怪:

圖片描述

這是什么鬼?為什么有那么多交叉線?

其實這和Line類型的繪制策略有關(guān),Line是把vertices的點一個一個連起來的,比如vertices里有四個點[A,B,C,D],那么Line在畫的時候,就是A-->B-->C--D,而你想的可能是A-->B,C-->D,簡單驗證一下,使用下面的函數(shù):

            function initObject(){
                var material = new THREE.LineBasicMaterial({
                    color: 0x0000ff
                });
                var geometry = new THREE.Geometry();
                geometry.vertices.push(
                    new THREE.Vector3( -500, 0, 0 ),
                    new THREE.Vector3( 500, 0, 0 ),
                    new THREE.Vector3( 0, 0, -500 ),
                    new THREE.Vector3( 0, 0, 500 )
                );
                var line = new THREE.Line( geometry, material );
                scene.add( line );
            }

運行的結(jié)果如下圖:

圖片描述

確實是A-->B-->C--D這樣連的

(3)利用吸附算法使中間連線吸附到邊緣

對于Line的A-->B-->C--D這種畫法我們是沒辦法改變,但是,在這個例子中,我們可以人為的將B-->C邊吸附到邊緣。比如有個上面四個點的坐標如下:

A:[1,0,0]
B:[-1,0,0]
C:[0,0,1]
D:[0,0,-1]

我們可以人為的插一個點E:
A:[1,0,0]
B:[-1,0,0]
E:[-1,0,1]
C:[0,0,1]
D:[0,0,-1]
使得B-->C由斜線變成了沿著邊緣走的斜線:

圖片描述

吸附算法如下:

 // 吸附算法
            function adsorb(geometry,compares){
                var vertices =  geometry.vertices;
                var cdt1 = compares[0];
                var cdt2 = compares[1];
                for (var i = 0 ; i < vertices.length-1; i++) {
                    var vertice = vertices[i];
                    var nextVertice = vertices[i+1];
                    if(Math.round(vertice[cdt1]) !== Math.round(nextVertice[cdt1])
                        && Math.round(vertice[cdt2]) !== Math.round(nextVertice[cdt2])){ // 差異超過兩個維度
                        var vector = new THREE.Vector3();
                        vector[cdt1] = vertice[cdt1];
                        vector[cdt2] = nextVertice[cdt2];
                        vertices.splice(i+1, 0,vector); // 插入一個點
                        i++;
                    }
                }
                geometry.vertices = vertices;
            }

將吸附算法加入到創(chuàng)建過程中:

 function initObject() {
                var geometry = new THREE.Geometry();
                var allLine=new THREE.Geometry();
                geometry.vertices.push( new THREE.Vector3( - 500, 0, 0 ) );
                geometry.vertices.push( new THREE.Vector3( 500, 0, 0 ) );
                for ( var i = 0; i <= 20; i ++ ) {
                    var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
                    line.position.z = ( i * 50 ) - 500;
                    line.updateMatrix();
                    allLine.merge(line.geometry,line.matrix)
                    var line = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } ) );
                    line.position.x = ( i * 50 ) - 500;
                    line.rotation.y = 90 * Math.PI / 180;
                    line.updateMatrix();
                    allLine.merge(line.geometry,line.matrix)
                }
                adsorb(allLine,["x","z"]);  // 添加這一行
                allLine.verticesNeedUpdate = true;
                allLineMesh=new THREE.Line(allLine,new THREE.MeshBasicMaterial({color:0x000000,side:THREE.DoubleSide}))
                scene.add( allLineMesh );
            }

這樣看起來就正確了

2018年1月8日 02:20