dengsixing 1 vuosi sitten
vanhempi
commit
5e0f8ac12f

+ 12 - 0
src/main/java/com/fdkankan/jp/xspace/common/constant/NasPathConstant.java

@@ -0,0 +1,12 @@
+package com.fdkankan.jp.xspace.common.constant;
+
+public class NasPathConstant {
+
+    public final static String BASE_PATH = "/mnt/xspace/";
+    public final static String UNITY_WORK_PATH = BASE_PATH + "unity/";
+
+
+
+
+
+}

+ 16 - 0
src/main/java/com/fdkankan/jp/xspace/common/constant/OSSPathConstant.java

@@ -0,0 +1,16 @@
+package com.fdkankan.jp.xspace.common.constant;
+
+public class OSSPathConstant {
+
+    public final static String SCENE_VIEW_DATA = "scene_view_data/";
+
+    public final static String SCENE_VIEW_DATA_IMAGES = SCENE_VIEW_DATA + "%s/images/";
+
+    public final static String SCENE_VIEW_DATA_DATA = SCENE_VIEW_DATA + "%s/data/";
+
+    public final static String SCENE_VIEW_DATA_USER = SCENE_VIEW_DATA + "%s/user/";
+
+    public final static String XSPACE_SCENE_FORMAT = "xspace/%s/%s/";
+
+
+}

+ 7 - 0
src/main/java/com/fdkankan/jp/xspace/common/constant/UnityConstant.java

@@ -0,0 +1,7 @@
+package com.fdkankan.jp.xspace.common.constant;
+
+public class UnityConstant {
+
+    public final static String EXEC_UNITY_FORMAT = "<Unity可执行文件> -accept-apiupdate -batchmode -disable-gpu-skinning -nographics -silent-crashes -projectPath %s -serial %s -username %s -password %s -executeMethod FDKKSceneTiles.Editor.BuildPipeline.StartBuildPipeline -quit";
+
+}

+ 1 - 1
src/main/java/com/fdkankan/jp/xspace/util/PasswordUtil.java

