dem-net/DEM.Net

transform hgt to glb

sui0312feng opened this issue · 11 comments

Describe the bug
i use this code ,transform hgt to glb ,the glb file can be loaded by cesium-1.58 ,but it can not display normally,it seem to have no height.

**string str2 = "zsq4";
        string str3 = @"C:\Users\sui03\Desktop\DEM.Net\DEM.Net.xUnit.Test\TestData\N43E005.hgt.zip\N43E005.hgt";
        HGTFile hgtFile = new HGTFile(str3);
        FileMetadata fileMetadata2= hgtFile.ParseMetaData();
        HeightMap heightMap2 = hgtFile.GetHeightMap(fileMetadata2);
        // ILogger <MeshService> loger=LoggerFactor
        MeshService meshService = new MeshService();
        glTFService gltfService = new glTFService(meshService);
        MeshPrimitive meshPrimitive = gltfService.GenerateTriangleMesh(heightMap2);
        Model model = gltfService.GenerateModel(meshPrimitive, str2);
        gltfService.Export(model, @"c:\geotiff_gltf\", str2, false, true);**

Hi @sui0312feng thanks for reporting this issue. I'll get a look at it and let you know.

@sui0312feng Your code was ok. You need to reproject the height map to cartesian coordinates :

Native coords units (lon, lat, elevation) are (degrees, degrees, meters)
After a call like this :
heightMap = heightMap.ReprojectGeodeticToCartesian();

Heightmap coordinates units will be (meters, meters, meters).
You can then call ZScale for Z exageration factor.

I have made a test called Test_GLB_Export for you to check.
There's also a Sample project

Let me know how you go.

@xfischer I test code that you give to me, it is right ,but the model have flew in the cesium-1.58, is it problem that transform the coords?

image
image

@xfischer the test data is WGS84 in your unit.test , is it ?

Wow this is interesting... ok I understand your problem. Can you share the sample code you used ?
When you call ‘ReprojectGeodeticToCartesian’ the model coordinates are in meters, centered to the model box center.

I add code you say : "ReprojectGeodeticToCartesian().ZScale(2.5f)",

string str2 = "zsq4";
string str3 = @"C:\Users\sui03\Desktop\DEM.Net\DEM.Net.xUnit.Test\TestData\N43E005.hgt.zip\N43E005.hgt";
HGTFile hgtFile = new HGTFile(str3);
FileMetadata fileMetadata2= hgtFile.ParseMetaData();
HeightMap heightMap2 = hgtFile.GetHeightMap(fileMetadata2).ReprojectGeodeticToCartesian().ZScale(2.5f);
// ILogger loger=LoggerFactor
MeshService meshService = new MeshService();
glTFService gltfService = new glTFService(meshService);
MeshPrimitive meshPrimitive = gltfService.GenerateTriangleMesh(heightMap2);
Model model = gltfService.GenerateModel(meshPrimitive, str2);
gltfService.Export(model, @"c:\geotiff_gltf", str2, false, true);

this is code in cesuim-1.58:
I use "Cartesian3.fromRadians" to reproject coords to cartesian coordinates.
longitude : FileMetadata.StartLon
latitude : FileMetadata.StartLat

/*
* Returns a Cartesian3 position from longitude and latitude values given in radians.
*
* @param {Number} longitude The longitude, in radians
* @param {Number} latitude The latitude, in radians
* @param {Number} [height=0.0] The height, in meters, above the ellipsoid.
* @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies.
* @param {Cartesian3} [result] The object onto which to store the result.
* @returns {Cartesian3} The position
*
* @example
* var position = Cesium.Cartesian3.fromRadians(-2.007, 0.645);
*/
Cartesian3.fromRadians = function(longitude, latitude, height, ellipsoid, result) {
//includeStart('debug', pragmas.debug);
Check.typeOf.number('longitude', longitude);
Check.typeOf.number('latitude', latitude);
//includeEnd('debug');

    height = defaultValue(height, 0.0);
    var radiiSquared = defined(ellipsoid) ? ellipsoid.radiiSquared : wgs84RadiiSquared;

    var cosLatitude = Math.cos(latitude);
    scratchN.x = cosLatitude * Math.cos(longitude);
    scratchN.y = cosLatitude * Math.sin(longitude);
    scratchN.z = Math.sin(latitude);
    scratchN = Cartesian3.normalize(scratchN, scratchN);

    Cartesian3.multiplyComponents(radiiSquared, scratchN, scratchK);
    var gamma = Math.sqrt(Cartesian3.dot(scratchN, scratchK));
    scratchK = Cartesian3.divideByScalar(scratchK, gamma, scratchK);
    scratchN = Cartesian3.multiplyByScalar(scratchN, height, scratchN);

    if (!defined(result)) {
        result = new Cartesian3();
    }
    return Cartesian3.add(scratchK, scratchN, result);
};

@sui0312feng Thanks for taking the time to report this.
Cesium can load WGS84 model out of the box (you may not need to reproject at all, the first code you sent was OK). I have tried with Cesium sandbox and I think the orientation XYZ is bad in DEM.net. I'll try to change it. I'm on vacation now, but I'll get back to you next week.

@xfischer I hava updated your latest code ,the result is same!

Hi @sui0312feng ! Yes it is normal I’m on holidays with poor internet connection. I’ll get back to you as soon as I can.

@xfischer OK , Have a nice vacation!

Hi @sui0312feng do you finally could get it right ? Sorry for no answering this.