唯杰地图 logo唯杰地图
VJMAP
EN

资源加载

vjmap3d/references/graphics/resource.md 11.5 KB305 行
原文

引擎通常需要加载不同的资源文件,为了统一管理所有文件的加载和读取,我们在 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)