|
|
@@ -8646,8 +8646,7 @@ function createSphere(sphere, transform, result) {
|
|
|
result.center = center;
|
|
|
result.radius = radius;
|
|
|
return result;
|
|
|
- }
|
|
|
-
|
|
|
+ }
|
|
|
return new BoundingSphere(center, radius);
|
|
|
}
|
|
|
|
|
|
@@ -9102,14 +9101,18 @@ class TilesetTraverser {
|
|
|
return tile.contentAvailable && !this.options.skipLevelOfDetail;
|
|
|
}
|
|
|
|
|
|
- shouldRefine(tile, frameState, useParentMetric) {
|
|
|
+ shouldRefine(tile, frameState, useParentMetric) {// 是否更新更精细的模型 canTraverse
|
|
|
+ if (tile.tileset.options.loadMaxLevelDirect) {
|
|
|
+ return true //xzw add : 直接加载到最高清晰度,用于截图 //是只加载屏幕里的吗
|
|
|
+ }
|
|
|
let screenSpaceError = tile._screenSpaceError;
|
|
|
|
|
|
if (useParentMetric) {
|
|
|
screenSpaceError = tile.getScreenSpaceError(frameState, true);
|
|
|
}
|
|
|
-
|
|
|
- return screenSpaceError > this.options.maximumScreenSpaceError;
|
|
|
+ let maxSSE = this.options.maximumScreenSpaceError;
|
|
|
+ if(tile.tileset.root.header.boundingVolume.sphere) maxSSE /= 5 //cesium那边的自带坐标的模型
|
|
|
+ return screenSpaceError > maxSSE; // 距离越近,SSE越大
|
|
|
}
|
|
|
|
|
|
updateTileVisibility(tile, frameState) {
|
|
|
@@ -9623,7 +9626,11 @@ class TileHeader {
|
|
|
}
|
|
|
|
|
|
_initializeTransforms(tileHeader) {
|
|
|
- this.transform = tileHeader.transform ? new Matrix4(tileHeader.transform) : new Matrix4();
|
|
|
+ //xzw改
|
|
|
+ let transform = tileHeader.transform // || tileHeader.boundingVolume.sphere && [1,0,0,0, 0,1,0,0, 0,0,1,0, ...tileHeader.boundingVolume.sphere.slice(0,3),1 ] //xzw add
|
|
|
+ this.transform = transform ? new Matrix4(transform) : new Matrix4();
|
|
|
+
|
|
|
+ //this.transform = tileHeader.transform ? new Matrix4(tileHeader.transform) : new Matrix4();
|
|
|
const parent = this.parent;
|
|
|
const tileset = this.tileset;
|
|
|
const parentTransform = parent && parent.computedTransform ? parent.computedTransform.clone() : new Matrix4().elements // tileset.modelMatrix.clone(); 改:去掉左乘modelMatrix
|
|
|
@@ -9700,7 +9707,8 @@ class TileHeader {
|
|
|
console.log('root_0')
|
|
|
} */
|
|
|
if(!this.tileset.lastRootTransform){//没事过后会因_updateTransform重算
|
|
|
- computedTransform = new Matrix4(this.tileset.modelMatrix).multiplyRight(this.computedTransform); //add
|
|
|
+ /* if(header.boundingVolume.sphere) computedTransform = new Matrix4(this.tileset.modelMatrix)//xzw改
|
|
|
+ else */computedTransform = new Matrix4(this.tileset.modelMatrix).multiplyRight(this.computedTransform); //add
|
|
|
}else{
|
|
|
computedTransform = new Matrix4(new Matrix4$1().multiplyMatrices(this.tileset.lastRootTransform, this.getContentTransform()).elements)
|
|
|
}
|
|
|
@@ -9709,6 +9717,9 @@ class TileHeader {
|
|
|
this.boundingVolume = createBoundingVolume(header.boundingVolume, computedTransform/* this.computedTransform */, this.boundingVolume);
|
|
|
const content = header.content;
|
|
|
|
|
|
+ //if(this.boundingVolume.center.y > 500){
|
|
|
+ // console.log(this.boundingVolume.center)
|
|
|
+ //}
|
|
|
|
|
|
if (!content) {
|
|
|
return;
|
|
|
@@ -9726,9 +9737,7 @@ class TileHeader {
|
|
|
|
|
|
|
|
|
getBoundUntransformed(){//add 这个会在mesh加载好后才会执行
|
|
|
- if(!this.contentTransform){
|
|
|
- console.error('?')
|
|
|
- }
|
|
|
+
|
|
|
this.getContentTransform()
|
|
|
|
|
|
let computedTransform2 = new Matrix4(this.contentTransform.elements)
|
|
|
@@ -9743,30 +9752,41 @@ class TileHeader {
|
|
|
|
|
|
|
|
|
getContentTransform(force){ //add 获取该tile在创建boundingVolume时需要的matrix,不包含最外层对整体模型的变换.
|
|
|
+
|
|
|
let rtcCenter, contentTransform
|
|
|
if(this.contentTransform && !force){//无需更新
|
|
|
return this.contentTransform.clone()
|
|
|
}
|
|
|
|
|
|
- if(!this.tileset.tileTransInvert){
|
|
|
- this.tileset.tileTransInvert = new Matrix4()
|
|
|
- }
|
|
|
|
|
|
- this.contentTransform = new Matrix4$1().fromArray(this.computedTransform).premultiply(new Matrix4$1().fromArray(this.tileset.tileTransInvert))
|
|
|
-
|
|
|
- if(this.tileContent){
|
|
|
- rtcCenter = this.content.rtcCenter
|
|
|
+
|
|
|
+ if(this.header.boundingVolume.sphere){
|
|
|
+ this.contentTransform = this.tileset.root.header.boundingVolume.rotGeoToZeroMat
|
|
|
+
|
|
|
}else{
|
|
|
- rtcCenter = this.rtcCenterState
|
|
|
+
|
|
|
+ if(!this.tileset.tileTransInvert){
|
|
|
+ this.tileset.tileTransInvert = new Matrix4()
|
|
|
+ }
|
|
|
+
|
|
|
+ this.contentTransform = new Matrix4$1().fromArray(this.computedTransform).premultiply(new Matrix4$1().fromArray(this.tileset.tileTransInvert))
|
|
|
+
|
|
|
+ rtcCenter = !!this.tileset.root.header.boundingVolume.sphere //针对适应cesium的自带坐标的模型
|
|
|
+ if(!rtcCenter){
|
|
|
+ if(this.tileContent){
|
|
|
+ rtcCenter = this.content.rtcCenter
|
|
|
+ }else{
|
|
|
+ rtcCenter = this.rtcCenterState
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!rtcCenter) {
|
|
|
+ let tranM = new Matrix4$1()
|
|
|
+ tranM.makeScale(1,1,-1)//大部分是这种情况. 就是因为这个变换才加的这个函数,之前bounding没考虑这个不准。不知道为什么原生的代码不用scaleZ
|
|
|
+ this.contentTransform.premultiply(tranM)
|
|
|
+ }
|
|
|
+ //如果有rtcCenter的话一开始boundingVolume不准?会不会有显示问题?
|
|
|
}
|
|
|
-
|
|
|
- if(!rtcCenter) {
|
|
|
- let tranM = new Matrix4$1()
|
|
|
- tranM.makeScale(1,1,-1)//大部分是这种情况. 就是因为这个变换才加的这个函数,之前bounding没考虑这个不准。不知道为什么原生的代码不用scaleZ
|
|
|
- this.contentTransform.premultiply(tranM)
|
|
|
- }
|
|
|
- //如果有rtcCenter的话一开始boundingVolume不准?会不会有显示问题?
|
|
|
-
|
|
|
return this.contentTransform.clone()
|
|
|
}
|
|
|
|
|
|
@@ -10381,6 +10401,24 @@ class Tileset3D extends EventDispatcher{//xzw add EventDispatcher
|
|
|
}
|
|
|
|
|
|
_initializeTileSet(tilesetJson) {
|
|
|
+ if(tilesetJson.root.boundingVolume.sphere){//xzw add 针对适应cesium的自带坐标的模型
|
|
|
+ //this.boundWhole = new THREE.Box3
|
|
|
+
|
|
|
+ tilesetJson.root.boundingVolume.sphereOri = tilesetJson.root.boundingVolume.sphere //cesium坐标
|
|
|
+ tilesetJson.root.boundingVolume.sphere = [0,0,0,tilesetJson.root.boundingVolume.sphere[3]]
|
|
|
+
|
|
|
+ //将其转到地球正面(经纬度0,0)
|
|
|
+ let origin = new THREE.Vector3().fromArray(tilesetJson.root.boundingVolume.sphereOri)
|
|
|
+ let qua = Potree.math.getQuaFromPosAim(new THREE.Vector3, origin.normalize() ) //法向量
|
|
|
+ let quaInv = qua.invert()//这样就能朝向(0,0,-1)
|
|
|
+ //viewer.objs.children[0].applyQuaternion(quaInv)
|
|
|
+ let lastQua = new THREE.Quaternion().setFromEuler(new THREE.Euler(Math.PI,0,Math.PI))//最后翻转下修正 测出来的
|
|
|
+ //viewer.objs.children[0].applyQuaternion(qua1)
|
|
|
+ quaInv.premultiply(lastQua)
|
|
|
+ tilesetJson.root.boundingVolume.rotGeoToZeroMat = new THREE.Matrix4().makeRotationFromQuaternion(quaInv)
|
|
|
+ //尚不知是否所有sphere的都带坐标,不是的话再说
|
|
|
+ }
|
|
|
+
|
|
|
this.root = this._initializeTileHeaders(tilesetJson, null);
|
|
|
|
|
|
if (this.type === TILESET_TYPE.TILES3D) {
|
|
|
@@ -10425,11 +10463,30 @@ class Tileset3D extends EventDispatcher{//xzw add EventDispatcher
|
|
|
this.stats.get(POINTS_COUNT, 'memory');
|
|
|
this.stats.get(TILES_GPU_MEMORY, 'memory');
|
|
|
}
|
|
|
-
|
|
|
- _initializeTileHeaders(tilesetJson, parentTileHeader) {
|
|
|
+
|
|
|
+
|
|
|
+ changeHeaderBoundSphere(header, json){//add 去掉 适应cesium的自带坐标的模型的位移
|
|
|
+ if(header.boundingVolume.sphereOri )return //is root
|
|
|
+ const rootVolume = this.root ? this.root.header.boundingVolume : json.root.boundingVolume
|
|
|
+
|
|
|
+ if(header.boundingVolume.sphere){
|
|
|
+
|
|
|
+ header.boundingVolume.sphereOri = header.boundingVolume.sphere
|
|
|
+ for(let i=0;i<3;i++){
|
|
|
+ header.boundingVolume.sphere[i] -= rootVolume.sphereOri[i]
|
|
|
+ }
|
|
|
|
|
|
+ let center = new THREE.Vector3(...header.boundingVolume.sphere)
|
|
|
+ //this.boundWhole.expandByPoint(center)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ _initializeTileHeaders(tilesetJson, parentTileHeader) {//建立该tileset的某个json所有tile xzw改
|
|
|
+
|
|
|
+
|
|
|
+ this.changeHeaderBoundSphere(tilesetJson.root, tilesetJson)//add
|
|
|
const rootTile = new TileHeader(this, tilesetJson.root, parentTileHeader, parentTileHeader == void 0 && 'root_'+tilesetSid++);
|
|
|
-
|
|
|
+
|
|
|
if (parentTileHeader) {
|
|
|
parentTileHeader.children.push(rootTile);
|
|
|
rootTile.depth = parentTileHeader.depth + 1;
|
|
|
@@ -10447,6 +10504,7 @@ class Tileset3D extends EventDispatcher{//xzw add EventDispatcher
|
|
|
// !zeg改
|
|
|
if(tile.depth < /* this.options. */maxDepth){
|
|
|
for (const childHeader of children) {
|
|
|
+ this.changeHeaderBoundSphere(childHeader, tilesetJson) //xzw add
|
|
|
const childTile = new TileHeader(this, childHeader, tile);
|
|
|
tile.children.push(childTile);
|
|
|
childTile.depth = tile.depth + 1;
|
|
|
@@ -10456,7 +10514,9 @@ class Tileset3D extends EventDispatcher{//xzw add EventDispatcher
|
|
|
window.maxTileDepth = Math.max(window.maxTileDepth||0, tile.depth)
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
return rootTile;
|
|
|
}
|
|
|
|
|
|
@@ -16846,7 +16906,7 @@ function normalizeTileData(tile, options) {
|
|
|
tile.id = tile.contentUrl;
|
|
|
tile.lodMetricType = LOD_METRIC_TYPE.GEOMETRIC_ERROR;
|
|
|
tile.lodMetricValue = tile.geometricError;
|
|
|
- tile.transformMatrix = tile.transform;
|
|
|
+ tile.transformMatrix = tile.transform
|
|
|
tile.type = getTileType(tile);
|
|
|
tile.refine = getRefine(tile.refine);
|
|
|
return tile;
|
|
|
@@ -17572,6 +17632,9 @@ class Loader3DTiles {
|
|
|
props.loadingManager.itemStart(url);
|
|
|
}
|
|
|
const tilesetJson = yield load(url, Tiles3DLoader, Object.assign({}, loadersGLOptions));
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
const renderMap = {};
|
|
|
const boxMap = {};
|
|
|
const unloadQueue = [];
|
|
|
@@ -18092,25 +18155,25 @@ function createGLTFNodes(gltfLoader, tile, unlitMaterial, options, rootTransform
|
|
|
|
|
|
tile.rtcCenterState = rtcCenterGlobal = !!tile.content.rtcCenter
|
|
|
|
|
|
+ let translate = tile.content.rtcCenter || tile.header.boundingVolume.sphere //大部分模型无 rtcCenter
|
|
|
+
|
|
|
let contentTransform = tile.getContentTransform(needUpdate)
|
|
|
|
|
|
- if(tile.content.rtcCenter){//大部分模型无 rtcCenter
|
|
|
- //console.error('rtcCenter有?!') //似乎bounding中包含这个信息了 所以getContentTransform不含这个
|
|
|
+ if(translate){ //需要位移后才和boundingVolume一样
|
|
|
let tranM = new Matrix4$1()
|
|
|
- tranM.makeTranslation(tile.content.rtcCenter[0], tile.content.rtcCenter[1], tile.content.rtcCenter[2])
|
|
|
- contentTransform.premultiply(tranM)
|
|
|
- }
|
|
|
-
|
|
|
+ tranM.makeTranslation(...translate)
|
|
|
+ contentTransform.multiply(tranM)
|
|
|
+ }
|
|
|
+
|
|
|
if(needUpdate ){
|
|
|
tile._updateBoundingVolume(tile.header) //add 重新更新
|
|
|
- }
|
|
|
-
|
|
|
+ }
|
|
|
if (shouldRotate) { //大部分模型 无需 Rotate
|
|
|
contentTransform.multiply(rotateX); // convert from GLTF Y-up to Z-up
|
|
|
}
|
|
|
-
|
|
|
tileContent.applyMatrix4(contentTransform);
|
|
|
|
|
|
+
|
|
|
//'https://testgis.4dage.com/LVBADUI_qp/tileset.json', //村庄 这个案例是 要rotateX 且有rtcCenter的。boundingVolume已经是转换这两者后的值所以getContentTransform不加这个
|
|
|
|
|
|
//tile总共要左乘的矩阵 rotateX -> tileTransInvert * computedTransform -> 对geometry的tranM修改 -> 整个模型的matrixWorld
|
|
|
@@ -18287,6 +18350,8 @@ class tileset3D 最外层整体。 获取方法: viewer.objs.children[index].run
|
|
|
class tileHeader 也就是tileset里面的一个个tile 。 其上有.tileset
|
|
|
|
|
|
|
|
|
+_initializeTileSet(tilesetJson)
|
|
|
+_initializeTileHeaders(tilesetJson, parentTileHeader) //json里tile初始化
|
|
|
|
|
|
|
|
|
|
|
|
@@ -18323,8 +18388,27 @@ viewer.objs.children[0].runtime.getTileset().tiles
|
|
|
tile.depth最低为1 , root是0
|
|
|
|
|
|
|
|
|
+===============
|
|
|
+带坐标osgb参考ces初始化位置 (用付费软件转的那个)特点:tileset.json里的boundingVolume有sphere而非box,无transform
|
|
|
+用另一个工程 3DTilesRendererJS 也显示不出来。 改了很多代码才显示对。
|
|
|
+思路:把json里的sphere.center提取出来,作为最后默认的position,这样模型就在原点上,很多变量都是000了,简化很多。
|
|
|
+和box型的不同的是,需要手动将children里的也按照其sphere.center(减去外层的原始center)位移。box的似乎geo里已经位移好了。
|
|
|
+
|
|
|
+然后会看到模型是斜的,如案例港湾一号的mesh,因cesium中地球正面为经纬度0,0的位置,在非洲左侧,对应x轴正向,右侧为y轴正向。
|
|
|
+模型位于地球右侧靠后上一点,朝向地心。所以把它转正一下就行了。 (现在写进了rotGeoToZeroMat)
|
|
|
+
|
|
|
+原始center为cesium坐标,要转化为经纬度再用:
|
|
|
+let lonlat = Potree.sdk.cesMath.fromCes(center, true)
|
|
|
+let pos = viewer.transform.lonlatToLocal.forward(lonlat) // {x:113.5933488,y:22.36711151}
|
|
|
+model.position.copy(pos)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+cesium显示:http://192.168.0.59:1234/examples/tomcat/allTest/Cesium-3dTiles/index.html
|
|
|
+tile.header.boundingVolume.sphere 应用上变换才是 tile.boundingVolume.center
|
|
|
+
|
|
|
|
|
|
-============
|
|
|
+==============
|
|
|
|
|
|
3dtiles在四维看看和激光里摆放不同,这里的需要位移一段距离才能和四维看看一样,也就是和无transform后的点云一样。
|
|
|
见load4dkkPanos函数
|