xzw vor 2 Monaten
Ursprung
Commit
487df9498e
3 geänderte Dateien mit 104 neuen und 16 gelöschten Zeilen
  1. 26 9
      libs/three.js/build/three.module.js
  2. 1 1
      src/custom/start.js
  3. 77 6
      src/custom/utils/DrawUtil.js

+ 26 - 9
libs/three.js/build/three.module.js

@@ -30829,7 +30829,7 @@ class ExtrudeBufferGeometry extends BufferGeometry {
 
 			if ( extrudePath ) {
 
-				extrudePts = extrudePath.getSpacedPoints( steps );
+				extrudePts = options.dontSmooth ?  extrudePath.points.slice() : extrudePath.getSpacedPoints( steps ); //add!!!!!!!!! 不要平均分,直接用原来的点
 
 				extrudeByPath = true;
 				bevelEnabled = false; // bevels not supported for path extrusion
@@ -30838,7 +30838,7 @@ class ExtrudeBufferGeometry extends BufferGeometry {
 
 				// TODO1 - have a .isClosed in spline?
 
-				splineTube = extrudePath.computeFrenetFrames( steps, false );
+				splineTube = extrudePath.computeFrenetFrames( steps, false, options.dontSmooth ); ///xzw add true !!!!! 
 
 				// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);
 
@@ -37552,7 +37552,7 @@ Object.assign( Curve.prototype, {
 
 	},
 
-	computeFrenetFrames: function ( segments, closed ) {
+	computeFrenetFrames: function ( segments, closed, getCtrlPointsDirect ) {//xzw add getCtrlPointsDirect
 
 		// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf
 
@@ -37566,15 +37566,32 @@ Object.assign( Curve.prototype, {
 		const mat = new Matrix4();
 
 		// compute the tangent vectors for each segment on the curve
+        
+        
+        if(getCtrlPointsDirect){//xzw 直接返回控制点所在的 
+            this.getCurveLengths() 
+            segments = this.cacheLengths.length 
+            let lengthSum = this.cacheLengths[this.cacheLengths.length - 1] //xzw add  计算控制点处所在处的比例
+            
+            for ( let i = 0; i <= segments; i ++ ) {
 
-		for ( let i = 0; i <= segments; i ++ ) {
-
-			const u = i / segments;
+                const u = i == 0 ? 0 : this.cacheLengths[i-1] / lengthSum;
+                
+                tangents[ i ] = this.getTangentAt( u, new Vector3() );
+                tangents[ i ].normalize();
+            }
+        }else{
+            for ( let i = 0; i <= segments; i ++ ) {//这是平均分线长度
 
-			tangents[ i ] = this.getTangentAt( u, new Vector3() );
-			tangents[ i ].normalize();
+                const u = i / segments;
+                
+     
+                tangents[ i ] = this.getTangentAt( u, new Vector3() );
+                tangents[ i ].normalize();
 
-		}
+            }
+        }
+        
 
 		// select an initial normal vector perpendicular to the first tangent vector,
 		// and in the direction of the minimum tangent xyz component

+ 1 - 1
src/custom/start.js

@@ -212,7 +212,7 @@ export function start(dom, mapDom, number ){ //t-Zvd3w0m
             }
             
             
-            
+             
             viewer.addVideo()//addFire()
             
             

+ 77 - 6
src/custom/utils/DrawUtil.js

@@ -311,6 +311,53 @@ var MeshDraw = {
 		
 	},
     
+    
+    lessCurvePoints: function(points, oldCount, minRad=0.03, UtoTMapArr){//减少点数(拐弯的部分紧凑些,直线部分宽松些):
+        
+        let count = points.length  
+        let newUtoTMapArr = [] 
+        let newPoints = [] 
+        let pointIndexs = [] 
+        let lastVec
+        let startTime = performance.now()
+        /* if(UtoTMapArr){
+            for(let n=1;n<oldCount-1;n++){ 
+                pointIndexs.push(  UtoTMapArr.findIndex(e=>e>= n / (oldCount-1) ) )
+            }   
+        } */   
+        //console.log('cost dur:', performance.now() - startTime )    
+        let nextUtoTIndex = 1 
+        for(let i=0;i<count;i++){
+            let point = points[i];
+            let last = points[i-1]
+            let next = points[i+1]
+            
+            if(i == 0 || i == count-1 ) {
+                newPoints.push(point) //直接加入
+                UtoTMapArr && newUtoTMapArr.push(i == 0 ? 0 : 1) 
+            }else{ 
+                let curVec = new THREE.Vector3().subVectors(next,point)
+                if(!lastVec) lastVec = curVec
+                if(i>1){// 和上一个加入点的vec之间的夹角如果过大就加入 
+                     
+                    let reachNextUToT //找出新点中对应原先控制点的index,这些点必须加入拐点,否则会出现控制点偏移path(当它所在部分接近直线时)
+                    while(UtoTMapArr[i] > nextUtoTIndex / (oldCount-1)){//可能多个控制点对应一个点,当控制点很近时
+                        reachNextUToT = true
+                        nextUtoTIndex ++ 
+                    } 
+                
+                    if(/* pointIndexs.includes(i) || */  reachNextUToT ||  curVec.angleTo(lastVec) > minRad){//最小角度    (注意原始点不能太稀疏)
+                        newPoints.push(point)
+                        UtoTMapArr && newUtoTMapArr.push(UtoTMapArr[i])
+                        lastVec = curVec
+                       
+                    }  
+                }
+            }  
+        }   
+            
+        return {newUtoTMapArr, newPoints}
+    },
      
     getExtrudeGeo:  function(shapes, holes, options={openEnded:false, shapeDontClose:false}){//获得挤出棱柱,可以选择传递height,或者extrudePath
         var shape = this.getShape(shapes, holes) //points是横截面 [vector2,...]
@@ -350,28 +397,52 @@ var MeshDraw = {
                 }) 
                 options.extrudePath = path               
             }
+            
+            
+            if(!options.dontSmooth){
+                //平滑连续的曲线(但经常会有扭曲的问题,tension:0能缓解, 另外shape和path都最好在原点附近,也就是点需减去bound.min )
+                options.extrudePath = new THREE.CatmullRomCurve3(options.extrudePath, options.closed ,  'catmullrom'  /* 'centripetal' */  , options.tension)//tension:张力, 越大弯曲越大。 随着长度增长,该值需要减小,否则会扭曲
+                if(options.lessPoints !== false ){//曲线但压缩直线部分点数量
+                    options.extrudePath.UtoTMapArr = [] //用于存储 getSpacedPoints得到的点对应points的百分比对应
+                    let count = Math.max(2, Math.round(length* (options.lessSpace || 200)  )) //为了防止有大拐弯才设置这么高
+                    let points = options.extrudePath.getSpacedPoints(count-1) //拆分为更密集的点 
+                    let result = this.lessCurvePoints(points, options.extrudePath.points.length,  options.minRad,   options.extrudePath.UtoTMapArr  )  //传UtoTMapArr的话点太多了卡住了
+                    //options.extrudePath = points
+                    options.extrudePath = result.newPoints 
+                    options.dontSmooth = true        
+                } 
+            }
+            
+              
+            
             if(options.dontSmooth){
                 let curvePath = new THREE.CurvePath()//通用的曲线路径对象,它可以包含直线段和曲线段。在这里只做折线
+                curvePath.points = options.extrudePath//add
                 for (let i = 0; i < options.extrudePath.length - 1; i++){ 
                     let curve3 = new THREE.LineCurve3(options.extrudePath[i], options.extrudePath[i + 1]);//添加线段
                     curvePath.add(curve3);
                 } 
-                options.extrudePath = curvePath
-            }else{ 
-                //平滑连续的曲线(但经常会有扭曲的问题,tension:0能缓解, 另外shape和path都最好在原点附近,也就是点需减去bound.min )
-                options.extrudePath = new THREE.CatmullRomCurve3(options.extrudePath, options.closed ,  'catmullrom'  /* 'centripetal' */  , options.tension)//tension:拐弯剧烈程度,但随着长度增长,该值需要减小,否则会扭曲
-                                     
+                options.steps = options.extrudePath.length - 1  
+                options.extrudePath = curvePath 
+                options.tension = 0
+                //已修改过three,原本会平分细分,现在dontSmooth时会直接按照控制点来分段
             } 
         }
         
  
         var extrudeSettings = $.extend(options,{
-            steps: options.steps != void 0 ? options.steps : ( options.extrudePath ? Math.round(length/(options.spaceDis || 0.3)) : 1), //分成几段    spaceDis每段长度
+            steps: options.steps != void 0 ? options.steps : ( options.extrudePath ? Math.round(length/(options.spaceDis || 0.2)) : 1), //分成几段    spaceDis每段长度
             bevelEnabled: false, //不加的话,height为0时会有圆弧高度
             //openEnded默认false 
         }) 
         var geometry = new THREE.ExtrudeBufferGeometry( shape, extrudeSettings ); //修改了three.js文件,  buildLidFaces处,创建顶底面加了选项,可以选择开口。 
         return geometry;
+        
+        
+        /*     tension = 0:曲线会变成一条直线,没有弯曲。
+        tension = 0.5:曲线会经过所有控制点,并保持自然的弯曲。  
+        tension > 0.5:曲线会更平滑,远离控制点之间的路径。
+        tension < 0.5:曲线会更贴近控制点之间的路径,弯曲更明显。 */
     },