增加三维课程播放器,增加第一人称控制碰撞检测,完善编辑器数据
88
src/jlmap3d/lesson3d/lesson3dplayer.js
Normal file
@ -0,0 +1,88 @@
|
||||
import store from '@/store/index';
|
||||
// import { Loading } from 'element-ui';
|
||||
import {Stats} from '@/jlmap3d/main/lib/stats.min.js';
|
||||
//静态资源文件路径
|
||||
import { JL3D_LOCAL_STATIC } from '@/api/jlmap3d/assets3d.js';
|
||||
//loader
|
||||
import { FBXLoader } from '@/jlmap3d/main/loaders/FBXLoader';
|
||||
//轨道视角控制
|
||||
import { OrbitControls } from '@/jlmap3d/main/control/OrbitControls';
|
||||
//骨骼动画模型辅助工具
|
||||
import { SkeletonUtils } from '@/jlmap3d/main/utils/SkeletonUtils.js';
|
||||
|
||||
import { AssetModelManager } from '@/jlmap3d/lesson3d/manager/assetmodelmanager.js';
|
||||
|
||||
import { ControlManager } from '@/jlmap3d/lesson3d/manager/controlmanager.js';
|
||||
|
||||
// import { AnimationManager } from '@/jlmap3d/lesson3d/manager/assetmodelmanager.js';
|
||||
|
||||
|
||||
//动画播放相关
|
||||
let clock = new THREE.Clock();
|
||||
let delta;
|
||||
|
||||
let scene;
|
||||
|
||||
export function Lesson3dPlayer(dom,lessonData,lessonIndex) {
|
||||
|
||||
// let stats = new Stats();
|
||||
// dom.appendChild( stats.dom );
|
||||
|
||||
let scope = this;
|
||||
this.dom = dom;
|
||||
|
||||
//定义相机
|
||||
|
||||
|
||||
//定义场景(渲染容器)
|
||||
scene = new THREE.Scene();
|
||||
scene.background = new THREE.Color(0xa0a0a0);
|
||||
|
||||
//定义全局光
|
||||
let ambientLight = new THREE.AmbientLight(0xffffff, 1.3);
|
||||
scene.add(ambientLight);
|
||||
var light = new THREE.HemisphereLight( 0xffffff, 0x444444 );
|
||||
light.position.set( 0, 4000, 0 );
|
||||
scene.add( light );
|
||||
|
||||
let controlManager = new ControlManager( dom,scene,lessonData,lessonIndex);
|
||||
|
||||
let assetModelManager = new AssetModelManager(scene,controlManager);
|
||||
assetModelManager.lessonAssetsLoader(lessonData.assetList,lessonData.modelList).then((result) => {
|
||||
controlManager.initOctree(assetModelManager.loadAsset['default1'].mesh);
|
||||
|
||||
animate();
|
||||
console.log(lessonData.lessonProgress[lessonIndex]);
|
||||
if(lessonData.lessonProgress[lessonIndex].action.length>0){
|
||||
controlManager.initNewEvent(lessonData.lessonProgress[lessonIndex].action,assetModelManager.lessonTriggerList);
|
||||
}
|
||||
resolve("loadeend"); //['成功了', 'success']
|
||||
}).catch((error) => {
|
||||
//console.log(error);
|
||||
});;
|
||||
|
||||
|
||||
|
||||
this.actionRemove = function(actionModel){
|
||||
assetModelManager.otherModel.remove(actionModel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//循环渲染函数
|
||||
function animate() {
|
||||
|
||||
if(controlManager.controlMode == "free"){
|
||||
controlManager.updateOrbitControl();
|
||||
}
|
||||
if(controlManager.controlMode == "fps"){
|
||||
controlManager.updateFpsControl();
|
||||
}
|
||||
// delta = clock.getDelta();
|
||||
requestAnimationFrame(animate);
|
||||
|
||||
}
|
||||
|
||||
this.attachModel = function(selectModel){
|
||||
}
|
||||
}
|
160
src/jlmap3d/lesson3d/manager/assetmodelmanager.js
Normal file
@ -0,0 +1,160 @@
|
||||
import { BASE_ASSET_API } from '@/api/jlmap3d/assets3d.js';
|
||||
|
||||
export function AssetModelManager(scene) {
|
||||
let scope = this;
|
||||
|
||||
|
||||
this.assetList = [];
|
||||
|
||||
this.otherModel = new THREE.Group();
|
||||
|
||||
scene.add(this.otherModel);
|
||||
|
||||
this.loadAsset = [];
|
||||
|
||||
this.loadAsset['default1'] = {
|
||||
modelId:'default1',
|
||||
packageName:"车站",
|
||||
url:"/MODEL/2021-04-06/1381-54584.FBX",
|
||||
mesh:"",
|
||||
assetType:'default',
|
||||
isUse:true,
|
||||
resourceType:"三维课程",
|
||||
};
|
||||
|
||||
//场景中可触发事件模型
|
||||
this.lessonTriggerList = [];
|
||||
|
||||
//加载课程资源
|
||||
this.lessonAssetsLoader = function(assetList,modelList){
|
||||
let initlist = [];
|
||||
if(assetList){
|
||||
for(let i = 0;i<assetList.length;i++){
|
||||
assetList[i].mesh = "";
|
||||
scope.loadAsset[assetList[i].modelId] = assetList[i];
|
||||
|
||||
}
|
||||
}
|
||||
for(let k in scope.loadAsset){
|
||||
initlist.push(fbxpromise(scope.loadAsset[k]));
|
||||
|
||||
}
|
||||
|
||||
return new Promise(function(resolve, reject){
|
||||
Promise.all(initlist).then((result) => {
|
||||
|
||||
initTriggerList();
|
||||
for(let i=0;i<modelList.length;i++){
|
||||
let newModelTrigger = scope.loadAsset[modelList[i].modelId].mesh.clone(true);
|
||||
newModelTrigger.showType = "loadModel";
|
||||
newModelTrigger.label = modelList[i].label;
|
||||
newModelTrigger.modelId = modelList[i].modelId;
|
||||
newModelTrigger.visible = modelList[i].visible;
|
||||
newModelTrigger.position.x = modelList[i].pos.x;
|
||||
newModelTrigger.position.y = modelList[i].pos.y;
|
||||
newModelTrigger.position.z = modelList[i].pos.z;
|
||||
newModelTrigger.rotation.x = modelList[i].rot.x;
|
||||
newModelTrigger.rotation.y = modelList[i].rot.y;
|
||||
newModelTrigger.rotation.z = modelList[i].rot.z;
|
||||
scope.otherModel.add(newModelTrigger);
|
||||
scope.lessonTriggerList.push(newModelTrigger);
|
||||
}
|
||||
|
||||
updateTriggerList(scope.lessonTriggerList);
|
||||
resolve("loaderassets"); //['成功了', 'success']
|
||||
}).catch((error) => {
|
||||
//console.log(error);
|
||||
});
|
||||
|
||||
});
|
||||
resolve("loaderassets");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// <el-option label="车站" value="standstation"></el-option>
|
||||
// <el-option label="停车场" value="stopstation"></el-option>
|
||||
// <el-option label="单体设备" value="device"></el-option>
|
||||
// <el-option label="线路" value="xl"></el-option>
|
||||
// <el-option label="道岔" value="dc"></el-option>
|
||||
//FT 扶梯
|
||||
//FTAN 扶梯按钮(急停)
|
||||
//FTD 扶梯灯
|
||||
//FTKG 扶梯开关(钥匙孔)
|
||||
//FTTJ 扶梯台阶
|
||||
function initTriggerList(){
|
||||
|
||||
scope.loadAsset['default1'].mesh.getObjectByName("FTAN").showType = "default";
|
||||
scope.loadAsset['default1'].mesh.getObjectByName("FTAN").label = "扶梯急停按钮";
|
||||
scope.lessonTriggerList.push(scope.loadAsset['default1'].mesh.getObjectByName("FTAN"));
|
||||
|
||||
scope.loadAsset['default1'].mesh.getObjectByName("FTKG").showType = "default";
|
||||
scope.loadAsset['default1'].mesh.getObjectByName("FTKG").label = "扶梯钥匙孔";
|
||||
scope.lessonTriggerList.push(scope.loadAsset['default1'].mesh.getObjectByName("FTKG"));
|
||||
|
||||
|
||||
// console.log(scope.loadAsset['default1'].mesh.getObjectByName("FTKG"));
|
||||
}
|
||||
|
||||
//动态加载资源
|
||||
this.lessonAssetsNewLoader = function(assetData,pos){
|
||||
let isLoaded = false;
|
||||
|
||||
if(scope.loadAsset[assetData.id]){
|
||||
let newModelTrigger = scope.loadAsset[assetData.id].mesh.clone(true);
|
||||
newModelTrigger.modelId = assetData.id;
|
||||
newModelTrigger.showType = "loadModel";
|
||||
newModelTrigger.label = assetData.packageName;
|
||||
newModelTrigger.position.copy(pos);
|
||||
scope.otherModel.add(newModelTrigger);
|
||||
scope.lessonTriggerList.push(newModelTrigger);
|
||||
updateTriggerList(scope.lessonTriggerList);
|
||||
}else{
|
||||
scope.loadAsset[assetData.id] = {
|
||||
modelId:assetData.id,
|
||||
packageName:assetData.packageName,
|
||||
url:assetData.url,
|
||||
mesh:"",
|
||||
assetType:'loadModel',
|
||||
isUse:true,
|
||||
resourceType:"三维课程",
|
||||
};
|
||||
|
||||
fbxpromise(scope.loadAsset[assetData.id]).then(function(object){
|
||||
|
||||
let newModelTrigger = scope.loadAsset[assetData.id].mesh.clone(true);
|
||||
newModelTrigger.showType = "loadModel";
|
||||
newModelTrigger.modelId = assetData.id;
|
||||
newModelTrigger.label = assetData.packageName;
|
||||
newModelTrigger.position.copy(pos);
|
||||
scope.otherModel.add(newModelTrigger);
|
||||
scope.lessonTriggerList.push(newModelTrigger);
|
||||
|
||||
updateTriggerList(scope.lessonTriggerList);
|
||||
// resolve("loadednew");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//fbx模型加载
|
||||
function fbxpromise(asset){
|
||||
return new Promise(function(resolve, reject){
|
||||
var loader = new THREE.FBXLoader();
|
||||
loader.load( BASE_ASSET_API+asset.url, function ( object ) {
|
||||
|
||||
if(asset.assetType == "default"){
|
||||
scene.add(object);
|
||||
}else if(asset.assetType == 'loadModel'){
|
||||
|
||||
}
|
||||
object.label = asset.packageName;
|
||||
asset.mesh = object;
|
||||
resolve();
|
||||
} );
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
403
src/jlmap3d/lesson3d/manager/controlmanager.js
Normal file
@ -0,0 +1,403 @@
|
||||
|
||||
import { Capsule } from '@/jlmap3d/lesson3d/math/Capsule.js';
|
||||
|
||||
import { Octree } from '@/jlmap3d/lesson3d/math/Octree.js';
|
||||
|
||||
export function ControlManager(dom,scene,lessonData,lessonIndex) {
|
||||
|
||||
let scope = this;
|
||||
this.controlMode = "";
|
||||
this.controls = {};
|
||||
this.nowCamera = null;
|
||||
this.eventHitMode = false;
|
||||
|
||||
let eventBoxs = [];
|
||||
|
||||
|
||||
|
||||
let renderer = new THREE.WebGLRenderer({ antialias: true });
|
||||
renderer.setClearColor(new THREE.Color(0x000000));
|
||||
renderer.setViewport( 0, 0, dom.offsetWidth, dom.offsetHeight);
|
||||
renderer.setScissor( 0, 0, dom.offsetWidth, dom.offsetHeight);
|
||||
renderer.setScissorTest( false );
|
||||
renderer.setSize(dom.offsetWidth, dom.offsetHeight);
|
||||
renderer.sortObjects = true;
|
||||
dom.appendChild(renderer.domElement);
|
||||
|
||||
let orbitCamera = new THREE.PerspectiveCamera(70, dom.offsetWidth / dom.offsetHeight, 0.01, 1000);
|
||||
orbitCamera.position.set(0, 80, 40);
|
||||
orbitCamera.aspect = dom.offsetWidth / dom.offsetHeight;
|
||||
orbitCamera.updateProjectionMatrix();
|
||||
|
||||
let oribitControl = new THREE.OrbitControls(orbitCamera,dom);
|
||||
oribitControl.maxPolarAngle = Math.PI / 2;
|
||||
oribitControl.minPolarangle = Math.PI / 5;
|
||||
oribitControl.maxDistance = 800;
|
||||
oribitControl.screenSpacePanning = true;
|
||||
oribitControl.update();
|
||||
|
||||
|
||||
let fpsCamera = new THREE.PerspectiveCamera( 75,dom.offsetWidth / dom.offsetHeight, 0.1, 1000 );
|
||||
fpsCamera.aspect = dom.offsetWidth / dom.offsetHeight;
|
||||
fpsCamera.rotation.order = 'YXZ';
|
||||
|
||||
let attachBox = new THREE.Mesh(
|
||||
new THREE.BoxGeometry(1, 5, 1),
|
||||
new THREE.MeshBasicMaterial({color: 0xff00000})//RED box
|
||||
);
|
||||
let hitBox = new THREE.Box3(new THREE.Vector3(), new THREE.Vector3());
|
||||
hitBox.setFromObject(attachBox);
|
||||
scene.add(attachBox);
|
||||
|
||||
//fps control
|
||||
const GRAVITY = 30;
|
||||
|
||||
const NUM_SPHERES = 20;
|
||||
const SPHERE_RADIUS = 0.2;
|
||||
|
||||
const sphereGeometry = new THREE.SphereGeometry( SPHERE_RADIUS, 32, 32 );
|
||||
const sphereMaterial = new THREE.MeshStandardMaterial( { color: 0x888855, roughness: 0.8, metalness: 0.5 } );
|
||||
|
||||
const spheres = [];
|
||||
let sphereIdx = 0;
|
||||
|
||||
for ( let i = 0; i < NUM_SPHERES; i ++ ) {
|
||||
|
||||
const sphere = new THREE.Mesh( sphereGeometry, sphereMaterial );
|
||||
|
||||
|
||||
scene.add( sphere );
|
||||
|
||||
spheres.push( { mesh: sphere, collider: new THREE.Sphere( new THREE.Vector3( 0, - 100, 0 ), SPHERE_RADIUS ), velocity: new THREE.Vector3() } );
|
||||
|
||||
}
|
||||
|
||||
scope.controlMode = lessonData.lessonProgress[lessonIndex].controlMode;
|
||||
// scope.controls = oribitControl;
|
||||
if(scope.controlMode == "free"){
|
||||
scope.nowCamera = orbitCamera;
|
||||
scope.controls.enabled = true;
|
||||
}else if(scope.controlMode == "fps"){
|
||||
scope.nowCamera = fpsCamera;
|
||||
scope.controls.enabled = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const worldOctree = new Octree();
|
||||
|
||||
const playerCollider = new Capsule( new THREE.Vector3( 0, 10, 0 ), new THREE.Vector3( 0, 11.9, 0 ), 1 );
|
||||
playerCollider.set(
|
||||
new THREE.Vector3(
|
||||
lessonData.lessonProgress[lessonIndex].cameraPosition.x,
|
||||
lessonData.lessonProgress[lessonIndex].cameraPosition.y,
|
||||
lessonData.lessonProgress[lessonIndex].cameraPosition.z),
|
||||
new THREE.Vector3(
|
||||
lessonData.lessonProgress[lessonIndex].cameraPosition.x,
|
||||
lessonData.lessonProgress[lessonIndex].cameraPosition.y+1.5,
|
||||
lessonData.lessonProgress[lessonIndex].cameraPosition.z ), 1);
|
||||
attachBox.position.x = lessonData.lessonProgress[lessonIndex].cameraPosition.x;
|
||||
attachBox.position.y = lessonData.lessonProgress[lessonIndex].cameraPosition.y ;
|
||||
attachBox.position.z = lessonData.lessonProgress[lessonIndex].cameraPosition.z;
|
||||
|
||||
|
||||
|
||||
|
||||
const playerVelocity = new THREE.Vector3();
|
||||
const playerDirection = new THREE.Vector3();
|
||||
|
||||
let playerOnFloor = false;
|
||||
|
||||
const keyStates = {};
|
||||
let clock = new THREE.Clock();
|
||||
|
||||
this.updateOrbitControl = function(){
|
||||
oribitControl.update();
|
||||
};
|
||||
|
||||
this.updateFpsControl = function(){
|
||||
const deltaTime = Math.min( 0.1, clock.getDelta() );
|
||||
|
||||
controls( deltaTime );
|
||||
|
||||
updatePlayer( deltaTime );
|
||||
|
||||
updateSpheres( deltaTime );
|
||||
|
||||
if(scope.eventHitMode == true){
|
||||
if(eventBoxs.length>0){
|
||||
|
||||
attachBox.position.copy(fpsCamera.position);
|
||||
for(let i=0;i<eventBoxs.length;i++){
|
||||
hitBox.setFromObject(attachBox);
|
||||
eventBoxs[i].setFromObject(eventBoxs[i].mesh);
|
||||
// console.log(eventBoxs[i]);
|
||||
if(hitBox.intersectsBox(eventBoxs[i])){
|
||||
console.log("相交");
|
||||
console.log(eventBoxs[i].action);
|
||||
if(eventBoxs[i].action.actionMode == "jump"){
|
||||
jumpEvent("action",eventBoxs[i].action);
|
||||
}
|
||||
if(eventBoxs[i].action.actionMode == "remove"){
|
||||
actionEvent("remove",eventBoxs[i].action,eventBoxs[i].mesh);
|
||||
}
|
||||
eventBoxs.splice(i,1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
scope.eventHitMod = false;
|
||||
}
|
||||
// attachBox.position.copy(fpsCamera.position);
|
||||
// hitBox.setFromObject(attachBox);
|
||||
// eventTestBox.setFromObject(eventBox);
|
||||
//
|
||||
// if(hitBox.intersectsBox(eventTestBox)){
|
||||
// //两个物体相交了
|
||||
// console.log("相交");
|
||||
// scope.eventHitMode = false;
|
||||
// }
|
||||
// else{
|
||||
// console.log("不相交");
|
||||
// }
|
||||
}
|
||||
|
||||
render();
|
||||
};
|
||||
|
||||
this.initOctree = function(object){
|
||||
worldOctree.fromGraphNode( object.getObjectByName("Object173") );
|
||||
// scope.controlMode = lessonData.lessonProgress[lessonIndex].controlMode;
|
||||
}
|
||||
|
||||
document.addEventListener( 'keydown', ( event ) => {
|
||||
|
||||
keyStates[ event.code ] = true;
|
||||
|
||||
} );
|
||||
|
||||
document.addEventListener( 'keyup', ( event ) => {
|
||||
|
||||
keyStates[ event.code ] = false;
|
||||
|
||||
} );
|
||||
let fpsMouseStatus = false;
|
||||
document.addEventListener( 'mousedown', () => {
|
||||
fpsMouseStatus = true;
|
||||
// document.body.requestPointerLock();
|
||||
} );
|
||||
|
||||
document.body.addEventListener( 'mousemove', ( event ) => {
|
||||
if(fpsMouseStatus == true){
|
||||
fpsCamera.rotation.y -= event.movementX / 500;
|
||||
fpsCamera.rotation.x -= event.movementY / 500;
|
||||
}
|
||||
// if ( document.pointerLockElement === document.body ) {
|
||||
// }
|
||||
} );
|
||||
|
||||
document.addEventListener( 'mouseup', () => {
|
||||
fpsMouseStatus = false;
|
||||
} );
|
||||
|
||||
|
||||
function playerCollitions() {
|
||||
|
||||
const result = worldOctree.capsuleIntersect( playerCollider );
|
||||
|
||||
playerOnFloor = false;
|
||||
|
||||
if ( result ) {
|
||||
|
||||
playerOnFloor = result.normal.y > 0;
|
||||
|
||||
if ( ! playerOnFloor ) {
|
||||
|
||||
playerVelocity.addScaledVector( result.normal, - result.normal.dot( playerVelocity ) );
|
||||
|
||||
}
|
||||
|
||||
playerCollider.translate( result.normal.multiplyScalar( result.depth ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function updatePlayer( deltaTime ) {
|
||||
|
||||
if ( playerOnFloor ) {
|
||||
|
||||
const damping = Math.exp( - 3 * deltaTime ) - 1;
|
||||
playerVelocity.addScaledVector( playerVelocity, damping );
|
||||
|
||||
} else {
|
||||
|
||||
playerVelocity.y -= GRAVITY * deltaTime;
|
||||
|
||||
}
|
||||
|
||||
const deltaPosition = playerVelocity.clone().multiplyScalar( deltaTime );
|
||||
playerCollider.translate( deltaPosition );
|
||||
|
||||
playerCollitions();
|
||||
|
||||
fpsCamera.position.copy( playerCollider.end );
|
||||
|
||||
}
|
||||
|
||||
function spheresCollisions() {
|
||||
|
||||
for ( let i = 0; i < spheres.length; i ++ ) {
|
||||
|
||||
const s1 = spheres[ i ];
|
||||
|
||||
for ( let j = i + 1; j < spheres.length; j ++ ) {
|
||||
|
||||
const s2 = spheres[ j ];
|
||||
|
||||
const d2 = s1.collider.center.distanceToSquared( s2.collider.center );
|
||||
const r = s1.collider.radius + s2.collider.radius;
|
||||
const r2 = r * r;
|
||||
|
||||
if ( d2 < r2 ) {
|
||||
|
||||
const normal = s1.collider.clone().center.sub( s2.collider.center ).normalize();
|
||||
const v1 = normal.clone().multiplyScalar( normal.dot( s1.velocity ) );
|
||||
const v2 = normal.clone().multiplyScalar( normal.dot( s2.velocity ) );
|
||||
s1.velocity.add( v2 ).sub( v1 );
|
||||
s2.velocity.add( v1 ).sub( v2 );
|
||||
|
||||
const d = ( r - Math.sqrt( d2 ) ) / 2;
|
||||
|
||||
s1.collider.center.addScaledVector( normal, d );
|
||||
s2.collider.center.addScaledVector( normal, - d );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function updateSpheres( deltaTime ) {
|
||||
|
||||
spheres.forEach( sphere =>{
|
||||
|
||||
sphere.collider.center.addScaledVector( sphere.velocity, deltaTime );
|
||||
|
||||
const result = worldOctree.sphereIntersect( sphere.collider );
|
||||
|
||||
if ( result ) {
|
||||
|
||||
sphere.velocity.addScaledVector( result.normal, - result.normal.dot( sphere.velocity ) * 1.5 );
|
||||
sphere.collider.center.add( result.normal.multiplyScalar( result.depth ) );
|
||||
|
||||
} else {
|
||||
|
||||
sphere.velocity.y -= GRAVITY * deltaTime;
|
||||
|
||||
}
|
||||
|
||||
const damping = Math.exp( - 1.5 * deltaTime ) - 1;
|
||||
sphere.velocity.addScaledVector( sphere.velocity, damping );
|
||||
|
||||
spheresCollisions();
|
||||
|
||||
sphere.mesh.position.copy( sphere.collider.center );
|
||||
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
function getForwardVector() {
|
||||
|
||||
fpsCamera.getWorldDirection( playerDirection );
|
||||
playerDirection.y = 0;
|
||||
playerDirection.normalize();
|
||||
|
||||
return playerDirection;
|
||||
|
||||
}
|
||||
|
||||
function getSideVector() {
|
||||
|
||||
fpsCamera.getWorldDirection( playerDirection );
|
||||
playerDirection.y = 0;
|
||||
playerDirection.normalize();
|
||||
playerDirection.cross( fpsCamera.up );
|
||||
|
||||
return playerDirection;
|
||||
|
||||
}
|
||||
|
||||
function controls( deltaTime ) {
|
||||
|
||||
const speed = 25;
|
||||
|
||||
if ( playerOnFloor ) {
|
||||
|
||||
if ( keyStates[ 'KeyW' ] ) {
|
||||
|
||||
playerVelocity.add( getForwardVector().multiplyScalar( speed * deltaTime ) );
|
||||
|
||||
}
|
||||
|
||||
if ( keyStates[ 'KeyS' ] ) {
|
||||
|
||||
playerVelocity.add( getForwardVector().multiplyScalar( - speed * deltaTime ) );
|
||||
|
||||
}
|
||||
|
||||
if ( keyStates[ 'KeyA' ] ) {
|
||||
|
||||
playerVelocity.add( getSideVector().multiplyScalar( - speed * deltaTime ) );
|
||||
|
||||
}
|
||||
|
||||
if ( keyStates[ 'KeyD' ] ) {
|
||||
|
||||
playerVelocity.add( getSideVector().multiplyScalar( speed * deltaTime ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function render(){
|
||||
|
||||
if(scope.nowCamera){
|
||||
renderer.render( scene, scope.nowCamera );
|
||||
}
|
||||
}
|
||||
window.onresize = function () {
|
||||
renderer.setSize(dom.offsetWidth,dom.offsetHeight);
|
||||
}
|
||||
|
||||
this.initNewEvent = function(actions,lessonTriggerList){
|
||||
console.log(actions);
|
||||
console.log(lessonTriggerList);
|
||||
eventBoxs = [];
|
||||
for(let i=0;i<actions.length;i++){
|
||||
if(actions[i].actionType == "contact"){
|
||||
for(let j=0;j<lessonTriggerList.length;j++){
|
||||
|
||||
if(lessonTriggerList[j].label == actions[i].actionModel){
|
||||
let eventTestBox = new THREE.Box3(new THREE.Vector3(), new THREE.Vector3());
|
||||
eventTestBox.setFromObject(lessonTriggerList[j]);
|
||||
eventTestBox.mesh = lessonTriggerList[j];
|
||||
eventTestBox.action = actions[i];
|
||||
eventBoxs.push(eventTestBox);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
scope.eventHitMode = true;
|
||||
|
||||
};
|
||||
console.log(lessonData);
|
||||
}
|
138
src/jlmap3d/lesson3d/math/Capsule.js
Normal file
@ -0,0 +1,138 @@
|
||||
var Capsule = ( function () {
|
||||
|
||||
var _v1 = new THREE.Vector3();
|
||||
var _v2 = new THREE.Vector3();
|
||||
var _v3 = new THREE.Vector3();
|
||||
|
||||
var EPS = 1e-10;
|
||||
|
||||
function Capsule( start, end, radius ) {
|
||||
|
||||
this.start = start == undefined ? new THREE.Vector3( 0, 0, 0 ) : start;
|
||||
this.end = end == undefined ? new THREE.Vector3( 0, 1, 0 ) : end;
|
||||
this.radius = radius == undefined ? 1 : radius;
|
||||
|
||||
}
|
||||
|
||||
Object.assign( Capsule.prototype, {
|
||||
|
||||
clone: function () {
|
||||
|
||||
return new Capsule( this.start.clone(), this.end.clone(), this.radius );
|
||||
|
||||
},
|
||||
|
||||
set: function ( start, end, radius ) {
|
||||
|
||||
this.start.copy( start );
|
||||
this.end.copy( end );
|
||||
this.radius = radius;
|
||||
|
||||
},
|
||||
|
||||
copy: function ( capsule ) {
|
||||
|
||||
this.start.copy( capsule.start );
|
||||
this.end.copy( capsule.end );
|
||||
this.radius = capsule.radius;
|
||||
|
||||
},
|
||||
|
||||
getCenter: function ( target ) {
|
||||
|
||||
return target.copy( this.end ).add( this.start ).multiplyScalar( 0.5 );
|
||||
|
||||
},
|
||||
|
||||
translate: function ( v ) {
|
||||
|
||||
this.start.add( v );
|
||||
this.end.add( v );
|
||||
|
||||
},
|
||||
|
||||
checkAABBAxis: function ( p1x, p1y, p2x, p2y, minx, maxx, miny, maxy, radius ) {
|
||||
|
||||
return (
|
||||
( minx - p1x < radius || minx - p2x < radius ) &&
|
||||
( p1x - maxx < radius || p2x - maxx < radius ) &&
|
||||
( miny - p1y < radius || miny - p2y < radius ) &&
|
||||
( p1y - maxy < radius || p2y - maxy < radius )
|
||||
);
|
||||
|
||||
},
|
||||
|
||||
intersectsBox: function ( box ) {
|
||||
|
||||
return (
|
||||
this.checkAABBAxis(
|
||||
this.start.x, this.start.y, this.end.x, this.end.y,
|
||||
box.min.x, box.max.x, box.min.y, box.max.y,
|
||||
this.radius ) &&
|
||||
this.checkAABBAxis(
|
||||
this.start.x, this.start.z, this.end.x, this.end.z,
|
||||
box.min.x, box.max.x, box.min.z, box.max.z,
|
||||
this.radius ) &&
|
||||
this.checkAABBAxis(
|
||||
this.start.y, this.start.z, this.end.y, this.end.z,
|
||||
box.min.y, box.max.y, box.min.z, box.max.z,
|
||||
this.radius )
|
||||
);
|
||||
|
||||
},
|
||||
|
||||
lineLineMinimumPoints: function ( line1, line2 ) {
|
||||
|
||||
var r = _v1.copy( line1.end ).sub( line1.start );
|
||||
var s = _v2.copy( line2.end ).sub( line2.start );
|
||||
var w = _v3.copy( line2.start ).sub( line1.start );
|
||||
|
||||
var a = r.dot( s ),
|
||||
b = r.dot( r ),
|
||||
c = s.dot( s ),
|
||||
d = s.dot( w ),
|
||||
e = r.dot( w );
|
||||
|
||||
var t1, t2, divisor = b * c - a * a;
|
||||
|
||||
if ( Math.abs( divisor ) < EPS ) {
|
||||
|
||||
var d1 = - d / c;
|
||||
var d2 = ( a - d ) / c;
|
||||
|
||||
if ( Math.abs( d1 - 0.5 ) < Math.abs( d2 - 0.5 ) ) {
|
||||
|
||||
t1 = 0;
|
||||
t2 = d1;
|
||||
|
||||
} else {
|
||||
|
||||
t1 = 1;
|
||||
t2 = d2;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
t1 = ( d * a + e * c ) / divisor;
|
||||
t2 = ( t1 * a - d ) / c;
|
||||
|
||||
}
|
||||
|
||||
t2 = Math.max( 0, Math.min( 1, t2 ) );
|
||||
t1 = Math.max( 0, Math.min( 1, t1 ) );
|
||||
|
||||
var point1 = r.multiplyScalar( t1 ).add( line1.start );
|
||||
var point2 = s.multiplyScalar( t2 ).add( line2.start );
|
||||
|
||||
return [ point1, point2 ];
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
return Capsule;
|
||||
|
||||
} )();
|
||||
|
||||
export { Capsule };
|
460
src/jlmap3d/lesson3d/math/Octree.js
Normal file
@ -0,0 +1,460 @@
|
||||
|
||||
import { Capsule } from '@/jlmap3d/lesson3d/math/Capsule.js';
|
||||
var Octree = ( function () {
|
||||
|
||||
var _v1 = new THREE.Vector3();
|
||||
var _v2 = new THREE.Vector3();
|
||||
var _plane = new THREE.Plane();
|
||||
var _line1 = new THREE.Line3();
|
||||
var _line2 = new THREE.Line3();
|
||||
var _sphere = new THREE.Sphere();
|
||||
var _capsule = new Capsule();
|
||||
|
||||
function Octree( box ) {
|
||||
|
||||
this.triangles = [];
|
||||
this.box = box;
|
||||
this.subTrees = [];
|
||||
|
||||
}
|
||||
|
||||
Object.assign( Octree.prototype, {
|
||||
|
||||
addTriangle: function ( triangle ) {
|
||||
|
||||
if ( ! this.bounds ) this.bounds = new THREE.Box3();
|
||||
|
||||
this.bounds.min.x = Math.min( this.bounds.min.x, triangle.a.x, triangle.b.x, triangle.c.x );
|
||||
this.bounds.min.y = Math.min( this.bounds.min.y, triangle.a.y, triangle.b.y, triangle.c.y );
|
||||
this.bounds.min.z = Math.min( this.bounds.min.z, triangle.a.z, triangle.b.z, triangle.c.z );
|
||||
this.bounds.max.x = Math.max( this.bounds.max.x, triangle.a.x, triangle.b.x, triangle.c.x );
|
||||
this.bounds.max.y = Math.max( this.bounds.max.y, triangle.a.y, triangle.b.y, triangle.c.y );
|
||||
this.bounds.max.z = Math.max( this.bounds.max.z, triangle.a.z, triangle.b.z, triangle.c.z );
|
||||
|
||||
this.triangles.push( triangle );
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
calcBox: function () {
|
||||
|
||||
this.box = this.bounds.clone();
|
||||
|
||||
// offset small ammount to account for regular grid
|
||||
this.box.min.x -= 0.01;
|
||||
this.box.min.y -= 0.01;
|
||||
this.box.min.z -= 0.01;
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
split: function ( level ) {
|
||||
|
||||
if ( ! this.box ) return;
|
||||
|
||||
var subTrees = [],
|
||||
halfsize = _v2.copy( this.box.max ).sub( this.box.min ).multiplyScalar( 0.5 ),
|
||||
box, v, triangle;
|
||||
|
||||
for ( var x = 0; x < 2; x ++ ) {
|
||||
|
||||
for ( var y = 0; y < 2; y ++ ) {
|
||||
|
||||
for ( var z = 0; z < 2; z ++ ) {
|
||||
|
||||
box = new THREE.Box3();
|
||||
v = _v1.set( x, y, z );
|
||||
|
||||
box.min.copy( this.box.min ).add( v.multiply( halfsize ) );
|
||||
box.max.copy( box.min ).add( halfsize );
|
||||
|
||||
subTrees.push( new Octree( box ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
while ( triangle = this.triangles.pop() ) {
|
||||
|
||||
for ( var i = 0; i < subTrees.length; i ++ ) {
|
||||
|
||||
if ( subTrees[ i ].box.intersectsTriangle( triangle ) ) {
|
||||
|
||||
subTrees[ i ].triangles.push( triangle );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 0; i < subTrees.length; i ++ ) {
|
||||
|
||||
var len = subTrees[ i ].triangles.length;
|
||||
|
||||
if ( len > 8 && level < 16 ) {
|
||||
|
||||
subTrees[ i ].split( level + 1 );
|
||||
|
||||
}
|
||||
|
||||
if ( len != 0 ) {
|
||||
|
||||
this.subTrees.push( subTrees[ i ] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
build: function () {
|
||||
|
||||
this.calcBox();
|
||||
this.split( 0 );
|
||||
|
||||
return this;
|
||||
|
||||
},
|
||||
|
||||
getRayTriangles: function ( ray, triangles ) {
|
||||
|
||||
for ( var i = 0; i < this.subTrees.length; i ++ ) {
|
||||
|
||||
var subTree = this.subTrees[ i ];
|
||||
if ( ! ray.intersectsBox( subTree.box ) ) continue;
|
||||
|
||||
if ( subTree.triangles.length > 0 ) {
|
||||
|
||||
for ( var j = 0; j < subTree.triangles.length; j ++ ) {
|
||||
|
||||
if ( triangles.indexOf( subTree.triangles[ j ] ) === - 1 ) triangles.push( subTree.triangles[ j ] );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
subTree.getRayTriangles( ray, triangles );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return triangles;
|
||||
|
||||
},
|
||||
|
||||
triangleCapsuleIntersect: function ( capsule, triangle ) {
|
||||
|
||||
var point1, point2, line1, line2;
|
||||
|
||||
triangle.getPlane( _plane );
|
||||
|
||||
var d1 = _plane.distanceToPoint( capsule.start ) - capsule.radius;
|
||||
var d2 = _plane.distanceToPoint( capsule.end ) - capsule.radius;
|
||||
|
||||
if ( ( d1 > 0 && d2 > 0 ) || ( d1 < - capsule.radius && d2 < - capsule.radius ) ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
var delta = Math.abs( d1 / ( Math.abs( d1 ) + Math.abs( d2 ) ) );
|
||||
var intersectPoint = _v1.copy( capsule.start ).lerp( capsule.end, delta );
|
||||
|
||||
if ( triangle.containsPoint( intersectPoint ) ) {
|
||||
|
||||
return { normal: _plane.normal.clone(), point: intersectPoint.clone(), depth: Math.abs( Math.min( d1, d2 ) ) };
|
||||
|
||||
}
|
||||
|
||||
var r2 = capsule.radius * capsule.radius;
|
||||
|
||||
line1 = _line1.set( capsule.start, capsule.end );
|
||||
|
||||
var lines = [
|
||||
[ triangle.a, triangle.b ],
|
||||
[ triangle.b, triangle.c ],
|
||||
[ triangle.c, triangle.a ]
|
||||
];
|
||||
|
||||
for ( var i = 0; i < lines.length; i ++ ) {
|
||||
|
||||
line2 = _line2.set( lines[ i ][ 0 ], lines[ i ][ 1 ] );
|
||||
|
||||
[ point1, point2 ] = capsule.lineLineMinimumPoints( line1, line2 );
|
||||
|
||||
if ( point1.distanceToSquared( point2 ) < r2 ) {
|
||||
|
||||
return { normal: point1.clone().sub( point2 ).normalize(), point: point2.clone(), depth: capsule.radius - point1.distanceTo( point2 ) };
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
},
|
||||
|
||||
triangleSphereIntersect: function ( sphere, triangle ) {
|
||||
|
||||
triangle.getPlane( _plane );
|
||||
|
||||
if ( ! sphere.intersectsPlane( _plane ) ) return false;
|
||||
|
||||
var depth = Math.abs( _plane.distanceToSphere( sphere ) );
|
||||
var r2 = sphere.radius * sphere.radius - depth * depth;
|
||||
|
||||
var plainPoint = _plane.projectPoint( sphere.center, _v1 );
|
||||
|
||||
if ( triangle.containsPoint( sphere.center ) ) {
|
||||
|
||||
return { normal: _plane.normal.clone(), point: plainPoint.clone(), depth: Math.abs( _plane.distanceToSphere( sphere ) ) };
|
||||
|
||||
}
|
||||
|
||||
var lines = [
|
||||
[ triangle.a, triangle.b ],
|
||||
[ triangle.b, triangle.c ],
|
||||
[ triangle.c, triangle.a ]
|
||||
];
|
||||
|
||||
for ( var i = 0; i < lines.length; i ++ ) {
|
||||
|
||||
_line1.set( lines[ i ][ 0 ], lines[ i ][ 1 ] );
|
||||
_line1.closestPointToPoint( plainPoint, true, _v2 );
|
||||
|
||||
var d = _v2.distanceToSquared( sphere.center );
|
||||
|
||||
if ( d < r2 ) {
|
||||
|
||||
return { normal: sphere.center.clone().sub( _v2 ).normalize(), point: _v2.clone(), depth: sphere.radius - Math.sqrt( d ) };
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
},
|
||||
|
||||
getSphereTriangles: function ( sphere, triangles ) {
|
||||
|
||||
for ( var i = 0; i < this.subTrees.length; i ++ ) {
|
||||
|
||||
var subTree = this.subTrees[ i ];
|
||||
|
||||
if ( ! sphere.intersectsBox( subTree.box ) ) continue;
|
||||
|
||||
if ( subTree.triangles.length > 0 ) {
|
||||
|
||||
for ( var j = 0; j < subTree.triangles.length; j ++ ) {
|
||||
|
||||
if ( triangles.indexOf( subTree.triangles[ j ] ) === - 1 ) triangles.push( subTree.triangles[ j ] );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
subTree.getSphereTriangles( sphere, triangles );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
getCapsuleTriangles: function ( capsule, triangles ) {
|
||||
|
||||
for ( var i = 0; i < this.subTrees.length; i ++ ) {
|
||||
|
||||
var subTree = this.subTrees[ i ];
|
||||
|
||||
if ( ! capsule.intersectsBox( subTree.box ) ) continue;
|
||||
|
||||
if ( subTree.triangles.length > 0 ) {
|
||||
|
||||
for ( var j = 0; j < subTree.triangles.length; j ++ ) {
|
||||
|
||||
if ( triangles.indexOf( subTree.triangles[ j ] ) === - 1 ) triangles.push( subTree.triangles[ j ] );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
subTree.getCapsuleTriangles( capsule, triangles );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
sphereIntersect( sphere ) {
|
||||
|
||||
_sphere.copy( sphere );
|
||||
|
||||
var triangles = [], result, hit = false;
|
||||
|
||||
this.getSphereTriangles( sphere, triangles );
|
||||
|
||||
for ( var i = 0; i < triangles.length; i ++ ) {
|
||||
|
||||
if ( result = this.triangleSphereIntersect( _sphere, triangles[ i ] ) ) {
|
||||
|
||||
hit = true;
|
||||
|
||||
_sphere.center.add( result.normal.multiplyScalar( result.depth ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( hit ) {
|
||||
|
||||
var collisionVector = _sphere.center.clone().sub( sphere.center );
|
||||
var depth = collisionVector.length();
|
||||
|
||||
return { normal: collisionVector.normalize(), depth: depth };
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
},
|
||||
|
||||
capsuleIntersect: function ( capsule ) {
|
||||
|
||||
_capsule.copy( capsule );
|
||||
|
||||
var triangles = [], result, hit = false;
|
||||
|
||||
this.getCapsuleTriangles( _capsule, triangles );
|
||||
|
||||
for ( var i = 0; i < triangles.length; i ++ ) {
|
||||
|
||||
if ( result = this.triangleCapsuleIntersect( _capsule, triangles[ i ] ) ) {
|
||||
|
||||
hit = true;
|
||||
|
||||
_capsule.translate( result.normal.multiplyScalar( result.depth ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( hit ) {
|
||||
|
||||
var collisionVector = _capsule.getCenter( new THREE.Vector3() ).sub( capsule.getCenter( _v1 ) );
|
||||
var depth = collisionVector.length();
|
||||
|
||||
return { normal: collisionVector.normalize(), depth: depth };
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
},
|
||||
|
||||
rayIntersect: function ( ray ) {
|
||||
|
||||
if ( ray.direction.length() === 0 ) return;
|
||||
|
||||
var triangles = [], triangle, position,
|
||||
distance = 1e100,
|
||||
result;
|
||||
|
||||
this.getRayTriangles( ray, triangles );
|
||||
|
||||
for ( var i = 0; i < triangles.length; i ++ ) {
|
||||
|
||||
result = ray.intersectTriangle( triangles[ i ].a, triangles[ i ].b, triangles[ i ].c, true, _v1 );
|
||||
|
||||
if ( result ) {
|
||||
|
||||
var newdistance = result.sub( ray.origin ).length();
|
||||
|
||||
if ( distance > newdistance ) {
|
||||
|
||||
position = result.clone().add( ray.origin );
|
||||
distance = newdistance;
|
||||
triangle = triangles[ i ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return distance < 1e100 ? { distance: distance, triangle: triangle, position: position } : false;
|
||||
|
||||
},
|
||||
|
||||
fromGraphNode: function ( group ) {
|
||||
|
||||
group.traverse( ( obj ) => {
|
||||
|
||||
if ( obj.type === 'Mesh' ) {
|
||||
|
||||
obj.updateMatrix();
|
||||
obj.updateWorldMatrix();
|
||||
|
||||
var geometry, isTemp = false;
|
||||
|
||||
if ( obj.geometry.index ) {
|
||||
|
||||
isTemp = true;
|
||||
geometry = obj.geometry.clone().toNonIndexed();
|
||||
|
||||
} else {
|
||||
|
||||
geometry = obj.geometry;
|
||||
|
||||
}
|
||||
|
||||
var positions = geometry.attributes.position.array;
|
||||
var transform = obj.matrixWorld;
|
||||
|
||||
for ( var i = 0; i < positions.length; i += 9 ) {
|
||||
|
||||
var v1 = new THREE.Vector3( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
|
||||
var v2 = new THREE.Vector3( positions[ i + 3 ], positions[ i + 4 ], positions[ i + 5 ] );
|
||||
var v3 = new THREE.Vector3( positions[ i + 6 ], positions[ i + 7 ], positions[ i + 8 ] );
|
||||
|
||||
v1.applyMatrix4( transform );
|
||||
v2.applyMatrix4( transform );
|
||||
v3.applyMatrix4( transform );
|
||||
|
||||
this.addTriangle( new THREE.Triangle( v1, v2, v3 ) );
|
||||
|
||||
}
|
||||
|
||||
if ( isTemp ) {
|
||||
|
||||
geometry.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
this.build();
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
return Octree;
|
||||
|
||||
} )();
|
||||
|
||||
export { Octree };
|
177
src/jlmap3d/lesson3d/model/lessondata.js
Normal file
@ -0,0 +1,177 @@
|
||||
|
||||
export function LessonData() {
|
||||
let scope = this;
|
||||
|
||||
this.lessonId = "";
|
||||
this.lessonName = "";
|
||||
this.lessonType = "";
|
||||
this.lessonStatus = "";
|
||||
this.lessonData = {
|
||||
//资源列表
|
||||
assetList:[],
|
||||
//场景交互物体列表
|
||||
modelList:[],
|
||||
//课程组件启用状态
|
||||
lessonTools:[],
|
||||
dataType:"",
|
||||
toolJobPane:[],
|
||||
//课程内容
|
||||
lessonProgress:[
|
||||
|
||||
]
|
||||
};
|
||||
|
||||
this.initLessonProgress = function(){
|
||||
let newLessonProgress = {
|
||||
id:generateUUID(),
|
||||
progressName:"命名",
|
||||
roleName:"",
|
||||
roleUse:true,
|
||||
|
||||
progressScene:"",
|
||||
nextCode:"",
|
||||
nextNode:"",
|
||||
triggerType:"",
|
||||
triggerMode:"",
|
||||
triggerTime:"",
|
||||
triggerModel:"",
|
||||
controlMode:"",
|
||||
cameraMode:"",
|
||||
changeCamera:false,
|
||||
cameraPosition:{
|
||||
x:0,
|
||||
y:0,
|
||||
z:0
|
||||
},
|
||||
cameraTarget:{
|
||||
x:0,
|
||||
y:0,
|
||||
z:0
|
||||
},
|
||||
assetId:scope.lessonData.lessonProgress.length,
|
||||
assetPos:"",
|
||||
assetRot:"",
|
||||
assetType:"",
|
||||
index:"",
|
||||
stepTipsData:{
|
||||
tittle:"标题",
|
||||
text:"内容",
|
||||
},
|
||||
explainPane:{
|
||||
tittle:"标题",
|
||||
picurl:"url",
|
||||
text:"内容",
|
||||
},
|
||||
action:[],
|
||||
};
|
||||
|
||||
scope.lessonData.lessonProgress.push(newLessonProgress);
|
||||
|
||||
}
|
||||
|
||||
this.loadLessonProgress = function(loadData){
|
||||
console.log(loadData);
|
||||
for(let i=0;i<loadData.length;i++){
|
||||
let newLessonProgress = {
|
||||
id:loadData[i].id,
|
||||
progressName:loadData[i].progressName,
|
||||
roleName:loadData[i].roleName,
|
||||
roleUse:loadData[i].roleUse,
|
||||
score:loadData[i].roleUse,
|
||||
progressScene:loadData[i].progressScene,
|
||||
nextCode:loadData[i].nextCode,
|
||||
nextNode:loadData[i].nextNode,
|
||||
triggerType:loadData[i].triggerType,
|
||||
triggerMode:loadData[i].triggerMode,
|
||||
triggerTime:loadData[i].triggerTime,
|
||||
triggerModel:loadData[i].triggerModel,
|
||||
controlMode:loadData[i].controlMode,
|
||||
cameraMode:loadData[i].cameraMode,
|
||||
changeCamera:loadData[i].changeCamera,
|
||||
cameraPosition:loadData[i].cameraPosition,
|
||||
cameraTarget:loadData[i].cameraTarget,
|
||||
assetId:loadData[i].assetId,
|
||||
assetPos:loadData[i].assetPos,
|
||||
assetRot:loadData[i].assetRot,
|
||||
assetType:loadData[i].assetType,
|
||||
index:loadData[i].index,
|
||||
stepTipsData:loadData[i].stepTipsData,
|
||||
explainPane:loadData[i].explainPane,
|
||||
action:loadData[i].action,
|
||||
jobPane:[],
|
||||
};
|
||||
|
||||
scope.lessonData.lessonProgress.push(newLessonProgress);
|
||||
}
|
||||
}
|
||||
|
||||
this.addLessonProgress = function(index){
|
||||
let inheirIndex = index - 1;
|
||||
let newLessonProgress = {
|
||||
id:generateUUID(),
|
||||
progressName:"命名",
|
||||
roleName:scope.lessonData.lessonProgress[inheirIndex].roleName,
|
||||
roleUse:scope.lessonData.lessonProgress[inheirIndex].roleUse,
|
||||
score:0,
|
||||
progressScene:scope.lessonData.lessonProgress[inheirIndex].progressScene,
|
||||
nextCode:"",
|
||||
nextNode:"",
|
||||
triggerType:"",
|
||||
triggerMode:"",
|
||||
triggerTime:"",
|
||||
triggerModel:"",
|
||||
controlMode:scope.lessonData.lessonProgress[inheirIndex].controlMode,
|
||||
cameraMode:scope.lessonData.lessonProgress[inheirIndex].cameraMode,
|
||||
changeCamera:scope.lessonData.lessonProgress[inheirIndex].changeCamera,
|
||||
cameraPosition:scope.lessonData.lessonProgress[inheirIndex].cameraPosition,
|
||||
cameraTarget:scope.lessonData.lessonProgress[inheirIndex].cameraTarget,
|
||||
assetId:scope.lessonData.lessonProgress.length,
|
||||
assetPos:"",
|
||||
assetRot:"",
|
||||
assetType:"",
|
||||
index:"",
|
||||
triger:[
|
||||
|
||||
],
|
||||
stepTipsData:{
|
||||
tittle:"标题",
|
||||
text:"内容",
|
||||
},
|
||||
explainPane:{
|
||||
tittle:"标题",
|
||||
picurl:"url",
|
||||
text:"内容",
|
||||
},
|
||||
action:[
|
||||
|
||||
],
|
||||
jobPane:[],
|
||||
};
|
||||
|
||||
scope.lessonData.lessonProgress.push(newLessonProgress);
|
||||
|
||||
}
|
||||
|
||||
this.changeLessonProgress = function(){
|
||||
|
||||
}
|
||||
|
||||
this.removeLessonProgress = function(index){
|
||||
scope.lessonData.lessonProgress.splice(index,1);
|
||||
}
|
||||
|
||||
function generateUUID() {
|
||||
var d = new Date().getTime();
|
||||
if (window.performance && typeof window.performance.now === "function") {
|
||||
d += performance.now(); //use high-precision timer if available
|
||||
}
|
||||
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
var r = (d + Math.random() * 16) % 16 | 0;
|
||||
d = Math.floor(d / 16);
|
||||
return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
|
||||
});
|
||||
return uuid;
|
||||
}
|
||||
|
||||
|
||||
}
|
307
src/jlmap3d/lesson3d/toolsmodel/jobpanedata.js
Normal file
@ -0,0 +1,307 @@
|
||||
|
||||
export function JobPaneData() {
|
||||
let scope = this;
|
||||
|
||||
// let
|
||||
this.dataList = [
|
||||
{
|
||||
name:"值班站长",
|
||||
value:"zbzz",
|
||||
text:"执行分公司、部、中心、车站的有关规章制度,加强班组管理,掌握列车运行情况,安排车站行车组织工作",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
//联控
|
||||
{
|
||||
name:"联控",
|
||||
data:[],
|
||||
},
|
||||
//动作
|
||||
{
|
||||
name:"动作",
|
||||
data:[],
|
||||
},
|
||||
//口呼
|
||||
{
|
||||
name:"口呼",
|
||||
data:[],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name:"行车值班员",
|
||||
value:"xczby",
|
||||
text:"在本班组值班站长的指挥下开展工作,负责本班组车站综合控制室,负责车站行车工作,监视列车到、发情况及乘客上下车、候车动态,监控设备运作状况。",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
//联控
|
||||
{
|
||||
name:"联控",
|
||||
data:[],
|
||||
},
|
||||
//动作
|
||||
{
|
||||
name:"动作",
|
||||
data:[],
|
||||
},
|
||||
//口呼
|
||||
{
|
||||
name:"口呼",
|
||||
data:[],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name:"客运值班员",
|
||||
value:"kyzby",
|
||||
text:"在值班站长的领导下,主管车站客运、票务管理,组织站务员从事客运服务工作",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
//联控
|
||||
{
|
||||
name:"联控",
|
||||
data:[],
|
||||
},
|
||||
//动作
|
||||
{
|
||||
name:"动作",
|
||||
data:[],
|
||||
},
|
||||
//口呼
|
||||
{
|
||||
name:"口呼",
|
||||
data:[],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name:"票厅员",
|
||||
value:"spy",
|
||||
text:"执行分公司、部、中心、车站的有关规章制度,在客运值班员领导下,负责车站售票工作。",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
//联控
|
||||
{
|
||||
name:"联控",
|
||||
data:[],
|
||||
},
|
||||
//动作
|
||||
{
|
||||
name:"动作",
|
||||
data:[],
|
||||
},
|
||||
//口呼
|
||||
{
|
||||
name:"口呼",
|
||||
data:[],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name:"站台岗",
|
||||
value:"ztg",
|
||||
text:"",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
//联控
|
||||
{
|
||||
name:"联控",
|
||||
data:[],
|
||||
},
|
||||
//动作
|
||||
{
|
||||
name:"动作",
|
||||
data:[],
|
||||
},
|
||||
//口呼
|
||||
{
|
||||
name:"口呼",
|
||||
data:[],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name:"站长",
|
||||
value:"zz",
|
||||
text:"在站务中心(副)主任领导下,组织领导站内员工开展车站各项工作。负责车站员工的日常管理,定期进行员工教育,掌握员工思想状况。",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
//联控
|
||||
{
|
||||
name:"联控",
|
||||
data:[],
|
||||
},
|
||||
//动作
|
||||
{
|
||||
name:"动作",
|
||||
data:[],
|
||||
},
|
||||
//口呼
|
||||
{
|
||||
name:"口呼",
|
||||
data:[],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name:"分部助理",
|
||||
value:"fbzl",
|
||||
text:"",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
//联控
|
||||
{
|
||||
name:"联控",
|
||||
data:[],
|
||||
},
|
||||
//动作
|
||||
{
|
||||
name:"动作",
|
||||
data:[],
|
||||
},
|
||||
//口呼
|
||||
{
|
||||
name:"口呼",
|
||||
data:[],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name:"行车调度",
|
||||
value:"xcdd",
|
||||
text:"",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
//联控
|
||||
{
|
||||
name:"联控",
|
||||
data:[],
|
||||
},
|
||||
//动作
|
||||
{
|
||||
name:"动作",
|
||||
data:[],
|
||||
},
|
||||
//口呼
|
||||
{
|
||||
name:"口呼",
|
||||
data:[],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name:"生产调度",
|
||||
value:"scdd",
|
||||
text:"",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
//联控
|
||||
{
|
||||
name:"联控",
|
||||
data:[],
|
||||
},
|
||||
//动作
|
||||
{
|
||||
name:"动作",
|
||||
data:[],
|
||||
},
|
||||
//口呼
|
||||
{
|
||||
name:"口呼",
|
||||
data:[],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name:"平台岗",
|
||||
value:"ptg",
|
||||
text:"负责站厅乘客服务,设备的巡视、紧急情况下事件的处理等。",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
//联控
|
||||
{
|
||||
name:"联控",
|
||||
data:[],
|
||||
},
|
||||
//动作
|
||||
{
|
||||
name:"动作",
|
||||
data:[],
|
||||
},
|
||||
//口呼
|
||||
{
|
||||
name:"口呼",
|
||||
data:[],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name:"地铁公安",
|
||||
value:"110",
|
||||
text:"",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
//联控
|
||||
{
|
||||
name:"联控",
|
||||
data:[],
|
||||
},
|
||||
//动作
|
||||
{
|
||||
name:"动作",
|
||||
data:[],
|
||||
},
|
||||
//口呼
|
||||
{
|
||||
name:"口呼",
|
||||
data:[],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name:"120",
|
||||
value:"120",
|
||||
text:"",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
//联控
|
||||
{
|
||||
name:"联控",
|
||||
data:[],
|
||||
},
|
||||
//动作
|
||||
{
|
||||
name:"动作",
|
||||
data:[],
|
||||
},
|
||||
//口呼
|
||||
{
|
||||
name:"口呼",
|
||||
data:[],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name:"119",
|
||||
value:"119",
|
||||
text:"",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
//联控
|
||||
{
|
||||
name:"联控",
|
||||
data:[],
|
||||
},
|
||||
//动作
|
||||
{
|
||||
name:"动作",
|
||||
data:[],
|
||||
},
|
||||
//口呼
|
||||
{
|
||||
name:"口呼",
|
||||
data:[],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
}
|
32
src/jlmap3d/lesson3d/toolsmodel/lessontrigger.js
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
export function LessonTrigger() {
|
||||
|
||||
let scope = this;
|
||||
|
||||
this.dataList = [
|
||||
|
||||
];
|
||||
// let
|
||||
this.triggerList = [
|
||||
{
|
||||
name:"移动触发器",
|
||||
type:"movetrigger",
|
||||
picurl:"",
|
||||
},
|
||||
{
|
||||
name:"置物触发器",
|
||||
type:"placetrigger",
|
||||
picurl:"",
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
this.createTrigger = function(type){
|
||||
|
||||
|
||||
}
|
||||
|
||||
this.deleteTrigger = function(selected){
|
||||
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@ export function LessonData() {
|
||||
this.initLessonProgress = function(){
|
||||
let newLessonProgress = {
|
||||
id:generateUUID(),
|
||||
progressName:"",
|
||||
progressName:"命名",
|
||||
roleName:"",
|
||||
roleUse:true,
|
||||
|
||||
@ -37,8 +37,17 @@ export function LessonData() {
|
||||
triggerModel:"",
|
||||
controlMode:"",
|
||||
cameraMode:"",
|
||||
cameraPosition:"",
|
||||
cameraTarget:"",
|
||||
changeCamera:false,
|
||||
cameraPosition:{
|
||||
x:0,
|
||||
y:0,
|
||||
z:0
|
||||
},
|
||||
cameraTarget:{
|
||||
x:0,
|
||||
y:0,
|
||||
z:0
|
||||
},
|
||||
assetId:scope.lessonData.lessonProgress.length,
|
||||
assetPos:"",
|
||||
assetRot:"",
|
||||
@ -78,6 +87,7 @@ export function LessonData() {
|
||||
triggerModel:loadData[i].triggerModel,
|
||||
controlMode:loadData[i].controlMode,
|
||||
cameraMode:loadData[i].cameraMode,
|
||||
changeCamera:loadData[i].changeCamera,
|
||||
cameraPosition:loadData[i].cameraPosition,
|
||||
cameraTarget:loadData[i].cameraTarget,
|
||||
assetId:loadData[i].assetId,
|
||||
@ -99,7 +109,7 @@ export function LessonData() {
|
||||
let inheirIndex = index - 1;
|
||||
let newLessonProgress = {
|
||||
id:generateUUID(),
|
||||
progressName:"",
|
||||
progressName:"命名",
|
||||
roleName:scope.lessonData.lessonProgress[inheirIndex].roleName,
|
||||
roleUse:scope.lessonData.lessonProgress[inheirIndex].roleUse,
|
||||
score:0,
|
||||
@ -112,6 +122,7 @@ export function LessonData() {
|
||||
triggerModel:"",
|
||||
controlMode:scope.lessonData.lessonProgress[inheirIndex].controlMode,
|
||||
cameraMode:scope.lessonData.lessonProgress[inheirIndex].cameraMode,
|
||||
changeCamera:scope.lessonData.lessonProgress[inheirIndex].changeCamera,
|
||||
cameraPosition:scope.lessonData.lessonProgress[inheirIndex].cameraPosition,
|
||||
cameraTarget:scope.lessonData.lessonProgress[inheirIndex].cameraTarget,
|
||||
assetId:scope.lessonData.lessonProgress.length,
|
||||
|
@ -6,6 +6,7 @@ export function JobPaneData() {
|
||||
this.dataList = [
|
||||
{
|
||||
name:"值班站长",
|
||||
value:"zbzz",
|
||||
text:"执行分公司、部、中心、车站的有关规章制度,加强班组管理,掌握列车运行情况,安排车站行车组织工作",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
@ -28,6 +29,7 @@ export function JobPaneData() {
|
||||
},
|
||||
{
|
||||
name:"行车值班员",
|
||||
value:"xczby",
|
||||
text:"在本班组值班站长的指挥下开展工作,负责本班组车站综合控制室,负责车站行车工作,监视列车到、发情况及乘客上下车、候车动态,监控设备运作状况。",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
@ -50,6 +52,7 @@ export function JobPaneData() {
|
||||
},
|
||||
{
|
||||
name:"客运值班员",
|
||||
value:"kyzby",
|
||||
text:"在值班站长的领导下,主管车站客运、票务管理,组织站务员从事客运服务工作",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
@ -71,7 +74,8 @@ export function JobPaneData() {
|
||||
],
|
||||
},
|
||||
{
|
||||
name:"票厅岗",
|
||||
name:"票厅员",
|
||||
value:"spy",
|
||||
text:"执行分公司、部、中心、车站的有关规章制度,在客运值班员领导下,负责车站售票工作。",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
@ -94,6 +98,7 @@ export function JobPaneData() {
|
||||
},
|
||||
{
|
||||
name:"站台岗",
|
||||
value:"ztg",
|
||||
text:"",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
@ -116,6 +121,7 @@ export function JobPaneData() {
|
||||
},
|
||||
{
|
||||
name:"站长",
|
||||
value:"zz",
|
||||
text:"在站务中心(副)主任领导下,组织领导站内员工开展车站各项工作。负责车站员工的日常管理,定期进行员工教育,掌握员工思想状况。",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
@ -138,6 +144,7 @@ export function JobPaneData() {
|
||||
},
|
||||
{
|
||||
name:"分部助理",
|
||||
value:"fbzl",
|
||||
text:"",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
@ -160,6 +167,7 @@ export function JobPaneData() {
|
||||
},
|
||||
{
|
||||
name:"行车调度",
|
||||
value:"xcdd",
|
||||
text:"",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
@ -182,6 +190,7 @@ export function JobPaneData() {
|
||||
},
|
||||
{
|
||||
name:"生产调度",
|
||||
value:"scdd",
|
||||
text:"",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
@ -203,7 +212,8 @@ export function JobPaneData() {
|
||||
],
|
||||
},
|
||||
{
|
||||
name:"厅巡岗",
|
||||
name:"平台岗",
|
||||
value:"ptg",
|
||||
text:"负责站厅乘客服务,设备的巡视、紧急情况下事件的处理等。",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
@ -226,6 +236,7 @@ export function JobPaneData() {
|
||||
},
|
||||
{
|
||||
name:"地铁公安",
|
||||
value:"110",
|
||||
text:"",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
@ -248,6 +259,7 @@ export function JobPaneData() {
|
||||
},
|
||||
{
|
||||
name:"120",
|
||||
value:"120",
|
||||
text:"",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
@ -270,6 +282,7 @@ export function JobPaneData() {
|
||||
},
|
||||
{
|
||||
name:"119",
|
||||
value:"119",
|
||||
text:"",
|
||||
picurl:"",
|
||||
controlList:[
|
||||
|
@ -6,11 +6,13 @@
|
||||
<el-tab-pane label="课程场景" name="progresslist" >
|
||||
<draggable v-model="lessonData.lessonData.lessonProgress" group="people" @start="drag=true" @end="drag=false" >
|
||||
<div class="progressdiv" v-for="(element,index) in lessonData.lessonData.lessonProgress">
|
||||
<div class="changeprogressdiv" @click="changeProgressView(index)">{{element.assetId}}</div>
|
||||
<div class="changeprogressdiv" @click="changeProgressView(index)">{{element.progressName}}</div>
|
||||
<div class="delprogressdiv" @click="removeProgress(index)" >X</div>
|
||||
</div>
|
||||
</draggable>
|
||||
<div class="progressdiv " icon="el-icon-folder-add" @click="addProgress"></div>
|
||||
<div class="progressdiv "
|
||||
:style="{'background-image': 'url('+localstatic+'/lesson3d/addbutton.png)'}"
|
||||
icon="el-icon-folder-add" @click="addProgress"></div>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="课程三维资源列表" name="assetlist" >
|
||||
@ -33,6 +35,7 @@
|
||||
import localStore from 'storejs';
|
||||
|
||||
import draggable from 'vuedraggable';
|
||||
import { JL3D_LOCAL_STATIC } from '@/api/jlmap3d/assets3d.js';
|
||||
|
||||
export default {
|
||||
name: 'LessonProgress',
|
||||
@ -42,6 +45,7 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
localstatic:JL3D_LOCAL_STATIC,
|
||||
activeName: 'progresslist',
|
||||
progressList:[
|
||||
|
||||
@ -89,7 +93,7 @@
|
||||
deleteModel(selectedModel){
|
||||
this.$emit('deleteModel',selectedModel);
|
||||
},
|
||||
|
||||
|
||||
|
||||
},
|
||||
|
||||
@ -122,6 +126,7 @@
|
||||
margin: 20px;
|
||||
float:left;
|
||||
border:solid 2px #000;
|
||||
background-size: 100%;
|
||||
}
|
||||
|
||||
.changeprogressdiv{
|
||||
|
@ -4,53 +4,83 @@
|
||||
<el-tabs v-model="activeName" class="activediv" type="card" @tab-click="handleClick">
|
||||
<el-tab-pane label="当前场景信息" name="cameraproperty">
|
||||
<el-form ref="form" class="camerapropertydiv" size="mini" v-if="selectLesson3dControl">
|
||||
|
||||
<el-form-item label="场景名称:" v-if="lessonData.lessonData.lessonProgress[lessonEditIndex].progressName" disabled="true">
|
||||
<el-input v-model="lessonData.lessonData.lessonProgress[lessonEditIndex].progressName" ></el-input>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
|
||||
<el-form-item label="三维场景设置:">
|
||||
<el-select v-model="lessonData.lessonData.lessonProgress[lessonEditIndex].progressScene" placeholder="请选择场景">
|
||||
<el-option label="车站" value="standstation"></el-option>
|
||||
<el-option label="停车场" value="stopstation"></el-option>
|
||||
<el-option label="单体设备" value="device"></el-option>
|
||||
<el-option label="线路" value="xl"></el-option>
|
||||
<el-option label="道岔" value="dc"></el-option>
|
||||
<el-option v-for="sceneItem in sceneDataList" :label="sceneItem.label" :value="sceneItem.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="课程角色:">
|
||||
<el-switch
|
||||
v-model="lessonData.lessonData.lessonProgress[lessonEditIndex].roleUse"
|
||||
active-text="启用角色"
|
||||
inactive-text="禁用角色">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="场景角色设置:">
|
||||
|
||||
<el-select v-model="lessonData.lessonData.lessonProgress[lessonEditIndex].roleName" :disabled="!lessonData.lessonData.lessonProgress[lessonEditIndex].roleUse" placeholder="请选择步骤归属角色">
|
||||
<el-option v-for="jobItem in jobDataList" :label="jobItem.name" :value="jobItem.value"></el-option>
|
||||
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="课程场景相机设置:">
|
||||
<el-switch
|
||||
v-model="lessonData.lessonData.lessonProgress[lessonEditIndex].changeCamera"
|
||||
active-text="场景改变视角"
|
||||
inactive-text="禁用改变视角">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
|
||||
<el-switch
|
||||
v-model="lessonData.lessonData.lessonProgress[lessonEditIndex].roleUse"
|
||||
active-text="启用角色"
|
||||
inactive-text="禁用角色">
|
||||
</el-switch>
|
||||
|
||||
<el-select v-model="lessonData.lessonData.lessonProgress[lessonEditIndex].roleName" :disabled="!lessonData.lessonData.lessonProgress[lessonEditIndex].roleUse" placeholder="请选择步骤归属角色">
|
||||
<el-option label="车站" value="standstation"></el-option>
|
||||
<el-option label="停车场" value="stopstation"></el-option>
|
||||
<el-option label="单体设备" value="device"></el-option>
|
||||
<el-option label="线路" value="xl"></el-option>
|
||||
<el-option label="道岔" value="dc"></el-option>
|
||||
</el-select>
|
||||
|
||||
<el-form-item label="相机坐标:" v-if="selectLesson3dControl.object.position" disabled="true">
|
||||
|
||||
<el-input v-model="selectLesson3dControl.object.position.x" ></el-input>
|
||||
<el-input v-model="selectLesson3dControl.object.position.y" ></el-input>
|
||||
<el-input v-model="selectLesson3dControl.object.position.z" ></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="相机角度:" v-if="selectLesson3dControl.target" disabled="true">
|
||||
|
||||
<el-input v-model="selectLesson3dControl.target.x" ></el-input>
|
||||
<el-input v-model="selectLesson3dControl.target.y" ></el-input>
|
||||
<el-input v-model="selectLesson3dControl.target.z" ></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-select v-model="value" placeholder="当前场景镜头控制模式">
|
||||
<el-option
|
||||
v-for="item in cameraMode"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-form-item label="该场景中用户操作模式:">
|
||||
<el-select v-model="lessonData.lessonData.lessonProgress[lessonEditIndex].controlMode" placeholder="当前场景镜头控制模式">
|
||||
<el-option
|
||||
v-for="item in cameraMode"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-button v-if="selectLesson3dControl" @click="resetCamera">重置镜头位置</el-button>
|
||||
<el-button v-if="selectLesson3dControl" @click="recordCamera">记录初始镜头位置</el-button>
|
||||
<el-button v-if="selectLesson3dControl" @click="recordCamera">记录初始镜头位置</el-button>
|
||||
<el-form-item label="保存的相机坐标:" v-if="lessonData.lessonData.lessonProgress[lessonEditIndex].cameraPosition" disabled="true">
|
||||
<el-input v-model="lessonData.lessonData.lessonProgress[lessonEditIndex].cameraPosition.x" ></el-input>
|
||||
<el-input v-model="lessonData.lessonData.lessonProgress[lessonEditIndex].cameraPosition.y" ></el-input>
|
||||
<el-input v-model="lessonData.lessonData.lessonProgress[lessonEditIndex].cameraPosition.z" ></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="保存的相机角度:" v-if="lessonData.lessonData.lessonProgress[lessonEditIndex].cameraTarget" disabled="true">
|
||||
<el-input v-model="lessonData.lessonData.lessonProgress[lessonEditIndex].cameraTarget.x" ></el-input>
|
||||
<el-input v-model="lessonData.lessonData.lessonProgress[lessonEditIndex].cameraTarget.y" ></el-input>
|
||||
<el-input v-model="lessonData.lessonData.lessonProgress[lessonEditIndex].cameraTarget.z" ></el-input>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
|
||||
@ -59,7 +89,9 @@
|
||||
<div class="addmodeleventdiv"
|
||||
v-for="(actionitem,actionindex) in lessonData.lessonData.lessonProgress[lessonEditIndex].action"
|
||||
@click="selsectAction(actionitem)">{{actionitem.actionName}}</div>
|
||||
<div class="addmodeleventdiv" @click="addaction()">添加</div>
|
||||
<div class="addmodeleventdiv"
|
||||
:style="{'background-image': 'url('+localstatic+'/lesson3d/addbutton.png)'}"
|
||||
@click="addaction()"></div>
|
||||
</div>
|
||||
<el-form>
|
||||
|
||||
@ -69,12 +101,12 @@
|
||||
|
||||
<el-form-item label="操作的模型:" >
|
||||
<el-select v-model="selectedAction.actionModel" placeholder="选择操作的模型">
|
||||
<el-option
|
||||
v-for="(item,index) in triggerList"
|
||||
:label="item.label"
|
||||
:value="item.label">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-option
|
||||
v-for="(item,index) in triggerList"
|
||||
:label="item.label"
|
||||
:value="item.label">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="事件类型:" >
|
||||
@ -82,7 +114,7 @@
|
||||
<el-option label="接触" value="contact"></el-option>
|
||||
<el-option label="自动" value="auto"></el-option>
|
||||
<el-option label="开关" value="switch"></el-option>
|
||||
<el-option label="跳转" value="jump"></el-option>
|
||||
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
@ -91,6 +123,7 @@
|
||||
<el-option label="播放动画" value="play"></el-option>
|
||||
<el-option label="显示模型" value="show"></el-option>
|
||||
<el-option label="隐藏模型" value="remove"></el-option>
|
||||
<el-option label="跳转" value="jump"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
@ -98,17 +131,19 @@
|
||||
|
||||
|
||||
|
||||
<el-form-item label="跳转节点:" v-if="selectedAction.actionType == 'jump'">
|
||||
<el-form-item label="跳转节点:" v-if="selectedAction.actionMode == 'jump'">
|
||||
<el-select v-model="selectedAction.jumpNode" placeholder="当前场景镜头控制模式">
|
||||
<el-option
|
||||
v-for="(item,index) in lessonData.lessonData.lessonProgress"
|
||||
:key="index"
|
||||
:label="index"
|
||||
:label="item.progressName+'/'+index"
|
||||
:value="index">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-button @click="deleteEventItem(selectedAction)" v-if="selectedAction">删除事件</el-button>
|
||||
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
|
||||
@ -118,6 +153,12 @@
|
||||
<el-input v-model="selected.tittle" ></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="发起联控角色:" v-if="selected.explainRole" >
|
||||
<el-select v-model="selected.explainRole" placeholder="请选择步骤归属角色">
|
||||
<el-option v-for="jobItem in jobDataList" :label="jobItem.name" :value="jobItem.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="内容:" v-if="selected.text">
|
||||
<el-input v-model="selected.text" ></el-input>
|
||||
</el-form-item>
|
||||
@ -131,19 +172,21 @@
|
||||
<el-option
|
||||
v-for="(item,index) in lessonData.lessonData.lessonProgress"
|
||||
:key="index"
|
||||
:label="index"
|
||||
:label="item.progressName+'/'+index"
|
||||
:value="index">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
|
||||
<el-form-item label="触发的场景:" v-if="selected.sceneIndex ||selected.sceneIndex == 0">
|
||||
<el-input v-model="selected.sceneIndex" ></el-input>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
|
||||
<el-button @click="updateData">保存修改</el-button>
|
||||
<el-button @click="deleteJobItem(selected)" v-if="selected.explainRole">删除联控信息</el-button>
|
||||
<!-- <el-button @click="updateData">保存修改</el-button> -->
|
||||
</el-form>
|
||||
|
||||
<el-form ref="form" class="camerapropertydiv" label-width="130px" size="mini" v-if="selectType == 'modelproperty'">
|
||||
@ -156,6 +199,7 @@
|
||||
<el-option label="隐藏" :value=false></el-option>
|
||||
</el-select>
|
||||
|
||||
|
||||
<el-form-item label="模型坐标:" v-if="selected.position" disabled="true">
|
||||
<el-input v-model="selected.position.x" ></el-input>
|
||||
<el-input v-model="selected.position.y" ></el-input>
|
||||
@ -184,6 +228,8 @@
|
||||
import Vue from 'vue';
|
||||
import localStore from 'storejs';
|
||||
|
||||
import { JobPaneData } from '@/jlmap3d/lesson3dedit/toolsmodel/jobpanedata.js';
|
||||
import { JL3D_LOCAL_STATIC } from '@/api/jlmap3d/assets3d.js';
|
||||
|
||||
export default {
|
||||
name: 'ProPerty',
|
||||
@ -193,6 +239,7 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
localstatic:JL3D_LOCAL_STATIC,
|
||||
activeName: 'cameraproperty',
|
||||
selectLesson3dControl:"",
|
||||
selected:"",
|
||||
@ -204,6 +251,7 @@
|
||||
actionType:"事件操作类型",
|
||||
actionMode:"触发事件类型",
|
||||
},
|
||||
revisionList:[],
|
||||
selectType:"",
|
||||
cameraMode:[
|
||||
{
|
||||
@ -217,6 +265,29 @@
|
||||
label: '自由视角控制'
|
||||
}
|
||||
],
|
||||
sceneDataList:[
|
||||
{
|
||||
label:"车站",
|
||||
value:"standstation",
|
||||
},
|
||||
{
|
||||
label:"停车场",
|
||||
value:"stopstation",
|
||||
},
|
||||
{
|
||||
label:"单体设备",
|
||||
value:"device",
|
||||
},
|
||||
{
|
||||
label:"线路",
|
||||
value:"xl",
|
||||
},
|
||||
{
|
||||
label:"道岔",
|
||||
value:"dc",
|
||||
},
|
||||
],
|
||||
jobDataList:[],
|
||||
value:'',
|
||||
}
|
||||
},
|
||||
@ -230,6 +301,9 @@
|
||||
window.lesson3dUpdateControl = this.lesson3dUpdateControl;
|
||||
window.lesson3dSelect = this.lesson3dSelect;
|
||||
window.lesson3dUpdatePicurl = this.lesson3dUpdatePicurl;
|
||||
|
||||
let jobList = new JobPaneData();
|
||||
this.jobDataList = jobList.dataList;
|
||||
},
|
||||
beforeDestroy() {
|
||||
|
||||
@ -247,7 +321,7 @@
|
||||
console.log("reset");
|
||||
this.activeName = 'cameraproperty';
|
||||
},
|
||||
lesson3dSelect(mode,type,obj){
|
||||
lesson3dSelect(mode,type,obj,revisionlist){
|
||||
this.activeName = mode;
|
||||
this.selectType = type;
|
||||
// console.log(this.lessonData.lessonData.lessonProgress[this.lessonEditIndex].stepTipsData);
|
||||
@ -263,6 +337,7 @@
|
||||
|
||||
if(type == "jobpane"){
|
||||
this.selected = obj;
|
||||
this.revisionList = revisionlist;
|
||||
}
|
||||
|
||||
if(type == "modelproperty"){
|
||||
@ -274,11 +349,46 @@
|
||||
updateData(){
|
||||
// this.lessonData.lessonData.lessonProgress[this.lessonEditIndex].stepTipsData;
|
||||
},
|
||||
deleteJobItem(selectedJob){
|
||||
console.log(selectedJob);
|
||||
for(let i=0;i<this.revisionList.data.length;i++){
|
||||
if(this.revisionList.data[i].cname == selectedJob.cname){
|
||||
console.log(selectedJob);
|
||||
this.revisionList.data.splice(i,1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
deleteEventItem(deleteAction){
|
||||
console.log(this.lessonData.lessonData.lessonProgress[this.lessonEditIndex].action);
|
||||
console.log(deleteAction);
|
||||
for(let i=0;i<this.lessonData.lessonData.lessonProgress[this.lessonEditIndex].action.length;i++){
|
||||
if(this.lessonData.lessonData.lessonProgress[this.lessonEditIndex].action[i].actionName == deleteAction.actionName){
|
||||
this.lessonData.lessonData.lessonProgress[this.lessonEditIndex].action.splice(i,1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
resetCamera(){
|
||||
|
||||
this.selectLesson3dControl.object.position.x = 40;
|
||||
this.selectLesson3dControl.object.position.y = 80;
|
||||
this.selectLesson3dControl.object.position.z = 0;
|
||||
this.selectLesson3dControl.target = new THREE.Vector3(0,0,0);
|
||||
},
|
||||
recordCamera(){
|
||||
let newPos = {
|
||||
x:this.selectLesson3dControl.object.position.x,
|
||||
y:this.selectLesson3dControl.object.position.y,
|
||||
z:this.selectLesson3dControl.object.position.z,
|
||||
};
|
||||
this.lessonData.lessonData.lessonProgress[this.lessonEditIndex].cameraPosition = newPos;
|
||||
|
||||
let newTarget = {
|
||||
x:this.selectLesson3dControl.target.x,
|
||||
y:this.selectLesson3dControl.target.y,
|
||||
z:this.selectLesson3dControl.target.z,
|
||||
};
|
||||
this.lessonData.lessonData.lessonProgress[this.lessonEditIndex].cameraTarget = newTarget;
|
||||
},
|
||||
lesson3dUpdatePicurl(picAsset){
|
||||
if(this.selectType == "explainpane"){
|
||||
@ -350,9 +460,10 @@
|
||||
|
||||
.addmodeleventdiv{
|
||||
width:98%;
|
||||
height:50px;
|
||||
height:64px;
|
||||
margin: 1%;
|
||||
border:solid 2px #000;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -13,8 +13,12 @@
|
||||
<div class="eltabpaneover" >
|
||||
<el-tabs >
|
||||
<el-tab-pane v-for="(item,index) in selectedJob.controlList" label-width="33%" :key="item.name" :label="item.name" >
|
||||
<div class="addjobdivs" v-for="(itemin,indexin) in selectedJob.controlList[index].data" @click="selsectJobTool(itemin)">{{itemin.text}}</div>
|
||||
<div class="addjobdiv" @click="addjob(index)">添加</div>
|
||||
<div class="addjobdivs" v-for="(itemin,indexin) in selectedJob.controlList[index].data" @click="selsectJobTool(itemin,selectedJob.controlList[index])">
|
||||
{{itemin.text}}
|
||||
</div>
|
||||
<div class="addjobdiv"
|
||||
:style="{'background-image': 'url('+localstatic+'/lesson3d/addbutton.png)'}"
|
||||
@click="addjob(index)"></div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
@ -39,6 +43,7 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
localstatic:JL3D_LOCAL_STATIC,
|
||||
jobList:[],
|
||||
showJobList:false,
|
||||
showJob:false,
|
||||
@ -79,17 +84,30 @@
|
||||
},
|
||||
addjob(index){
|
||||
this.selectedJob.controlList[index].data.push({
|
||||
cname:"1",
|
||||
cname:this.generateUUID(),
|
||||
text:"123",
|
||||
explainRole:"角色",
|
||||
nextNode:"null",
|
||||
sceneId:this.lessonData.lessonData.lessonProgress[this.lessonEditIndex].id,
|
||||
type:"",
|
||||
});
|
||||
},
|
||||
selsectJobTool(selectTool){
|
||||
lesson3dSelect('toolproperty','jobpane',selectTool);
|
||||
selsectJobTool(selectTool,jobList){
|
||||
lesson3dSelect('toolproperty','jobpane',selectTool,jobList);
|
||||
console.log(selectTool);
|
||||
},
|
||||
generateUUID() {
|
||||
var d = new Date().getTime();
|
||||
if (window.performance && typeof window.performance.now === "function") {
|
||||
d += performance.now(); //use high-precision timer if available
|
||||
}
|
||||
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
var r = (d + Math.random() * 16) % 16 | 0;
|
||||
d = Math.floor(d / 16);
|
||||
return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
|
||||
});
|
||||
return uuid;
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
@ -195,12 +213,16 @@
|
||||
border:solid 2px #000;
|
||||
}
|
||||
|
||||
|
||||
.addjobdiv{
|
||||
width:98%;
|
||||
height:50px;
|
||||
height:64px;
|
||||
margin: 1%;
|
||||
border:solid 2px #000;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
|
@ -135,7 +135,7 @@
|
||||
bottom:0;
|
||||
border-radius:10px;
|
||||
border:solid 2px #000;
|
||||
background-color: #fff;
|
||||
// background-color: #fff;
|
||||
z-index:1;
|
||||
}
|
||||
|
||||
|
@ -5,29 +5,29 @@
|
||||
<div class="lesson3dplayer">
|
||||
<Step-Tips
|
||||
:lessonData='lessonData'
|
||||
:lessonEditIndex='lessonEditIndex'
|
||||
v-show="lessonTools[0].isShow && lessonData.lessonData.lessonProgress[lessonEditIndex].progressScene == 'standstation'">
|
||||
:lessonPlayIndex='lessonPlayIndex'
|
||||
v-show="lessonTools[0].isShow && lessonData.lessonData.lessonProgress[lessonPlayIndex].progressScene == 'standstation'">
|
||||
</Step-Tips>
|
||||
|
||||
<Process-Log
|
||||
v-show="lessonTools[1].isShow && lessonData.lessonData.lessonProgress[lessonEditIndex].progressScene == 'standstation'">
|
||||
v-show="lessonTools[1].isShow && lessonData.lessonData.lessonProgress[lessonPlayIndex].progressScene == 'standstation'">
|
||||
</Process-Log>
|
||||
|
||||
<Explain-Pane
|
||||
:lessonData='lessonData'
|
||||
:lessonEditIndex='lessonEditIndex'
|
||||
v-show="lessonTools[2].isShow && lessonData.lessonData.lessonProgress[lessonEditIndex].progressScene == 'standstation'">
|
||||
:lessonPlayIndex='lessonPlayIndex'
|
||||
v-show="lessonTools[2].isShow && lessonData.lessonData.lessonProgress[lessonPlayIndex].progressScene == 'standstation'">
|
||||
</Explain-Pane>
|
||||
|
||||
<Job-Pane
|
||||
:jobPaneData='jobPaneData'
|
||||
:lessonData='lessonData'
|
||||
:lessonEditIndex='lessonEditIndex'
|
||||
:lessonPlayIndex='lessonPlayIndex'
|
||||
ref="jobpane"
|
||||
v-show="lessonTools[3].isShow && lessonData.lessonData.lessonProgress[lessonEditIndex].progressScene == 'standstation'">
|
||||
v-show="lessonTools[3].isShow && lessonData.lessonData.lessonProgress[lessonPlayIndex].progressScene == 'standstation'">
|
||||
</Job-Pane>
|
||||
|
||||
<Tool-Bar v-show="lessonTools[4].isShow && lessonData.lessonData.lessonProgress[lessonEditIndex].progressScene == 'standstation'"></Tool-Bar>
|
||||
<Tool-Bar v-show="lessonTools[4].isShow && lessonData.lessonData.lessonProgress[lessonPlayIndex].progressScene == 'standstation'"></Tool-Bar>
|
||||
|
||||
<div id="lesson3ddraw" class="lesson3ddraw">
|
||||
</div>
|
||||
@ -50,10 +50,10 @@
|
||||
import ToolBar from '@/views/jlmap3d/lesson3dplayer/tools/toolbar';
|
||||
|
||||
|
||||
import { Lesson3dEditor } from '@/jlmap3d/lesson3dedit/lesson3deditor.js';
|
||||
import { Lesson3dPlayer } from '@/jlmap3d/lesson3d/lesson3dplayer.js';
|
||||
|
||||
import { LessonData } from '@/jlmap3d/lesson3dedit/model/lessondata.js';
|
||||
import { JobPaneData } from '@/jlmap3d/lesson3dedit/toolsmodel/jobpanedata.js';
|
||||
import { LessonData } from '@/jlmap3d/lesson3d/model/lessondata.js';
|
||||
import { JobPaneData } from '@/jlmap3d/lesson3d/toolsmodel/jobpanedata.js';
|
||||
|
||||
import { getLesson3dData,updateLesson3dData } from '@/api/jmap/lesson3d';
|
||||
export default {
|
||||
@ -85,7 +85,7 @@
|
||||
}
|
||||
},
|
||||
jobPaneData:{},
|
||||
lessonEditIndex:0,
|
||||
lessonPlayIndex:0,
|
||||
lessonTools:[
|
||||
{
|
||||
name:"步骤组件",
|
||||
@ -118,7 +118,8 @@
|
||||
},
|
||||
mounted() {
|
||||
window.updateTriggerList = this.updateTriggerList;
|
||||
|
||||
window.jumpEvent = this.jumpEvent;
|
||||
window.actionEvent = this.actionEvent;
|
||||
this.init(this.$route.query.lessonId);
|
||||
},
|
||||
beforeDestroy() {
|
||||
@ -138,7 +139,6 @@
|
||||
let loadData;
|
||||
if(data.data.data){
|
||||
loadData = JSON.parse(data.data.data);
|
||||
console.log(loadData);
|
||||
|
||||
this.jobPaneData.dataList = loadData.toolJobPane;
|
||||
this.$refs.jobpane.initJobList(this.jobPaneData.dataList);
|
||||
@ -151,7 +151,7 @@
|
||||
}
|
||||
console.log("loaddata----------------");
|
||||
console.log(loadData);
|
||||
this.jl3d = new Lesson3dEditor(dom,loadData);
|
||||
this.jl3d = new Lesson3dPlayer(dom,loadData,this.lessonPlayIndex);
|
||||
}).catch(() => {
|
||||
});
|
||||
},
|
||||
@ -173,7 +173,19 @@
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
jumpEvent(type,action){
|
||||
if(type == "action"){
|
||||
this.lessonPlayIndex = action.jumpNode;
|
||||
}
|
||||
if(type == "tools"){
|
||||
this.lessonPlayIndex = action.nextNode;
|
||||
}
|
||||
},
|
||||
actionEvent(type,action,mesh){
|
||||
if(type == "remove"){
|
||||
this.jl3d.actionRemove(mesh);
|
||||
}
|
||||
},
|
||||
updateTriggerList(newTriggerList){
|
||||
this.triggerList = newTriggerList;
|
||||
console.log(this.triggerList);
|
||||
|
@ -1,13 +1,16 @@
|
||||
<template>
|
||||
<div class="explainpanediv" v-if="lessonData.lessonData.lessonProgress[lessonEditIndex]" @click="selectTool">
|
||||
<div class="explainpanediv"
|
||||
v-if="lessonData.lessonData.lessonProgress[lessonPlayIndex]"
|
||||
@click="selectTool"
|
||||
:style="{'background-image': 'url('+lessonbg+')'}">
|
||||
<div class="explainpanetittle" >
|
||||
{{lessonData.lessonData.lessonProgress[lessonEditIndex].explainPane.tittle}}
|
||||
{{lessonData.lessonData.lessonProgress[lessonPlayIndex].explainPane.tittle}}
|
||||
</div>
|
||||
<div class="explainpanepic" :style="{'background-image': 'url('+localStatic+lessonData.lessonData.lessonProgress[lessonEditIndex].explainPane.picurl+')'}" >
|
||||
<div class="explainpanepic" :style="{'background-image': 'url('+localStatic+lessonData.lessonData.lessonProgress[lessonPlayIndex].explainPane.picurl+')'}" >
|
||||
|
||||
</div>
|
||||
<div class="explainpanetext" >
|
||||
{{lessonData.lessonData.lessonProgress[lessonEditIndex].explainPane.text}}
|
||||
{{lessonData.lessonData.lessonProgress[lessonPlayIndex].explainPane.text}}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -19,13 +22,14 @@
|
||||
|
||||
export default {
|
||||
name: 'ExplainPane',
|
||||
props:['lessonData','lessonEditIndex'],
|
||||
props:['lessonData','lessonPlayIndex'],
|
||||
components: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
localStatic:BASE_ASSET_API,
|
||||
lessonbg:JL3D_LOCAL_STATIC+"/lesson3d/lessonbg.png",
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -60,7 +64,7 @@
|
||||
top:0;
|
||||
border-radius:10px;
|
||||
border:solid 2px #000;
|
||||
background-color: #fff;
|
||||
color:#fff;
|
||||
z-index:1;
|
||||
}
|
||||
.explainpanetittle{
|
||||
@ -70,12 +74,18 @@
|
||||
}
|
||||
|
||||
.explainpanepic{
|
||||
position:relative;
|
||||
width:90%;
|
||||
left:5%;
|
||||
height:65%;
|
||||
border:solid 2px #000;
|
||||
background-size: 100%;
|
||||
}
|
||||
|
||||
.explainpanetext{
|
||||
position:relative;
|
||||
left:5%;
|
||||
width:90%;
|
||||
font-size: 14px;
|
||||
// height:20%;
|
||||
}
|
||||
|
@ -1,20 +1,36 @@
|
||||
<template>
|
||||
|
||||
<div class="jobpanediv">
|
||||
<div class="jobshowbutton" @click="openList">岗位联络</div>
|
||||
<div class="joblistdiv" v-show="showJobList">
|
||||
<div class="jobdiv" v-for="(jobitem,index) in jobList" @click="selectJob(jobitem)" >{{jobitem.name}}</div>
|
||||
<div class="jobshowbutton" @click="openList"
|
||||
:style="{'background-image': 'url('+lessonbg+')'}">
|
||||
<div class="jobshowbuttonpic" :style="{'background-image': 'url('+lkgwbg+')'}">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="jobtab" v-if="selectedJob">
|
||||
|
||||
<div class="joblistdiv" v-show="showJobList"
|
||||
:style="{'background-image': 'url('+lessonbg+')'}">
|
||||
<div class="jobdiv" v-for="(jobitem,index) in jobList" @click="selectJob(jobitem)" >
|
||||
<img :src="jobpic" />
|
||||
<div class="jobdivtext" >{{jobitem.name}}</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="jobtab" v-if="selectedJob"
|
||||
:style="{'background-image': 'url('+lessonbg+')'}">
|
||||
<div class="jobtabmsg" >
|
||||
<div class="jobtabmsgdiv" >{{selectedJob.name}}</div>
|
||||
<div class="jobtabmsgdiv" >
|
||||
<img :src="jobpic" />
|
||||
<div class="jobdivtext" >{{selectedJob.name}}</div>
|
||||
</div>
|
||||
<div class="jobtabmsgtext" >{{selectedJob.text}}</div>
|
||||
</div>
|
||||
<div class="eltabpaneover" >
|
||||
<el-tabs >
|
||||
<el-tab-pane v-for="(item,index) in selectedJob.controlList" label-width="33%" :key="item.name" :label="item.name" >
|
||||
<el-tab-pane v-for="(item,index) in selectedJob.controlList"
|
||||
style="color:#fff"label-width="33%" :key="item.name" :label="item.name" >
|
||||
<div class="addjobdivs" v-for="(itemin,indexin) in selectedJob.controlList[index].data" @click="selsectJobTool(itemin)">{{itemin.text}}</div>
|
||||
<div class="addjobdiv" @click="addjob(index)">添加</div>
|
||||
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
@ -32,13 +48,16 @@
|
||||
//岗位
|
||||
export default {
|
||||
name: 'JobPane',
|
||||
props:['jobPaneData','lessonData','lessonEditIndex'],
|
||||
props:['jobPaneData','lessonData','lessonPlayIndex'],
|
||||
|
||||
components: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
lessonbg:JL3D_LOCAL_STATIC+"/lesson3d/lessonbg.png",
|
||||
lkgwbg:JL3D_LOCAL_STATIC+"/lesson3d/lkgw.png",
|
||||
jobpic:JL3D_LOCAL_STATIC+"/lesson3d/jobpic.png",
|
||||
jobList:[],
|
||||
showJobList:false,
|
||||
showJob:false,
|
||||
@ -70,25 +89,20 @@
|
||||
},
|
||||
initJobList(data){
|
||||
this.jobList = data;
|
||||
console.log(data);
|
||||
},
|
||||
selectJob(item){
|
||||
console.log(item);
|
||||
this.selectedJob = item;
|
||||
},
|
||||
|
||||
},
|
||||
addjob(index){
|
||||
this.selectedJob.controlList[index].data.push({
|
||||
cname:"1",
|
||||
text:"123",
|
||||
nextNode:"null",
|
||||
sceneId:this.lessonData.lessonData.lessonProgress[this.lessonEditIndex].id,
|
||||
type:"",
|
||||
});
|
||||
},
|
||||
selsectJobTool(selectTool){
|
||||
lesson3dSelect('toolproperty','jobpane',selectTool);
|
||||
console.log(selectTool);
|
||||
console.log(this.lessonData.lessonData.lessonProgress[this.lessonPlayIndex]);
|
||||
let nowProgress = this.lessonData.lessonData.lessonProgress[this.lessonPlayIndex];
|
||||
if(selectTool.sceneId == nowProgress.id){
|
||||
jumpEvent("tools",selectTool);
|
||||
}
|
||||
// console.log(this.lessonData.lessonProgress[this.lessonPlayIndex]);
|
||||
},
|
||||
},
|
||||
|
||||
@ -105,10 +119,18 @@
|
||||
right:0;
|
||||
top:0;
|
||||
// border:solid 2px #000;
|
||||
|
||||
text-align: center;
|
||||
z-index:1;
|
||||
}
|
||||
|
||||
.jobshowbuttonpic{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-size: 100%;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.jobshowbutton{
|
||||
position: absolute;
|
||||
width:100px;
|
||||
@ -116,9 +138,12 @@
|
||||
right:0;
|
||||
top:0;
|
||||
border:solid 2px #000;
|
||||
background-color: #fff;
|
||||
// background-color: #fff;
|
||||
color:#fff;
|
||||
}
|
||||
.el-tabs__item{
|
||||
color:'#fff'
|
||||
}
|
||||
|
||||
.joblistdiv{
|
||||
position: absolute;
|
||||
width:100px;
|
||||
@ -128,16 +153,22 @@
|
||||
border:solid 2px #000;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
background-color: #fff;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
.jobdiv{
|
||||
width:75px;
|
||||
height:75px;
|
||||
height:90px;
|
||||
margin-top: 5px;
|
||||
margin-left: 2px;
|
||||
border:solid 2px #000;
|
||||
background-color: #fff;
|
||||
color:#fff;
|
||||
}
|
||||
.jobdivtext{
|
||||
// position: absolute;
|
||||
bottom: 0;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
@ -148,7 +179,7 @@
|
||||
top:50px;
|
||||
width: 300px;
|
||||
height:450px;
|
||||
background-color: #fff;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
.eltabpaneover{
|
||||
@ -167,21 +198,21 @@
|
||||
|
||||
.jobtabmsgdiv{
|
||||
width:80px;
|
||||
height:80px;
|
||||
height:90px;
|
||||
position:absolute;
|
||||
top:10px;
|
||||
left:5px;
|
||||
border:solid 2px #000;
|
||||
background-color: #fff;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
.jobtabmsgtext{
|
||||
width:200px;
|
||||
height:80px;
|
||||
height:90px;
|
||||
// margin-top: 5px;
|
||||
// margin-left: 2px;
|
||||
border:solid 2px #000;
|
||||
background-color: #fff;
|
||||
color:#fff;
|
||||
position: absolute;
|
||||
font-size: 12px;
|
||||
right:10px;
|
||||
|
@ -68,7 +68,9 @@
|
||||
bottom:0;
|
||||
// border-radius:10px;
|
||||
border:solid 2px #000;
|
||||
background-color: #fff;
|
||||
background-color: #000080;
|
||||
opacity: 0.6;
|
||||
color:#fff;
|
||||
z-index:1;
|
||||
}
|
||||
.processtext{
|
||||
|
@ -1,10 +1,13 @@
|
||||
<template>
|
||||
<div class="stepstipsdiv" v-if="lessonData.lessonData.lessonProgress[lessonEditIndex]" @click="selectTool">
|
||||
<div class="stepstipsdiv"
|
||||
v-if="lessonData.lessonData.lessonProgress[lessonPlayIndex]"
|
||||
@click="selectTool"
|
||||
:style="{'background-image': 'url('+lessonbg+')'}">
|
||||
<div class="stepstipstittle" >
|
||||
{{lessonData.lessonData.lessonProgress[lessonEditIndex].stepTipsData.tittle}}
|
||||
{{lessonData.lessonData.lessonProgress[lessonPlayIndex].stepTipsData.tittle}}
|
||||
</div>
|
||||
<div class="stepstipstext" >
|
||||
{{lessonData.lessonData.lessonProgress[lessonEditIndex].stepTipsData.text}}
|
||||
{{lessonData.lessonData.lessonProgress[lessonPlayIndex].stepTipsData.text}}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -15,13 +18,13 @@
|
||||
//步骤提示
|
||||
export default {
|
||||
name: 'StepTips',
|
||||
props:['lessonData','lessonEditIndex'],
|
||||
props:['lessonData','lessonPlayIndex'],
|
||||
components: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
lessonbg:JL3D_LOCAL_STATIC+"/lesson3d/lessonbg.png",
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -60,7 +63,9 @@
|
||||
top:0;
|
||||
border-radius:10px;
|
||||
border:solid 2px #000;
|
||||
background-color: #fff;
|
||||
// background-color: #223458;
|
||||
// opacity: 0.6;
|
||||
color:#fff;
|
||||
z-index:1;
|
||||
}
|
||||
.stepstipstittle{
|
||||
|
@ -1,17 +1,32 @@
|
||||
<template>
|
||||
<div class="toolbardiv" >
|
||||
<div class="toolbarbutton" @click="openGuide"></div>
|
||||
<div class="toolbarbutton" @click="openBag"></div>
|
||||
<div class="toolbarbutton" ></div>
|
||||
<div class="toolbardiv" :style="{'background-image': 'url('+lessonbg+')'}">
|
||||
|
||||
<div class="toolbarguides" v-show="showGuide">
|
||||
<div class="toolbarbutton"
|
||||
:style="{'background-image': 'url('+localstatic+'/lesson3d/guide.png)'}"
|
||||
@click="openGuide">
|
||||
</div>
|
||||
|
||||
<div class="toolbarbutton"
|
||||
:style="{'background-image': 'url('+localstatic+'/lesson3d/bag.png)'}"
|
||||
@click="openBag">
|
||||
</div>
|
||||
|
||||
<div class="toolbarbutton"
|
||||
:style="{'background-image': 'url('+localstatic+'/lesson3d/back.png)'}">
|
||||
</div>
|
||||
|
||||
<div class="toolbarguides"
|
||||
:style="{'background-image': 'url('+lessonbg+')'}"
|
||||
v-show="showGuide">
|
||||
<div class="toolbarguide" v-for="(guide,index) in guideList">
|
||||
{{guide.name}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="toolbarbag" v-show="showBag">
|
||||
<div class="toolbarbag"
|
||||
:style="{'background-image': 'url('+lessonbg+')'}"
|
||||
v-show="showBag">
|
||||
<div class="toolbarplaid" v-for="(tool,index) in toolsList"></div>
|
||||
</div>
|
||||
</div>
|
||||
@ -28,6 +43,8 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
localstatic:JL3D_LOCAL_STATIC,
|
||||
lessonbg:JL3D_LOCAL_STATIC+"/lesson3d/lessonbg.png",
|
||||
tipsTittle:"步骤一",
|
||||
tipsText:"步骤一",
|
||||
guideList:[],
|
||||
@ -135,7 +152,6 @@
|
||||
bottom:0;
|
||||
border-radius:10px;
|
||||
border:solid 2px #000;
|
||||
background-color: #fff;
|
||||
z-index:1;
|
||||
}
|
||||
|
||||
@ -146,6 +162,7 @@
|
||||
border-radius:10px;
|
||||
border:solid 2px #000;
|
||||
margin: 2px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.toolbarguides{
|
||||
@ -157,14 +174,18 @@
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
border-radius:10px;
|
||||
color: #fff;
|
||||
border:solid 2px #000;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.toolbarguide{
|
||||
margin-top: 5px;
|
||||
width: 90px;
|
||||
height: 30px;
|
||||
border-radius:10px;
|
||||
border:solid 2px #000;
|
||||
font-size: 20px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
|
BIN
static/lesson3d/addbutton.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
static/lesson3d/back.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
static/lesson3d/bag.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
static/lesson3d/guide.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
static/lesson3d/jobpic.png
Normal file
After Width: | Height: | Size: 7.9 KiB |
BIN
static/lesson3d/lessonbg.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
static/lesson3d/lkgw.png
Normal file
After Width: | Height: | Size: 8.0 KiB |
BIN
static/lesson3d/选项.png
Normal file
After Width: | Height: | Size: 4.0 KiB |