ThingJS教你开发物体爆炸图,3D创业团队松一口气啦!

简介: 塌陷不能把模型变小,但是可以减少对内存的占用。

image.png
塌陷不能把模型变小,但是可以减少对内存的占用。ThingJS是做3D轻量化开发的PAAS平台,在模型导入后进行更多事件控制。

今天来讲讲如何基于js语法来开发一个物体模型拆解展开的效果,专业名称叫“物体爆炸图”,标准ThingJS体系模型出于互动模型性能考虑,都要求在模型上传前做塌陷,这种建模细节对于提升3D开发效率很有必要,目的是减少模型对内存的占用。

在3D开发之前,模型本身会重叠很多命令,占用很大一部分内存和CPU,拖慢电脑,所以针对模型进行塌陷后(指的是把很多个物体合并成一个,转换为一个命令可编辑多边形或可编辑网格),就会去除这些多余的命令参数,不再花时间记录和存储,从而加快运行速度。

制作物体模型时,根据爆炸图中各个零件的拆分需要,针对子模型或子节点定义并命名物体子对象,在3DMAX等建模软件里就能创建子对象。这些子对象在ThingJS在线开发中可作为模型子节点来控制,能够像单独模型对象物体一样进行移动、添加事件等操作。

拆分后磨性子节点如果有多材质或点数超过上限,那在ThingJS开发中会继续拆分,并在子节点中被命名成组,组内继续拆分“01”、“02”等对象。例如:3dmax命名, 一个子节点名字为“box”,由于该子节点使用了多种材质,该子节点在在线开发中会被命名成组,组内会被拆分并命名为“box_0”,“box_1”等对象。

注意经塌陷的模型不再有子节点保留,只有上述分项控制模型局部要求,保留已命名的子对象信息,最大程度上提高开发性能,又满足模型拆分的特殊需要。

官方示例请各位看官参考:

// 加载场景代码 
var app = new THING.App({ 
    url: '/api/scene/406e419fae9000a47a4a8899'
});

// 发电机模型节点数据
var nodeObjData = {
    '1': {name: '机座', offset: [0, 0, -1]},
    '2': {name: '保护装置', offset: [0, -1, 0]},
    '3': {name: '电瓶', offset: [0, -1, 0]},
    '4': {name: '排气口', offset: [0, 0, 1]},
    '5_0': {name: '过滤器', offset: [0, 0, 1]},
    '5_1': {name: '过滤网', offset: [0.5, 0, 1]},
    '6': {name: '供给装置', offset: [0, 0, 1]},
    '7': {name: '烟囱', offset: [-1, 0, 0]},
    '8': {name: '发电机'},
    '9': {name: '控制器', offset: [0, 1, 0]}
}
// 发电机模型节点对象
var nodeJsonData = null;
// 发电机对象
var generatorObj = null;
// 发电机展开状态
var expandState = false;
// 发电机展开次数
var expandCount = 0;

// 场景加载完成后执行
app.on('load', function (ev) {
    // 查询发电机对象
    generatorObj = app.query('#generator')[0]
    // 获取发电机模型节点对象
    nodeJsonData = getNode(generatorObj);

    // 创建测试按钮
    new THING.widget.Button('展开', expandObj);
    new THING.widget.Button('还原', unexpandObj);
    new THING.widget.Button('顶牌显示', createAllPanel);
    new THING.widget.Button('顶牌隐藏', hiddenAllPanel);
})

/**
 * 说明:显示所有顶牌
 */
function createAllPanel(){
    for (let key in nodeObjData) {
        nodeJsonData[key].name = nodeObjData[key].name;
        createPanel(nodeJsonData[key]);
    }
}

/**
 * 说明:隐藏所有顶牌
 */
function hiddenAllPanel(){
    for (let key in nodeObjData) {
        hiddenPanel(nodeJsonData[key]);
    }
}

/**
 * 说明:展开物体
 */
function expandObj() {
    // 防止发电机在执行一次展开过程中多次点击
    if (expandState) {
        return;
    }
    expandState = true;
    expandCount++;
    for (let key in nodeObjData) {
        // 各子节点进行偏移
        objOffset(nodeJsonData[key], nodeObjData[key].offset);
    }
}

/**
 * 说明:还原物体
 */
function unexpandObj() {
    // 展开次数为0,代表未展开
    if (expandCount == 0) {
        return;
    }
    for (let key in nodeObjData) {
        if(nodeObjData[key].offset){
            // 计算还原时子节点需要进行的偏移量,数值为 -1 * 展开次数 * nodeObjData中定义的该子节点对应的偏移量
            let offsetValue = [-1 * expandCount * nodeObjData[key].offset[0], -1 * expandCount * nodeObjData[key].offset[1], -1 * expandCount * nodeObjData[key].offset[2]]
            objOffset(nodeJsonData[key], offsetValue);
        }
    }
    expandCount = 0;
}

/**
 * 说明:获取节点对象
 */
function getNode(obj) {
    let nodeJson = {};
    // obj.subNodes 即可获取到一个物体的所有子节点
    for (let i = 0; i < obj.subNodes.length; i++) {
        let subnode = obj.subNodes[i];
        // 获取物体子节点对象中node属性的type值,只有当type值为Mesh时,才能对物体添加事件
        let type = subnode.node.type;
        if(type == 'Mesh'){
            nodeJson[subnode.name] = subnode;
        }
    }
    return nodeJson;
}

