资源加载
引擎通常需要加载不同的资源文件,为了统一管理所有文件的加载和读取,我们在 vjmap3d 里封装了统一的资源管理器,可以方便用户加载,存储和读取各种文件资源。
LoaderManager
LoaderManager 用于加载不同的资源。
默认情况下,LoaderManager通过资源文件路径类型后缀来根据不同的加载器来加载资源。
LoadManager 是LoaderManager的单例对象`。
默认加载器
| 文本后缀 | 加载器 | 变量 |
|---|---|---|
| webp | ImageLoader | imageLoader |
| jpg | ImageLoader | imageLoader |
| png | ImageLoader | imageLoader |
| jpeg | ImageLoader | imageLoader |
| obj | OBJLoader | objLoader |
| mtl | MTLLoader | mtlLoader |
| mp4 | VideoLoader | videoLoader |
| webm | VideoLoader | videoLoader |
| ogg | VideoLoader | videoLoader |
| hdr | HDRLoader | hdrLoader |
| gltf | GLTFLoader | gltfLoader |
| glb | GLTFLoader | gltfLoader |
| fbx | FBXLoader | fbxLoader |
| dds | DDSLoader | ddsLoader |
| svg | SVGLoader | svgLoader |
| particle | ParticleLoader | particleLoader |
| img | ImageLoader | imageLoader |
| json | FileLoader | fileLoader(返回原始文本,不会自动 JSON.parse) |
| ktx2 | KTX2Loader | ktx2Loader |
提示
如需加载其他类型的资源,请使用插件进行加载
常用方法
| 方法 | 描述 |
|---|---|
| setPath | 设置统一资源路径前缀 |
| setRequestHeader | 设置请求头 |
| setResponseType | 设置响应类型 |
| getLoader | 获取加载器 |
| load | 加载资源 |
| register | 注册loader |
| hasLoaded | 资源是否已经加载 |
| getResource | 获取url的资源 |
| getResourceStatus | 获取url的资源状态 |
| getLoadDetailMap | 获取详细资源信息 |
| setLoaderPath | 设置加载路径 |
| dispose | 清空缓存 |
| loadExtensionLoader | 加载扩展的loader库 |
| loadExtensionIfcLoader | 加载扩展的IfcLoader库 |
坑位:
register注册的自定义 loader 必须实现setPath(path)方法——getLoader()命中后缀后内部会调loader.setPath(this.path),缺失该方法时getLoader直接抛xxx.setPath is not a function(而不是返回 null)。未知后缀才会返回null/undefined。
信号事件
| 事件 | 描述 |
|---|---|
| beforeLoad | 开始加载前 |
| loading | 加载中 |
| detailLoading | 每项加载前 |
| detailLoaded | 每项加载完成 |
| loaded | 加载完成 |
通过指定加载类型进行加载
let gltf = vjmap3d.LoadManager.gltfLoader;
//let gltf = vjmap3d.LoadManager.getLoader("gltf"); // 或者也可以这么写
gltf.load(env.assetsPath + "models/soldier.glb", ( gltf ) => {
const root = gltf.scene;
app.scene.add( root );
})
直接传资源路径,自动加载
vjmap3d.LoadManager.load(env.assetsPath + "models/soldier.glb", false,
(resource) => {
// onLoad
console.log("onLoad", resource)
app.scene.add(resource.scene)
},
(event) => {
// onProgress
console.log("onProgress", event)
},
(event) => {
// onError
console.error(event)
},
"glb" // fileType:
)
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
scene: { // 场景设置
gridHelper: { visible: true } // 是否显示坐标网格
}
})
let gltf = vjmap3d.LoadManager.gltfLoader;
//let gltf = vjmap3d.LoadManager.getLoader("gltf"); // 或者也可以这么写
gltf.load(env.assetsPath + "models/soldier.glb", ( gltf ) => {
const root = gltf.scene;
app.scene.add( root );
})
ResourceManager
ResourceManager 用于资源加载管理,内部通过 loaderManager 加载资源。
提示
因为 ResourceManager 中包含了对 loaderManager的操作,所以一般直接通过 ResourceManager来加载资源。
ResManager 是ResourceManager的单例对象`。
常用方法
| 方法 | 描述 |
|---|---|
| setServiceUrlPath | 设置服务器资源数据 |
| svrUrl | 根据名称获取服务器端资源路径 |
| loadRes | 获取资源 |
| loadTexture | 获取材质(默认srgb空间) |
| loadTextureSync | 获取材质(默认srgb空间)返回一个promise |
| loadTextureLinear | 获取材质(线性空间) |
| loadTextureLinearSync | 获取材质(线性空间)返回一个promise |
| loadModelRes | 加载模型资源文件 |
| addModel | 增加模型资源对象 |
| loadModel | 加载模型url文件 |
| loadResources | 加载资源数组 |
| clearResourceCache | 清除资源缓存 |
| loadExtensionLoader | 加载扩展的loader库 |
| loadExtensionIfcLoader | 加载扩展的IfcLoader库 |
| getLoader | 获取加载器 |
加载模型
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
})
let ent = await vjmap3d.ResManager.loadModel(env.assetsPath + "models/soldier.glb", {
splitSubEntity: true,
anchor: "front-bottom-right"
});
ent.addTo(app);
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
})
let ent = await vjmap3d.ResManager.loadModel(env.assetsPath + "models/soldier.glb", {
splitSubEntity: true,
anchor: "front-bottom-right"
});
ent.addTo(app);
加载材质
// 同步返回 Texture 对象(图像内容异步填充),无需 await
let texture = vjmap3d.ResManager.loadTexture(env.assetsPath + "image/sensor1.png")
// 返回 Promise<Texture>,await 得到加载完成的纹理
let texture2 = await vjmap3d.ResManager.loadTextureSync(env.assetsPath + "image/sensor1.png")
对于有复杂步骤的加载,如obj需要先加载mtl文件做为材质,可这样实现:
// 如果是obj,需要先加载mtl文件
let materials = await vjmap3d.ResManager.loadRes(env.assetsPath + "models/table/table.mtl", true);
materials.preload();
let loader = vjmap3d.LoadManager.getLoader("obj");
// 设置材质
loader.setMaterials(materials);
let ent = await vjmap3d.ResManager.loadModel(env.assetsPath + "models/table/table.obj", {
size: 5,
splitSubEntity: true,
useCache: true
});
ent.addTo(app);
// 取消设置材质
vjmap3d.LoadManager.getLoader("obj")?.setMaterials(null);
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
scene: { // 场景设置
gridHelper: { visible: true } // 是否显示坐标网格
}
})
// 如果是obj,需要先加载mtl文件
let materials = await vjmap3d.ResManager.loadRes(env.assetsPath + "models/table/table.mtl", true);
materials.preload();
let loader = vjmap3d.LoadManager.getLoader("obj");
// 设置材质
loader.setMaterials(materials);
let ent = await vjmap3d.ResManager.loadModel(env.assetsPath + "models/table/table.obj", {
size: 5,
splitSubEntity: true,
useCache: true
});
ent.addTo(app);
// 取消设置材质
vjmap3d.LoadManager.getLoader("obj")?.setMaterials(null);
应用初始资源加载
对于一个应用,如果在应用初始的时候需要加载,并且有进度条显示,可使用 loadResources 加载资源数组
const resources = [
{
name: "sm_car",
url: "mesh/sm_car.gltf",
type: "model"
},
{
name: "ut_car_body_ao",
url: "texture/t_car_body_AO.raw.jpg",
type: "texture"
},
{
name: "skybox",
type: "hdr",
url: "./skybox_512px.hdr",
},
{
name: "algorithm",
type: "plugin",
url: "algorithm",
}
];
let allResources = await app.loadResources(resources, {
showShadertoy: false,
showHtml: true
});
// 根据名称获取资源
let car = allResources.getResource("sm_car");
car.addTo(app);
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
container: "map", // 容器id
scene: { // 场景设置
gridHelper: { visible: true } // 是否显示坐标网格
}
})
const resources = [
{
name: "car",
url: env.assetsPath + "models/car.glb",
type: "model"
},
{
name: "soldier",
url: env.assetsPath + "models/soldier.glb",
type: "model"
},
{
name: "skybox",
type: "hdr",
url: env.assetsPath + "skybox/skybox_512px.hdr",
},
];
let allResources = await app.loadResources(resources, {
showShadertoy: false,
showHtml: true
});
// 设置背景和环境
app.setBackgroundEnvironment({
background: {
texture: allResources.getResource("skybox")
},
environmentSameAsBackground: false
});
// 根据名称获取资源
let soldier = allResources.getResource("soldier");
soldier.addTo(app);
let car = allResources.getResource("car");
car.position.set(2, 0, 2)
car.addTo(app)