热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于WEBGL架构的3D可视化平台—家居城3D展现

本文将模仿一个“欧派”,让人人深居简出在家里就能够越发直观平面的遴选家具。第一步,应用CampusBuilder搭建模仿场景。CampusBuilder的模子库有林林总总的模子,使

本文将模仿一个“欧派”,让人人深居简出在家里就能够越发直观平面的遴选家具。

第一步,应用CampusBuilder搭建模仿场景。CampusBuilder的模子库有林林总总的模子,使我们搭建出的场景更传神。运用CampusBuilde建立层级,以后再给层级加外立面就涌现了当前的结果。此次我们实在只是须要一个楼层,所以我们就把上次运用的过的场景拿来革新一下。概况移步:CampusBuilder3D场景制造东西

演示地点:EXAMPLE

《基于WEBGL架构的3D可视化平台—家居城3D展现》

/加载场景代码
var app = new THING.App({
// 场景地点
"url": "http://www.thingjs.com/./uploads/wechat/oLX7p05lsWJZUIxnIWsNXAzJ40X8/scene/家具城",
//背景设置
"skyBox": "BlueSky"
});

第二步,开启层级切换。由于我们模仿的“宜家”是某修建中的一层,所以这里要开启层级切换以便进入家具城。

app.on('load', function (ev) {
//开启层级切换
app.level.change(ev.campus);
});

同时给家具城建立一个广告牌,防备我们在第一人称下行走会“迷路”。贴图能够自行上传。

//建立广告牌
var advertisingSign = app.create({
type: 'Box',
width: 15.0, // 宽度
height: 5.0, // 高度
depth: 0.5, // 深度
widthSegments: 1.0, //宽度上的节数
heightSegments: 1.0, // 高度上的节数
depthSegments: 1.0, // 深度上的节数
center: 'Bottom', // 中心点
style: {
color: '#ffffff',
opacity: 2,
image: '/uploads/wechat/oLX7p05lsWJZUIxnIWsNXAzJ40X8/file/家具展销/欧派.jpg'
},
parent: app.query('building_01')[0],
});
advertisingSign.position = [50.957, 15.883, -16];

这里给我们给悉数场景用笼统物体围起来了,以避免第一人称控件开启时会构成无碰撞系统坠落出场景。记得要给他们组兼并命名为‘碰撞盒’,在场景加载完成后将他们“隐蔽”起来。

《基于WEBGL架构的3D可视化平台—家居城3D展现》

app.on('load', function (ev) {
//开启层级切换
app.level.change(ev.campus);
//将碰撞盒的透明度设置为0,而且将他们的pickable属性设置为false,不可被选中。
var crashBox = app.query('碰撞盒')[0];
crashBox.style.opacity = 0;
crashBox.pickable = false;
});

第三步,增加第一人称控件。

先建立两个按钮来掌握第一人称控件。

new THING.widget.Button('第一人称', add_control);
new THING.widget.Button('自在视角', remove_control);

增加第一人称控件

//第一人称组件
var ctrl = null;
function add_control() {
if (app.level.current.name == 'Campus') {
app.camera.position = [75.28812158204005, 1.8016147124541857, 29.699063489018236];
app.camera.target = [53.32909358623788, 4.541642332131091, -9.470748625431646];
}
if (app.level.current.name != 'Campus') {
app.level.change(app.query('新楼层')[0]);
app.camera.flyTo({
'position': [41.05650213795261, 1.3469938677565356, -18.6143831867287],
'target': [38.982251559488404, 0.7081383467333933, -23.867802267306008],
'time': 2000,
'complete': function () {
}
});
}
if (ctrl) return;
ctrl = app.addControl(
new THING.WalkControl({
walkSpeed: 0.02,
turnSpeed: 0.25,
gravity: 30,
eyeHeight: 1.7,
jumpSpeed: 0,
enableKeyRotate: false,
useCollision: true,//app.scene
useGravity: true,
groundObjects: [app.scene] //把悉数场景都增加,可把楼层或其他须要检测的增加进入碰撞系统里 | 默许值 园区地板
})
);
}

移除第一人称控件

function remove_control() {
if (!ctrl)
return;
app.removeControl(ctrl);
ctrl = null;
}

第四步,建立界面panel用于显现家居的详细信息。

增加界面

var panel = null;
function add_panel(title, total, goodsInfo) {
panel = new THING.widget.Panel({
titleText: '商品名称:' + title,
closeIcon: true, // 是不是有封闭按钮
dragable: false, // 是不是能够拖拽
retractable: true,
opacity: 0.9, // 透明度
hasTitle: true
});
panel.position = [1000, 0];
var dataObj = {
total: total,
goodsInfo: goodsInfo
};
var total = panel.addString(dataObj, 'total').caption('总价');
var goodsInfo = panel.addString(dataObj, 'goodsInfo').caption('商品引见');
}

