唯杰地图 logo唯杰地图
VJMAP
EN

实例化Mesh实体

vjmap3d/references/entity/instancedMeshEntity.md 9.6 KB209 行
原文

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();
})