diff --git a/lib/combineTileset.js b/lib/combineTileset.js index f879f5d..c2868fc 100644 --- a/lib/combineTileset.js +++ b/lib/combineTileset.js @@ -3,8 +3,11 @@ var Cesium = require('cesium'); var fsExtra = require('fs-extra'); var path = require('path'); +var Matrix4 = Cesium.Matrix4; var defaultValue = Cesium.defaultValue; var defined = Cesium.defined; +var Cartesian3 = Cesium.Cartesian3; +var Cartographic = Cesium.Cartographic; module.exports = combineTileset; @@ -20,6 +23,8 @@ function combineTileset(options) { var south = Number.POSITIVE_INFINITY; var north = Number.NEGATIVE_INFINITY; var east = Number.NEGATIVE_INFINITY; + var minBox = [Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY]; + var maxBox = [Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY]; var minheight = Number.POSITIVE_INFINITY; var maxheight = Number.NEGATIVE_INFINITY; var inputDir = defaultValue(options.inputDir, './'); @@ -32,6 +37,8 @@ function combineTileset(options) { inputDir = path.normalize(inputDir); outputTileset = path.normalize(outputTileset); var outputDir = path.dirname(outputTileset); + var gltfUpAxis = "Y"; + var transform; getJsonFiles(inputDir, jsonFiles); jsonFiles.forEach(function(jsonFile) { @@ -40,8 +47,10 @@ function combineTileset(options) { if(!json.root) {return Promise.resolve();} var boundingVolume = json.root.boundingVolume; var geometricError = json.geometricError; + transform = json.root.transform; var refine = json.root.refine; + gltfUpAxis = json.asset.gltfUpAxis; if (defined(boundingVolume) && defined(geometricError)) { // Use external tileset instand of b3dm. var url = path.relative(outputDir, jsonFile); @@ -55,6 +64,21 @@ function combineTileset(options) { north = Math.max(north, boundingVolume.region[3]); minheight = Math.min(minheight, boundingVolume.region[4]); maxheight = Math.max(maxheight, boundingVolume.region[5]); + }else if(boundingVolume.box) + { + var tempMin = [boundingVolume.box[0]-boundingVolume.box[3]/2, + boundingVolume.box[1]-boundingVolume.box[7]/2, + boundingVolume.box[2]-boundingVolume.box[11]/2]; + var tempMax = [boundingVolume.box[0]+boundingVolume.box[3]/2, + boundingVolume.box[1]+boundingVolume.box[7]/2, + boundingVolume.box[2]+boundingVolume.box[11]/2]; + minBox = [tempMin[0]maxBox[0]?tempMax[0]:maxBox[0], + tempMax[1]>maxBox[1]?tempMax[1]:maxBox[1], + tempMax[2]>maxBox[2]?tempMax[2]:maxBox[2]]; } var child = { @@ -76,29 +100,62 @@ function combineTileset(options) { }); return Promise.all(promises).then(function() { - var tileset = { - 'asset': { - 'version': '0.0', - 'tilesetVersion': '1.0.0-obj23dtiles', - }, - 'geometricError': geometricError, - 'root': { - 'boundingVolume': { - 'region': [ - west, - south, - east, - north, - minheight, - maxheight - ] + var tileset; + if(minBox === [Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY]) + { + tileset = { + 'asset': { + 'version': '0.0', + 'tilesetVersion': '1.0.0-obj23dtiles', + 'gltfUpAxis': gltfUpAxis }, - 'refine': 'ADD', 'geometricError': geometricError, - 'children': children + 'root': { + 'boundingVolume': { + 'region': [ + west, + south, + east, + north, + minheight, + maxheight + ] + }, + 'refine': 'ADD', + 'geometricError': geometricError, + 'children': children + } + }; + }else + { + var center = new Cartesian3((minBox[0]+maxBox[0])/2,(minBox[1]+maxBox[1])/2,(minBox[2]+maxBox[2])/2); + if(transform !== undefined) + { + var transformArray = (defined(transform) && !Matrix4.equals(transform, Matrix4.IDENTITY)) ? Matrix4.pack(transform, new Array(16)) : undefined; + center = Matrix4.multiplyByPoint(transformArray, center, new Cartesian3()); } - }; - + tileset = { + 'asset': { + 'version': '0.0', + 'tilesetVersion': '1.0.0-obj23dtiles', + 'gltfUpAxis': gltfUpAxis + }, + 'geometricError': geometricError, + 'root': { + 'boundingVolume': { + 'box': [ + center.x,center.y,center.z, + maxBox[0]-minBox[0],0,0, + 0,maxBox[1]-minBox[1],0, + 0,0,maxBox[2]-minBox[2] + ] + }, + 'refine': 'ADD', + 'geometricError': geometricError, + 'children': children + } + }; + } return Promise.resolve({ tileset: tileset, output: outputTileset diff --git a/lib/createSingleTileset.js b/lib/createSingleTileset.js index d4baad3..1318dd1 100644 --- a/lib/createSingleTileset.js +++ b/lib/createSingleTileset.js @@ -8,6 +8,7 @@ var defaultValue = Cesium.defaultValue; var HeadingPitchRoll = Cesium.HeadingPitchRoll; var Matrix4 = Cesium.Matrix4; var Transforms = Cesium.Transforms; +var Cartographic = Cesium.Cartographic; module.exports = createSingleTileset; @@ -46,8 +47,10 @@ function createSingleTileset(options) { var properties = defaultValue(options.properties, undefined); var geometricError = defaultValue(options.geometricError, 200.0); var tileTransform = wgs84Transform(longitude, latitude, transHeight); - var transform = defaultValue(options.transfrom, tileTransform); + var transform = defaultValue(options.transform, tileTransform); + var transformArray = (defined(transform) && !Matrix4.equals(transform, Matrix4.IDENTITY)) ? Matrix4.pack(transform, new Array(16)) : undefined; + var height = maxHeight - minHeight; if(!(options.region||options.box||options.sphere)) { @@ -58,10 +61,17 @@ function createSingleTileset(options) { var longitudeExtent = metersToLongitude(tileWidth, latitude); var latitudeExtent = metersToLatitude(tileHeight); - var west = longitude - longitudeExtent / 2 + offsetX / tileWidth * longitudeExtent; - var south = latitude - latitudeExtent / 2 - offsetY / tileHeight * latitudeExtent; - var east = longitude + longitudeExtent / 2 + offsetX / tileWidth * longitudeExtent; - var north = latitude + latitudeExtent / 2 - offsetY / tileHeight * latitudeExtent; + // var west = longitude - longitudeExtent / 2 + offsetX / tileWidth * longitudeExtent; + // var south = latitude - latitudeExtent / 2 - offsetY / tileHeight * latitudeExtent; + // var east = longitude + longitudeExtent / 2 + offsetX / tileWidth * longitudeExtent; + // var north = latitude + latitudeExtent / 2 - offsetY / tileHeight * latitudeExtent; + + var center = Cesium.Cartographic.fromCartesian(Matrix4.multiplyByPoint(transformArray, new Cartesian3(offsetX,offsetY,(maxHeight+minHeight)/2), new Cartesian3()),Cesium.Ellipsoid.WGS84,new Cartographic()); + + var west = center.longitude-longitudeExtent / 2; + var south = center.latitude-latitudeExtent / 2; + var east = center.longitude+longitudeExtent /2; + var north = center.latitude+latitudeExtent /2; boundingVolume = { region : [ @@ -69,15 +79,15 @@ function createSingleTileset(options) { south, east, north, - minHeight, - maxHeight + minHeight + transHeight, + maxHeight + transHeight ] }; } else if (options.box) { boundingVolume = { box : [ - offsetX, -offsetY, height / 2 + minHeight, // center + offsetX, offsetY, height / 2 + minHeight, // center tileWidth / 2, 0, 0, // width 0, tileHeight / 2, 0, // depth 0, 0, height / 2 // height @@ -87,7 +97,7 @@ function createSingleTileset(options) { else if (options.sphere) { boundingVolume = { sphere : [ - offsetX, -offsetY, height / 2 + minHeight, + offsetX, offsetY, height / 2 + minHeight, Math.sqrt(tileWidth * tileWidth / 4 + tileHeight * tileHeight / 4 + height * height / 4) ] }; diff --git a/lib/obj2Tileset.js b/lib/obj2Tileset.js index ce7f1ac..df0e28d 100644 --- a/lib/obj2Tileset.js +++ b/lib/obj2Tileset.js @@ -22,26 +22,76 @@ function obj2Tileset(objPath, outputpath, options) { var tilePath = path.join(folder, tilesetFolderName, tileFullName); var tilesetPath = path.join(folder, tilesetFolderName, 'tileset.json'); var tilesetOptions = options.tilesetOptions || {}; + + var upAxis = defaultValue(tilesetOptions.gltfUpAxis, 'Y'); if (options.b3dm) { return obj2B3dm(objPath, options) .then(function(result){ var batchTableJson = result.batchTableJson; var minmaxPoint = getPoint3MinMax(batchTableJson.minPoint.concat(batchTableJson.maxPoint)); - var width = minmaxPoint.max[0] - minmaxPoint.min[0]; - var height = minmaxPoint.max[2] - minmaxPoint.min[2]; - width = Math.ceil(width); - height = Math.ceil(height); - var offsetX = width / 2 + minmaxPoint.min[0]; - var offsetY = height / 2 + minmaxPoint.min[2]; + var offsetX; + var offsetY; + var minHeight; + var maxHeight; + var width; + var height; + var transHeight; + + var x,y,z; + if(upAxis === 'Y') + { + x = 0; + y = 2; + z = 1; + + width = minmaxPoint.max[x] - minmaxPoint.min[x]; + height = minmaxPoint.max[y] - minmaxPoint.min[y]; + + offsetX = width / 2 + minmaxPoint.min[x]; + offsetY = -(height / 2 + minmaxPoint.min[y]); + } + else if(upAxis === 'Z') + { + x = 0; + y = 1; + z = 2; + + width = minmaxPoint.max[x] - minmaxPoint.min[x]; + height = minmaxPoint.max[y] - minmaxPoint.min[y]; + + offsetX = width / 2 + minmaxPoint.min[x]; + offsetY = height / 2 + minmaxPoint.min[y]; + } + else if(upAxis === 'X') + { + x = 2; + y = 1; + z = 0; + + width = minmaxPoint.max[x] - minmaxPoint.min[x]; + height = minmaxPoint.max[y] - minmaxPoint.min[y]; + + offsetX = -(width / 2 + minmaxPoint.min[x]); + offsetY = height / 2 + minmaxPoint.min[y]; + } + + width = Math.ceil(width); + height = Math.ceil(height); + + minHeight = minmaxPoint.min[z]; + maxHeight = minmaxPoint.max[z]; + transHeight = -minmaxPoint.min[z]; return new Promise(function(resolve) { tilesetOptions.tileName = tileFullName; tilesetOptions.tileWidth = defaultValue(tilesetOptions.tileWidth, width); tilesetOptions.tileHeight = defaultValue(tilesetOptions.tileHeight, height); - tilesetOptions.transHeight = defaultValue(tilesetOptions.transHeight, -minmaxPoint.min[1]); - tilesetOptions.minHeight = defaultValue(tilesetOptions.minHeight, minmaxPoint.min[1] + tilesetOptions.transHeight); - tilesetOptions.maxHeight = defaultValue(tilesetOptions.maxHeight, minmaxPoint.max[1] + tilesetOptions.transHeight); + tilesetOptions.transHeight = defaultValue(tilesetOptions.transHeight, transHeight); + tilesetOptions.minHeight = defaultValue(tilesetOptions.minHeight, minHeight); + tilesetOptions.maxHeight = defaultValue(tilesetOptions.maxHeight, maxHeight); tilesetOptions.offsetX = defaultValue(tilesetOptions.offsetX, offsetX); tilesetOptions.offsetY = defaultValue(tilesetOptions.offsetY, offsetY); + tilesetOptions.transform = defaultValue(tilesetOptions.transform, undefined); + return resolve({ b3dm : result.b3dm, batchTableJson: result.batchTableJson,