|
@@ -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:曲线会更贴近控制点之间的路径,弯曲更明显。 */
|
|
|
},
|
|
|
|
|
|
|