移除界面

function remove_panel() {
if (panel) {
panel.destroy();
panel = null;
}
}

末了一步,为商品和大楼增加点击事宜。这里我们也要卸载双击事宜,由于鼠标双击时会聚焦当前物体,与我们的营业逻辑有争执所以这里给他卸载掉。首先是一般的点击事宜,鼠标左键点击时会涌现商品的信息。右键点击时,会移除第一人称控件。

//鼠标点击事宜
app.on('click', function (ev) {
if (ev.button == 2) {
remove_control();
return;
}
remove_panel();
switch (ev.object.name) {
case "桌椅组合1": add_panel('天然作风餐桌系列', "2598.00", "  简约的圆桌设想,微冷的当代居室围成一桌大天然的觉得。天然本性,简介的设想,彰显朴素、有用、少等于多的线代生涯哲学。");
break;
case "桌椅组合2": add_panel('线代都会餐桌系列', "2198.00", "  爽利线条,描写多少形底座。天然致简的浅木色橡木拼花,带有淡淡的手工白蜡处置惩罚,搭配内敛的深灰色线条,构成玄妙均衡,线代感呼之欲出。");
break;
case "桌椅组合3": add_panel('紧凑家庭餐桌系列', "1998.00", "  紧凑家庭餐厅,享四人围坐的宽适与舒服。精致的尺寸,圆融包涵的圆桌设想,即便是紧凑的客餐厅一体空间,也能欢乐小谈。");
break;
case "沙发组合1": add_panel('本性笔记组合沙发', "2598.00", "  简约的圆桌设想,微冷的当代居室围成一桌大天然的觉得。天然本性,简介的设想,彰显朴素、有用、少等于多的线代生涯哲学。");
break;
case "沙发组合2": add_panel('云海衰退组合沙发', "8888.00", "  百口人围坐的澹泊时刻,更多一份温馨。借一抹海天的蓝,再偷来云朵的舒软,只为百口围坐的时刻,尽享温馨怡然。");
break;
case "沙发组合3": add_panel('商务温馨组合沙发', "8598.00", "  简约的圆桌设想,微冷的当代居室围成一桌大天然的觉得。天然本性,简介的设想,彰显朴素、有用、少等于多的线代生涯哲学。");
break;
case "沙发组合4": add_panel('天然作风餐桌系列', "5508.00", "  简约的圆桌设想,微冷的当代居室围成一桌大天然的觉得。天然本性,简介的设想,彰显朴素、有用、少等于多的线代生涯哲学。");
break;
case "沙发组合5": add_panel('天然作风餐桌系列', "2578.00", "  简约的圆桌设想,微冷的当代居室围成一桌大天然的觉得。天然本性,简介的设想,彰显朴素、有用、少等于多的线代生涯哲学。");
break;
}
});
app.off('dblclick');

代码块 => 层级 => 触发 => 修正进入层级操纵

《基于WEBGL架构的3D可视化平台—家居城3D展现》

这里我们将进入层级的操纵改成直接进入我们的家具城这一层“新楼层”。

//修正singleClick点击以后进入级的操纵
app.on(THING.EventType.SingleClick, function (ev) {
var object = ev.object;
if (object.name == "building_01") {
app.level.change(app.query('新楼层')[0]);
app.camera.flyTo({
'position': [41.05650213795261, 1.3469938677565356, -18.6143831867287],
'target': [38.982251559488404, 0.7081383467333933, -23.867802267306008],
'time': 2000,
complete: function () {
console.log("我已进来了" + app.level.current.name);
}
});
}
return;
}, 'customLevelEnterMethod');

小结:

第一人称控件的题目,Campus => 新楼层 ,假如不设置摄像机飞到一合理位置,摄像机将离开楼层,由于进入楼层的时刻摄像机的默许位置不在楼层上,所以每次在楼层内增加第一人称控件时我们必需要将摄像机放到一个合理的位置。

悉数代码

