@yangyongtao/gaea 1.1.26 → 1.1.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/package.json +1 -1
- package/src/GaeaMethods.js +327 -82
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yangyongtao/gaea",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.27",
|
|
4
4
|
"description": "Gaea 3D visualization component library - Vue 3 components based on Godot WASM engine. Includes WMTS layer loading, camera view control, Vite plugin auto-injection, etc.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.cjs",
|
package/src/GaeaMethods.js
CHANGED
|
@@ -105,7 +105,7 @@ function showLoading() {
|
|
|
105
105
|
if (document.getElementById('gaea-loading-overlay')) return;
|
|
106
106
|
const overlay = document.createElement('div');
|
|
107
107
|
overlay.id = 'gaea-loading-overlay';
|
|
108
|
-
overlay.innerHTML =
|
|
108
|
+
overlay.innerHTML = `<div class="gaea-spinner"></div><div class="gaea-text">${_config.loadingText}</div>`;
|
|
109
109
|
document.body.appendChild(overlay);
|
|
110
110
|
}
|
|
111
111
|
|
|
@@ -160,6 +160,8 @@ const defaultConfig = {
|
|
|
160
160
|
defaultCameraPosition: '27.3680928977018,120.414139621887,0,109379.690132486,0,0',
|
|
161
161
|
/** 引擎加载进度回调 */
|
|
162
162
|
onProgress: null,
|
|
163
|
+
/** 引擎加载提示文字 */
|
|
164
|
+
loadingText: 'GAEA 引擎加载中...',
|
|
163
165
|
/** DataHub API 地址(图层树数据接口),为空则只用默认数据 */
|
|
164
166
|
dataHubApiUrl: '',
|
|
165
167
|
/** 是否显示图层树按钮(右上角重置按钮旁边) */
|
|
@@ -290,8 +292,6 @@ export class GaeaApp {
|
|
|
290
292
|
this._screenIconList = [];
|
|
291
293
|
this._hiddenCategories = new Set();
|
|
292
294
|
this._tilesetMap = {}; // 已加载的 3D Tiles 引用,key 为 tileset 名称
|
|
293
|
-
this._flattenTool = null; // 压平工具
|
|
294
|
-
this._flattenPolygon = null; // 压平多边形元素
|
|
295
295
|
this._secIsClickArr = [];
|
|
296
296
|
this._secScreenIconKeyValue = {};
|
|
297
297
|
this._groundPolygonElements = [];
|
|
@@ -630,6 +630,7 @@ export class GaeaApp {
|
|
|
630
630
|
{ name: '岭尾水闸游览模型', position: { x: 27.215661, y: 120.462325, z: 34 }, rotate: [0, -66, 0], size: [1, 1, 1], show: false, url: 'gltf/box.gltf' },
|
|
631
631
|
{ name: '岭尾新闸游览模型', position: { x: 27.21038, y: 120.458513, z: 4 }, rotate: [0, 30, 0], size: [1, 1, 1], show: false, url: 'gltf/box.gltf' },
|
|
632
632
|
{ name: '盒子模型-yanpu', position: { x: 27.231665, y: 120.456095, z: 48.608 }, rotate: [0, 90, 0], size: [10, 10, 10], show: true, url: 'gltf/box.gltf' },
|
|
633
|
+
{ name: '防汛沙袋', position: { x: 27.218723, y: 120.460473, z: 18 }, rotate: [0, 0, 0], size: [1, 1, 1], show: false, url: 'gltf/sanddai.glb' },
|
|
633
634
|
];
|
|
634
635
|
|
|
635
636
|
this._gltfCfgMap = {};
|
|
@@ -1183,7 +1184,7 @@ export class GaeaApp {
|
|
|
1183
1184
|
const tilesetUrl = typeof item === 'string' ? item : item.jsonUrl
|
|
1184
1185
|
const name = typeof item === 'string' ? '' : (item.tilName || '')
|
|
1185
1186
|
const height = typeof item === 'string' ? 0 : (item.height || 0)
|
|
1186
|
-
const
|
|
1187
|
+
const enabledClip = typeof item === 'object' ? (item.enabledClip || false) : false
|
|
1187
1188
|
const tileset = new Gaea.Gaea3DTileset()
|
|
1188
1189
|
tileset.Name = name
|
|
1189
1190
|
tileset.TilesetUrl = tilesetUrl
|
|
@@ -1192,7 +1193,7 @@ export class GaeaApp {
|
|
|
1192
1193
|
tileset.SkipLevelOfDetail = false
|
|
1193
1194
|
tileset.IsZUp = true
|
|
1194
1195
|
tileset.RecalculateNormals = true
|
|
1195
|
-
tileset.
|
|
1196
|
+
tileset.EnabledClip = enabledClip
|
|
1196
1197
|
tileset.BaseUrl = tilesetUrl.slice(0, tilesetUrl.lastIndexOf('/') + 1)
|
|
1197
1198
|
tileset.InitTileSet(name, tilesetUrl)
|
|
1198
1199
|
tileset.MaximumMemoryUsage = 512
|
|
@@ -1204,109 +1205,352 @@ export class GaeaApp {
|
|
|
1204
1205
|
if (name) {
|
|
1205
1206
|
this._tilesetMap[name] = tileset
|
|
1206
1207
|
}
|
|
1207
|
-
console.log('[GaeaApp] 3D Tiles 已加载:', name || tilesetUrl, height ? `高度: ${height}` : '',
|
|
1208
|
+
console.log('[GaeaApp] 3D Tiles 已加载:', name || tilesetUrl, height ? `高度: ${height}` : '', enabledClip ? '(裁剪已启用)' : '')
|
|
1208
1209
|
return tileset
|
|
1209
1210
|
};
|
|
1210
1211
|
|
|
1211
|
-
// ----
|
|
1212
|
+
// ---- 倾斜挖方 ----
|
|
1212
1213
|
|
|
1213
1214
|
/**
|
|
1214
|
-
*
|
|
1215
|
-
* @param {
|
|
1216
|
-
* @param {
|
|
1217
|
-
* @param {
|
|
1218
|
-
* @
|
|
1215
|
+
* 根据多边形坐标裁剪地形(倾斜挖方)
|
|
1216
|
+
* @param {Array<{x: number, y: number, z: number}>} pointList - 多边形顶点坐标数组 [{x: 纬度, y: 经度, z: 高程}, ...]
|
|
1217
|
+
* @param {number} height - 裁剪深度/高度
|
|
1218
|
+
* @param {Function} [callback] - 完成后的回调函数,接收 _Holeitem
|
|
1219
|
+
* @returns {boolean} 是否成功
|
|
1219
1220
|
* @example
|
|
1220
|
-
* app.
|
|
1221
|
-
*
|
|
1222
|
-
*
|
|
1223
|
-
*
|
|
1224
|
-
*
|
|
1225
|
-
* { lat: 27.2195, lng: 120.458 },
|
|
1226
|
-
* { lat: 27.2190, lng: 120.456 }
|
|
1227
|
-
* ],
|
|
1228
|
-
* height: 30
|
|
1229
|
-
* })
|
|
1221
|
+
* app.editTerrainTool([
|
|
1222
|
+
* { x: 27.2205, y: 120.456, z: 10 },
|
|
1223
|
+
* { x: 27.2210, y: 120.458, z: 10 },
|
|
1224
|
+
* { x: 27.2195, y: 120.458, z: 10 }
|
|
1225
|
+
* ], 50, (item) => { console.log('挖方完成', item) })
|
|
1230
1226
|
*/
|
|
1231
|
-
|
|
1232
|
-
if (!
|
|
1233
|
-
console.warn('[GaeaApp]
|
|
1234
|
-
return
|
|
1227
|
+
editTerrainTool = (pointList, height, callback) => {
|
|
1228
|
+
if (!pointList || pointList.length === 0) {
|
|
1229
|
+
console.warn('[GaeaApp] editTerrainTool: pointList 不能为空')
|
|
1230
|
+
return false
|
|
1235
1231
|
}
|
|
1236
1232
|
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1233
|
+
const Position = pointList.map(point => new Gaea.Vector3(point.x, point.y, point.z))
|
|
1234
|
+
|
|
1235
|
+
// 经纬度 → 笛卡尔坐标
|
|
1236
|
+
const originPoint = pointList.map(p => Gaea.GaeaMath.SphericalToCartesianDeg(new Gaea.Vector3(p.x, p.y, p.z)))
|
|
1237
|
+
|
|
1238
|
+
// 启用 QueryServer
|
|
1239
|
+
Gaea.QueryServer.Instance.Enable = true
|
|
1240
|
+
|
|
1241
|
+
// 清旧挖方
|
|
1242
|
+
if (this._holeItem) {
|
|
1243
|
+
Gaea.ExcavationManager.Instance.RemoveItem(this._holeItem)
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
// 创建挖方对象 (坐标点, 插值距离, 深度, UV缩放, 是否法线材质, 是否需要edge)
|
|
1247
|
+
this._holeItem = Gaea.ExcavationManager.Instance.CreateItem(originPoint, 100, height, 100, true, true)
|
|
1248
|
+
Gaea.ExcavationManager.Instance.ExposureLength = 0
|
|
1249
|
+
Gaea.ExcavationManager.Instance.AddItem(this._holeItem)
|
|
1250
|
+
Gaea.ExcavationManager.Instance.NeedFence = true
|
|
1251
|
+
|
|
1252
|
+
if (Gaea.QueryServer.Instance != null) {
|
|
1253
|
+
Gaea.ExcavationManager.Instance.FenceHeight = 10
|
|
1254
|
+
const box = Gaea.World.Instance.SimplePolygonGenerater(originPoint, false, false, false, false, Gaea.ExcavationManager.Instance.FenceHeight, 0, 2, Gaea.ExcavationManager.Instance.FenceHeight)
|
|
1255
|
+
Gaea.World.Instance.AddChild(box, false)
|
|
1256
|
+
Gaea.QueryServer.Instance.ClipBox = box
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
console.log('[GaeaApp] 挖方已执行:', `深度: ${height}`, `顶点数: ${pointList.length}`)
|
|
1260
|
+
|
|
1261
|
+
setTimeout(() => {
|
|
1262
|
+
if (typeof callback === 'function') {
|
|
1263
|
+
callback(this._holeItem)
|
|
1250
1264
|
}
|
|
1251
|
-
|
|
1265
|
+
}, 1000)
|
|
1266
|
+
};
|
|
1267
|
+
|
|
1268
|
+
/**
|
|
1269
|
+
* 还原地形(清除所有挖方效果)
|
|
1270
|
+
*/
|
|
1271
|
+
restoreTerrain = () => {
|
|
1272
|
+
if (this._holeItem) {
|
|
1273
|
+
Gaea.ExcavationManager.Instance.RemoveItem(this._holeItem)
|
|
1274
|
+
this._holeItem = null
|
|
1275
|
+
}
|
|
1276
|
+
Gaea.ExcavationManager.Instance.Clear()
|
|
1277
|
+
Gaea.World.Instance.SetCurrentTool(null)
|
|
1278
|
+
if (Gaea.QueryServer.Instance != null && Gaea.QueryServer.Instance.ClipBox != null) {
|
|
1279
|
+
Gaea.QueryServer.Instance.ClipBox.QueueFree()
|
|
1280
|
+
Gaea.QueryServer.Instance.ClipBox = null
|
|
1281
|
+
}
|
|
1282
|
+
console.log('[GaeaApp] 地形已还原')
|
|
1283
|
+
};
|
|
1284
|
+
|
|
1285
|
+
/**
|
|
1286
|
+
* 监听画布鼠标点击,获取点击位置的经纬度坐标
|
|
1287
|
+
* @example
|
|
1288
|
+
* app.addMouseClick((pos) => {
|
|
1289
|
+
* console.log('点击位置:', pos) // { x: 纬度, y: 经度, z: 高程 }
|
|
1290
|
+
* })
|
|
1291
|
+
*/
|
|
1292
|
+
addMouseClick = (callback) => {
|
|
1293
|
+
const canvas = document.getElementById('canvas')
|
|
1294
|
+
if (!canvas) {
|
|
1295
|
+
console.warn('[GaeaApp] addMouseClick: canvas 元素未找到')
|
|
1296
|
+
return
|
|
1252
1297
|
}
|
|
1298
|
+
canvas.addEventListener('mousedown', (event) => {
|
|
1299
|
+
const result = Gaea.GaeaMath.ProjectPosition(new Gaea.Vector2(event.offsetX, event.offsetY))
|
|
1300
|
+
const lonlat = Gaea.GaeaMath.CartesianToSphericalDeg(result)
|
|
1301
|
+
const pos = { x: lonlat.x, y: lonlat.y, z: lonlat.z }
|
|
1302
|
+
console.log('[GaeaApp] 点击位置:', pos)
|
|
1303
|
+
if (typeof callback === 'function') {
|
|
1304
|
+
callback(pos)
|
|
1305
|
+
}
|
|
1306
|
+
})
|
|
1307
|
+
};
|
|
1253
1308
|
|
|
1254
|
-
|
|
1309
|
+
/**
|
|
1310
|
+
* 获取已加载的模型元素
|
|
1311
|
+
* @param {string} name - 模型名称
|
|
1312
|
+
* @returns {object} GLTFElement 或 null
|
|
1313
|
+
*/
|
|
1314
|
+
getModel = (name) => {
|
|
1315
|
+
return this._gltfElements[name] || null
|
|
1316
|
+
};
|
|
1255
1317
|
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1318
|
+
/**
|
|
1319
|
+
* 获取模型当前状态(位置、旋转、缩放)
|
|
1320
|
+
* @param {string} name - 模型名称
|
|
1321
|
+
* @returns {object|null} { position, rotate, scale, visible }
|
|
1322
|
+
*/
|
|
1323
|
+
getModelInfo = (name) => {
|
|
1324
|
+
const el = this._gltfElements[name]
|
|
1325
|
+
if (!el) return null
|
|
1326
|
+
return {
|
|
1327
|
+
position: { x: el.GeographyPosition.x, y: el.GeographyPosition.y, z: el.GeographyPosition.z },
|
|
1328
|
+
rotate: { x: el.TiltHeadingBank.x, y: el.TiltHeadingBank.y, z: el.TiltHeadingBank.z },
|
|
1329
|
+
scale: { x: el.Root.Scale.x, y: el.Root.Scale.y, z: el.Root.Scale.z },
|
|
1330
|
+
visible: el.Root.Visible,
|
|
1261
1331
|
}
|
|
1262
|
-
|
|
1332
|
+
};
|
|
1263
1333
|
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1334
|
+
/**
|
|
1335
|
+
* 设置模型位置(经纬度 + 高程)
|
|
1336
|
+
* @param {string} name - 模型名称
|
|
1337
|
+
* @param {object} position - { x: 纬度, y: 经度, z: 高程 }
|
|
1338
|
+
*/
|
|
1339
|
+
setModelPosition = (name, position) => {
|
|
1340
|
+
const el = this._gltfElements[name]
|
|
1341
|
+
if (!el) { console.warn(`[GaeaApp] 模型 "${name}" 未找到`); return }
|
|
1342
|
+
el.GeographyPosition = new Gaea.Vector3(position.x, position.y, position.z)
|
|
1343
|
+
};
|
|
1267
1344
|
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
Gaea.
|
|
1345
|
+
/**
|
|
1346
|
+
* 设置模型旋转
|
|
1347
|
+
* @param {string} name - 模型名称
|
|
1348
|
+
* @param {number[]} rotate - [pitch, yaw, roll]
|
|
1349
|
+
*/
|
|
1350
|
+
setModelRotation = (name, rotate) => {
|
|
1351
|
+
const el = this._gltfElements[name]
|
|
1352
|
+
if (!el) { console.warn(`[GaeaApp] 模型 "${name}" 未找到`); return }
|
|
1353
|
+
el.TiltHeadingBank = new Gaea.Vector3(rotate[0], rotate[1], rotate[2])
|
|
1354
|
+
};
|
|
1355
|
+
|
|
1356
|
+
/**
|
|
1357
|
+
* 设置模型缩放
|
|
1358
|
+
* @param {string} name - 模型名称
|
|
1359
|
+
* @param {number[]} size - [sx, sy, sz]
|
|
1360
|
+
*/
|
|
1361
|
+
setModelScale = (name, size) => {
|
|
1362
|
+
const el = this._gltfElements[name]
|
|
1363
|
+
if (!el) { console.warn(`[GaeaApp] 模型 "${name}" 未找到`); return }
|
|
1364
|
+
el.Root.Scale = new Gaea.Vector3(size[0], size[1], size[2])
|
|
1365
|
+
};
|
|
1277
1366
|
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1367
|
+
/**
|
|
1368
|
+
* 设置模型可见性
|
|
1369
|
+
* @param {string} name - 模型名称
|
|
1370
|
+
* @param {boolean} visible
|
|
1371
|
+
*/
|
|
1372
|
+
setModelVisible = (name, visible) => {
|
|
1373
|
+
const el = this._gltfElements[name]
|
|
1374
|
+
if (!el) { console.warn(`[GaeaApp] 模型 "${name}" 未找到`); return }
|
|
1375
|
+
el.Root.Visible = visible
|
|
1376
|
+
};
|
|
1377
|
+
|
|
1378
|
+
/**
|
|
1379
|
+
* 移除模型(参考 ht_3dview removeGltf)
|
|
1380
|
+
* @param {string} name - 模型名称
|
|
1381
|
+
*/
|
|
1382
|
+
removeGltf = (name) => {
|
|
1383
|
+
const el = this._gltfElements[name]
|
|
1384
|
+
if (!el) { console.warn(`[GaeaApp] 模型 "${name}" 未找到`); return }
|
|
1385
|
+
Gaea.World.Instance.RenderableObjectList.Remove(el)
|
|
1386
|
+
delete this._gltfElements[name]
|
|
1387
|
+
delete this._gltfCfgMap[name]
|
|
1388
|
+
};
|
|
1389
|
+
|
|
1390
|
+
/**
|
|
1391
|
+
* 修改模型配置(位置/旋转/缩放一起设置,参考 ht_3dview updateElementPosition)
|
|
1392
|
+
* @param {object} options
|
|
1393
|
+
* @param {string} options.name - 模型名称
|
|
1394
|
+
* @param {object} options.position - { x: 纬度, y: 经度, z: 高程 }
|
|
1395
|
+
* @param {number[]} [options.rotate] - [pitch, yaw, roll]
|
|
1396
|
+
* @param {number[]} [options.size] - [sx, sy, sz]
|
|
1397
|
+
*/
|
|
1398
|
+
updateElementPosition = ({ name, position, rotate, size }) => {
|
|
1399
|
+
const el = this._gltfElements[name]
|
|
1400
|
+
if (!el) { console.warn(`[GaeaApp] 模型 "${name}" 未找到`); return }
|
|
1401
|
+
if (position) {
|
|
1402
|
+
el.GeographyPosition = new Gaea.Vector3(position.x, position.y, position.z)
|
|
1403
|
+
}
|
|
1404
|
+
if (rotate && rotate.length > 0) {
|
|
1405
|
+
el.TiltHeadingBank = new Gaea.Vector3(rotate[0], rotate[1], rotate[2])
|
|
1281
1406
|
}
|
|
1407
|
+
if (size && size.length > 0) {
|
|
1408
|
+
el.Root.Scale = new Gaea.Vector3(size[0], size[1], size[2])
|
|
1409
|
+
}
|
|
1410
|
+
};
|
|
1282
1411
|
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1412
|
+
/**
|
|
1413
|
+
* 添加鼠标移动监听(参考 ht_3dview addMouseMove,使用 Gaea 引擎事件)
|
|
1414
|
+
* 回调返回当前鼠标所在位置的经纬度坐标
|
|
1415
|
+
* @param {function} cb - (pos: {x,y,z}) => void
|
|
1416
|
+
* @returns {function} 调用可取消监听
|
|
1417
|
+
*/
|
|
1418
|
+
addMouseMove = (cb = null) => {
|
|
1419
|
+
const handle = Gaea.World.Instance.OnMouseMove((p, b) => {
|
|
1420
|
+
const screenpos = new Gaea.Vector2(p.x, p.y)
|
|
1421
|
+
const spacepos = Gaea.GaeaMath.ProjectPosition(screenpos)
|
|
1422
|
+
const latlonalt = Gaea.GaeaMath.CartesianToSphericalDeg(spacepos)
|
|
1423
|
+
const pos = { x: latlonalt.x, y: latlonalt.y, z: latlonalt.z }
|
|
1424
|
+
if (typeof cb === 'function') cb(pos)
|
|
1425
|
+
})
|
|
1426
|
+
this._mouseMoveHandle = handle
|
|
1427
|
+
return () => {
|
|
1428
|
+
if (handle) Gaea.World.Instance.ClearEvent(handle)
|
|
1429
|
+
this._mouseMoveHandle = null
|
|
1430
|
+
}
|
|
1286
1431
|
};
|
|
1287
1432
|
|
|
1288
1433
|
/**
|
|
1289
|
-
*
|
|
1290
|
-
* @param {string} [tilesetName] - 目标 tileset 名称(不传则清除压平多边形并重置工具)
|
|
1434
|
+
* 移除鼠标移动监听
|
|
1291
1435
|
*/
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
this._flattenPolygon = null
|
|
1436
|
+
removeMouseMove = () => {
|
|
1437
|
+
if (this._mouseMoveHandle) {
|
|
1438
|
+
Gaea.World.Instance.ClearEvent(this._mouseMoveHandle)
|
|
1439
|
+
this._mouseMoveHandle = null
|
|
1297
1440
|
}
|
|
1441
|
+
};
|
|
1298
1442
|
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1443
|
+
/**
|
|
1444
|
+
* 添加鼠标抬起监听(参考 ht_3dview,使用 Gaea 引擎 OnMouseUp 事件)
|
|
1445
|
+
* 回调返回点击位置的经纬度坐标
|
|
1446
|
+
* @param {function} cb - (pos: {x,y,z}) => void
|
|
1447
|
+
* @returns {function} 调用可取消监听
|
|
1448
|
+
*/
|
|
1449
|
+
addMouseUp = (cb = null) => {
|
|
1450
|
+
const handle = Gaea.World.Instance.OnMouseUp((p, b) => {
|
|
1451
|
+
if (b !== 1) return // 仅左键
|
|
1452
|
+
const screenpos = new Gaea.Vector2(p.x, p.y)
|
|
1453
|
+
const spacepos = Gaea.GaeaMath.ProjectPosition(screenpos)
|
|
1454
|
+
const latlonalt = Gaea.GaeaMath.CartesianToSphericalDeg(spacepos)
|
|
1455
|
+
const pos = { x: latlonalt.x, y: latlonalt.y, z: latlonalt.z }
|
|
1456
|
+
if (typeof cb === 'function') cb(pos)
|
|
1457
|
+
})
|
|
1458
|
+
this._mouseUpHandle = handle
|
|
1459
|
+
return () => {
|
|
1460
|
+
if (handle) Gaea.World.Instance.ClearEvent(handle)
|
|
1461
|
+
this._mouseUpHandle = null
|
|
1462
|
+
}
|
|
1463
|
+
};
|
|
1303
1464
|
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1465
|
+
/**
|
|
1466
|
+
* 移除鼠标抬起监听
|
|
1467
|
+
*/
|
|
1468
|
+
removeMouseUp = () => {
|
|
1469
|
+
if (this._mouseUpHandle) {
|
|
1470
|
+
Gaea.World.Instance.ClearEvent(this._mouseUpHandle)
|
|
1471
|
+
this._mouseUpHandle = null
|
|
1307
1472
|
}
|
|
1473
|
+
};
|
|
1308
1474
|
|
|
1309
|
-
|
|
1475
|
+
/**
|
|
1476
|
+
* 交互式拾取坐标(点击地图获取经纬度,参考 ht_3dview 选择坐标流程)
|
|
1477
|
+
* 点击地图后回调返回坐标,自动取消监听
|
|
1478
|
+
* @param {function} cb - (pos: {x,y,z}) => void
|
|
1479
|
+
* @returns {function} 调用可取消拾取
|
|
1480
|
+
*/
|
|
1481
|
+
pickPosition = (cb) => {
|
|
1482
|
+
const cancel = this.addMouseUp((pos) => {
|
|
1483
|
+
cancel()
|
|
1484
|
+
if (typeof cb === 'function') cb(pos)
|
|
1485
|
+
})
|
|
1486
|
+
return cancel
|
|
1487
|
+
};
|
|
1488
|
+
|
|
1489
|
+
/**
|
|
1490
|
+
* 交互式拾取模型,返回模型信息
|
|
1491
|
+
* @param {function} callback - (modelInfo) => void
|
|
1492
|
+
* @returns {function} 调用可取消拾取
|
|
1493
|
+
*/
|
|
1494
|
+
pickModel = (callback) => {
|
|
1495
|
+
const canvas = document.getElementById('canvas')
|
|
1496
|
+
if (!canvas) return () => {}
|
|
1497
|
+
|
|
1498
|
+
const onClick = (event) => {
|
|
1499
|
+
const hit = Gaea.World.Instance.Pick(new Gaea.Vector2(event.offsetX, event.offsetY))
|
|
1500
|
+
if (hit && hit.Element && hit.Element.Root) {
|
|
1501
|
+
const modelName = hit.Element.Root.Name
|
|
1502
|
+
const info = this.getModelInfo(modelName)
|
|
1503
|
+
if (info) {
|
|
1504
|
+
info.name = modelName
|
|
1505
|
+
callback(info)
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
canvas.addEventListener('click', onClick)
|
|
1511
|
+
return () => canvas.removeEventListener('click', onClick)
|
|
1512
|
+
};
|
|
1513
|
+
|
|
1514
|
+
/**
|
|
1515
|
+
* 获取所有可选模型列表(用于面板下拉选择,参考 ht_3dview gaeaData.gltfList)
|
|
1516
|
+
* @returns {Array<{name: string, url: string, position?: object}>}
|
|
1517
|
+
*/
|
|
1518
|
+
getGltfList = () => {
|
|
1519
|
+
return Object.values(this._gltfCfgMap).map(cfg => ({
|
|
1520
|
+
name: cfg.name,
|
|
1521
|
+
url: cfg.url,
|
|
1522
|
+
}));
|
|
1523
|
+
};
|
|
1524
|
+
|
|
1525
|
+
/**
|
|
1526
|
+
* 加载用户自定义模型(参考 ht_3dview addGltf)
|
|
1527
|
+
* 新增模型到场景并记录到配置表
|
|
1528
|
+
* @param {object} cfg
|
|
1529
|
+
* @param {string} cfg.name - 模型实例名(不能重复)
|
|
1530
|
+
* @param {string} cfg.url - 模型 URL
|
|
1531
|
+
* @param {object} cfg.position - { x: 纬度, y: 经度, z: 高程 }
|
|
1532
|
+
* @param {number[]} cfg.rotate - [pitch, yaw, roll]
|
|
1533
|
+
* @param {number[]} cfg.size - [sx, sy, sz]
|
|
1534
|
+
* @param {boolean} [cfg.show=true]
|
|
1535
|
+
* @param {boolean} [cfg.enablePick=true]
|
|
1536
|
+
* @returns {Promise<object>} gltf element
|
|
1537
|
+
*/
|
|
1538
|
+
addGltf = async (cfg) => {
|
|
1539
|
+
const { name, url, position, rotate, size, show = true, enablePick = true } = cfg;
|
|
1540
|
+
if (!name || !url || !position || !rotate || !size) {
|
|
1541
|
+
console.warn('[GaeaApp] addGltf: 缺少必要参数', cfg);
|
|
1542
|
+
return null;
|
|
1543
|
+
}
|
|
1544
|
+
// 记录到配置表,供后续面板编辑
|
|
1545
|
+
this._gltfCfgMap[name] = {
|
|
1546
|
+
name, url, position: { ...position }, rotate: [...rotate], size: [...size],
|
|
1547
|
+
show, enablePick, isUserAdd: true
|
|
1548
|
+
};
|
|
1549
|
+
const element = await this.AddGltf({
|
|
1550
|
+
name, url, position, rotate, size, show, enablePick, useAbsoluteHeight: true,
|
|
1551
|
+
});
|
|
1552
|
+
if (element) this._gltfElements[name] = element;
|
|
1553
|
+
return element;
|
|
1310
1554
|
};
|
|
1311
1555
|
|
|
1312
1556
|
/**
|
|
@@ -2195,8 +2439,9 @@ export class GaeaApp {
|
|
|
2195
2439
|
Gaea.World.Instance.SetMtlFloat(material, 'flow_speed', flowSpeed)
|
|
2196
2440
|
Gaea.World.Instance.SetMtlColor(material, 'color_shallow', new Gaea.Color(0 / 255, 157 / 255, 187 / 255, 1))
|
|
2197
2441
|
Gaea.World.Instance.SetMtlColor(material, 'color_deep', new Gaea.Color(colorDeep[0] / 255, colorDeep[1] / 255, colorDeep[2] / 255, 1))
|
|
2198
|
-
Gaea.World.Instance.SetMtlFloat(material, 'transparency_clarity',
|
|
2199
|
-
Gaea.World.Instance.SetMtlFloat(material,
|
|
2442
|
+
Gaea.World.Instance.SetMtlFloat(material, 'transparency_clarity', 0)
|
|
2443
|
+
Gaea.World.Instance.SetMtlFloat(material, "transparency_refraction", 0); // 折射度
|
|
2444
|
+
Gaea.World.Instance.SetMtlFloat(material, "foam_amount", 0.8); // 气泡大小
|
|
2200
2445
|
})
|
|
2201
2446
|
|
|
2202
2447
|
Gaea.World.Instance.RenderableObjectList.AddLast(element)
|