draco是谷歌发布的三维模型压缩库,可以用于压缩三维模型的顶点等数据,减小模型大小,使用c++版本的draco压缩后的模型在cesium1.89上可以正常加载显示,但是cesium1.92版本时,无法正常加载,会报Cannot read property '__destroy__' of undefined的错,下面是cesium报错信息:

后来通过调试分析draco源码,发现我在使用draco压缩时只是对顶点纹理和面进行了操作,没有对材质进行绑定,所以cesium1.92以上版本无法加载,但是低版本的cesium是可以正常加载的,主要原因就是将其他数据格式组织成draco的mesh格式时存在问题,具体的mesh加载方式可以参考源码中ObjDecoder::DecodeInternal()方法。

在进行压缩时,需要设置材质相关属性:

//设置材质相关,此项为必要操作,否则cesium1.92以上版本无法加载该b3dm
{draco::GeometryAttribute va;const auto geometry_attribute_type=draco::GeometryAttribute::GENERIC;va.Init(geometry_attribute_type,nullptr,1,draco::DT_UINT8,false,1,0);material_att_id=pointCloud->AddAttribute(va,false,1);int index=0;pointCloud->attribute(material_att_id)->SetAttributeValue(draco::AttributeValueIndex(0),&index);
}

我的数据中只有一个纹理,所以index设置为0,如果有多个纹理材质,则需要遍历设置材质属性值:

{for(int i=0;i<count;++i)pointCloud->attribute(material_att_id)->SetAttributeValue(draco::AttrubuteValueIndex(i),&i);
}

在设置三角面时,需要将面的每一个顶点都绑定一个材质id:

