123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541 |
- <!-- 实现具体3d逻辑使用 -->
- <script setup lang="ts">
- import CourseChapter3dMain from '@/components/student/CourseChapter3dMain.vue';
- import { threeWorld } from "@/stores/threeWorld.ts";
- import { courseChapter3dShow } from "@/stores/courseChapter3dShow.ts";
- import { ref, watch } from "vue";
- const props = defineProps({
- config : {
- type: Object
- },
- // 获取当前学生任务ID缺陷列表
- studentTaskIdList : {
- type: Object
- },
- });
- // 定义发射给父组件的方法
- const emits = defineEmits([
- // 上一步是否显示
- 'tipsBtnsUpOpen',
- // 下一步是否显示
- 'tipsBtnsDownOpen',
- ]);
- // setInterval(function() {
- // console.log(
- // "3d场景参数", props.config
- // );
- // }, 1000);
- // 【开发的时候】3d场景,iframe地址
- let threeWorldUrl = "3dMain/index.html#/main?id=zidingyi";
- // babylon 对象
- let BABYLON : any = null;
- // // 【发布的时候】3d场景,iframe地址
- // // 配置文件地址
- // // let commonconfig = "https://www.3dyzt.com/eduTrain/3dMain/model/";
- // let commonconfig = "https://www.3dyzt.com/eduTrain/3dMain/model2/";// 正式
- // // let commonconfig = "https://www.3dyzt.com/eduTrain/3dMain/model3/";// 临时测试
- // // 模型地址
- // // let commonmodel = "https://www.3dyzt.com/eduTrain/3dMain/model/";
- // let commonmodel = "https://www.3dyzt.com/eduTrain/3dMain/model2/";// 正式
- // // let commonmodel = "https://www.3dyzt.com/eduTrain/3dMain/model3/";// 临时测试
- // // 发布后的地址
- // let threeWorldUrl = "https://www.3dyzt.com/main/index.html#/main?id=zidingyi&user=zidingyi&commonconfig=" + commonconfig + "&commonmodel=" + commonmodel;
- /**
- * 上一步是否显示
- * open true - 显示, false - 隐藏
- */
- const tipsBtnsUpOpenEvent = (open : Boolean) => {
- emits('tipsBtnsUpOpen', open);
- }
- /**
- * 下一步是否显示
- * open true - 显示, false - 隐藏
- */
- const tipsBtnsDownOpenEvent = (open : Boolean) => {
- emits('tipsBtnsDownOpen', open);
-
- }
- // 记录当前的流程
- let thisFlowPath : any = null;
- // 记录最后一次播放完成的状态
- let thisFlowPathEnd : any = null;
- /**
- * 监听发送参数变化,流程完成的时候
- */
- watch(
- () => courseChapter3dShow().show.showEndViewBool,
- (newVal, oldVal) => {
- // console.log(
- // newVal, oldVal,
- // props.config
- // );
-
- // 如果没有加载完成,则不触发后面的逻辑
- if (courseChapter3dShow().show.showEndViewBool == false) {
- return;
- }
- if (thisFlowPathEnd != thisFlowPath) {
- thisFlowPathEnd = thisFlowPath;
-
- }
- }
- );
- /**
- * 监听发送参数变化,来控制切换3d的逻辑
- */
- watch(
- () => props.config,
- (newVal, oldVal) => {
- // console.log(
- // newVal, oldVal,
- // props.config
- // );
-
- // 如果没有加载完成,则不触发后面的逻辑
- if (threeWorld().loadSuccess == false) {
- return;
- }
- typeEvent(props.config?.threeDimensionalConfig);
- }
- );
- /**
- * 回调加载百分比
- */
- const callbackLoadPercentageEvent = (json: { loadPercentage: any; }) => {
- // console.log("回调加载百分比", json)
- const loadPercentage = parseFloat(json["loadPercentage"]);
- // 加载小于百分比
- if (loadPercentage < 100) {
- // ##############################【这里只做控制】隐藏其他按钮界面等
- threeWorld().loadSuccess = false;
- goPlayCallbackEventMain();
- return
- }
- }
- /**
- * 回调加载完成
- */
- const callbackLoadEndEvent = (json : { 'roleChoiceOpenBool' : true }) => {
- // console.log("回调加载完成", json)
- // 此时是显示角色的界面
- if (json["roleChoiceOpenBool"] === true) {
- // ############################## 隐藏其他按钮界面等
- threeWorld().loadSuccess = false;
-
- return;
- }
- // ############################## 这个时候,是真正的进入3d画面了,才显示其他按钮界面等
- threeWorld().loadSuccess = true;
-
- }
- /**
- * 回调距离范围内
- */
- const callbackDistanceYesEvent = (json : any) => {
- // console.log("回调距离范围内", json);
- }
- /**
- * 回调距离范围外
- */
- const callbackDistanceNoEvent = (json : any) => {
- // console.log("回调距离范围外", json);
- }
- /**
- * 回调视角切换完成
- */
- const callbackCameraVisualAngleJsonToLookEvent = (json : any) => {
- // console.log("视角触发完成", json);
- }
- /**
- * 记录出生点
- */
- const birthPointInit = () => {
- courseChapter3dShow().show.birthPoint = {};
- // @ts-ignore
- for (let i = 0; i < threeWorld().obj.newIframe.objIframe.ChengGuangYuanJing.CommonBirthplace.find().list.length; i++) {
- // @ts-ignore
- let json = threeWorld().obj.newIframe.objIframe.ChengGuangYuanJing.CommonBirthplace.find().list[i];
- // console.log(
- // "json", json
- // );
- // @ts-ignore
- courseChapter3dShow().show.birthPoint[json.name] = json;
- }
- // console.log(
- // "courseChapter3dShow().show.birthPoint = {};",
- // courseChapter3dShow().show.birthPoint
- // );
-
- }
- /**
- * 记录3d里配置的移动速度
- */
- const carMoveSpeedInitEvent = () => {
- // // @ts-ignore
- // let objRoleConfig = threeWorld().obj.newIframe.objIframe.ChengGuangYuanJing.Role.find().roleCodeAllConfig[
- // // @ts-ignore
- // threeWorld().obj.newIframe.objIframe.ChengGuangYuanJing.Role.find().roleCode
- // ];
- // @ts-ignore
- let roleConfig = threeWorld().obj.newIframe.objIframe.ChengGuangYuanJing.CommonVal.find().roleConfig;
-
- courseChapter3dShow().show.carMoveSpeed = parseFloat("" + roleConfig.speedMove);
- // console.log(
- // "roleConfig",
- // roleConfig,
- // "courseChapter3dShow().show.carMoveSpeed",
- // courseChapter3dShow().show.carMoveSpeed
- // );
-
- }
- setInterval(function() {
- // 如果没有加载完成,则不触发后面的逻辑
- if (threeWorld().loadSuccess == false) {
- return;
- }
- // 更新时间
- var cur = new Date(); // 创建当前日期对象 cur
- var years = cur.getFullYear(); // 从日期对象cur中取得年数
- var months = cur.getMonth() + 1; // 取得月数
- var days = cur.getDate(); // 取得天数
- var hours = cur.getHours(); // 取得小时数
- var minutes = cur.getMinutes(); // 取得分钟数
- courseChapter3dShow().show.showCarEyeYears = years;
- courseChapter3dShow().show.showCarEyeMonths = months;
- courseChapter3dShow().show.showCarEyeDays = days;
- courseChapter3dShow().show.showCarEyeHours = hours;
- courseChapter3dShow().show.showCarEyeMinutes = minutes;
-
- }, 1000);
- /**
- * 监听是否点击 进入活动,或者是点击屏幕进入3d场景回调
- */
- const goPlayCallbackEventMain = () => {
- if (
- // @ts-ignore
- threeWorld().obj.newIframe.objIframe.window["goPlayCallbackEvent"] != null
- // @ts-ignore
- && threeWorld().obj.newIframe.objIframe.window["goPlayCallbackEvent"] != undefined
- ) {
- return;
- }
- // @ts-ignore
- threeWorld().obj.newIframe.objIframe.window["goPlayCallbackEvent"] = function(res : any) {
- // console.log(
- // " ========== 监听是否点击 进入活动,或者是点击屏幕进入3d场景 ========== ",
- // res
- // );
- setTimeout(function() {
- initScene();
- }, 200);
- }
- }
- /**
- * 设置3d事件
- */
- const threeEvent = () => {
-
- // @ts-ignore
- let objScene = threeWorld().obj.newIframe.objIframe.ChengGuangYuanJing.CommonVal.find().objScene;
- /**
- * 可以被追加事件的API【 可以不断追加进来 】
- */
- // @ts-ignore
- threeWorld().obj.newIframe.objIframe.ChengGuangYuanJing.CommonVal.find().objScene.onPointerObservable.add(
- (pointerInfo : any) => {
- // console.log(
- // " ============================== 鼠标事件触发了 ============================== ",
- // pointerInfo.pickInfo,
- // pointerInfo.pickInfo.hit
- // );
- // 当前的步骤状态
- let statue = props.config?.threeDimensionalConfig;
- if (courseChapter3dShow().show.pickResultMoveBool == true) {
- courseChapter3dShow().show.showDirectionViewBool = false;
- courseChapter3dShow().show.showClickRotationViewBool = false;
- // 获取选择的对象, 通过测试 scene.pick() 方法是非常消耗性能的
- let pickResultMove = objScene.pick(
- objScene.pointerX,
- objScene.pointerY
- );
- if (pickResultMove.hit) {
- // console.log(
- // "鼠标移动触发逻辑",
- // "pickResultMove", pickResultMove
- // );
-
- }
-
- }
-
- // 如果点击到3d世界里的物体的时候
- if (pointerInfo.pickInfo.hit) {
-
- var pickResult = pointerInfo.pickInfo;
- // console.log(
- // " threeEvent = () => { 鼠标事件 》》》》》》》》》》 ", pickResult
- // );
- // // 获取点击对象的方向【 一定要加上 true,否则载入的获取模型的方向,会有问题 】
- // var getNormal = pickResult.getNormal(true);
- // console.log({
- // '事件' : 'lickType 鼠标事件点击到物体了',
- // '被点击到的物体' : pickResult,
- // '坐标' : pickResult.pickedPoint,
- // '被点击的物体的名字' : pickResult.pickedMesh.name,
- // '被点击物体的材质' : pickResult.pickedMesh.material,
- // '获取点击对象的方向' : getNormal,
- // '得到点击物体的所有点位集合[ 物体都是通过很多点为链接而形成的,可以通过这个方法知道物体的最大尺寸,或者最小尺寸等 ]' : pickResult.pickedMesh._geometry._positions,
- // '得到被点击物体的绝对坐标,后续该坐标例如取中心点垂直就很有用处【3d模型如果错位,说明是3d建模把模型给合并导致的,需要跟对方沟通,让模型单独】' : pickResult.pickedMesh._absolutePosition
- // });
- switch (pointerInfo.type) {
- case BABYLON.PointerEventTypes.POINTERDOWN:
- // console.log("clickType 鼠标按下");
- courseChapter3dShow().show.showDirectionViewBool = false;
- courseChapter3dShow().show.showClickRotationViewBool = false;
-
-
- break;
- case BABYLON.PointerEventTypes.POINTERUP:
- // console.log("clickType 鼠标弹起");
-
- break;
- case BABYLON.PointerEventTypes.POINTERMOVE:
- // console.log("clickType 鼠标移动中");
-
- break;
- case BABYLON.PointerEventTypes.POINTERWHEEL:
- // console.log("clickType 鼠标滚轮滚动中");
- break;
- case BABYLON.PointerEventTypes.POINTERPICK:
- // console.log("clickType 鼠标指针选中事件");
- break;
- case BABYLON.PointerEventTypes.POINTERTAP:
- // console.log("clickType 当对象被触摸并在没有拖动的情况下释放时,触发指针触发事件。");
- break;
- case BABYLON.PointerEventTypes.POINTERDOUBLETAP:
- // console.log("clickType 鼠标双击");
-
- break;
- }
- }
-
- });
-
- // @ts-ignore 添加帧事件
- threeWorld().obj.newIframe.objIframe.ChengGuangYuanJing.CommonVal.find().objScene.onBeforeRenderObservable.add(function() {
-
- });
-
- }
- /**
- * 3d加载完成优先切换到默认的视角
- */
- const initScene = () => {
- // console.log(
- // "initScene = () => {",
- // threeWorld().obj.newIframe,
- // threeWorld().obj.newIframe.getCameraVisualAngleGetList()
- // );
-
- // @ts-ignore
- threeWorld().obj.newIframe.cameraVisualAngleGetListNameGpsTo("检测车");
- // @ts-ignore
- threeWorld().obj.newIframe.roleShow(false);
- // 清空3d背景
- // @ts-ignore
- threeWorld().obj.newIframe.objIframe.ChengGuangYuanJing.CommonVal.find().objScene.clearColor = {
- "r" : 0, "g" : 0, "b" : 0, "a" : 0
- };
- groundNoRemove();
- typeEvent(props.config?.threeDimensionalConfig);
- // 触发自动点击逻辑
- // @ts-ignore
- threeWorld().obj.newIframe.objIframe.ChengGuangYuanJing.CommonVal.find().screenClickNumEvent();
- }
- /**
- * 将所有设置为地面的,改为不设置为地面
- */
- const groundNoRemove = () => {
-
- // @ts-ignore
- for (const key in threeWorld().obj.newIframe.objIframe.ChengGuangYuanJing.ModelObjEdit.find().meshListIdToJson) {
-
- if (
- // @ts-ignore
- threeWorld().obj.newIframe.objIframe.ChengGuangYuanJing.ModelObjEdit.find().meshListIdToJson[key]['isGround'] == true
- ) {
- // 通过更新材质的参数,来更新
- // @ts-ignore
- threeWorld().obj.newIframe.objIframe.ChengGuangYuanJing.ModelObjEdit.find().objOneMeshListIdToJsonUpdate(
- key,
- {
-
- "isGround" : false,
- }
- );
- }
-
- }
- // @ts-ignore
- for (let i = 0; i < threeWorld().obj.newIframe.objIframe.ChengGuangYuanJing.CommonVal.find().objScene.meshes.length; i++) {
- // @ts-ignore
- let objMesh = threeWorld().obj.newIframe.objIframe.ChengGuangYuanJing.CommonVal.find().objScene.meshes[i];
- // console.log(
- // "myIsGround",
- // objMesh["myIsGround"]
- // );
- // if (objMesh["myIsGround"] == true) {
- // delete objMesh["myIsGround"];
- // }
- delete objMesh["myIsGround"];
- }
- // @ts-ignore
- threeWorld().obj.newIframe.objIframe.ChengGuangYuanJing.Role.find().isGroundList = {};
- // @ts-ignore
- threeWorld().obj.newIframe.objIframe.ChengGuangYuanJing.ModelObjEdit.find().myIsGroundConfigNum = 0;
- }
- /**
- * 根据不同的类型,切换对应的3d逻辑
- */
- const typeEvent = (type : any) => {
- console.log(
- "根据不同的类型,切换对应的3d逻辑",
- type
- );
-
- switch(type) {
- // 操作帮助
- case 'operationHelp':
-
- break;
-
- // 设备拆解
- case 'equipmentDisassembly':
-
- break;
-
- default:
-
- break;
-
- }
-
- }
- </script>
- <template>
- <!-- 3d课程配置:{{ props.config }} -->
- <img v-if="courseChapter3dShow().show.threeWorldMask == true" class="threeWorldMask" src="../../assets/student/mask.webp" />
- <CourseChapter3dMain
- :iframeId="'newIframe'"
- :url="threeWorldUrl"
- @callbackLoadPercentage="callbackLoadPercentageEvent"
- @callbackLoadEnd="callbackLoadEndEvent"
- @callbackDistanceYes="callbackDistanceYesEvent"
- @callbackDistanceNo="callbackDistanceNoEvent"
- @callbackCameraVisualAngleJsonToLook="callbackCameraVisualAngleJsonToLookEvent"
- ></CourseChapter3dMain>
- </template>
- <style scoped>
- .threeWorldMask {
- position: fixed;
- z-index: 1;
- width: 100%;
- height: 100%;
- top: 0px;
- left: 0px;
- pointer-events: none;
- }
- </style>
|