//加载场景代码
var app = new THING.App({
// 场景地点
"url": "http://www.thingjs.com/./uploads/wechat/oLX7p05lsWJZUIxnIWsNXAzJ40X8/scene/家具城",
//背景设置
"skyBox": "BlueSky"
});
app.on('load', function (ev) {
app.level.change(ev.campus);
var crashBox = app.query('碰撞盒')[0];
crashBox.style.opacity = 0;
crashBox.pickable = false;
new THING.widget.Button('第一人称', add_control);
new THING.widget.Button('自在视角', remove_control);
});
//修正singleClick点击以后进入级的操纵
app.on(THING.EventType.SingleClick, function (ev) {
var object = ev.object;
if (object.name == "building_01") {
app.level.change(app.query('新楼层')[0]);
app.camera.flyTo({
'position': [41.05650213795261, 1.3469938677565356, -18.6143831867287],
'target': [38.982251559488404, 0.7081383467333933, -23.867802267306008],
'time': 2000,
complete: function () {
console.log("我已进来了" + app.level.current.name);
}
});
}
return;
}, 'customLevelEnterMethod');
//鼠标点击事宜
app.on('click', function (ev) {
if (ev.button == 2) {
remove_control();
}
if (typeof (ev.object) == undefined)
return;
remove_panel();
switch (ev.object.name) {
case "桌椅组合1": add_panel('天然作风餐桌系列', "2598.00", "  简约的圆桌设想,微冷的当代居室围成一桌大天然的觉得。天然本性,简介的设想,彰显朴素、有用、少等于多的线代生涯哲学。");
break;
case "桌椅组合2": add_panel('线代都会餐桌系列', "2198.00", "  爽利线条,描写多少形底座。天然致简的浅木色橡木拼花,带有淡淡的手工白蜡处置惩罚,搭配内敛的深灰色线条,构成玄妙均衡,线代感呼之欲出。");
break;
case "桌椅组合3": add_panel('紧凑家庭餐桌系列', "1998.00", "  紧凑家庭餐厅,享四人围坐的宽适与舒服。精致的尺寸,圆融包涵的圆桌设想,即便是紧凑的客餐厅一体空间,也能欢乐小谈。");
break;
case "沙发组合1": add_panel('本性笔记组合沙发', "2598.00", "  简约的圆桌设想,微冷的当代居室围成一桌大天然的觉得。天然本性,简介的设想,彰显朴素、有用、少等于多的线代生涯哲学。");
break;
case "沙发组合2": add_panel('云海衰退组合沙发', "8888.00", "  百口人围坐的澹泊时刻,更多一份温馨。借一抹海天的蓝,再偷来云朵的舒软,只为百口围坐的时刻,尽享温馨怡然。");
break;
case "沙发组合3": add_panel('商务温馨组合沙发', "8598.00", "  简约的圆桌设想,微冷的当代居室围成一桌大天然的觉得。天然本性,简介的设想,彰显朴素、有用、少等于多的线代生涯哲学。");
break;
case "沙发组合4": add_panel('天然作风餐桌系列', "5508.00", "  简约的圆桌设想,微冷的当代居室围成一桌大天然的觉得。天然本性,简介的设想,彰显朴素、有用、少等于多的线代生涯哲学。");
break;
case "沙发组合5": add_panel('天然作风餐桌系列', "2578.00", "  简约的圆桌设想,微冷的当代居室围成一桌大天然的觉得。天然本性,简介的设想,彰显朴素、有用、少等于多的线代生涯哲学。");
break;
}
});
//卸载双击事宜
app.off('dblclick');
// 界面组件
var panel = null;
function add_panel(title, total, goodsInfo) {
panel = new THING.widget.Panel({
titleText: '商品名称:' + title,
closeIcon: true, // 是不是有封闭按钮
dragable: false, // 是不是能够拖拽
retractable: true,
opacity: 0.9, // 透明度
hasTitle: true
});
panel.position = [1000, 0];
var dataObj = {
total: total,
goodsInfo: goodsInfo
};
var total = panel.addString(dataObj, 'total').caption('总价');
var goodsInfo = panel.addString(dataObj, 'goodsInfo').caption('商品引见');
}
function remove_panel() {
if (panel) {
panel.destroy();
panel = null;
}
}
//建立广告牌
var advertisingSign = app.create({
type: 'Box',
width: 15.0, // 宽度
height: 5.0, // 高度
depth: 0.5, // 深度
widthSegments: 1.0, //宽度上的节数
heightSegments: 1.0, // 高度上的节数
depthSegments: 1.0, // 深度上的节数
center: 'Bottom', // 中心点
style: {
color: '#ffffff',
opacity: 2,
image: '/uploads/wechat/oLX7p05lsWJZUIxnIWsNXAzJ40X8/file/家具展销/欧派.jpg'
},
parent: app.query('building_01')[0],
});
advertisingSign.position = [50.957, 15.883, -16];
//第一人称组件
var ctrl = null;
function add_control() {
if (app.level.current.name == 'Campus') {
app.camera.position = [75.28812158204005, 1.8016147124541857, 29.699063489018236];
app.camera.target = [53.32909358623788, 4.541642332131091, -9.470748625431646];
}
if (app.level.current.name != 'Campus') {
app.level.change(app.query('新楼层')[0]);
app.camera.flyTo({
'position': [41.05650213795261, 1.3469938677565356, -18.6143831867287],
'target': [38.982251559488404, 0.7081383467333933, -23.867802267306008],
'time': 2000,
'complete': function () {
}
});
}
if (ctrl) return;
ctrl = app.addControl(
new THING.WalkControl({
walkSpeed: 0.02,
turnSpeed: 0.25,
gravity: 30,
eyeHeight: 1.7,
jumpSpeed: 0,
enableKeyRotate: false,
useCollision: true,//app.scene
useGravity: true,
groundObjects: [app.scene] //把悉数场景都增加,可把楼层或其他须要检测的增加进入碰撞系统里 | 默许值 园区地板
})
);
}
function remove_control() {
if (!ctrl)
return;
app.removeControl(ctrl);
ctrl = null;
}