/**
 * 说明:物体偏移
 */
function objOffset(obj, value) {
    if (!value) {
        return;
    }
    // 物体移动
    obj.moveTo({
        offsetPosition: value,  // 自身坐标系下的相对位置
        time: 500,  // 移动完成需要的时间
        complete: function () {
            expandState = false;
        }
    });
}

/**
 * 说明:创建面板
 */
function createPanel(obj) {
    // 判断是否已经创建过面板,如果已创建,显示,否则创建面板
    var panel = obj.getAttribute('panel');
    if (panel != null) {
        panel.visible = true;
        return;
    }
    // 创建panel
    panel = new THING.widget.Panel({
        // 设置面板宽度
        width: '100px',
        // 没有角标 none ,没有线的角标 noline ,折线角标 polyline
        cornerType: 'polyline'

    })
    // 绑定物体身上相应的属性数据
    panel.addString(obj, 'name').caption('');
    // 创建UIAnchor面板
    var uiAnchor = app.create({
        // 类型
        type: 'UIAnchor',
        // 设置父物体
        parent: obj,
        // 要绑定的dom元素对象
        element: panel.domElement,
        // 设置 localPosition 为 [0, 0, 0]
        localPosition: [0, 0, 0],
        // 相对于面板左上角的偏移像素值,当前用值是角标的中心点
        pivotPixel: [-16, 109]
    });
    // 更改面板文本样式
    $('.ThingJS_wrap .main .ThingJS_UI .ThingJS_string-value').css('text-align', 'center');
    obj.setAttribute('panel', uiAnchor);
}

/**
 * 说明:隐藏面板
 */
function hiddenPanel(obj) {
    var panel = obj.getAttribute('panel');
    if (panel != null) {
        panel.visible = false;
    }
}

ThingJS让3D开发更加简单,让3D创业团队松一口气啦!

相关文章
|
Java Maven Android开发
在Eclipse里配置Maven插件
Maven是一款比较常用的Java开发拓展包,它相当于一个全自动jar包管理器,会导入用户开发时需要使用的相应jar包。使用Maven开发Java程序,可以极大提升开发者的开发效率。下面我就跟大家介绍一下如何在Eclipse里安装和配置Maven插件。
526 0
|
监控 JavaScript 前端开发
百度统计分析埋点最佳实战篇
百度统计分析埋点最佳实战篇
2464 0
百度统计分析埋点最佳实战篇
|
存储 编译器
[Eigen中文文档] 深入了解 Eigen - 类层次结构
本页面介绍了Eigen类层次结构中 Core 类的设计及其相互关系。一般用户可能不需要关注这些细节,但对于高级用户和Eigen开发人员可能会有用。
551 0
|
9月前
|
人工智能 程序员 C++
【实战经验】C/C++右移高位补0还是1?
本文探讨了C/C++中右移运算时高位补0还是补1的问题。通过示例代码分析,揭示了右移规则:无符号类型高位补0;有符号类型根据正负决定(正数补0,负数补1)。文中列举了可能导致错误的场景,并提供了两种规避措施——使用无符号类型和掩码校正,确保结果符合预期。最后总结指出,右移运算虽常见,但若处理不当易引发隐晦Bug,需谨慎对待。
500 85
|
10月前
|
传感器 人工智能 数据可视化
数智入海,GIS赋能智慧海洋
随着科技发展,各国积极推进海洋数字化建设,建立全球海洋观测网络,获取实时数据并挖掘价值。我国从“十四五”规划到二十大报告强调海洋强国战略,利用地理空间信息技术和物联网整合监测数据,提供智能管理与决策支持,实现海洋环境的可视化三维场景、实时监测、环境保护、灾害预警及专题图件服务,推动海洋经济高质量发展。
|
JSON Unix Linux
如何在windows系统下安装swoole(cgywin环境)
如何在windows系统下安装swoole(cgywin环境)
653 0
如何在windows系统下安装swoole(cgywin环境)
|
数据采集 传感器 大数据
大数据中数据采集 (Data Collection)
【10月更文挑战第17天】
902 2
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的家政服务预约系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的家政服务预约系统的详细设计和实现(源码+lw+部署文档+讲解等)
276 0
|
JavaScript 数据可视化 UED
用Vue搭建一个大屏数据可视化页面实战二(Vue实战系列)
用Vue搭建一个大屏数据可视化页面实战二(Vue实战系列)
764 4
|
关系型数据库 数据库 Docker
使用 SQLStudio 进行数据库管理并通过 Docker Compose 进行部署
在现代软件开发中,数据库管理是一个至关重要的环节。SQLStudio 是一个强大的工具,可以帮助开发人员轻松管理数据库,现在改名成SQLynx,我们用的是旧的镜像,本文还是用SQLStudio这个名称。同时,使用 Docker Compose 可以简化应用程序的部署过程,使整个开发流程更加高效和可靠。最近了看到有合作伙伴在内网使用SQLStudio,我们这篇文章就介绍 SQLStudio 的基本特点,并指导如何使用 Docker Compose 部署应用程序。
1026 2
使用 SQLStudio 进行数据库管理并通过 Docker Compose 进行部署