SuperMap iClient3D for WebGLで.glbモデルを平面でクリッピングする方法

1、機能紹介

この記事では、SuperMap3DCesiumに似た3D地理可視化エンジン)をベースにしたモデルクリッピング機能を実現します 。主な特徴は次のとおりです。

  • 3Dモデルの読み込みと表示:航空機モデル(Cesium_Air.glb)を読み込みます 。
  • 動的なクリッピング平面:ClippingPlaneを通じてモデルのクリッピングを実現します。ユーザーはスライダーでクリッピング平面の位置(wheightパラメータ)を調整し、リアルタイムでモデルをカットできます 。
  • インタラクティブな制御:入力ボックス(#lodScale)を提供し、ユーザーが数値を入力してクリッピング距離を動的に変更し、モデルのカット効果をインタラクティブに調整できるようにします 。

 

2、主要なコードインターフェース

平面をClippingPlaneCollectionに適したヘッセ法線形式(Hessian Normal Form)に変換し、数学的なPlane関数と互換性を持たせる必要があります 。

名前

説明

normal

Cartesian3

平面の単位法線ベクトル(正規化処理後の平面法線ベクトルで、その長さは1です)。

distance

Number

原点から平面までの最短距離。その符号によって原点が平面のどちら側にあるかが決まります。距離が正の場合、原点は法線ベクトルの方向の半空間内にあり、距離が負の場合、原点は法線ベクトルの反対方向の半空間内にあります。距離がゼロの場合、平面は原点を通過します 。

 

var clippingPlanes = [

    new SuperMap3D.ClippingPlane(

        new SuperMap3D.Cartesian3(0.0, 0.0, -1.0), // 平面の法線(下向き)

        wheight // 平面から原点までの距離(0に設定するとモデルの中心からクリッピング)

    )

]; // クリッピング平面の配列

 

const modelEntityClippingPlanes = new SuperMap3D.ClippingPlaneCollection({

    planes: clippingPlanes,

    edgeWidth: 1

});

 

3、完全なフロントエンドコード

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="utf-8">

    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">

    <meta name="viewport"

          [cite_start]content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">

    <title>CBD</title>

    <link href="../../Build/SuperMap3D/Widgets/widgets.css" rel="stylesheet">

    <script src="./js/config.js"></script>

    <link href="./css/pretty.css" rel="stylesheet">

    <link href="./css/style.css" rel="stylesheet">

    <script src="./js/jquery.min.js"></script>

    <script type="text/javascript" src="../../Build/SuperMap3D/SuperMap3D.js"></script>

</head>

<body>

<div id="Container"></div>

<div id="tool-bar" class="param-container tool-bar">

    <div class="param-item">

        <label>距離</label>

        <input type="number" id="lodScale" min="-1000" max="1000" value="1" step="10" style="width: 140px">

    </div>

</div>

<script type="text/javascript">

    function onload(SuperMap3D) {

        // config.jsgetEngineTypeを通じてエンジンタイプ(EngineType)を取得し、起動方法を設定します

        var EngineType = getEngineType();

        var viewer = new SuperMap3D.Viewer('Container', {

            contextOptions: {

                contextType: Number(EngineType), // Webgl2:2 ; WebGPU:3

            }

        });

        viewer.scenePromise.then(function (scene) {

            init(SuperMap3D, scene, viewer);

        });

    }

 

    function init(SuperMap3D, scene, viewer) {

        var scene = viewer.scene;

        scene.shadowMap.darkness = 1.275; // 2回目のベイクテクスチャの効果(明暗度)を設定

        scene.debugShowFramesPerSecond = false;

        scene.hdrEnabled = false;

        scene.sun.show = true;

        let wheight = 1;

        var widget = viewer.Widget;

        try {

            // クリッピング平面の位置を更新

            function updateClippingPlanes() {

                console.log("更新しました");

                var clippingPlanes = [

                    new SuperMap3D.ClippingPlane(

                        new SuperMap3D.Cartesian3(0.0, 0.0, -1.0), // 平面の法線(下向き)

                        wheight // 平面から原点までの距離(0に設定するとモデルの中心からクリッピング)

                    )

                ]; // クリッピング平面の配列

                const modelEntityClippingPlanes = new SuperMap3D.ClippingPlaneCollection({

                    planes: clippingPlanes,

                    edgeWidth: 1

                });

                return modelEntityClippingPlanes;

            }

 

            const modelentity = new SuperMap3D.Entity({

                id: "chuanboplay",

                name: "chuanboplay",

                position: new SuperMap3D.Cartesian3.fromDegrees(116.45553697698202,

                    39.90657994600217, 21.542919457733646),

                label: {

                    text: "某航空機",

                    font: '14px sans-serif'

                },

                model: {

                    uri: './Cesium_Air.glb',

                    scale: 10,

                    clippingPlanes: new SuperMap3D.CallbackProperty(updateClippingPlanes,

                        false) // 重要:クリッピング平面を設定する場所

                }

            })

            var mentity = viewer.entities.add(modelentity);

            viewer.zoomTo(mentity);

            $("#lodScale").on("input change", function () {

                var lod = $("#lodScale").val();

                wheight = Number(lod);

            });

 

        } catch (e) {

            if (widget._showRenderLoopErrors) {

                var title = 'レンダリング中にエラーが発生したため、レンダリングを停止しました。';

                widget.showErrorPanel(title, undefined, e);

            }

        }

    }

 

    if (typeof SuperMap3D !== 'undefined') {

        window.startupCalled = true;

        onload(SuperMap3D);

    }

</script>

</body>

</html>

4、読み込み効果

(画像は、航空機モデルがクリッピングされる前と後の様子を示しています)


コメント

このブログの人気の投稿

【GIS初心者向け】国土数値情報、ShapefileとGeoJSONどっちをダウンロードすべき?特徴と使い分けを徹底解説!

伝統漁業の未来を変える宇宙の視点!定置網漁業と衛星データの賢い付き合い方

3分でわかる住所と地番の違い