推荐阅读
  • 在JavaWeb开发中,文件上传是一个常见的需求。无论是通过表单还是其他方式上传文件,都必须使用POST请求。前端部分通常采用HTML表单来实现文件选择和提交功能。后端则利用Apache Commons FileUpload库来处理上传的文件,该库提供了强大的文件解析和存储能力,能够高效地处理各种文件类型。此外,为了提高系统的安全性和稳定性,还需要对上传文件的大小、格式等进行严格的校验和限制。 ... [详细]
  • Spring Boot 中配置全局文件上传路径并实现文件上传功能
    本文介绍如何在 Spring Boot 项目中配置全局文件上传路径,并通过读取配置项实现文件上传功能。通过这种方式,可以更好地管理和维护文件路径。 ... [详细]
  • 在PHP中如何正确调用JavaScript变量及定义PHP变量的方法详解 ... [详细]
  • 本文介绍了如何利用Struts1框架构建一个简易的四则运算计算器。通过采用DispatchAction来处理不同类型的计算请求,并使用动态Form来优化开发流程,确保代码的简洁性和可维护性。同时,系统提供了用户友好的错误提示,以增强用户体验。 ... [详细]
  • 本文探讨了使用JavaScript在不同页面间传递参数的技术方法。具体而言,从a.html页面跳转至b.html时,如何携带参数并使b.html替代当前页面显示,而非新开窗口。文中详细介绍了实现这一功能的代码及注释,帮助开发者更好地理解和应用该技术。 ... [详细]
  • 本文详细介绍了一种利用 ESP8266 01S 模块构建 Web 服务器的成功实践方案。通过具体的代码示例和详细的步骤说明,帮助读者快速掌握该模块的使用方法。在疫情期间,作者重新审视并研究了这一未被充分利用的模块,最终成功实现了 Web 服务器的功能。本文不仅提供了完整的代码实现,还涵盖了调试过程中遇到的常见问题及其解决方法,为初学者提供了宝贵的参考。 ... [详细]
  • 本文详细探讨了 jQuery 中 `ajaxSubmit` 方法的使用技巧及其应用场景。首先,介绍了如何正确引入必要的脚本文件,如 `jquery.form.js` 和 `jquery-1.8.0.min.js`。接着,通过具体示例展示了如何利用 `ajaxSubmit` 方法实现表单的异步提交,包括数据的发送、接收和处理。此外,还讨论了该方法在不同场景下的应用,如文件上传、表单验证和动态更新页面内容等,提供了丰富的代码示例和最佳实践建议。 ... [详细]
  • Flutter 2.* 路由管理详解
    本文详细介绍了 Flutter 2.* 中的路由管理机制,包括路由的基本概念、MaterialPageRoute 的使用、Navigator 的操作方法、路由传值、命名路由及其注册、路由钩子等。 ... [详细]
  • javascript分页类支持页码格式
    前端时间因为项目需要,要对一个产品下所有的附属图片进行分页显示,没考虑ajax一张张请求,所以干脆一次性全部把图片out,然 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 检查在所有可能的“?”替换中,给定的二进制字符串中是否出现子字符串“10”带 1 或 0 ... [详细]
  • 本文介绍了如何使用 Node.js 和 Express(4.x 及以上版本)构建高效的文件上传功能。通过引入 `multer` 中间件,可以轻松实现文件上传。首先,需要通过 `npm install multer` 安装该中间件。接着,在 Express 应用中配置 `multer`,以处理多部分表单数据。本文详细讲解了 `multer` 的基本用法和高级配置,帮助开发者快速搭建稳定可靠的文件上传服务。 ... [详细]
  • 浏览器作为我们日常不可或缺的软件工具,其背后的运作机制却鲜为人知。本文将深入探讨浏览器内核及其版本的演变历程,帮助读者更好地理解这一关键技术组件,揭示其内部运作的奥秘。 ... [详细]
  • 在 Vue 项目中,为了提高页面加载速度和优化用户体验,实现图片上传前的压缩处理至关重要。本文介绍了如何通过集成第三方库和自定义组件,有效减小图片文件大小,确保在不影响图像质量的前提下,提升应用性能。 ... [详细]
author-avatar
minimiai_559
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有