@@ -1,4 +1,4 @@
-package com.fdkankan.jp.xspace.util;
+package com.fdkankan.jp.xspace.common.util;
 
 public class PasswordUtil {
 

+ 1 - 1
src/main/java/com/fdkankan/jp/xspace/util/UniqueStringGenerator.java

@@ -1,4 +1,4 @@
-package com.fdkankan.jp.xspace.util;
+package com.fdkankan.jp.xspace.common.util;
 
 public class UniqueStringGenerator {
     private static final int MAX_GENERATE_COUNT = 99999;

+ 16 - 20
src/main/java/com/fdkankan/jp/xspace/listener/RabbitMqListener.java

@@ -1,14 +1,15 @@
 package com.fdkankan.jp.xspace.listener;
 
 import cn.hutool.core.bean.BeanUtil;
-import com.fdkankan.common.constant.CommonStatus;
 import com.fdkankan.common.constant.CommonSuccessStatus;
 import com.fdkankan.dingtalk.DingTalkSendUtils;
-import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import com.fdkankan.jp.xspace.common.constant.NasPathConstant;
 import com.fdkankan.jp.xspace.common.exception.PackException;
 import com.fdkankan.jp.xspace.common.rabbitmq.RabbitmqConstant;
 import com.fdkankan.jp.xspace.entity.SceneXspace;
 import com.fdkankan.jp.xspace.entity.User;
+import com.fdkankan.jp.xspace.service.ISceneXspaceService;
+import com.fdkankan.jp.xspace.service.IUnityService;
 import com.fdkankan.jp.xspace.service.IUserService;
 import com.rabbitmq.client.Channel;
 import lombok.extern.slf4j.Slf4j;
@@ -21,6 +22,7 @@ import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
 import java.nio.charset.StandardCharsets;
+import java.util.Date;
 
 /**
  * <p>
@@ -39,17 +41,18 @@ public class RabbitMqListener {
             "**失败原因**: %s\n\n" +
             "**场景码**: %s\n\n" +
             "**账号**: %s\n\n" +
-            "**资源地址**: %s\n\n";
+            "**工程目录**: %s\n\n";
 
     @Value("${spring.profiles.active}")
     private String profile;
-
-    @Resource
-    private FYunFileServiceInterface fYunFileService;
     @Resource
     private DingTalkSendUtils dingTalkSendUtils;
     @Autowired
     private IUserService userService;
+    @Autowired
+    private IUnityService unityService;
+    @Autowired
+    private ISceneXspaceService sceneXspaceService;
 
 
     /**
@@ -68,35 +71,28 @@ public class RabbitMqListener {
 
         SceneXspace bean = BeanUtil.toBean(msg, SceneXspace.class);
         String errorReason = null;
-        String dataSource = null;
 
         try {
-            // TODO: 2024/7/24 准备资源
-
-            // TODO: 2024/7/24 调用unity打包
-
-            // TODO: 2024/7/24 处理文件 上传oss
-
-            // TODO: 2024/7/25 删除本地资源
-
+            unityService.packXspace(bean);
             bean.setStatus(CommonSuccessStatus.SUCCESS.code());
         }catch (PackException e){
             bean.setStatus(CommonSuccessStatus.FAIL.code());
-            errorReason = "unity打包失败";
+            errorReason = e.getMessage();
         } catch (Exception e) {
             bean.setStatus(CommonSuccessStatus.FAIL.code());
             errorReason = "后端报错";
         }
 
-
         if(bean.getStatus() == CommonSuccessStatus.FAIL.code()){
             User user = userService.getById(bean.getUserId());
-            String content = String.format(DINGTALK_MSG_PATTERN, profile, errorReason, bean.getNum(), user.getUserName(), dataSource);
+            String workPath = NasPathConstant.UNITY_WORK_PATH + bean.getNum() + "/" + bean.getSerial() + "/";
+            String content = String.format(DINGTALK_MSG_PATTERN, profile, errorReason, bean.getNum(), user.getUserName(), workPath);
             dingTalkSendUtils.sendActioncardMsgToDingRobot(content, "场景同步失败");
         }
 
-
-        // TODO: 2024/7/24 更新记录
+        //更新状态
+        bean.setUpdateTime(new Date());
+        sceneXspaceService.updateById(bean);
 
         log.info("结束消费消息,id:{}", messageId);
         channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);

+ 12 - 0
src/main/java/com/fdkankan/jp/xspace/service/IUnityService.java

@@ -0,0 +1,12 @@
+package com.fdkankan.jp.xspace.service;
+
+import com.fdkankan.jp.xspace.entity.SceneXspace;
+
+public interface IUnityService {
+
+    void packXspace(SceneXspace bean) throws Exception;
+
+
+
+
+}

+ 1 - 1
src/main/java/com/fdkankan/jp/xspace/service/impl/SceneXspaceServiceImpl.java

@@ -18,7 +18,7 @@ import com.fdkankan.jp.xspace.service.ISceneXspaceService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fdkankan.jp.xspace.service.IUserRoleService;
 import com.fdkankan.jp.xspace.service.IUserService;
-import com.fdkankan.jp.xspace.util.UniqueStringGenerator;
+import com.fdkankan.jp.xspace.common.util.UniqueStringGenerator;
 import com.fdkankan.jp.xspace.vo.XspaceVO;
 import com.fdkankan.rabbitmq.util.RabbitMqProducer;
 import org.springframework.beans.factory.annotation.Autowired;

+ 188 - 0
src/main/java/com/fdkankan/jp/xspace/service/impl/UnityServiceImpl.java

@@ -0,0 +1,188 @@
+package com.fdkankan.jp.xspace.service.impl;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.fdkankan.common.constant.CommonStatus;
+import com.fdkankan.common.util.CmdUtils;
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import com.fdkankan.jp.xspace.common.constant.NasPathConstant;
+import com.fdkankan.jp.xspace.common.constant.OSSPathConstant;
+import com.fdkankan.jp.xspace.common.constant.UnityConstant;
+import com.fdkankan.jp.xspace.common.exception.PackException;
+import com.fdkankan.jp.xspace.entity.SceneXspace;
+import com.fdkankan.jp.xspace.entity.UnityConfig;
+import com.fdkankan.jp.xspace.service.IUnityConfigService;
+import com.fdkankan.jp.xspace.service.IUnityService;
+import com.fdkankan.jp.xspace.vo.SceneEditControlsVO;
+import com.fdkankan.jp.xspace.vo.SceneInfoVO;
+import com.fdkankan.redis.constant.RedisKey;
+import com.fdkankan.redis.util.RedisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.Objects;
+
+@Slf4j
+@Service
+public class UnityServiceImpl implements IUnityService {
+
+    @Resource
+    private FYunFileServiceInterface fYunFileService;
+    @Autowired
+    private IUnityConfigService unityConfigService;
+    @Resource
+    private RedisUtil redisUtil;
+
+
+    @Override
+    public void packXspace(SceneXspace bean) throws Exception {
+
+        //准备资源
+        String workPath = this.pre(bean);
+
+        //调用unity打包
+        this.callUnity(workPath);
+
+        //文件处理/上传
+        this.dealFileAndUpload(bean, workPath);
+
+        //删除本地资源
+        FileUtil.del(workPath);
+    }
+
+
+    private String pre(SceneXspace bean){
+        String num = bean.getNum();
+        String workPath = NasPathConstant.UNITY_WORK_PATH + bean.getNum() + "/" + bean.getSerial() + "/";
+        String localMeshPath = workPath + "mesh/";
+        List<String> fileList = fYunFileService.listRemoteFiles(String.format(OSSPathConstant.SCENE_VIEW_DATA_DATA, num) + "mesh/");
+        fileList.stream().forEach(v->{
+            fYunFileService.downloadFile(v, localMeshPath);
+        });
+
+        return workPath;
+    }
+
+    private void callUnity(String workPath) throws Exception {
+        UnityConfig unityConfig = unityConfigService.getOne(new LambdaQueryWrapper<>());
+        String cmdStr = String.format(UnityConstant.EXEC_UNITY_FORMAT, workPath, unityConfig.getSerial(), unityConfig.getAccount(), unityConfig.getPassword());
+        try {
+            CmdUtils.callLine(cmdStr);
+        }catch (Exception e){
+            log.error("unity执行报错,workPath:{}", workPath, e);
+            throw new PackException("unity执行报错");
+        }
+
+        String resultFilePath = workPath + "result.txt";
+        boolean completed = this.checkComputeCompleted(resultFilePath, 3, 300);
+        if(!completed){
+            throw new PackException("unity异常,没有生成result.txt");
+        }
+        String resultStr = FileUtil.readUtf8String(resultFilePath);
+        JSONObject resultObj = JSON.parseObject(resultStr);
+        boolean success = resultObj.getBooleanValue("success");
+        if(!success){
+            throw new PackException(resultObj.getString("reason"));
+        }
+    }
+
+    private boolean checkComputeCompleted(String uploadJsonPath, int maxCheckTimes, long waitTime) throws Exception{
+        int checkTimes = 1;
+        boolean exist = false;
+        do {
+            if(new File(uploadJsonPath).exists()){
+                exist = true;
+                break;
+            }
+            Thread.sleep(waitTime);
+            ++checkTimes;
+        }while (checkTimes <= maxCheckTimes);
+
+        return exist;
+    }
+
+    private void dealFileAndUpload(SceneXspace bean, String workPath){
+
+        String xspaceSceneOssPath = String.format(OSSPathConstant.XSPACE_SCENE_FORMAT,bean.getNum(), bean.getSerial());
+
+        //上传mesh
+        List<File> fileList = FileUtil.loopFiles(workPath);
+        fileList.parallelStream().forEach(v->{
+            fYunFileService.uploadFile(v.getAbsolutePath(), v.getAbsolutePath().replace(workPath, xspaceSceneOssPath));
+        });
+
+        //上传文件映射json
+        fYunFileService.uploadFile(workPath + "xxx.json", xspaceSceneOssPath + "xxx.json");
+
+        //复制skybox图
+        String sourceImagesPath = String.format(OSSPathConstant.SCENE_VIEW_DATA_IMAGES, bean.getNum()) + "tiles/4k/";
+        String targetImagesPath = xspaceSceneOssPath + "images/";
+        fYunFileService.copyFileInBucket(sourceImagesPath, targetImagesPath);
+
+        //复制user
+        String sourceUserPath = String.format(OSSPathConstant.SCENE_VIEW_DATA_USER, bean.getNum());
+        String targetUserPath = xspaceSceneOssPath + "user/";
+        fYunFileService.copyFileInBucket(sourceUserPath, targetUserPath);
+
+        //上传getInfo.json
+        String getInfoKey = xspaceSceneOssPath + "getInfo.json";
+        SceneInfoVO getInfoJson = this.getSceneInfo4View(bean.getNum());
+        fYunFileService.uploadFile(JSON.toJSONString(getInfoJson).toString().getBytes(StandardCharsets.UTF_8), getInfoKey);
+
+        //上传floorplan.json
+        String floorplanPath = String.format(OSSPathConstant.SCENE_VIEW_DATA_DATA, bean.getNum()) + "floorplan.json";
+        if(getInfoJson.getFloorPlanUser() == 1){
+            floorplanPath = String.format(OSSPathConstant.SCENE_VIEW_DATA_USER, bean.getNum()) + "floorplan.json";
+        }
+        String xspaceFloorplanPath = xspaceSceneOssPath + "floorplan.json";
+        fYunFileService.copyFileInBucket(floorplanPath, xspaceFloorplanPath);
+
+        //复制vision.modeldata
+        String sourceVisionPath = String.format(OSSPathConstant.SCENE_VIEW_DATA_IMAGES, bean.getNum()) + "vision.modeldata";
+        String tagetVisionPath = xspaceFloorplanPath + "vision.modeldata";
+        fYunFileService.copyFileInBucket(sourceVisionPath, tagetVisionPath);
+
+    }
+
+    private SceneInfoVO getSceneInfo4View(String num){
+
+        String key = String.format(RedisKey.SCENE_JSON, num);
+        String sceneJson = redisUtil.get(key);
+        SceneInfoVO sceneInfoVO = null;
+        //先查询redis
+        if(StrUtil.isEmpty(sceneJson)) {
+            String objectName = String.format(OSSPathConstant.SCENE_VIEW_DATA, num) + "scene.json";
+            sceneJson = fYunFileService.getFileContent(objectName);
+        }
+        sceneInfoVO = JSON.parseObject(sceneJson, SceneInfoVO.class);
+        sceneInfoVO.setScenePassword(null);
+        if(Objects.isNull(sceneInfoVO.getFloorPlanAngle())){
+            sceneInfoVO.setFloorPlanAngle(0f);
+        }
+        if(Objects.isNull(sceneInfoVO.getFloorPlanCompass())){
+            sceneInfoVO.setFloorPlanCompass(0f);
+        }
+        SceneEditControlsVO controls = sceneInfoVO.getControls();
+        if(Objects.isNull(controls.getShowShare())){
+            controls.setShowShare(CommonStatus.YES.code().intValue());
+        }
+        if(Objects.isNull(controls.getShowCapture())){
+            controls.setShowCapture(CommonStatus.YES.code().intValue());
+        }
+        if(Objects.isNull(controls.getShowBillboardTitle())){
+            controls.setShowBillboardTitle(CommonStatus.YES.code().intValue());
+        }
+
+        return sceneInfoVO;
+    }
+
+
+}

+ 1 - 5
src/main/java/com/fdkankan/jp/xspace/service/impl/XspaceUserServiceImpl.java

@@ -1,6 +1,5 @@
 package com.fdkankan.jp.xspace.service.impl;
 
-import cn.hutool.core.collection.CollUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -15,17 +14,14 @@ import com.fdkankan.jp.xspace.dto.XspaceUserDTO;
 import com.fdkankan.jp.xspace.entity.User;
 import com.fdkankan.jp.xspace.entity.XspaceUser;
 import com.fdkankan.jp.xspace.mapper.IXspaceUserMapper;
-import com.fdkankan.jp.xspace.service.IUserRoleService;
 import com.fdkankan.jp.xspace.service.IUserService;
 import com.fdkankan.jp.xspace.service.IXspaceUserService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.fdkankan.jp.xspace.util.PasswordUtil;
-import org.apache.commons.lang3.StringUtils;
+import com.fdkankan.jp.xspace.common.util.PasswordUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.util.Objects;
-import java.util.Set;
 
 /**
  * <p>

+ 109 - 0
src/main/java/com/fdkankan/jp/xspace/vo/SceneEditControlsVO.java

@@ -0,0 +1,109 @@
+package com.fdkankan.jp.xspace.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/1/18
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SceneEditControlsVO implements Serializable {
+
+    /**
+     * 是否展示小地图(0-不展示,1-展示)
+     */
+    private Integer showMap;
+
+    /**
+     * 是否需要密码(0-不需要,1-需要)
+     */
+    private Integer showLock;
+
+    /**
+     * 是否展示标题(0-不需要,1-需要)
+     */
+    private Integer showTitle;
+
+    /**
+     * 是否展示漫游按钮(0-不需要,1-需要)
+     */
+    private Integer showPanorama;
+
+    /**
+     * 是否展示3D按钮(0-不需要,1-需要)
+     */
+    private Integer showDollhouse;
+
+    /**
+     * 是否展示2D按钮(0-不需要,1-需要)
+     */
+    private Integer showFloorplan;
+
+    /**
+     * 是否展示VR(0-不需要,1-需要)
+     */
+    private Integer showVR;
+
+    /**
+     * 是否展示自动导览(0-不需要,1-需要)
+     */
+    private Integer showTour;
+
+    /**
+     * 是否展示测量线(0-不需要,1-需要)
+     */
+    private Integer showRule;
+
+    /**
+     * 是否展示标尺(0-不需要,1-需要)
+     */
+    private Integer showScale;
+
+    /**
+     * 是否展示分享场景(0-不需要,1-需要)
+     */
+    private Integer showShare;
+
+    /**
+     * 是否展示分享热点(0-不需要,1-需要)
+     */
+    private Integer showTagshare;
+
+    /**
+     * 是否展示合照开关(0-不需要,1-需要)
+     */
+    private Integer showCapture;
+
+    /**
+     * 多媒体标签标题
+     */
+    private Integer showTagTitle;
+
+    /**
+     * 指示牌标签标题
+     */
+    private Integer showBillboardTitle;
+
+    /**
+     * 视频监控标签标题
+     */
+    private Integer showCameraTitle;
+
+    /**
+     * 场景关联标签标题
+     */
+    private Integer showLinkTitle;
+
+}

+ 257 - 0
src/main/java/com/fdkankan/jp/xspace/vo/SceneInfoVO.java

@@ -0,0 +1,257 @@
+package com.fdkankan.jp.xspace.vo;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/1/19
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SceneInfoVO {
+
+    /**
+     * 场景码
+     */
+    private String num;
+
+    /**
+     * 地面logo名称
+     */
+    private String floorLogo;
+
+    /**
+     * 地面logo大小
+     */
+    private Integer floorLogoSize;
+
+    /**
+     * 地面logo文件名称
+     */
+    private String floorLogoFile;
+
+    /**
+     * 背景音乐
+     */
+    private String music;
+
+    /**
+     * 背景音乐文件名称
+     */
+    private String musicFile;
+
+    /**
+     * 浏览密码
+     */
+    private String scenePassword;
+
+    /**
+     * 场景标题
+     */
+    private String title;
+
+    /**
+     * 场景描述
+     */
+    private String description;
+
+    private SceneEditControlsVO controls;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+//    /**
+//     * 点位数量
+//     */
+//    private Integer panoCount;
+//
+//    /**
+//     * 球幕视频数量
+//     */
+//    private Integer videoCount;
+
+    /**
+     * 版本
+     */
+    private Integer version;
+
+    /**
+     * 图片版本
+     */
+    private Integer imgVersion;
+
+    /**
+     * 场景关联版本
+     */
+    private Integer linkVersion;
+
+    /**
+     * 是否上传了户型图(0-否,1-是)
+     */
+    private Byte floorPlanUser;
+
+//    private String cadInfo;
+//
+//    private Byte isUploadObj;
+//
+//    private Integer floorEditVer;
+//
+//    private Integer floorPublishVer;
+
+    /**
+     * 初始点信息
+     */
+    private String entry;
+
+    /**
+     * 全景图加载方式,tiles/1k:1k瓦片图,tiles/2:2k瓦片图,tiles/4k:4k瓦片图,pan:全景图 ,local:本地切片,cube:立体图
+     */
+    private String sceneResolution;
+
+    /**
+     * 场景来源,lite:双目lite相机,pro:八目相机,minion:双面转台相机,laser:激光相机,virtual:虚拟场景,sketch:图片建模场景
+     */
+    private String sceneFrom;
+
+    /**
+     * 切图方式(tiles:瓦片图,face:切片图,pan:全景图 ,local:本地切片,cube:立体图)
+     */
+    private String sceneKind;
+
+    /**
+     * 算法模型类型(dam,3dtiles)
+     */
+    private String modelKind;
+
+    /**
+     * 空间视频数据
+     */
+    private String boxVideos;
+    /**
+     * 空间贴图数据
+     */
+    private String boxPhotos;
+
+    /**
+     * 空间模型数据
+     */
+    private String boxModels;
+
+    /**
+     *点位视频
+     */
+    private String videos;
+
+    /**
+     * 是否有热点数据
+     */
+    private Integer tags;
+
+    /**
+     * 加载logo名
+     */
+    private String loadingLogo;
+
+    /**
+     * 加载logo文件名
+     */
+    private String loadingLogoFile;
+
+    /**
+     * 数据同步方式
+     */
+    private String dataSync;
+
+    /**
+     * 户型角度
+     */
+    private Float floorPlanAngle;
+
+    /**
+     * 指南针角度
+     */
+    private Float floorPlanCompass;
+
+    /**
+     * 用户上传自定义平面图
+     */
+    private JSONArray floorPlanUpload;
+
+    /**
+     * 是否保存导览
+     */
+    private Integer tours;
+
+    /**
+     * 是否有马赛克
+     */
+    private Integer mosaic;
+
+    /**
+     * 马赛克列表
+     */
+    private List<JSONObject> mosaicList;
+
+    /**
+     * 水印文件名
+     */
+    private String waterMark;
+
+    /**
+     * 是否有场景关联(0-否,1-是)
+     */
+    private Integer links;
+
+    /**
+     * 是否有滤镜(0-否,1-是)
+     */
+    private Integer filters;
+
+    /**
+     * 是否有监控摄像头数据
+     */
+    private Integer surveillances;
+
+    /**
+     * 场景容量 单位 MB
+     */
+    private Integer space;
+
+    /**
+     * 分享信息
+     */
+    private JSONObject sns;
+
+    /**
+     * 是否有指示牌(0-否,1-是)
+     */
+    private Integer billboards;
+
+    /**
+     * 是否有模型裁剪(0-否,1-是)
+     */
+    private Integer cutModel = 0;
+
+    /**
+     * 启动页配置信息
+     */
+    private JSONObject started;
+
+
+}