SuperMap iClient3D for WebGLで.glbモデルを平面でクリッピングする方法
1、機能紹介
この記事では、SuperMap3D(Cesiumに似た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.jsのgetEngineTypeを通じてエンジンタイプ(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、読み込み効果
(画像は、航空機モデルがクリッピングされる前と後の様子を示しています)
コメント
コメントを投稿