{for(int j=0;j<tri_indices.size();++j){//三角面的第一个点const draco::PointIndex vert_id1(3*j+0);pointCloud->attribute(material_att_id)->SetPointMapEntry(vert_id1,draco::AttributeValueIndex(0));//三角面的第二个点const draco::PointIndex vert_id2(3*j+1);pointCloud->attribute(material_att_id)->SetPointMapEntry(vert_id2,draco::AttributeValueIndex(0));//三角面的第三个点const draco::PointIndex vert_id3(3*j+2);pointCloud->attribute(material_att_id)->SetPointMapEntry(vert_id3,draco::AttributeValueIndex(0));}
}

因为我的数据中只有一个纹理,所以每个面的每一个点对应的材质属性值都是0,即draco::AttributeValueIndex(0),如果有多个材质,需要注意设置成对应的材质属性值。

下面附上部分代码:

{std::vector<osg::Vec3> tri_positions;//osg读取的顶点,自己实现std::vector<osg::Vec2> tri_texcoords0;//osg读取的纹理坐标,自己实现std::vector<osg::Vec3> tri_indices;//osg读取的三角面,自己实现//使用draco进行模型压缩代码int vertexCount = tri_positions.size(); // 顶点数量std::unique_ptr<draco::Mesh> dracoMesh(new draco::Mesh());draco::PointCloud* pointCloud = static_cast<draco::PointCloud*>(dracoMesh.get());dracoMesh->set_num_points(tri_indices.size() * 3);//设置要压缩的点个数dracoMesh->SetNumFaces(tri_indices.size());//设置要压缩的面个数int pos_att_id = 0;int tex_att_id = 0;int material_att_id = 0;//设置材质,此项为必须操作,否则cesium1.92以上版本无法加载该b3dm{draco::GeometryAttribute va;const auto geometry_attribute_type = draco::GeometryAttribute::GENERIC;va.Init(geometry_attribute_type, nullptr, 1, draco::DT_UINT8, false, 1, 0);material_att_id = pointCloud->AddAttribute(va, false, 1);int vvv = 0;pointCloud->attribute(material_att_id)->SetAttributeValue(draco::AttributeValueIndex(0), &vvv);}//设置顶点相关{draco::GeometryAttribute va;va.Init(draco::GeometryAttribute::POSITION, nullptr, 3, draco::DT_FLOAT32, false, sizeof(float) * 3, 0);pos_att_id = pointCloud->AddAttribute(va, false, vertexCount);//添加到dracoPointCloud中draco::PointAttribute* att_ptr = pointCloud->attribute(pos_att_id);//获取添加的对象//将顶点数据添加到压缩属性att中for (int j = 0; j < tri_positions.size(); j++) {att_ptr->SetAttributeValue(draco::AttributeValueIndex(j), &tri_positions[j][0]);//顶点数据添加到压缩属性att中}}//设置纹理坐标相关{draco::GeometryAttribute va;va.Init(draco::GeometryAttribute::TEX_COORD, nullptr, 2, draco::DT_FLOAT32, false, sizeof(float)*2, 0);tex_att_id = pointCloud->AddAttribute(va, false, vertexCount);//添加到dracoPointCloud中draco::PointAttribute* att_ptr = dracoMesh->attribute(tex_att_id);//获取添加的对象//将纹理数据添加到压缩属性att中for (int j = 0; j < tri_texcoords0.size(); j++) {att_ptr->SetAttributeValue(draco::AttributeValueIndex(j), &tri_texcoords0[j][0]);//纹理数据添加到压缩属性att中}}//遍历面,每一个三角面的三个点设置对应的材质、顶点和纹理坐标for (int j = 0; j < tri_indices.size(); ++j) {//三角面的第一个顶点const draco::PointIndex vert_id1(3 * j + 0);//设置对应的材质,此项为必须操作,否则cesium1.92以上版本无法加载该b3dmpointCloud->attribute(material_att_id)->SetPointMapEntry(vert_id1, draco::AttributeValueIndex(0));pointCloud->attribute(pos_att_id)->SetPointMapEntry(vert_id1, draco::AttributeValueIndex(tri_indices[j].x()));pointCloud->attribute(tex_att_id)->SetPointMapEntry(vert_id1, draco::AttributeValueIndex(tri_indices[j].x()));//三角面的第二个顶点const draco::PointIndex vert_id2(3 * j + 1);//设置对应材质,此项为必须操作,否则cesium1.92以上版本无法加载该b3dmpointCloud->attribute(material_att_id)->SetPointMapEntry(vert_id2, draco::AttributeValueIndex(0));pointCloud->attribute(pos_att_id)->SetPointMapEntry(vert_id2, draco::AttributeValueIndex(tri_indices[j].y()));pointCloud->attribute(tex_att_id)->SetPointMapEntry(vert_id2, draco::AttributeValueIndex(tri_indices[j].y()));//三角面的第三个顶点const draco::PointIndex vert_id3(3 * j + 2);//设置对应材质,此项为必须操作,否则cesium1.92以上版本无法加载该b3dmpointCloud->attribute(material_att_id)->SetPointMapEntry(vert_id3, draco::AttributeValueIndex(0));pointCloud->attribute(pos_att_id)->SetPointMapEntry(vert_id3, draco::AttributeValueIndex(tri_indices[j].z()));pointCloud->attribute(tex_att_id)->SetPointMapEntry(vert_id3, draco::AttributeValueIndex(tri_indices[j].z()));draco::Mesh::Face face;for (int c = 0; c < 3; ++c) {face[c] = 3 * j + c;}dracoMesh->SetFace(draco::FaceIndex(j), face);}//去除重复数据pointCloud->DeduplicateAttributeValues();pointCloud->DeduplicatePointIds();//设置压缩参数const int dracoCompressionSpeed = 5;const int dracoPositionBits = 14;draco::EncoderBuffer dracoBuffer;//压缩后的数据存储到draco的缓存区中draco::Encoder encoder;//压缩对象//设置压缩参数encoder.SetSpeedOptions(dracoCompressionSpeed, dracoCompressionSpeed);encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION,dracoPositionBits);//设置压缩方法encoder.SetEncodingMethod(draco::MeshEncoderMethod::MESH_EDGEBREAKER_ENCODING);
}

关于cesium1.92以上版本无法加载draco压缩模型问题相关推荐

  1. 【Android 安全】DEX 加密 ( 不同 Android 版本的 DEX 加载 | Android 8.0 版本 DEX 加载分析 | Android 5.0 版本 DEX 加载分析 )

    文章目录 一.不同版本的 DEX 加载 1.Android 8.0 版本 DEX 加载分析 2.Android 6.0 版本 DEX 加载分析 3.Android 5.0 版本 DEX 加载分析 一. ...

  2. pytorch 1.7.x训练保存的模型在1.4低版本无法加载

    pytorch1.6.x及更高版本,在保存模型和低版本有区别,因此导致高版本的保存模型在低版本下加载失败的问题: 我们只需在较高版本torch下保存时,设置_use_new_zipfile_seria ...

  3. pytorch 1.7训练保存的模型在1.4低版本无法加载:frame #63: <unknown function> + 0x1db3e0 (0x55ba98ddd3e0 in /data/user

    pytorch 1.7高版本训练保存的模型在1.4低版本无法加载,报错: torch.load('/home/user1/model_best_b.pth.tar') Traceback (most ...

  4. JVM(Java SE 11版本)加载类和接口

    本文介绍了Java虚拟机(Java SE 11版本)加载类和接口. 加载类和接口 加载是指查找具有特定名称的类或接口类型的二进制形式的过程.典型的做法是,查找事先由Java编译器从源代码计算而来二进制 ...

  5. 超图桌面版加载obj 3D模型 - 2

    在 https://blog.csdn.net/bcbobo21cn/article/details/109041525 里,加载obj格式模型没有出来效果: 下面来看一下其他方法:当前用的版本是10 ...

  6. 用《捕鱼达人3》讲解Cocos引擎3D技术(一):加载鱼的模型和播放动画

    大家好,相信许多朋友们都听过或玩过<捕鱼达人>这款游戏.今年7月中旬,<捕鱼达人3>正式发布,24小时就突破实现1千万下载,欢迎大家一起来下载试玩! 本次<捕鱼达人3&g ...

  7. 人脸检测实战:使用opencv加载深度学习模型实现人脸检测

    使用 OpenCV 和深度学习进行人脸检测 今天的博文分为三个部分. 在第一部分中,我们将讨论更准确的 OpenCV 人脸检测器的起源以及它们在 OpenCV 库中的位置. 然后我将演示如何使用 Op ...

  8. TensorFlow 加载多个模型的方法 - 知乎 https://zhuanlan.zhihu.com/p/53642222

    TensorFlow 加载多个模型的方法 - 知乎 什么是Tensorflow模型? 当你训练好一个神经网络后,你会想保存好你的模型便于以后使用并且用于生产.因此,什么是Tensorflow模型?Te ...

  9. 第一节:加载鱼的模型和播放动画

    大家好,相信许多朋友们都听过或玩过<捕鱼达人>这款游戏.今年7月中旬,<捕鱼达人3>正式发布,24小时就突破实现1千万下载,欢迎大家一起来下载试玩! 本次<捕鱼达人3&g ...

  10. 【深度学习】Keras加载权重更新模型训练的教程(MobileNet)

    [深度学习]Keras加载权重更新模型训练的教程(MobileNet) 文章目录 1 重新训练 2 keras常用模块的简单介绍 3 使用预训练模型提取特征(口罩检测) 4 总结 1 重新训练 重新建 ...

最新文章

  1. 如何手工删除AD RMS SCP?
  2. vmware tools安装程序无法继续,Microsoft Runtime DLL安装程序未能完成安装。的解决方法
  3. vim 双剑合璧,天下无敌(笔记)
  4. centos nginx不是命令_Nginx 在CentOS 6/7 上的安装与使用
  5. 安装mysql5.5时常见错误--缺失make
  6. MyEclipse工具的优化使用
  7. SEO人生衔接后用户可随时随地同他的合作伙伴协同工作
  8. 将CSV和SQL数据加载到Pandas中
  9. SQLServer 批量插入数据的两种方法
  10. Java-Runtime
  11. Rocky4.2下安装达梦(DM)6数据库
  12. 《Getting Started with WebRTC》第二章 WebRTC技术介绍
  13. matlab二元一次方程求解_方程的计算机处理913_Matlab
  14. 程序员面试题之解读构造函数
  15. python接口自动化 post请求,body 带headers参数
  16. 【大数据】Azkaban学习笔记
  17. 腾讯滑块验证码识别和加速度模拟(1)
  18. 库克:苹果正在开发“会震爆你”的未来产品
  19. Spring的注解 @Bean用法
  20. 如何下载自己喜欢的网站

热门文章

  1. HTML渐变背景不重复,在身体上设置的CSS3渐变背景不会拉伸,而是重复?
  2. 小米硬盘路由器服务器,小米路由零售版699元 1T硬盘定位家庭服务器
  3. 普加项目管理甘特图使用--安装部署
  4. 二、鼎捷T100总账管理之核算项管理篇
  5. 冬吃萝卜有讲究 名中医解疑惑
  6. 快门光圈感光度口诀_摄影:一张图让你明白什么叫光圈、快门、感光度、景深、ISO。...
  7. 用户注册时图片验证码和短信验证码的逻辑
  8. python中怎么判断字母大小写_python判断大小写字母
  9. 金士顿内存条真假测试软件,金士顿内存条真伪怎么看?金士顿内存条判别真伪的几种方法...
  10. PNG编解码算法详解