实例化Mesh实体
InstancedMeshEntity 是由 实体Entity 和 InstancedMeshModule 模块组合而成的新的实体。
InstancedMeshEntity = Entity + InstancedMeshModule
常用方法
InstancedMeshEntity 是由 实体Entity 派生而来。具体 Entity 的所有属性和方法。同时也具有InstancedMeshModule 的相关方法。
| 方法 | 描述 |
|---|---|
| addInstance | 增加实例化对象,如存在则修改。⚠️ 只有显式传 id: "" 才自动生成 id(省略 id 会以字符串 "undefined" 作 id,第二次省略就变成"修改"上一个);容量上限是构造时的 maxCapacity(取它与初始 instances.length 的较大者),满了直接抛 InstancedMesh maxCapacity is N;color 必须是 THREE.Color(传字符串/数字会抛错) |
| setInstance | 根据id设置实例化对象属性,如不存在则走 addInstance 新增(同上:仅 id: "" 自动生成、超容量抛错、color 须为 THREE.Color,传 color: null 还原原色) |
| removeInstance | 根据一个id删除实例化对象 |
| getInstancedMeshList | 获取实体化mesh列表 |
| getGroup | 获取实体化的组对象 |
| getIdByIndex | 通过索引获取id |
| getIndexById | 通过id获取索引 |
| setInstanceHighlight | 设置实例高亮与否 |
| isInstanceHighlight | 实例是否高亮 |
| clearInstanceHighlight | 清除所有实例高亮 |
| setInstanceSelected | 设置实例选择与否 |
| isInstanceSelected | 实例是否选中 |
| clearInstanceSelected | 清除所有实例选中 |
| setInstanceBloom | 设置实例辉光与否 |
| isInstanceBloom | 实例是否辉光 |
| clearInstanceBloom | 清除所有实例辉光 |
| setInstanceOutline | 设置实例描边与否 |
| isInstanceOutline | 实例是否描边 |
| clearInstanceOutline | 清除所有实例描边 |
| setInstanceAttr | 设置实例属性 |
| getInstanceAttr | 获取实例属性 |
| getInstanceBox3 | 获取实例的外包盒 |
用法
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
scene: {
gridHelper: { visible: true } // 是否显示坐标网格
},
stat: {
show: true,
left: "0"
},
camera: { // 相机设置
viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
}
})
// 生成资源加载生成一个mesh
let mesh = await vjmap3d.ResManager.loadModel(env.assetsPath + "models/car.glb", {
toEntity: false
});
// 根据这个mesh生成多个实例对象。这里模拟生成10000个
let instances = [];
for(let i = 0; i < 100; i++) {
for(let j = 0; j < 100; j++) {
instances.push({
id: "inst" + (j * 100 + i), // 实例id,后续高亮/选中/属性接口都按id操作
position: new THREE.Vector3(i - 50, 0, j - 50),
rotation: new THREE.Vector3(0, Math.random() * Math.PI, 0),
scale: Math.random() * 0.5 + 0.5,
color: vjmap3d.randColor(),
card: j * 100 + i
})
}
}
// 创建mesh实例化对象
let instanceMesh = new vjmap3d.InstancedMeshEntity({
mesh: mesh,
maxCapacity: 100 * 100,
instances
})
instanceMesh.addTo(app)
//
// 设置实体能响应鼠标事件
instanceMesh.pointerEvents = true;
let instId; // 当前鼠标在的实例id(setInstanceHighlight/Selected 等接口均按id操作)
let popup;
const cancelSelect = () => {
// 取消之前的选择
if (instId !== undefined) {
// 取消之前的高亮(不传颜色即恢复原色)
instanceMesh.setInstanceHighlight(instId)
//instanceMesh.setInstanceSelected(instId, false) // 用选择的话,用这个,不用上面的
}
if (popup) {
popup.remove();
popup = null;
}
}
instanceMesh.on("mouseover", e => {
cancelSelect();
if (e.intersection.object.isInstancedMesh) {
// 通过射线拾取的数组索引获取实例id
instId = instanceMesh.getIdByIndex(e.intersection.instanceId);
// 设置高亮
instanceMesh.setInstanceHighlight(instId, "#777");
//instanceMesh.setInstanceSelected(instId, true); // 用选择的话,用这个,不用上面的
let box3d = instanceMesh.getInstanceBox3(instId);
if (!popup) {
popup = new vjmap3d.Popup2D({
backgroundColor: "#A0FFA0",
closeButton: false
})
popup.addTo(app);
}
let position = vjmap3d.getObjectAnchorPoint(box3d, 'middle-top');
popup.setPosition(position); // 设置位置
popup.setHTML(`第 ${instances[e.intersection.instanceId].card} 辆`);
}
})
instanceMesh.on("mouseout", e => {
cancelSelect();
})
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
scene: {
gridHelper: { visible: true } // 是否显示坐标网格
},
stat: {
show: true,
left: "0"
},
camera: { // 相机设置
viewHelper: { enable: true, position: "leftBottom" } // 是否显示视角指示器
}
})
// 生成资源加载生成一个mesh
let mesh = await vjmap3d.ResManager.loadModel(env.assetsPath + "models/car.glb", {
toEntity: false
});
// 根据这个mesh生成多个实例对象。这里模拟生成10000个
let instances = [];
for(let i = 0; i < 100; i++) {
for(let j = 0; j < 100; j++) {
instances.push({
id: "inst" + (j * 100 + i), // 实例id,后续高亮/选中/属性接口都按id操作
position: new THREE.Vector3(i - 50, 0, j - 50),
rotation: new THREE.Vector3(0, Math.random() * Math.PI, 0),
scale: Math.random() * 0.5 + 0.5,
color: vjmap3d.randColor(),
card: j * 100 + i
})
}
}
// 创建mesh实例化对象
let instanceMesh = new vjmap3d.InstancedMeshEntity({
mesh: mesh,
maxCapacity: 100 * 100,
instances
})
instanceMesh.addTo(app)
//
// 设置实体能响应鼠标事件
instanceMesh.pointerEvents = true;
let instId; // 当前鼠标在的实例id(setInstanceHighlight/Selected 等接口均按id操作)
let popup;
const cancelSelect = () => {
// 取消之前的选择
if (instId !== undefined) {
// 取消之前的高亮(不传颜色即恢复原色)
instanceMesh.setInstanceHighlight(instId)
//instanceMesh.setInstanceSelected(instId, false) // 用选择的话,用这个,不用上面的
}
if (popup) {
popup.remove();
popup = null;
}
}
instanceMesh.on("mouseover", e => {
cancelSelect();
if (e.intersection.object.isInstancedMesh) {
// 通过射线拾取的数组索引获取实例id
instId = instanceMesh.getIdByIndex(e.intersection.instanceId);
// 设置高亮
instanceMesh.setInstanceHighlight(instId, "#777");
//instanceMesh.setInstanceSelected(instId, true); // 用选择的话,用这个,不用上面的
let box3d = instanceMesh.getInstanceBox3(instId);
if (!popup) {
popup = new vjmap3d.Popup2D({
backgroundColor: "#A0FFA0",
closeButton: false
})
popup.addTo(app);
}
let position = vjmap3d.getObjectAnchorPoint(box3d, 'middle-top');
popup.setPosition(position); // 设置位置
popup.setHTML(`第 ${instances[e.intersection.instanceId].card} 辆`);
}
})
instanceMesh.on("mouseout", e => {
cancelSelect();
})