xushiting 3 лет назад
Родитель
Сommit
db6a314e40
59 измененных файлов с 6079 добавлено и 0 удалено
  1. BIN
      dist/assets/BreathPoint_turing.47d4d03d.png
  2. 218 0
      dist/assets/config1.json
  3. BIN
      dist/assets/default-img.24b9c32e.png
  4. BIN
      dist/assets/env/environment_office.env
  5. BIN
      dist/assets/environment_office.env
  6. BIN
      dist/assets/zixunqiang.7c2c5bc8.png
  7. 1 0
      dist/css/index.3c280baa.css
  8. BIN
      dist/css/xverse_bg.d88826fa.png
  9. 363 0
      dist/libs/babylonjs.expand.js
  10. 7 0
      dist/libs/clipboard.min.js
  11. 415 0
      dist/libs/nipple.js
  12. 147 0
      dist/libs/super.js
  13. 15 0
      dist/libs/toastify-js.js
  14. 191 0
      dist/libs/utils.js
  15. 102 0
      src/AssetsStorage.js
  16. 17 0
      src/Avatar.js
  17. 18 0
      src/AvatarManager.js
  18. 35 0
      src/ByPasser.js
  19. 1245 0
      src/Constant.js
  20. 8 0
      src/Error/AbnormalDataStructureError.js
  21. 9 0
      src/Error/ConnectingAlreadyError.js
  22. 8 0
      src/Error/UnReachableError.js
  23. 61 0
      src/Marker.js
  24. 9 0
      src/Singleton.js
  25. 61 0
      src/Tracker.js
  26. 7 0
      src/WorldStore.js
  27. 105 0
      src/XAccessory.js
  28. 79 0
      src/XActor.js
  29. 41 0
      src/XActorComponent.js
  30. 74 0
      src/XArchive.js
  31. 55 0
      src/XEngineOption.js
  32. 160 0
      src/XJoystick.js
  33. 24 0
      src/XLevel.js
  34. 22 0
      src/XMatrix.js
  35. 645 0
      src/XMovementComponent.js
  36. 215 0
      src/XNavigationComponents.js
  37. 32 0
      src/XObject.js
  38. 9 0
      src/XPlane.js
  39. 102 0
      src/XPlayerController.js
  40. 642 0
      src/XRoom.js
  41. 205 0
      src/XSceneComponent.js
  42. 209 0
      src/XSequence.js
  43. 113 0
      src/XStream.js
  44. 32 0
      src/XWorld.js
  45. 146 0
      src/XverseAvatarTools.js
  46. 104 0
      src/XverseEffect.js
  47. 17 0
      src/XverseEngine.js
  48. 6 0
      src/enum/ChangeComponentsMode.js
  49. 21 0
      src/enum/ClickTargetName.js
  50. 14 0
      src/enum/ComponentItemType.js
  51. 6 0
      src/enum/EAllNicknameStatus.js
  52. 11 0
      src/enum/EDressType.js
  53. 7 0
      src/enum/EMotionType.js
  54. 10 0
      src/enum/FeatureSwitchEnum.js
  55. 5 0
      src/enum/IEffectType.js
  56. 8 0
      src/enum/MotionAnimtion.js
  57. 7 0
      src/enum/PathType.js
  58. 10 0
      src/enum/PointerEventTypes.js
  59. 6 0
      src/enum/TransferType.js

BIN
dist/assets/BreathPoint_turing.47d4d03d.png


+ 218 - 0
dist/assets/config1.json

@@ -0,0 +1,218 @@
+{
+    "code": 0,
+    "msg": "",
+    "data": {
+        "config": {
+            "avatars": [
+                {
+                    "id": "My_Actor",
+                    "name": "My_Actor",
+                    "url": "./assets/avatar/woman_0.zip",
+                    "gender": "man",
+                    "components": [],
+                    "animations": [
+                        {
+                            "name": "Walking",
+                            "url": "./assets/avatar/woman_0/animations/Walking.glb"
+                        },
+                        {
+                            "name": "Idle",
+                            "url": "./assets/avatar/woman_0/animations/Idle.glb"
+                        }
+                    ]
+                }
+            ],
+            "skins": [
+                {
+                    "id": "0000000001",
+                    "name": "梁启超_Cookonlymaps",
+                    "versionId": "00008",
+                    "isEnable": false,
+                    "fov": "90",
+                    "resolution": {
+                        "width": 1728,
+                        "height": 720
+                    },
+                    "assetList": [
+                        {
+                            "typeName": "MODEL",
+                            "className": "粗模",
+                            "assetId": "",
+                            "name": "KyotoAlley_Showcase.glb",
+                            "url": "./assets/level_L01_00006.glb",
+                            "thumbnailUrl": ""
+                        },
+                        {
+                          "typeName": "MODEL",
+                          "className": "TV",
+                          "assetId": "",
+                          "name": "yqtgTV_xverse.glb",
+                          "url": "https://app-mgt-resource-1258211750.file.myqcloud.com/model/fefa5e668b634bc283feb5d6769f95ad/yqtgTV_xverse.glb",
+                          "thumbnailUrl": ""
+                        },
+                        {
+                            "typeName": "CONFIG",
+                            "className": "环境光",
+                            "assetId": "",
+                            "name": "environment_musicfesti.env",
+                            "url": "./assets/environment_musicfesti.env",
+                            "thumbnailUrl": ""
+                        }
+                    ],
+                    "pointList": [],
+                    "routeList": [
+                        {
+                            "id": "thirdwalk",
+                            "birthPointList": [
+                                {
+                                    "player": {
+                                        "position": {
+                                            "x": "-727.49",
+                                            "y": "-1441.18",
+                                            "z": "-32.25"
+                                        },
+                                        "rotation": {
+                                            "pitch": "0.00",
+                                            "yaw": "0.00",
+                                            "roll": "0.00"
+                                        }
+                                    },
+                                    "camera": {
+                                        "position": {
+                                            "x": "-1047.49",
+                                            "y": "-1441.18",
+                                            "z": "87.75"
+                                        },
+                                        "rotation": {
+                                            "pitch": "0.00",
+                                            "yaw": "0.00",
+                                            "roll": "0.00"
+                                        }
+                                    }
+                                }
+                            ],
+                            "areaName": "LQC",
+                            "pathName": "thirdwalk",
+                            "attitude": "walk",
+                            "step": 5
+                        }
+                    ],
+                    "visibleRules": [],
+                    "animationList": [
+                        {
+                            "avatarId": "My_Actor",
+                            "animations": [
+                                "Walking",
+                                "Idle"
+                            ]
+                        }
+                    ]
+                }
+            ]
+        },
+        "preload": {
+            "version": "20220318183823",
+            "assetTotalSize": 24248947,
+            "assetUrls": [
+                {
+                    "url": "./assets/avatar/woman_0/component_list.json",
+                    "packName": "",
+                    "typeName": "avatar",
+                    "className": "",
+                    "skinId": "",
+                    "size": 14294
+                },
+                {
+                    "url": "./assets/avatar/woman_0/body.glb",
+                    "packName": "",
+                    "typeName": "avatar",
+                    "className": "",
+                    "skinId": "",
+                    "size": 137548
+                },
+                {
+                    "url": "./assets/avatar/woman_0/animations/Walking.glb",
+                    "packName": "",
+                    "typeName": "avatar",
+                    "className": "",
+                    "skinId": "",
+                    "size": 99844
+                },
+                {
+                    "url": "./assets/avatar/woman_0/animations/Idle.glb",
+                    "packName": "",
+                    "typeName": "avatar",
+                    "className": "",
+                    "skinId": "",
+                    "size": 208772
+                },
+                {
+                    "url": "./assets/level_L01.glb",
+                    "packName": "",
+                    "typeName": "MODEL",
+                    "className": "粗模",
+                    "skinId": "0000000001",
+                    "size": 3638904
+                },
+                {
+                    "url": "./assets/environment_musicfesti.env",
+                    "packName": "",
+                    "typeName": "CONFIG",
+                    "className": "环境光",
+                    "skinId": "0000000001",
+                    "size": 2723658
+                },
+                {
+                    "url": "./assets/textures/Point_Light.png",
+                    "packName": "",
+                    "typeName": "TEXTURES",
+                    "className": "贴图",
+                    "skinId": "",
+                    "size": 8463
+                },
+                {
+                    "url": "./assets/textures/Light_tex0.png",
+                    "packName": "",
+                    "typeName": "TEXTURES",
+                    "className": "贴图",
+                    "skinId": "",
+                    "size": 7478
+                },
+                {
+                    "url": "./assets/textures/Light_tex1.png",
+                    "packName": "",
+                    "typeName": "TEXTURES",
+                    "className": "贴图",
+                    "skinId": "",
+                    "size": 26724
+                },
+                {
+                    "url": "./assets/textures/Light_tex2.png",
+                    "packName": "",
+                    "typeName": "TEXTURES",
+                    "className": "贴图",
+                    "skinId": "",
+                    "size": 28517
+                },
+                {
+                    "url": "./assets/textures/VS_Disco.png",
+                    "packName": "",
+                    "typeName": "TEXTURES",
+                    "className": "贴图",
+                    "skinId": "",
+                    "size": 8842
+                },
+                {
+                    "url": "./assets/textures/NM_Door.png",
+                    "packName": "",
+                    "typeName": "TEXTURES",
+                    "className": "贴图",
+                    "skinId": "",
+                    "size": 271090
+                }
+            ],
+            "baseUrls": [],
+            "observeUrls": []
+        }
+    }
+}

BIN
dist/assets/default-img.24b9c32e.png


BIN
dist/assets/env/environment_office.env


BIN
dist/assets/environment_office.env


BIN
dist/assets/zixunqiang.7c2c5bc8.png


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
dist/css/index.3c280baa.css


BIN
dist/css/xverse_bg.d88826fa.png


+ 363 - 0
dist/libs/babylonjs.expand.js

@@ -0,0 +1,363 @@
+BABYLON.AssetContainer.prototype.clone = function(d, o=!0, s, c=!0) {
+    const _ = new BABYLON.AssetContainer(this.scene);
+    d || (d = "");
+    const b = tt=>d + "_CloneOf_" + tt
+      , k = {}
+      , j = {}
+      , $ = []
+      , _e = [];
+    s || (s = {
+        doNotInstantiate: !0
+    });
+    const et = (tt,rt)=>{
+        if (k[tt.uniqueId] = rt.uniqueId,
+        j[rt.uniqueId] = rt,
+        b && (rt.name = b(tt.name)),
+        rt instanceof Mesh) {
+            const it = rt;
+            if (_.meshes.push(rt),
+            rt.geometry && _.geometries.push(rt.geometry),
+            it.morphTargetManager) {
+                const nt = tt.morphTargetManager;
+                it.morphTargetManager = nt.clone(),
+                _.morphTargetManagers.push(it.morphTargetManager);
+                for (let at = 0; at < nt.numTargets; at++) {
+                    const ot = nt.getTarget(at)
+                      , st = it.morphTargetManager.getTarget(at);
+                    k[ot.uniqueId] = st.uniqueId,
+                    j[st.uniqueId] = st
+                }
+            }
+        } else
+            rt instanceof TransformNode && _.transformNodes.push(rt)
+    }
+    ;
+    return this.transformNodes.forEach(tt=>{
+        if (!tt.parent) {
+            const rt = tt.instantiateHierarchy(null, s, (it,nt)=>{
+                et(it, nt)
+            }
+            );
+            rt && _.rootNodes.push(rt)
+        }
+    }
+    ),
+    this.meshes.forEach(tt=>{
+        if (!tt.parent) {
+            const rt = tt.instantiateHierarchy(null, s, (it,nt)=>{
+                if (et(it, nt),
+                nt.material) {
+                    const at = nt;
+                    if (at.material)
+                        if (o) {
+                            const ot = it.material;
+                            if (_e.indexOf(ot) === -1) {
+                                let st = ot.clone(b ? b(ot.name) : "Clone of " + ot.name);
+                                if (_.materials.push(st),
+                                _e.push(ot),
+                                k[ot.uniqueId] = st.uniqueId,
+                                j[st.uniqueId] = st,
+                                ot.getClassName() === "MultiMaterial") {
+                                    const lt = ot;
+                                    for (const ut of lt.subMaterials)
+                                        !ut || (st = ut.clone(b ? b(ut.name) : "Clone of " + ut.name),
+                                        _e.push(ut),
+                                        k[ut.uniqueId] = st.uniqueId,
+                                        j[st.uniqueId] = st);
+                                    lt.subMaterials = lt.subMaterials.map(ut=>ut && j[k[ut.uniqueId]]),
+                                    _.multiMaterials.push(lt)
+                                }
+                            }
+                            at.getClassName() !== "InstancedMesh" && (at.material = j[k[ot.uniqueId]])
+                        } else
+                            at.material.getClassName() === "MultiMaterial" ? (this.scene.multiMaterials.indexOf(at.material) === -1 && this.scene.addMultiMaterial(at.material),
+                            _.multiMaterials.indexOf(at.material) === -1 && _.multiMaterials.push(at.material)) : (this.scene.materials.indexOf(at.material) === -1 && this.scene.addMaterial(at.material),
+                            _.materials.indexOf(at.material) === -1 && _.materials.push(at.material))
+                }
+            }
+            );
+            rt && _.rootNodes.push(rt)
+        }
+    }
+    ),
+    this.skeletons.forEach(tt=>{
+        const rt = tt.clone(b ? b(tt.name) : "Clone of " + tt.name);
+        tt.overrideMesh && (rt.overrideMesh = j[k[tt.overrideMesh.uniqueId]]);
+        for (const it of this.meshes)
+            if (it.skeleton === tt && !it.isAnInstance) {
+                const nt = j[k[it.uniqueId]];
+                if (nt.isAnInstance || (nt.skeleton = rt,
+                $.indexOf(rt) !== -1))
+                    continue;
+                $.push(rt);
+                for (const at of rt.bones)
+                    at._linkedTransformNode && (at._linkedTransformNode = j[k[at._linkedTransformNode.uniqueId]])
+            }
+        _.skeletons.push(rt)
+    }
+    ),
+    this.animationGroups.forEach(tt=>{
+        const rt = tt.clone(tt.name, it=>j[k[it.uniqueId]] || it, c);
+        _.animationGroups.push(rt)
+    }
+    ),
+    this.textures.forEach(tt=>{
+        const rt = tt.clone();
+        rt && _.textures.push(rt)
+    }
+    ),
+    this.cameras.forEach(tt=>{
+        _.cameras.push(tt.clone(b(tt.name)))
+    }
+    ),
+    this.lights.forEach(tt=>{
+        const rt = tt.clone(b(tt.name));
+        rt && _.lights.push(rt)
+    }
+    ),
+    _
+}
+;
+BABYLON.AssetContainer.prototype.GetName = function() {
+    return this._name || (this._name = ""),
+    this._name
+}
+;
+BABYLON.AssetContainer.prototype.SetName = function(d) {
+    this._name = d
+}
+;
+BABYLON.AssetContainer.prototype.GetRootNode = function() {
+    return this._rootNode || (this._rootNode = this.meshes[0]),
+    this._rootNode
+}
+;
+BABYLON.AssetContainer.prototype.CreateRootNodeByName = function(d) {
+    const o = new Mesh("BABYLON.AssetContainerRootMesh_" + d,this.scene);
+    return this.meshes.forEach(s=>{
+        s.parent || o.addChild(s)
+    }
+    ),
+    this.meshes.unshift(o),
+    o
+}
+;
+BABYLON.AssetContainer.prototype.GetMeshesWithoutParent = function() {
+    const d = new Array;
+    return this.meshes.forEach(o=>{
+        o.parent || d.push(o)
+    }
+    ),
+    d
+}
+;
+BABYLON.AssetContainer.prototype.GetOwner = function() {
+    return this._owner
+}
+;
+BABYLON.AssetContainer.prototype.SetOwner = function(d) {
+    this._owner || (this._owner = new XObject),
+    this._owner = d
+}
+;
+BABYLON.AssetContainer.prototype.toJSON = function() {
+    const d = this.GetOwner()
+      , o = d == null ? void 0 : d.outer;
+    return o ? o.SaveAsset(this) : ""
+}
+;
+BABYLON.AssetContainer.prototype.getClassName = function() {
+    return "BABYLON.AssetContainer"
+}
+;
+
+
+
+function CreateScreenshot(d, o, s, c, _="image/png", b=!1) {
+    const {height: k, width: j} = _getScreenshotSize(d, o, s);
+    if (console.info("[Engine]CreateScreenshot!"),
+    !(k && j)) {
+        console.error("[Engine]CreateScreenshot Invalid 'size' parameter !");
+        return
+    }
+    BABYLON.Tools._ScreenshotCanvas || (BABYLON.Tools._ScreenshotCanvas = document.createElement("canvas")),
+    BABYLON.Tools._ScreenshotCanvas.width = j,
+    BABYLON.Tools._ScreenshotCanvas.height = k;
+    const $ = BABYLON.Tools._ScreenshotCanvas.getContext("2d")
+      , _e = d.getRenderWidth() / d.getRenderHeight();
+    let et = j
+      , tt = et / _e;
+    tt > k && (tt = k,
+    et = tt * _e);
+    const rt = Math.max(0, j - et) / 2
+      , it = Math.max(0, k - tt) / 2;
+    o.getScene().onAfterRenderObservable.addOnce(function() {
+        const at = d.getRenderingCanvas();
+        $ && at ? $.drawImage(at, rt, it, et, tt) : console.error("[Engine]CreateScreenshot Invalid renderContext and renderingCanvas!"),
+        b ? (BABYLON.Tools.EncodeScreenshotCanvasData(void 0, _),
+        c && c("")) : BABYLON.Tools.EncodeScreenshotCanvasData(c, _)
+    })
+}
+
+
+function CreateScreenshotAsync(d, o, s, c="image/png") {
+    return new Promise((_,b)=>{
+        CreateScreenshot(d, o, s, k=>{
+            typeof k != "undefined" ? _(k) : b(new Error("Data is undefined"))
+        }
+        , c)
+    }
+    )
+}
+function CreateScreenshotUsingRenderTarget(d, o, s, c, _="image/png", b=1, k=!1, j, $=!1, _e=!1) {
+    const {height: et, width: tt} = _getScreenshotSize(d, o, s)
+      , rt = {
+        width: tt,
+        height: et
+    };
+    if (!(et && tt)) {
+        console.error("Invalid 'size' parameter !");
+        return
+    }
+    const it = o.getScene();
+    let nt = null;
+    const at = it.activeCameras;
+    it.activeCameras = null,
+    it.activeCamera !== o && (nt = it.activeCamera,
+    it.activeCamera = o),
+    it.render();
+    const ot = new RenderTargetTexture("screenShot",rt,it,!1,!1,Constants.TEXTURETYPE_UNSIGNED_INT,!1,Texture.NEAREST_SAMPLINGMODE,void 0,_e,void 0,void 0,void 0,b);
+    ot.renderList = null,
+    ot.samples = b,
+    ot.renderSprites = $,
+    it.onAfterRenderTargetsRenderObservable.addOnce(function() {
+        ot.readPixels(void 0, void 0, void 0, !1).then(lt=>{
+            BABYLON.Tools.DumpData(tt, et, lt, c, _, j, !0),
+            ot.dispose()
+        }
+        )
+    });
+    const st = ()=>{
+        it.incrementRenderId(),
+        it.resetCachedMaterial(),
+        ot.render(!0),
+        it.incrementRenderId(),
+        it.resetCachedMaterial(),
+        nt && (it.activeCamera = nt),
+        it.activeCameras = at,
+        o.getProjectionMatrix(!0),
+        it.render()
+    }
+    ;
+    if (k) {
+        const lt = new FxaaPostProcess("antialiasing",1,it.activeCamera);
+        ot.addPostProcess(lt),
+        lt.getEffect().isReady() ? st() : lt.getEffect().onCompiled = ()=>{
+            st()
+        }
+    } else
+        st()
+}
+function CreateScreenshotUsingRenderTargetAsync(d, o, s, c="image/png", _=1, b=!1, k, j=!1) {
+    return new Promise(($,_e)=>{
+        CreateScreenshotUsingRenderTarget(d, o, s, et=>{
+            typeof et != "undefined" ? $(et) : _e(new Error("Data is undefined"))
+        }
+        , c, _, b, k, j)
+    }
+    )
+}
+function _getScreenshotSize(d, o, s) {
+    let c = 0
+      , _ = 0;
+    if (typeof s == "object") {
+        const b = s.precision ? Math.abs(s.precision) : 1;
+        s.width && s.height ? (c = s.height * b,
+        _ = s.width * b) : s.width && !s.height ? (_ = s.width * b,
+        c = Math.round(_ / d.getAspectRatio(o))) : s.height && !s.width ? (c = s.height * b,
+        _ = Math.round(c * d.getAspectRatio(o))) : (_ = Math.round(d.getRenderWidth() * b),
+        c = Math.round(_ / d.getAspectRatio(o)))
+    } else
+        isNaN(s) || (c = s,
+        _ = s);
+    return _ && (_ = Math.floor(_)),
+    c && (c = Math.floor(c)),
+    {
+        height: c | 0,
+        width: _ | 0
+    }
+}
+const initSideEffects = ()=>{
+    BABYLON.Tools.CreateScreenshot = CreateScreenshot,
+    BABYLON.Tools.CreateScreenshotAsync = CreateScreenshotAsync,
+    BABYLON.Tools.CreateScreenshotUsingRenderTarget = CreateScreenshotUsingRenderTarget,
+    BABYLON.Tools.CreateScreenshotUsingRenderTargetAsync = CreateScreenshotUsingRenderTargetAsync
+}
+;
+
+BABYLON.ParticleSystem.prototype.isReady = function() {
+    if (!this.emitter || this._imageProcessingConfiguration && !this._imageProcessingConfiguration.isReady())
+        return !1;
+    if (this.blendMode !== BABYLON.ParticleSystem.BLENDMODE_MULTIPLYADD) {
+        if (!this._getWrapper(this.blendMode).effect.isReady())
+            return !1
+    } else if (!this._getWrapper(BABYLON.ParticleSystem.BLENDMODE_MULTIPLY).effect.isReady() || !this._getWrapper(BABYLON.ParticleSystem.BLENDMODE_ADD).effect.isReady())
+        return !1;
+    return !0
+}
+;
+
+
+function LinearBezierCurves(d, o, s) {
+    return BABYLON.Vector3.Lerp(o, s, 1 - d)
+}
+function QuadraticBezierCurves(d, o, s, c) {
+    const _ = LinearBezierCurves(d, o, s)
+      , b = LinearBezierCurves(d, s, c);
+    return LinearBezierCurves(d, _, b)
+}
+function CubicBezierCurves(d, o, s, c, _) {
+    const b = QuadraticBezierCurves(d, o, s, c)
+      , k = QuadraticBezierCurves(d, s, c, _);
+    return LinearBezierCurves(d, b, k)
+}
+function CardinalMultiply(d, o, s, c, _, b) {
+    const k = d[0] * o + d[1] * s + d[2] * c + d[3] * _
+      , j = d[4] * o + d[5] * s + d[6] * c + d[7] * _
+      , $ = d[8] * o + d[9] * s + d[10] * c + d[11] * _;
+    return d[12] * o + d[13] * s + d[14] * c + d[15] * _ + b * ($ + b * (j + b * k))
+}
+function CardinalCurves(d, o, s, c, _, b) {
+    const k = new Array(16)
+      , j = b;
+    return k[0] = -j,
+    k[1] = 2 - j,
+    k[2] = j - 2,
+    k[3] = j,
+    k[4] = 2 * j,
+    k[5] = j - 3,
+    k[8] = -j,
+    k[9] = 0,
+    k[12] = 0,
+    k[13] = 1,
+    k[6] = 3 - 2 * j,
+    k[7] = -j,
+    k[10] = j,
+    k[11] = 0,
+    k[14] = 0,
+    k[15] = 0,
+    new BABYLON.Vector3(CardinalMultiply(k, o.x, s.x, c.x, _.x, d),CardinalMultiply(k, o.y, s.y, c.y, _.x, d),CardinalMultiply(k, o.z, s.z, c.z, _.x, d))
+}
+function HermiteCurves(d, o, s, c, _) {
+    const b = Math.pow(d, 3)
+      , k = Math.pow(d, 2)
+      , j = 2 * b - 3 * k + 1
+      , $ = -2 * b + 3 * k
+      , _e = b - 2 * k + d
+      , et = b - k
+      , tt = o.multiplyByFloats(j, j, j)
+      , rt = s.multiplyByFloats($, $, $)
+      , it = c.multiplyByFloats(_e, _e, _e)
+      , nt = _.multiplyByFloats(et, et, et);
+    return tt.add(rt.add(it).add(nt))
+}

Разница между файлами не показана из-за своего большого размера
+ 7 - 0
dist/libs/clipboard.min.js


+ 415 - 0
dist/libs/nipple.js

@@ -0,0 +1,415 @@
+import Super from './super';
+import * as u from './utils';
+
+///////////////////////
+///   THE NIPPLE    ///
+///////////////////////
+
+function Nipple (collection, options) {
+    this.identifier = options.identifier;
+    this.position = options.position;
+    this.frontPosition = options.frontPosition;
+    this.collection = collection;
+
+    // Defaults
+    this.defaults = {
+        size: 100,
+        threshold: 0.1,
+        color: 'white',
+        fadeTime: 250,
+        dataOnly: false,
+        restJoystick: true,
+        restOpacity: 0.5,
+        mode: 'dynamic',
+        zone: document.body,
+        lockX: false,
+        lockY: false,
+        shape: 'circle'
+    };
+
+    this.config(options);
+
+    // Overwrites
+    if (this.options.mode === 'dynamic') {
+        this.options.restOpacity = 0;
+    }
+
+    this.id = Nipple.id;
+    Nipple.id += 1;
+    this.buildEl()
+        .stylize();
+
+    // Nipple's API.
+    this.instance = {
+        el: this.ui.el,
+        on: this.on.bind(this),
+        off: this.off.bind(this),
+        show: this.show.bind(this),
+        hide: this.hide.bind(this),
+        add: this.addToDom.bind(this),
+        remove: this.removeFromDom.bind(this),
+        destroy: this.destroy.bind(this),
+        setPosition:this.setPosition.bind(this),
+        resetDirection: this.resetDirection.bind(this),
+        computeDirection: this.computeDirection.bind(this),
+        trigger: this.trigger.bind(this),
+        position: this.position,
+        frontPosition: this.frontPosition,
+        ui: this.ui,
+        identifier: this.identifier,
+        id: this.id,
+        options: this.options
+    };
+
+    return this.instance;
+}
+
+Nipple.prototype = new Super();
+Nipple.constructor = Nipple;
+Nipple.id = 0;
+
+// Build the dom element of the Nipple instance.
+Nipple.prototype.buildEl = function (options) {
+    this.ui = {};
+
+    if (this.options.dataOnly) {
+        return this;
+    }
+
+    this.ui.el = document.createElement('div');
+    this.ui.back = document.createElement('div');
+    this.ui.front = document.createElement('div');
+
+    this.ui.el.className = 'nipple collection_' + this.collection.id;
+    this.ui.back.className = 'back';
+    this.ui.front.className = 'front';
+
+    this.ui.el.setAttribute('id', 'nipple_' + this.collection.id +
+        '_' + this.id);
+
+    this.ui.el.appendChild(this.ui.back);
+    this.ui.el.appendChild(this.ui.front);
+
+    return this;
+};
+
+// Apply CSS to the Nipple instance.
+Nipple.prototype.stylize = function () {
+    if (this.options.dataOnly) {
+        return this;
+    }
+    var animTime = this.options.fadeTime + 'ms';
+    var borderStyle = u.getVendorStyle('borderRadius', '50%');
+    var transitStyle = u.getTransitionStyle('transition', 'opacity', animTime);
+    var styles = {};
+    styles.el = {
+        position: 'absolute',
+        opacity: this.options.restOpacity,
+        display: 'block',
+        'zIndex': 999
+    };
+
+    styles.back = {
+        position: 'absolute',
+        display: 'block',
+        width: this.options.size + 'px',
+        height: this.options.size + 'px',
+        marginLeft: -this.options.size / 2 + 'px',
+        marginTop: -this.options.size / 2 + 'px',
+        background: this.options.color,
+        'opacity': '.5'
+    };
+
+    styles.front = {
+        width: this.options.size / 2 + 'px',
+        height: this.options.size / 2 + 'px',
+        position: 'absolute',
+        display: 'block',
+        marginLeft: -this.options.size / 4 + 'px',
+        marginTop: -this.options.size / 4 + 'px',
+        background: this.options.color,
+        'opacity': '.5'
+    };
+
+    u.extend(styles.el, transitStyle);
+    if(this.options.shape === 'circle'){
+        u.extend(styles.back, borderStyle);
+    }
+    u.extend(styles.front, borderStyle);
+
+    this.applyStyles(styles);
+
+    return this;
+};
+
+Nipple.prototype.applyStyles = function (styles) {
+    // Apply styles
+    for (var i in this.ui) {
+        if (this.ui.hasOwnProperty(i)) {
+            for (var j in styles[i]) {
+                this.ui[i].style[j] = styles[i][j];
+            }
+        }
+    }
+
+    return this;
+};
+
+// Inject the Nipple instance into DOM.
+Nipple.prototype.addToDom = function () {
+    // We're not adding it if we're dataOnly or already in dom.
+    if (this.options.dataOnly || document.body.contains(this.ui.el)) {
+        return this;
+    }
+    this.options.zone.appendChild(this.ui.el);
+    return this;
+};
+
+// Remove the Nipple instance from DOM.
+Nipple.prototype.removeFromDom = function () {
+    if (this.options.dataOnly || !document.body.contains(this.ui.el)) {
+        return this;
+    }
+    this.options.zone.removeChild(this.ui.el);
+    return this;
+};
+
+// Entirely destroy this nipple
+Nipple.prototype.destroy = function () {
+    clearTimeout(this.removeTimeout);
+    clearTimeout(this.showTimeout);
+    clearTimeout(this.restTimeout);
+    this.trigger('destroyed', this.instance);
+    this.removeFromDom();
+    this.off();
+};
+
+// Fade in the Nipple instance.
+Nipple.prototype.show = function (cb) {
+    var self = this;
+
+    if (self.options.dataOnly) {
+        return self;
+    }
+
+    clearTimeout(self.removeTimeout);
+    clearTimeout(self.showTimeout);
+    clearTimeout(self.restTimeout);
+
+    self.addToDom();
+
+    self.restCallback();
+
+    setTimeout(function () {
+        self.ui.el.style.opacity = 1;
+    }, 0);
+
+    self.showTimeout = setTimeout(function () {
+        self.trigger('shown', self.instance);
+        if (typeof cb === 'function') {
+            cb.call(this);
+        }
+    }, self.options.fadeTime);
+
+    return self;
+};
+
+// Fade out the Nipple instance.
+Nipple.prototype.hide = function (cb) {
+    var self = this;
+
+    if (self.options.dataOnly) {
+        return self;
+    }
+
+    self.ui.el.style.opacity = self.options.restOpacity;
+
+    clearTimeout(self.removeTimeout);
+    clearTimeout(self.showTimeout);
+    clearTimeout(self.restTimeout);
+
+    self.removeTimeout = setTimeout(
+        function () {
+            var display = self.options.mode === 'dynamic' ? 'none' : 'block';
+            self.ui.el.style.display = display;
+            if (typeof cb === 'function') {
+                cb.call(self);
+            }
+
+            self.trigger('hidden', self.instance);
+        },
+        self.options.fadeTime
+    );
+
+    if (self.options.restJoystick) {
+        const rest = self.options.restJoystick;
+        const newPosition = {};
+
+        newPosition.x = rest === true || rest.x !== false ? 0 : self.instance.frontPosition.x;
+        newPosition.y = rest === true || rest.y !== false ? 0 : self.instance.frontPosition.y;
+
+        self.setPosition(cb, newPosition);
+    }
+
+    return self;
+};
+
+// Set the nipple to the specified position
+Nipple.prototype.setPosition = function (cb, position) {
+    var self = this;
+    self.frontPosition = {
+        x: position.x,
+        y: position.y
+    };
+    var animTime = self.options.fadeTime + 'ms';
+
+    var transitStyle = {};
+    transitStyle.front = u.getTransitionStyle('transition',
+        ['top', 'left'], animTime);
+
+    var styles = {front: {}};
+    styles.front = {
+        left: self.frontPosition.x + 'px',
+        top: self.frontPosition.y + 'px'
+    };
+
+    self.applyStyles(transitStyle);
+    self.applyStyles(styles);
+
+    self.restTimeout = setTimeout(
+        function () {
+            if (typeof cb === 'function') {
+                cb.call(self);
+            }
+            self.restCallback();
+        },
+        self.options.fadeTime
+    );
+};
+
+Nipple.prototype.restCallback = function () {
+    var self = this;
+    var transitStyle = {};
+    transitStyle.front = u.getTransitionStyle('transition', 'none', '');
+    self.applyStyles(transitStyle);
+    self.trigger('rested', self.instance);
+};
+
+Nipple.prototype.resetDirection = function () {
+    // Fully rebuild the object to let the iteration possible.
+    this.direction = {
+        x: false,
+        y: false,
+        angle: false
+    };
+};
+
+Nipple.prototype.computeDirection = function (obj) {
+    var rAngle = obj.angle.radian;
+    var angle45 = Math.PI / 4;
+    var angle90 = Math.PI / 2;
+    var direction, directionX, directionY;
+
+    // Angular direction
+    //     \  UP /
+    //      \   /
+    // LEFT       RIGHT
+    //      /   \
+    //     /DOWN \
+    //
+    if (
+        rAngle > angle45 &&
+        rAngle < (angle45 * 3) &&
+        !obj.lockX
+    ) {
+        direction = 'up';
+    } else if (
+        rAngle > -angle45 &&
+        rAngle <= angle45 &&
+        !obj.lockY
+    ) {
+        direction = 'left';
+    } else if (
+        rAngle > (-angle45 * 3) &&
+        rAngle <= -angle45 &&
+        !obj.lockX
+    ) {
+        direction = 'down';
+    } else if (!obj.lockY) {
+        direction = 'right';
+    }
+
+    // Plain direction
+    //    UP                 |
+    // _______               | RIGHT
+    //                  LEFT |
+    //   DOWN                |
+    if (!obj.lockY) {
+        if (rAngle > -angle90 && rAngle < angle90) {
+            directionX = 'left';
+        } else {
+            directionX = 'right';
+        }
+    }
+
+    if (!obj.lockX) {
+        if (rAngle > 0) {
+            directionY = 'up';
+        } else {
+            directionY = 'down';
+        }
+    }
+
+    if (obj.force > this.options.threshold) {
+        var oldDirection = {};
+        var i;
+        for (i in this.direction) {
+            if (this.direction.hasOwnProperty(i)) {
+                oldDirection[i] = this.direction[i];
+            }
+        }
+
+        var same = {};
+
+        this.direction = {
+            x: directionX,
+            y: directionY,
+            angle: direction
+        };
+
+        obj.direction = this.direction;
+
+        for (i in oldDirection) {
+            if (oldDirection[i] === this.direction[i]) {
+                same[i] = true;
+            }
+        }
+
+        // If all 3 directions are the same, we don't trigger anything.
+        if (same.x && same.y && same.angle) {
+            return obj;
+        }
+
+        if (!same.x || !same.y) {
+            this.trigger('plain', obj);
+        }
+
+        if (!same.x) {
+            this.trigger('plain:' + directionX, obj);
+        }
+
+        if (!same.y) {
+            this.trigger('plain:' + directionY, obj);
+        }
+
+        if (!same.angle) {
+            this.trigger('dir dir:' + direction, obj);
+        }
+    } else {
+        this.resetDirection();
+    }
+
+    return obj;
+};
+
+export default Nipple;

+ 147 - 0
dist/libs/super.js

@@ -0,0 +1,147 @@
+///////////////////////
+///   SUPER CLASS   ///
+///////////////////////
+import * as u from './utils';
+
+// Constants
+var isTouch = !!('ontouchstart' in window);
+var isPointer = window.PointerEvent ? true : false;
+var isMSPointer = window.MSPointerEvent ? true : false;
+var events = {
+    touch: {
+        start: 'touchstart',
+        move: 'touchmove',
+        end: 'touchend, touchcancel'
+    },
+    mouse: {
+        start: 'mousedown',
+        move: 'mousemove',
+        end: 'mouseup'
+    },
+    pointer: {
+        start: 'pointerdown',
+        move: 'pointermove',
+        end: 'pointerup, pointercancel'
+    },
+    MSPointer: {
+        start: 'MSPointerDown',
+        move: 'MSPointerMove',
+        end: 'MSPointerUp'
+    }
+};
+var toBind;
+var secondBind = {};
+if (isPointer) {
+    toBind = events.pointer;
+} else if (isMSPointer) {
+    toBind = events.MSPointer;
+} else if (isTouch) {
+    toBind = events.touch;
+    secondBind = events.mouse;
+} else {
+    toBind = events.mouse;
+}
+
+function Super () {}
+
+// Basic event system.
+Super.prototype.on = function (arg, cb) {
+    var self = this;
+    var types = arg.split(/[ ,]+/g);
+    var type;
+    self._handlers_ = self._handlers_ || {};
+
+    for (var i = 0; i < types.length; i += 1) {
+        type = types[i];
+        self._handlers_[type] = self._handlers_[type] || [];
+        self._handlers_[type].push(cb);
+    }
+    return self;
+};
+
+Super.prototype.off = function (type, cb) {
+    var self = this;
+    self._handlers_ = self._handlers_ || {};
+
+    if (type === undefined) {
+        self._handlers_ = {};
+    } else if (cb === undefined) {
+        self._handlers_[type] = null;
+    } else if (self._handlers_[type] &&
+            self._handlers_[type].indexOf(cb) >= 0) {
+        self._handlers_[type].splice(self._handlers_[type].indexOf(cb), 1);
+    }
+
+    return self;
+};
+
+Super.prototype.trigger = function (arg, data) {
+    var self = this;
+    var types = arg.split(/[ ,]+/g);
+    var type;
+    self._handlers_ = self._handlers_ || {};
+
+    for (var i = 0; i < types.length; i += 1) {
+        type = types[i];
+        if (self._handlers_[type] && self._handlers_[type].length) {
+            self._handlers_[type].forEach(function (handler) {
+                handler.call(self, {
+                    type: type,
+                    target: self
+                }, data);
+            });
+        }
+    }
+};
+
+// Configuration
+Super.prototype.config = function (options) {
+    var self = this;
+    self.options = self.defaults || {};
+    if (options) {
+        self.options = u.safeExtend(self.options, options);
+    }
+};
+
+// Bind internal events.
+Super.prototype.bindEvt = function (el, type) {
+    var self = this;
+    self._domHandlers_ = self._domHandlers_ || {};
+
+    self._domHandlers_[type] = function () {
+        if (typeof self['on' + type] === 'function') {
+            self['on' + type].apply(self, arguments);
+        } else {
+            // eslint-disable-next-line no-console
+            console.warn('[WARNING] : Missing "on' + type + '" handler.');
+        }
+    };
+
+    u.bindEvt(el, toBind[type], self._domHandlers_[type]);
+
+    if (secondBind[type]) {
+        // Support for both touch and mouse at the same time.
+        u.bindEvt(el, secondBind[type], self._domHandlers_[type]);
+    }
+
+    return self;
+};
+
+// Unbind dom events.
+Super.prototype.unbindEvt = function (el, type) {
+    var self = this;
+    self._domHandlers_ = self._domHandlers_ || {};
+
+    u.unbindEvt(el, toBind[type], self._domHandlers_[type]);
+
+    if (secondBind[type]) {
+        // Support for both touch and mouse at the same time.
+        u.unbindEvt(el, secondBind[type], self._domHandlers_[type]);
+    }
+
+    delete self._domHandlers_[type];
+
+    return this;
+};
+
+export default Super;

Разница между файлами не показана из-за своего большого размера
+ 15 - 0
dist/libs/toastify-js.js


+ 191 - 0
dist/libs/utils.js

@@ -0,0 +1,191 @@
+///////////////////////
+///      UTILS      ///
+///////////////////////
+
+export const distance = (p1, p2) => {
+    const dx = p2.x - p1.x;
+    const dy = p2.y - p1.y;
+
+    return Math.sqrt((dx * dx) + (dy * dy));
+};
+
+export const angle = (p1, p2) => {
+    const dx = p2.x - p1.x;
+    const dy = p2.y - p1.y;
+
+    return degrees(Math.atan2(dy, dx));
+};
+
+export const findCoord = (p, d, a) => {
+    const b = {x: 0, y: 0};
+    a = radians(a);
+    b.x = p.x - d * Math.cos(a);
+    b.y = p.y - d * Math.sin(a);
+    return b;
+};
+
+export const radians = (a) => {
+    return a * (Math.PI / 180);
+};
+
+export const degrees = (a) => {
+    return a * (180 / Math.PI);
+};
+
+export const isPressed = (evt) => {
+    if (isNaN(evt.buttons)) {
+        return evt.pressure !== 0;
+    }
+    return evt.buttons !== 0;
+};
+
+const timers = new Map();
+export const throttle = (cb) => {
+    if (timers.has(cb)) {
+        clearTimeout(timers.get(cb));
+    }
+    timers.set(cb, setTimeout(cb, 100));
+};
+
+export const bindEvt = (el, arg, handler) => {
+    const types = arg.split(/[ ,]+/g);
+    let type;
+    for (let i = 0; i < types.length; i += 1) {
+        type = types[i];
+        if (el.addEventListener) {
+            el.addEventListener(type, handler, false);
+        } else if (el.attachEvent) {
+            el.attachEvent(type, handler);
+        }
+    }
+};
+
+export const unbindEvt = (el, arg, handler) => {
+    const types = arg.split(/[ ,]+/g);
+    let type;
+    for (let i = 0; i < types.length; i += 1) {
+        type = types[i];
+        if (el.removeEventListener) {
+            el.removeEventListener(type, handler);
+        } else if (el.detachEvent) {
+            el.detachEvent(type, handler);
+        }
+    }
+};
+
+export const trigger = (el, type, data) => {
+    const evt = new CustomEvent(type, data);
+    el.dispatchEvent(evt);
+};
+
+export const prepareEvent = (evt) => {
+    evt.preventDefault();
+    return evt.type.match(/^touch/) ? evt.changedTouches : evt;
+};
+
+export const getScroll = () => {
+    const x = (window.pageXOffset !== undefined) ?
+        window.pageXOffset :
+        (document.documentElement || document.body.parentNode || document.body)
+            .scrollLeft;
+
+    const y = (window.pageYOffset !== undefined) ?
+        window.pageYOffset :
+        (document.documentElement || document.body.parentNode || document.body)
+            .scrollTop;
+    return {
+        x: x,
+        y: y
+    };
+};
+
+export const applyPosition = (el, pos) => {
+    if (pos.top || pos.right || pos.bottom || pos.left) {
+        el.style.top = pos.top;
+        el.style.right = pos.right;
+        el.style.bottom = pos.bottom;
+        el.style.left = pos.left;
+    } else {
+        el.style.left = pos.x + 'px';
+        el.style.top = pos.y + 'px';
+    }
+};
+
+export const getTransitionStyle = (property, values, time) => {
+    const obj = configStylePropertyObject(property);
+    for (let i in obj) {
+        if (obj.hasOwnProperty(i)) {
+            if (typeof values === 'string') {
+                obj[i] = values + ' ' + time;
+            } else {
+                let st = '';
+                for (let j = 0, max = values.length; j < max; j += 1) {
+                    st += values[j] + ' ' + time + ', ';
+                }
+                obj[i] = st.slice(0, -2);
+            }
+        }
+    }
+    return obj;
+};
+
+export const getVendorStyle = (property, value) => {
+    const obj = configStylePropertyObject(property);
+    for (let i in obj) {
+        if (obj.hasOwnProperty(i)) {
+            obj[i] = value;
+        }
+    }
+    return obj;
+};
+
+export const configStylePropertyObject = (prop) => {
+    const obj = {};
+    obj[prop] = '';
+    const vendors = ['webkit', 'Moz', 'o'];
+    vendors.forEach(function (vendor) {
+        obj[vendor + prop.charAt(0).toUpperCase() + prop.slice(1)] = '';
+    });
+    return obj;
+};
+
+export const extend = (objA, objB) => {
+    for (let i in objB) {
+        if (objB.hasOwnProperty(i)) {
+            objA[i] = objB[i];
+        }
+    }
+    return objA;
+};
+
+// Overwrite only what's already present
+export const safeExtend = (objA, objB) => {
+    const obj = {};
+    for (let i in objA) {
+        if (objA.hasOwnProperty(i) && objB.hasOwnProperty(i)) {
+            obj[i] = objB[i];
+        } else if (objA.hasOwnProperty(i)) {
+            obj[i] = objA[i];
+        }
+    }
+    return obj;
+};
+
+// Map for array or unique item.
+export const map = (ar, fn) => {
+    if (ar.length) {
+        for (let i = 0, max = ar.length; i < max; i += 1) {
+            fn(ar[i]);
+        }
+    } else {
+        fn(ar);
+    }
+};
+
+// Clamp position within the range
+export const clamp = (pos, nipplePos, size) => ({
+    //                          left-clamping        right-clamping
+    x: Math.min(Math.max(pos.x, nipplePos.x - size), nipplePos.x + size),
+    //                          top-clamping         bottom-clamping
+    y: Math.min(Math.max(pos.y, nipplePos.y - size), nipplePos.y + size)
+});

+ 102 - 0
src/AssetsStorage.js

@@ -0,0 +1,102 @@
+
+import Logger from "./Logger.js"
+import {modelTable} from "./ModelTable.js"
+import {http} from "./Http.js"
+import InternalError from "./error/InternalError.js"
+
+const logger = new Logger('AssetsStorage')
+
+const blobToDataURI = async d=>new Promise((o,s)=>{
+    const c = new FileReader;
+    c.readAsDataURL(d),
+    c.onload = function(_) {
+        var b;
+        o((b = _.target) == null ? void 0 : b.result)
+    }
+    ,
+    c.onerror = function(_) {
+        s(_)
+    }
+}
+)
+
+export default class AssetsStorage {
+    static async readOrRequest(o, s) {
+        let c = null;
+        if (AssetsStorage.USE_INDEXEDDB)
+            try {
+                c = await modelTable.query("url", o)
+            } catch (b) {
+                return logger.debug(b),
+                logger.warn("cache query error", o),
+                Promise.resolve(o)
+            }
+        else
+            c = {};
+        let _ = c && c.model;
+        return _ || (_ = await this.requestAndPut({
+            url: o,
+            responseType: "blob",
+            retry: 2
+        })),
+        typeof _ == "string" && (_ = this.dataURItoBlob(_)),
+        s && s.returnBlob ? _ : URL.createObjectURL(_)
+    }
+    static async requestAndPut(o) {
+        let s;
+        const c = o.url;
+        try {
+            s = await http.get(o)
+        } catch (_) {
+            return logger.error(_),
+            Promise.reject(new InternalError("request " + c + " failed"))
+        }
+        if (!s.data)
+            throw new InternalError(`${c} response.data is empty`);
+        if (AssetsStorage.USE_INDEXEDDB)
+            try {
+                let _ = s.data;
+                this.useBase64 && (_ = await blobToDataURI(s.data)),
+                await modelTable.put({
+                    url: o.url,
+                    model: _
+                })
+            } catch {
+                return Promise.reject("put " + c + " to db error")
+            }
+        return s.data
+    }
+    static checkUseBase64() {
+        if (!isIos())
+            return !1;
+        const o = getIosVersion();
+        if (!o)
+            return !1;
+        const s = o.split("_")[0]
+          , c = parseInt(s) < 14;
+        return logger.warn("useBase64", c),
+        c
+    }
+}
+
+AssetsStorage.useBase64 = AssetsStorage.checkUseBase64()
+AssetsStorage.USE_INDEXEDDB = !1
+AssetsStorage.dataURItoBlob = o=>{
+    let s;
+    o.split(",")[0].indexOf("base64") >= 0 ? s = atob(o.split(",")[1]) : s = unescape(o.split(",")[1]);
+    const c = o.split(",")[0].split(":")[1].split(";")[0]
+      , _ = new Uint8Array(s.length);
+    for (let k = 0; k < s.length; k++)
+        _[k] = s.charCodeAt(k);
+    return new Blob([_],{
+        type: c
+    })
+}
+
+
+const urlMap = new Map
+window.urlTransformer = async(d,o=!1)=>typeof d != "string" ? (console.warn("url transformer error", d),
+d) : d.startsWith("blob:") ? d : o ? AssetsStorage.readOrRequest(d, {
+    returnBlob: !0
+}) : urlMap.has(d) ? urlMap.get(d) : AssetsStorage.readOrRequest(d).then(s=>(urlMap.set(d, s),
+s));

+ 17 - 0
src/Avatar.js

@@ -0,0 +1,17 @@
+
+import XverseAvatar from "./XverseAvatar.js"
+
+export default class Avatar extends XverseAvatar{
+    constructor({userId: o, isHost: s, room: c, avatarId: _, nickname: b, isSelf: k, group: j=AvatarGroup.Npc, avatarComponents: $=[]}) {
+        super({
+            userId: o,
+            isHost: s,
+            room: c,
+            avatarId: _,
+            nickname: b,
+            isSelf: k,
+            group: j,
+            avatarComponents: $
+        })
+    }
+}

+ 18 - 0
src/AvatarManager.js

@@ -0,0 +1,18 @@
+
+import XverseAvatarManager from "./XverseAvatarManager.js"
+import Avatar from "./Avatar.js"
+
+export default class AvatarManager extends XverseAvatarManager{
+    constructor(o) {
+        var s;
+        super(o),
+        (s = this._room.avatarManager) != null && s.xAvatarManager && (this._room.avatarManager.xAvatarManager.enableAllNickname(!0),
+        this._room.avatarManager.xAvatarManager.maxBillBoardDist = 3e3)
+    }
+    async addAvatar(o) {
+        return super.addAvatar(o).then(s=>(s.setScale(1.5),
+        s))
+    }
+}
+
+XverseAvatarManager.subAvatar = Avatar;

+ 35 - 0
src/ByPasser.js

@@ -0,0 +1,35 @@
+
+const BYPASS_MAP = new Map([[0, {
+    type: "decode",
+    name: "DecodeStream"
+}], [1, {
+    type: "sdk",
+    name: "PlayMV"
+}], [2, {
+    type: "engine",
+    name: "EngineFunc1"
+}], [3, {
+    type: "engine",
+    name: "EngineFunc2"
+}]]);
+
+
+export default class ByPasser {
+    constructor(o) {
+        const s = BYPASS_MAP.size;
+        this.status = new Array(s).fill(!1);
+        let c = 0;
+        for (; o > 0 && s - c > 0; )
+            o % 2 == 1 && (this.status[c] = !0),
+            o = o >> 1,
+            c += 1
+    }
+    getSwitches(o) {
+        const s = [];
+        let c = 0;
+        for (const _ of BYPASS_MAP.entries())
+            _[1].type == o && this.status[c] && s.push(_[1].name),
+            c++;
+        return s
+    }
+}

Разница между файлами не показана из-за своего большого размера
+ 1245 - 0
src/Constant.js


+ 8 - 0
src/Error/AbnormalDataStructureError.js

@@ -0,0 +1,8 @@
+import XverseError from "./XverseError.js"
+
+export default class AbnormalDataStructureError extends XverseError {
+    constructor(o) {
+        super(2998, o || "后端返回数据结构异常"),
+        this.name = "AbnormalDataStructureError"
+    }
+}

+ 9 - 0
src/Error/ConnectingAlreadyError.js

@@ -0,0 +1,9 @@
+
+import XverseError from "./XverseError.js"
+
+export default class ConnectingAlreadyError extends XverseError {
+    constructor(o) {
+        super(1015, o || "已经在连接中"),
+        this.name = "ConnectingAlreadyError"
+    }
+}

+ 8 - 0
src/Error/UnReachableError.js

@@ -0,0 +1,8 @@
+import XverseError from "./XverseError.js"
+
+export default class UnReachableError extends XverseError {
+    constructor(o) {
+        super(2335, o || "区域不可到达"),
+        this.name = "UnReachableError"
+    }
+}

+ 61 - 0
src/Marker.js

@@ -0,0 +1,61 @@
+
+export default class Marker {
+    constructor(o) {
+        const {mesh: s, id: c, position: _, rotation: b, mat: k, type: j="default", maxVisibleRegion: $=-1, scene: _e, skinInfo: et="default"} = o;
+        this._id = c,
+        s.mesh.position = ue4Position2Xverse(_),
+        s.mesh.rotation = ue4Rotation2Xverse(b),
+        this._staticmesh = s,
+        this._mat = k,
+        this._type = j,
+        this._maxVisibleRegion = $,
+        this._scene = _e,
+        this._skinInfo = et,
+        this._isInScene = !0
+    }
+    get isInScene() {
+        return this._isInScene
+    }
+    get skinInfo() {
+        return this._skinInfo
+    }
+    get maxvisibleregion() {
+        return this._maxVisibleRegion
+    }
+    getMesh() {
+        return this._staticmesh
+    }
+    get mesh() {
+        return this._staticmesh.mesh
+    }
+    toggleVisibility(o) {
+        o == !0 ? this._staticmesh.show() : this._staticmesh.hide()
+    }
+    changePickable(o) {
+        this._staticmesh.mesh.isPickable = o
+    }
+    removeFromScene() {
+        this._isInScene && (this._staticmesh.mesh != null && this._scene.removeMesh(this._staticmesh.mesh),
+        this._isInScene = !1)
+    }
+    addToScene() {
+        this._isInScene == !1 && (this._staticmesh.mesh != null && this._scene.addMesh(this._staticmesh.mesh),
+        this._isInScene = !0)
+    }
+    dispose() {
+        var o;
+        (o = this._staticmesh.mesh) == null || o.dispose(!1, !1)
+    }
+    set position(o) {
+        this._staticmesh.mesh.position = ue4Position2Xverse(o)
+    }
+    get position() {
+        return xversePosition2Ue4(this._staticmesh.mesh.position)
+    }
+    set rotation(o) {
+        this._staticmesh.mesh.rotation = ue4Rotation2Xverse(o)
+    }
+    get rotation() {
+        return xverseRotation2Ue4(this._staticmesh.mesh.rotation)
+    }
+}

+ 9 - 0
src/Singleton.js

@@ -0,0 +1,9 @@
+export default class Singleton {
+    constructor() {}
+    onCreate() {}
+    static getInstance() {
+        return this.instance || (this.instance = new this,
+        this.instance.onCreate()),
+        this.instance
+    }
+}

+ 61 - 0
src/Tracker.js

@@ -0,0 +1,61 @@
+
+export default class Tracker  {
+    constructor() {
+        this.options = null;
+        this._header = null;
+        this._send = (o={})=>{
+            const s = this._serilizeData(o)
+              , c = new Image
+              , _ = this.options.requestUrl;
+            c.src = `${_}?data=${btoa(JSON.stringify(s))}`,
+            this.options.debug && console.error("sendImg", s)
+        };
+        this._serilizeData = o=>({
+            data: o,
+            header: {
+                ...this._header,
+                timeStamp: Date.now()
+            }
+        });
+    }
+    init(o) {
+        o.debug = o.debug || !1,
+        this.options = o,
+        this.options.requestUrl = this.options.requestUrl || TRACKER_URL[this.options.appEnv],
+        this.updateHeader({
+            appId: this.options.appId,
+            appEnv: this.options.appEnv
+        })
+    }
+    trackEvent(o, s={}) {
+        this._send({
+            ...s,
+            eventId: o
+        })
+    }
+    updateHeader(o) {
+        this._header || (this._header = {}),
+        Object.assign(this._header, o)
+    }
+    _post(o) {
+        return new Promise((s,c)=>{
+            const _ = new XMLHttpRequest;
+            _.open("POST", this.options.requestUrl),
+            _.setRequestHeader("Content-Type", "application/json");
+            try {
+                _.send(JSON.stringify(o))
+            } catch (b) {
+                console.error(b)
+            }
+            _.addEventListener("readystatechange", ()=>{
+                if (_.readyState == 4)
+                    return _.status == 200 ? s(_) : c("Unable to send log")
+            }
+            )
+        }
+        )
+    }
+}
+
+const tracker = new Tracker();
+export { tracker };

+ 7 - 0
src/WorldStore.js

@@ -0,0 +1,7 @@
+export default class WorldStore {
+    static get DefaultWorld() {
+        return this.Instances.length === 0 ? null : this.Instances[this.Instances.length - 1]
+    }
+}
+
+WorldStore.Instances = new Array;

+ 105 - 0
src/XAccessory.js

@@ -0,0 +1,105 @@
+
+export default class XAccessory extends XActor{
+    constructor() {
+        super()
+    }
+    getClassName() {
+        return "XAccessory"
+    }
+    set attachType(o) {
+        this._attachType = o
+    }
+    get attachType() {
+        return this._attachType
+    }
+    set attachBoneId(o) {
+        this._attachBoneId = o
+    }
+    get attachBoneId() {
+        return this._attachBoneId
+    }
+    set attachPointOffset(o) {
+        this._attachPointOffset = o
+    }
+    get attachPointOffset() {
+        return this._attachPointOffset
+    }
+    set attachPointRotation(o) {
+        this._attachPointRotation = o
+    }
+    get attachPointScale() {
+        return this._attachPointScale
+    }
+    set pointId(o) {
+        this._pointId = o
+    }
+    get pointId() {
+        return this._pointId
+    }
+    set attachPointOffsetVector3(o) {
+        this._attachPointOffset = xversePosition2Ue4(o)
+    }
+    set attachPointScaleVector3(o) {
+        this._attachPointScale = {
+            x: o.x,
+            y: -o.z,
+            z: o.y
+        }
+    }
+    set attachPointRotationVector3(o) {
+        this._attachPointRotation = xverseRotation2Ue4_mesh(o)
+    }
+    setLocalRTS(o) {
+        if (o) {
+            const s = ue4Scaling2Xverse(this._attachPointScale);
+            s && (o.scaling = s);
+            const c = ue4Position2Xverse(this._attachPointOffset);
+            c && (o.position = c);
+            const _ = ue4Rotation2Xverse_mesh(this._attachPointRotation);
+            _ && (o.rotation = _)
+        }
+    }
+    setParentTo(o) {
+        this.rootComponent && this.rootComponent.rootNode && (this.rootComponent.rootNode.parent = o,
+        this.setLocalRTS(this.rootComponent.rootNode))
+    }
+    detachFrom(o=!0) {
+        o ? this.dispose() : this.rootComponent && this.rootComponent.rootNode && (this.rootComponent.rootNode.parent = null,
+        this.rootComponent.rootNode.detachFromBone(!1))
+    }
+    attachTo(o) {
+        var s;
+        if (!o.skeleton) {
+            (s = this.rootComponent.rootNode) == null || s.setEnabled(!1);
+            return
+        }
+        switch (this._attachType) {
+        case 0:
+            this.rootComponent && this.rootComponent.rootNode && o.component.virtualbody && (this.rootComponent.rootNode.parent = o.component.virtualbody.root,
+            this.setLocalRTS(this.rootComponent.rootNode));
+            break;
+        case 1:
+            {
+                const c = o.skeleton.bones.find(_=>_.name === this._attachBoneId);
+                c && this.rootComponent && this.rootComponent.rootNode && o.component.virtualbody && (this.rootComponent.rootNode.attachToBone(c, o.component.virtualbody.root),
+                this.setLocalRTS(this.rootComponent.rootNode));
+                break
+            }
+        }
+    }
+    async play() {
+        this.rootComponent.asset && this.rootComponent.asset.animationGroups && this.rootComponent.asset.animationGroups.length > 0 && (this.rootComponent.asset.animationGroups[0].play(),
+        this.rootComponent.asset.animationGroups[0].onAnimationGroupEndObservable.addOnce(()=>Promise.resolve(null)))
+    }
+    stop() {
+        this.rootComponent.asset && this.rootComponent.asset.animationGroups && this.rootComponent.asset.animationGroups.length > 0 && this.rootComponent.asset.animationGroups[0].stop()
+    }
+}
+
+__decorateClass([xProperty("_pointId")], XAccessory.prototype, "_pointId", 2);
+__decorateClass([xProperty("_attachBoneId")], XAccessory.prototype, "_attachBoneId", 2);
+__decorateClass([xProperty("_attachType")], XAccessory.prototype, "_attachType", 2);
+__decorateClass([xProperty("_attachPointOffset")], XAccessory.prototype, "_attachPointOffset", 2);
+__decorateClass([xProperty("_attachPointRotation")], XAccessory.prototype, "_attachPointRotation", 2);
+__decorateClass([xProperty("_attachPointScale")], XAccessory.prototype, "_attachPointScale", 2);
+RegisterXObjectClass("XAccessory", XAccessory);

+ 79 - 0
src/XActor.js

@@ -0,0 +1,79 @@
+
+ import XObject from "./XObject.js"
+ import XSceneComponent from "./XSceneComponent.js"
+ 
+export default class XActor extends XObject{
+    constructor() {
+        super();
+        const o = BABYLON.EngineStore.LastCreatedScene;
+        this._children = new Array,
+        this._ownedComponent = new Set,
+        this._rootComponent = new XSceneComponent,
+        this._rootComponent.owner = this,
+        this._tickInterval = 1;
+        let s = 0;
+        this._tickObserver = o.onAfterRenderObservable.add(()=>{
+            s += 1,
+            s == this._tickInterval && (this._tick(),
+            s = 0)
+        }
+        )
+    }
+    set outer(o) {
+        this._outer = o,
+        this._ownedComponent.forEach(s=>{
+            s.outer = o
+        }
+        )
+    }
+    get outer() {
+        return this._outer
+    }
+    get rootComponent() {
+        return this._rootComponent
+    }
+    getClassName() {
+        return "XActor"
+    }
+    _tick() {
+        this._ownedComponent.forEach(o=>{
+            o.ReceiveTick()
+        }
+        )
+    }
+    get tickInterval() {
+        return this._tickInterval
+    }
+    set tickInterval(o) {
+        this._tickInterval = o
+    }
+    AttachToActor(o) {
+        o._children.push(this),
+        this._rootComponent.AttachToComponent(o.rootComponent)
+    }
+    AddComponent(o) {
+        o && (o.owner = this,
+        o.RegisterComponent(),
+        this._ownedComponent.add(o))
+    }
+    RemoveComponent(o) {
+        o && (o.owner = null,
+        this._ownedComponent.delete(o),
+        o.UnRegisterComponent())
+    }
+    postLoad() {}
+    dispose() {
+        this._children = [],
+        this._ownedComponent.forEach(o=>{
+            o.UnRegisterComponent(),
+            o.dispose()
+        }
+        ),
+        this._ownedComponent.clear(),
+        this._rootComponent.dispose(),
+        this._tickObserver.unregisterOnNextCall = !0
+    }
+}
+
+__decorateClass([xProperty("rootComponent")], XActor.prototype, "_rootComponent", 2);
+RegisterXObjectClass("XActor", XActor);

+ 41 - 0
src/XActorComponent.js

@@ -0,0 +1,41 @@
+import XObject from "./XObject.js";
+import XWorld from "./XWorld.js";
+
+export default class XActorComponent extends XObject {
+    constructor() {
+        super(),
+        this._ownerPrivate = null,
+        this._worldPrivate = XWorld.GetDefaultWorld(),
+        this._tickEnabled = !0
+    }
+    GetWorld() {
+        return this._worldPrivate
+    }
+    Tick() {}
+    ReceiveTick() {
+        this.tickEnabled && this.Tick()
+    }
+    get tickEnabled() {
+        return this._tickEnabled
+    }
+    set tickEnabled(o) {
+        this._tickEnabled = o
+    }
+    get owner() {
+        return this._ownerPrivate
+    }
+    set owner(o) {
+        o && (this._ownerPrivate = o,
+        this._outer = o == null ? void 0 : o.outer)
+    }
+    set outer(o) {
+        this._outer = o
+    }
+    get outer() {
+        return this.owner && (this._outer = this.owner.outer),
+        this._outer
+    }
+    RegisterComponent() {}
+    UnRegisterComponent() {}
+    RegisterComponentWithWorld(o) {}
+}

+ 74 - 0
src/XArchive.js

@@ -0,0 +1,74 @@
+import XObject from "./XObject.js"
+
+export default class XArchive {
+    constructor() {
+        this.loadingPromises = new Array
+    }
+    static serialize(o) {
+        if (!o.outer)
+            return {
+                className: "",
+                uuid: 0,
+                xobjectInfo: {},
+                sceneInfo: ""
+            };
+        const c = o.outer.uuid
+          , _ = {
+            className: "",
+            uuid: 0,
+            xobjectInfo: {},
+            sceneInfo: ""
+        };
+        _.className = o.getClassName(),
+        _.uuid = c;
+        const b = getPropertiesMarkAsSerializable(o);
+        for (const k in b) {
+            const $ = b[k].sourceName || k
+              , _e = o[k];
+            _.xobjectInfo[$] = _e
+        }
+        return _
+    }
+    async deserializeObject(o, s="") {
+        if (o == null || typeof o != "object" || o instanceof Date)
+            return o;
+        if (o instanceof Array) {
+            for (let c = 0, _ = o.length; c < _; c++)
+                o[c] = this.deserializeObject(o[c], s);
+            return o
+        }
+        if (o instanceof Object) {
+            if (o.className)
+                GetXObjectClass(o.className) && this.deserialize(o, s);
+            else
+                return o;
+            return o
+        }
+        throw new Error("Unable to copy obj! Its type isn't supported.")
+    }
+    async deserialize(o, s="", c) {
+        const _ = GetXObjectClass(o.className);
+        if (!_)
+            throw new Error("Unable to deserialize obj! Its type isn't XObject.");
+        const b = new _
+          , k = getPropertiesMarkAsSerializable(b);
+        for (const j in k) {
+            const $ = k[j]
+              , _e = o.xobjectInfo[$.sourceName || j];
+            if (_e != null)
+                if (b[j]instanceof BABYLON.AssetContainer) {
+                    let et = s + _e.sceneInfo;
+                    c != null && (et = await c(et));
+                    const tt = await BABYLON.SceneLoader.LoadAssetContainerAsync("", et, BABYLON.EngineStore.LastCreatedScene, null, ".glb");
+                    b[j] = tt,
+                    tt.addAllToScene()
+                } else
+                    b[j]instanceof XObject ? b[j] = await this.deserialize(_e, s, c) : b[j] = await this.deserializeObject(_e, s)
+        }
+        return b.postLoad(),
+        b
+    }
+    static clone(o, s, c) {
+        return deepCopy(o, s, c)
+    }
+}

+ 55 - 0
src/XEngineOption.js

@@ -0,0 +1,55 @@
+export default class XEngineOption {
+    constructor(o=0) {
+        this._featureSwitch = new Map,
+        this._onSwitchChanged = new BABYLON.Observable,
+        this.bDisableWebGL2 = !1;
+        for (let s = 3; s < 9; ++s)
+            this._featureSwitch.set(s, (o >> s & 1) > 0)
+    }
+    get bDisableRemoteAvatar() {
+        return this._featureSwitch.get(3)
+    }
+    set bDisableRemoteAvatar(o) {
+        this.bDisableRemoteAvatar != o && this.setSwitchInternal(3, o)
+    }
+    get bDisableNickName() {
+        return this._featureSwitch.get(4)
+    }
+    set bDisableNickName(o) {
+        this.bDisableNickName != o && this.setSwitchInternal(4, o)
+    }
+    get bDisableSkeletonAnim() {
+        return this._featureSwitch.get(5)
+    }
+    set bDisableSkeletonAnim(o) {
+        this.bDisableSkeletonAnim != o && this.setSwitchInternal(5, o)
+    }
+    get bSimpleMaterialAvatar() {
+        return this._featureSwitch.get(6)
+    }
+    set bSimpleMaterialAvatar(o) {
+        this.bSimpleMaterialAvatar != o && this.setSwitchInternal(6, o)
+    }
+    get bDisableCloudRender() {
+        return this._featureSwitch.get(7)
+    }
+    set bDisableCloudRender(o) {
+        this.bDisableCloudRender != o && this.setSwitchInternal(7, o)
+    }
+    get bDisableLocalRender() {
+        return this._featureSwitch.get(8)
+    }
+    set bDisableLocalRender(o) {
+        this.bDisableLocalRender != o && this.setSwitchInternal(8, o)
+    }
+    get onFeatureSwitchChanged() {
+        return this._onSwitchChanged
+    }
+    setSwitchInternal(o, s) {
+        this._featureSwitch.set(o, s),
+        this._onSwitchChanged.notifyObservers({
+            changedSwitch: o,
+            newVal: s
+        })
+    }
+}

+ 160 - 0
src/XJoystick.js

@@ -0,0 +1,160 @@
+let thumbArea, puck, adt, xAddPos = 0, yAddPos = 0;
+
+export default class XJoystick{
+    constructor(o, s) {
+        this._config = {
+            thumbAreaSize: 0,
+            puckSize: 0,
+            leftPadding: 0,
+            bottomPadding: 0
+        },
+        this.degree = 0,
+        this.distance = 0,
+        this._updateCount = 0,
+        this.styleThumbAreaDownAlpha = .5,
+        this.styleThumbAreaUpAlpha = .2,
+        this.stylePuckDownAlpha = 1,
+        this.stylePuckUpAlpha = .8,
+        this.styleThumbAreaChickness = 3,
+        this.updateStep = 10,
+        this._config.thumbAreaSize = o.thumbAreaSize,
+        this._config.puckSize = o.puckSize,
+        this._config.leftPadding = o.leftPadding,
+        this._config.bottomPadding = -o.bottomPadding,
+        this._scene = s.Scene,
+        this._smgr = s,
+        this.drawJoystick(),
+        this.addObserver()
+    }
+    drawJoystick() {
+        adt = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI"),
+        adt.renderAtIdealSize = !0,
+        adt.idealHeight = window.innerHeight,
+        adt.idealWidth = window.innerWidth,
+        adt.clipChildren = !1,
+        thumbArea = new BABYLON.GUI.Ellipse,
+        thumbArea.name = "thumbArea",
+        thumbArea.thickness = this.styleThumbAreaChickness,
+        thumbArea.color = "white",
+        thumbArea.paddingLeft = "0px",
+        thumbArea.paddingRight = "0px",
+        thumbArea.paddingBottom = "0px",
+        thumbArea.paddingTop = "0px",
+        thumbArea.background = "black",
+        thumbArea.height = this._config.thumbAreaSize == null ? 100 : this._config.thumbAreaSize + "px",
+        thumbArea.width = thumbArea.height,
+        thumbArea.isPointerBlocker = !0,
+        thumbArea.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_LEFT,
+        thumbArea.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_BOTTOM,
+        thumbArea.alpha = this.styleThumbAreaUpAlpha,
+        thumbArea.left = this._config.leftPadding,
+        thumbArea.top = this._config.bottomPadding,
+        thumbArea.zIndex = 0,
+        thumbArea.clipChildren = !1,
+        thumbArea.clipContent = !1,
+        puck = new BABYLON.GUI.Ellipse,
+        puck.name = "puck",
+        puck.paddingLeft = "0px",
+        puck.paddingRight = "0px",
+        puck.paddingBottom = "0px",
+        puck.paddingTop = "0px",
+        puck.height = this._config.puckSize == null ? 30 : this._config.puckSize + "px",
+        puck.width = puck.height,
+        puck.isPointerBlocker = !0,
+        puck.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER,
+        puck.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER,
+        puck.isDown = !1,
+        puck.background = "white",
+        puck.isVisible = !0,
+        puck.zIndex = 1,
+        puck.clipContent = !1,
+        puck.alpha = this.stylePuckUpAlpha,
+        adt.addControl(thumbArea),
+        thumbArea.addControl(puck)
+    }
+    _updatePuckPosition(o) {
+        const s = this._config.thumbAreaSize / thumbArea._currentMeasure.width;
+        xAddPos = o.x - thumbArea._currentMeasure.width * .5 - thumbArea._currentMeasure.left,
+        yAddPos = thumbArea._currentMeasure.top - o.y + thumbArea._currentMeasure.height * .5;
+        const c = Math.sqrt(xAddPos * xAddPos + yAddPos * yAddPos);
+        this._updateCount > this.updateStep && (this._updateCount = 0),
+        this._updateCount == 0 && (c > thumbArea._currentMeasure.width / 2 ? (puck.floatLeft = s * .5 * xAddPos * thumbArea._currentMeasure.width / c,
+        puck.floatTop = s * (.5 * yAddPos * thumbArea._currentMeasure.width / c) * -1,
+        puck.left = puck.floatLeft,
+        puck.top = puck.floatTop) : (puck.floatLeft = xAddPos * s,
+        puck.floatTop = s * yAddPos * -1,
+        puck.left = puck.floatLeft,
+        puck.top = puck.floatTop)),
+        this._updateCount++
+    }
+    addObserver() {
+        this.onMoveObserver = adt.rootContainer.onPointerMoveObservable.add(o=>{
+            this._onMoveFunc && this._onMoveFunc(),
+            puck.isDown && this._updatePuckPosition(o)
+        }
+        ),
+        this.onStopObserver = thumbArea.onPointerUpObservable.add(o=>{
+            puck.isDown = !1,
+            this._smgr.playerController.puckActive = !1,
+            this._onEndFunc && this._onEndFunc(),
+            thumbArea.alpha = this.styleThumbAreaUpAlpha,
+            puck.alpha = this.stylePuckUpAlpha,
+            this._resetPunkPosition()
+        }
+        ),
+        this.onStartObserver = thumbArea.onPointerDownObservable.add(o=>{
+            puck.isDown = !0,
+            this._smgr.playerController.puckActive = !0,
+            this._onStartFunc && this._onStartFunc(),
+            this._updatePuckPosition(o),
+            thumbArea.alpha = this.styleThumbAreaDownAlpha,
+            puck.alpha = this.stylePuckDownAlpha
+        }
+        ),
+        this._scene || console.error("[Engine] joystick cannot find root scene!"),
+        this._scene.registerBeforeRender(()=>{
+            this.distance = Math.sqrt(xAddPos * xAddPos + yAddPos * yAddPos),
+            xAddPos > 0 && yAddPos > 0 ? this.degree = Math.atan(yAddPos / xAddPos) * 180 / Math.PI : xAddPos < 0 && yAddPos > 0 ? this.degree = Math.atan(yAddPos / xAddPos) * 180 / Math.PI + 180 : xAddPos < 0 && yAddPos < 0 ? this.degree = Math.atan(yAddPos / xAddPos) * 180 / Math.PI + 180 : xAddPos > 0 && yAddPos < 0 && (this.degree = Math.atan(yAddPos / xAddPos) * 180 / Math.PI + 360)
+        }
+        )
+    }
+    removeObserver() {
+        this.onStartObserver && thumbArea.onPointerDownObservable.remove(this.onStartObserver),
+        this.onMoveObserver && thumbArea.onPointerDownObservable.remove(this.onMoveObserver),
+        this.onStopObserver && thumbArea.onPointerDownObservable.remove(this.onStopObserver)
+    }
+    _resetPunkPosition() {
+        xAddPos = 0,
+        yAddPos = 0,
+        puck.floatLeft = 0,
+        puck.left = 0,
+        puck.floatTop = 0,
+        puck.top = 0
+    }
+    show() {
+        this.addObserver(),
+        this._resetPunkPosition(),
+        adt.rootContainer.isVisible = !0
+    }
+    hide() {
+        this.removeObserver(),
+        this._resetPunkPosition(),
+        this._smgr.playerController.puckActive = !1,
+        adt.rootContainer.isVisible = !1
+    }
+    onMove(o) {
+        this._onMoveFunc = o
+    }
+    onStart(o) {
+        this._onStartFunc = o
+    }
+    onEnd(o) {
+        this._onEndFunc = o
+    }
+    dispose() {
+        this.removeObserver(),
+        adt.dispose(),
+        puck.dispose(),
+        thumbArea.dispose()
+    }
+}

+ 24 - 0
src/XLevel.js

@@ -0,0 +1,24 @@
+import XObject from "./XObject.js";
+import XWorld from "./XWorld.js";
+
+export default class XLevel extends XObject {
+    constructor() {
+        var o;
+        super(),
+        this._OwningWorld = null,
+        (o = XWorld.GetDefaultWorld()) == null || o.Levels.push(this),
+        this.Actors = new Array,
+        this.Components = new Array
+    }
+    get OwningWorld() {
+        return this._OwningWorld
+    }
+    set OWningWorld(o) {
+        this._OwningWorld = o
+    }
+    dispose() {
+        var s;
+        const o = XWorld.GetDefaultWorld().Levels.indexOf(this);
+        (s = XWorld.GetDefaultWorld()) == null || s.Levels.splice(o, 1)
+    }
+}

+ 22 - 0
src/XMatrix.js

@@ -0,0 +1,22 @@
+export default class XMatrix {
+    constructor(o, s, c, _) {
+        this.M = new Array(4);
+        for (let b = 0; b < 4; b++) {
+            this.M[b] = new Float64Array(4);
+            for (let k = 0; k < 4; k++)
+                this.M[b][k] = 0
+        }
+        for (let b = 0; b < 4; b++)
+            this.M[0][b] = o.v[b],
+            this.M[1][b] = s.v[b],
+            this.M[2][b] = c.v[b],
+            this.M[3][b] = _.v[b]
+    }
+    loadData(o, s, c, _) {
+        for (let b = 0; b < 4; b++)
+            this.M[0][b] = o.v[b],
+            this.M[1][b] = s.v[b],
+            this.M[2][b] = c.v[b],
+            this.M[3][b] = _.v[b]
+    }
+}

Разница между файлами не показана из-за своего большого размера
+ 645 - 0
src/XMovementComponent.js


+ 215 - 0
src/XNavigationComponents.js

@@ -0,0 +1,215 @@
+
+import XObject from "./XObject.js"
+
+export default class XNavigationComponents extends XObject {
+    constructor() {
+        super(...arguments),
+        this.zero = 1e-5
+    }
+    navMeshShow() {
+        if (this.navmeshLines) {
+            for (let o = 0; o < this.navmeshLines.length; o++)
+                this.navmeshLines[o].dispose();
+            this.navmeshLines.length = 0
+        } else
+            this.navmeshLines = [];
+        for (let o = 0; o < this.navMeshM; o++) {
+            const s = {
+                x: this.navMeshEdge[o][0][0],
+                y: this.navMeshEdge[o][0][1],
+                z: this.navMeshEdge[o][0][2]
+            }
+              , c = {
+                x: this.navMeshEdge[o][1][0],
+                y: this.navMeshEdge[o][1][1],
+                z: this.navMeshEdge[o][1][2]
+            }
+              , _ = {
+                x: s.x,
+                y: s.y,
+                z: s.z
+            }
+              , b = {
+                x: c.x,
+                y: c.y,
+                z: c.z
+            }
+              , k = [ue4Position2Xverse(_), ue4Position2Xverse(b)]
+              , j = BABYLON.MeshBuilder.CreateLines("lines", {
+                points: k
+            }, this._sceneManager.Scene);
+            this.navmeshLines.push(j)
+        }
+    }
+    navMeshHidden() {
+        if (this.navmeshLines) {
+            for (let o = 0; o < this.navmeshLines.length; o++)
+                this.navmeshLines[o].dispose();
+            this.navmeshLines.length = 0
+        } else
+            this.navmeshLines = []
+    }
+    vector(o, s) {
+        return {
+            x: s.x - o.x,
+            y: s.y - o.y,
+            z: 0
+        }
+    }
+    negative(o) {
+        return {
+            x: -o.x,
+            y: -o.y,
+            z: 0
+        }
+    }
+    cross(o, s) {
+        return o.x * s.y - s.x * o.y
+    }
+    IsIntersected(o, s, c, _) {
+        if (Math.max(o.x, s.x) < Math.min(c.x, _.x) || Math.max(c.x, _.x) < Math.min(o.x, s.x) || Math.max(o.y, s.y) < Math.min(c.y, _.y) || Math.max(c.y, _.y) < Math.min(o.y, s.y) || Math.abs((s.y - o.y) * (_.x - c.x) - (o.x - s.x) * (c.y - _.y)) < this.zero)
+            return !1;
+        const b = this.vector(o, c)
+          , k = this.vector(o, _)
+          , j = this.vector(s, c)
+          , $ = this.vector(s, _);
+        return this.cross(b, k) * this.cross(j, $) <= this.zero && this.cross(b, j) * this.cross(k, $) <= this.zero
+    }
+    getDistance(o, s) {
+        const c = o.x - s.x
+          , _ = o.y - s.y;
+        return Math.sqrt(c * c + _ * _)
+    }
+    isWalkable(o) {
+        return this.getNavTriangleId(o) > -1
+    }
+    GetProjectivePoint(o, s, c) {
+        const _ = {
+            x: 0,
+            y: 0,
+            z: o.z
+        }
+          , b = s.x - o.x
+          , k = s.y - o.y;
+        if (Math.abs(b) < this.zero)
+            _.x = o.x,
+            _.y = c.y,
+            _.y = Math.min(Math.max(o.y, s.y), _.y),
+            _.y = Math.max(Math.min(o.y, s.y), _.y);
+        else if (Math.abs(k) < this.zero)
+            _.x = c.x,
+            _.y = o.y,
+            _.x = Math.min(Math.max(o.x, s.x), _.x),
+            _.x = Math.max(Math.min(o.x, s.x), _.x);
+        else {
+            const j = k / b
+              , $ = -b / k
+              , _e = o.y - j * o.x
+              , et = c.y - $ * c.x;
+            _.x = (et - _e) / (j - $),
+            _.y = j * _.x + _e,
+            b < 0 ? _.x < s.x ? (_.x = s.x,
+            _.y = s.y) : _.x > o.x && (_.x = o.x,
+            _.y = o.y) : _.x > s.x ? (_.x = s.x,
+            _.y = s.y) : _.x < o.x && (_.x = o.x,
+            _.y = o.y)
+        }
+        return _
+    }
+    GetTargetLocationByNavMesh(o, s) {
+        let c = {
+            x: s.x,
+            y: s.y,
+            z: s.z
+        };
+        if (this.getNavTriangleId(c),
+        this.getNavTriangleId(c) > -1)
+            return c;
+        let _ = 0;
+        for (let b = 0; b < this.navMeshM; b++) {
+            const k = {
+                x: this.navMeshEdge[b][0][0],
+                y: this.navMeshEdge[b][0][1],
+                z: this.navMeshEdge[b][0][2]
+            }
+              , j = {
+                x: this.navMeshEdge[b][1][0],
+                y: this.navMeshEdge[b][1][1],
+                z: this.navMeshEdge[b][1][2]
+            };
+            if (this.IsIntersected(o, s, k, j)) {
+                const $ = this.GetProjectivePoint(k, j, s)
+                  , _e = this.getDistance(o, $);
+                _e > _ && (_ = _e,
+                c = $)
+            }
+        }
+        return _ > this.zero ? c : o
+    }
+    sign(o, s, c) {
+        return (o[0] - c[0]) * (s[1] - c[1]) - (s[0] - c[0]) * (o[1] - c[1])
+    }
+    signvalue(o, s, c) {
+        return (o[0] - c[0]) * (s[1] - c[1]) - (s[0] - c[0]) * (o[1] - c[1])
+    }
+    inside(o, s, c, _) {
+        const b = this.sign(o, s, c) <= this.zero
+          , k = this.sign(o, c, _) <= this.zero
+          , j = this.sign(o, _, s) <= this.zero;
+        return b == k && k == j
+    }
+    GetIntersectPoint(o, s, c, _) {
+        const b = (s.y - o.y) * (_.x - c.x) - (o.x - s.x) * (c.y - _.y);
+        if (Math.abs(b) >= this.zero) {
+            const k = {
+                x: 0,
+                y: 0,
+                z: 0
+            };
+            return k.x = ((s.x - o.x) * (_.x - c.x) * (c.y - o.y) + (s.y - o.y) * (_.x - c.x) * o.x - (_.y - c.y) * (s.x - o.x) * c.x) / b,
+            k.y = -((s.y - o.y) * (_.y - c.y) * (c.x - o.x) + (s.x - o.x) * (_.y - c.y) * o.y - (_.x - c.x) * (s.y - o.y) * c.y) / b,
+            k
+        }
+    }
+    GetIntersectEdgeAndPoint(o, s) {
+        const c = []
+          , _ = [];
+        for (let b = 0; b < this.navMeshM; b++) {
+            const k = {
+                x: this.navMeshEdge[b][0][0],
+                y: this.navMeshEdge[b][0][1],
+                z: this.navMeshEdge[b][0][2]
+            }
+              , j = {
+                x: this.navMeshEdge[b][1][0],
+                y: this.navMeshEdge[b][1][1],
+                z: this.navMeshEdge[b][1][2]
+            };
+            if (this.IsIntersected(o, s, k, j)) {
+                const $ = this.GetIntersectPoint(o, s, k, j);
+                $ != null && (c.push(k),
+                c.push(j),
+                _.push($))
+            }
+        }
+        return [c, _]
+    }
+    getNavTriangleId(o) {
+        const s = new Float64Array(3);
+        s[0] = o.x,
+        s[1] = o.y,
+        s[2] = o.z;
+        for (let c = 0; c < this.navMeshN; c++)
+            if (this.inside(s, this.navMeshTriangle[c][0], this.navMeshTriangle[c][1], this.navMeshTriangle[c][2]))
+                return c;
+        return -1
+    }
+    async navMeshLoad(o) {
+        this.navMeshN = o.navMeshN,
+        this.navMeshM = o.navMeshM,
+        this.navMeshTriangle = o.navMeshTriangle,
+        this.navMeshEdge = o.navMeshEdge
+    }
+}
+
+RegisterXObjectClass("XNavigationComponents", XNavigationComponents);

+ 32 - 0
src/XObject.js

@@ -0,0 +1,32 @@
+export default class XObject {
+    constructor() {
+        this._name = "",
+        this._outer = null
+    }
+    set outer(o) {
+        this._outer = o
+    }
+    get outer() {
+        return this._outer
+    }
+    get name() {
+        return this._name
+    }
+    set name(o) {
+        this._name = o
+    }
+    getClassName() {
+        return "XObject"
+    }
+    toJSON() {
+        return XArchive.serialize(this)
+    }
+    dispose() {}
+    postLoad() {}
+    clone(o) {
+        return XArchive.clone(this, o)
+    }
+}
+
+__decorateClass([xProperty("name")], XObject.prototype, "_name", 2);
+RegisterXObjectClass("XObject", XObject);

+ 9 - 0
src/XPlane.js

@@ -0,0 +1,9 @@
+export default class XPlane {
+    constructor(o, s, c, _) {
+        this.v = new Float64Array(4),
+        this.v[0] = o,
+        this.v[1] = s,
+        this.v[2] = c,
+        this.v[3] = _
+    }
+}

+ 102 - 0
src/XPlayerController.js

@@ -0,0 +1,102 @@
+export default class XPlayerController {
+    constructor(o) {
+        this._moveLimitInCameraUaxis = 1,
+        this._moveLimitInCameraVaxis = 1,
+        this.bUseServerUpdate = !1,
+        this.clientAvatarPositionAsyncTime = 0,
+        this.onMoveFinishedDelegate = ()=>{}
+        ,
+        this._sceneManager = o,
+        this._moveLimitInCameraUaxis = 1.1,
+        this._moveLimitInCameraVaxis = 2
+    }
+    set puckActive(o) {
+        this._sceneManager.avatarComponent.getMainAvatar() && (this._sceneManager.avatarComponent.getMainAvatar().movementComponent.isPuckDown = o)
+    }
+    get controlRotation() {
+        return xverseRotation2Ue4(this._sceneManager.cameraComponent.MainCamera.rotation)
+    }
+    clientMoveForward(o, s) {
+        this._sceneManager.avatarComponent.getMainAvatar().movementComponent.clientMoveForward(o, s)
+    }
+    changeServerUpdateState(o) {
+        this.bUseServerUpdate = o,
+        this._sceneManager.avatarComponent.getMainAvatar().movementComponent.changeServerUpdateState(o)
+    }
+    updateNavmesh(o) {
+        const s = o.trianglecnt
+          , c = o.edgecnt
+          , _ = new Array(s);
+        for (let j = 0; j < s; j++) {
+            _[j] = new Array(3);
+            for (let $ = 0; $ < 3; $++)
+                _[j][$] = new Float32Array(3),
+                _[j][$][0] = o.triangles[j * 3 + $].x,
+                _[j][$][1] = o.triangles[j * 3 + $].y,
+                _[j][$][2] = o.triangles[j * 3 + $].z
+        }
+        const b = new Array(c);
+        for (let j = 0; j < c; j++) {
+            b[j] = new Array(2);
+            for (let $ = 0; $ < 2; $++)
+                b[j][$] = new Float32Array(3),
+                b[j][$][0] = o.edges[j * 2 + $].x,
+                b[j][$][1] = o.edges[j * 2 + $].y,
+                b[j][$][2] = o.edges[j * 2 + $].z
+        }
+        const k = {
+            navMeshN: s,
+            navMeshM: c,
+            navMeshTriangle: _,
+            navMeshEdge: b
+        };
+        this._sceneManager.avatarComponent.getMainAvatar().movementComponent.naviComp.navMeshLoad(k)
+    }
+    serverUpdatePlayerLocation(o) {
+        this.bUseServerUpdate ? this._sceneManager.avatarComponent.getMainAvatar().movementComponent.updateServerLocation(o) : this._sceneManager.avatarComponent.getMainAvatar().movementComponent.clearSeverUpdate()
+    }
+    updateMoveStep(o) {
+        this._sceneManager.avatarComponent.getMainAvatar().movementComponent.updateMoveStep(o)
+    }
+    updateServerAsyncPlayRate(o) {
+        this._sceneManager.avatarComponent.getMainAvatar().movementComponent.updateServerAsyncPlayRate(Math.floor(o))
+    }
+    updateServerAsyncThreshold(o) {
+        this._sceneManager.avatarComponent.getMainAvatar().movementComponent.updateServerAsyncThreshold(o)
+    }
+    get frameMovementData() {
+        return this._sceneManager.avatarComponent.getMainAvatar().movementComponent.frameMovementData
+    }
+    setMoveLimitInCameraUaxis(o) {
+        this._moveLimitInCameraUaxis = o
+    }
+    setMoveLimitInCameraVaxis(o) {
+        this._moveLimitInCameraVaxis = o
+    }
+    get moveLimitInCameraUaxis() {
+        return this._moveLimitInCameraUaxis
+    }
+    get moveLimitInCameraVaxis() {
+        return this._moveLimitInCameraVaxis
+    }
+    registerOnMoveFinished(o) {
+        this.onMoveFinishedDelegate = o
+    }
+    navMeshShow() {
+        this._sceneManager.avatarComponent.getMainAvatar().movementComponent.naviComp._sceneManager = this._sceneManager,
+        this._sceneManager.avatarComponent.getMainAvatar().movementComponent.naviComp.navMeshShow()
+    }
+    navMeshHidden() {
+        this._sceneManager.avatarComponent.getMainAvatar().movementComponent.naviComp._sceneManager = this._sceneManager,
+        this._sceneManager.avatarComponent.getMainAvatar().movementComponent.naviComp.navMeshHidden()
+    }
+    setMaxIncreaseAcceleration(o) {
+        this._sceneManager.avatarComponent.getMainAvatar().movementComponent.maxIncreaseAcceleration = o
+    }
+    setMaxDecreaseAcceleration(o) {
+        this._sceneManager.avatarComponent.getMainAvatar().movementComponent.maxDecreaseAcceleration = o
+    }
+    setSpeedSmoothScale(o) {
+        this._sceneManager.avatarComponent.getMainAvatar().movementComponent.speedSmoothScale = o
+    }
+}

+ 642 - 0
src/XRoom.js

@@ -0,0 +1,642 @@
+import XverseAvatarManager from "./XverseAvatarManager.js";
+import Codes from "./enum/Codes.js";
+import PathManager from "./PathManager.js";
+import Camera from "./Camera.js";
+import Stats from "./Stats.js";
+import ActionsHandler from "./ActionsHandler.js";
+import Signal from "./Signal.js";
+import ModelManager from "./ModelManager.js";
+import { reporter } from "./Reporter.js";
+import util from "./util.js";
+import XverseEffectManager from "./XverseEffectManager.js";
+import TimeoutError from "./error/TimeoutError.js";
+import ParamError from "./error/ParamError.js";
+import MotionType from "./enum/MotionType.js";
+import NetworkController from "./NetworkController.js";
+import InitNetworkTimeoutError from "./error/InitNetworkTimeoutError.js";
+import InitConfigTimeoutError from "./error/InitConfigTimeoutError.js";
+import InitDecoderTimeoutError from "./error/InitDecoderTimeoutError.js";
+import InitEngineError from "./error/InitEngineError.js";
+import { eventsManager } from "./EventsManager.js";
+import EngineProxy from "./EngineProxy.js";
+import EventsController from "./EventsController.js";
+import EImageQuality from "./enum/EImageQuality.js";
+import Panorama from "./Panorama.js";
+import Debug from "./Debug.js";
+import Logger from "./Logger.js";
+import NewUserStateType from "./enum/NewUserStateType.js";
+import {tracker} from "./Tracker.js"
+import ByPasser from "./ByPasser.js";
+import XEngineOption from "./XEngineOption.js";
+import QueueType from "./enum/QueueType.js"
+
+const logger = new Logger("xverse-room");
+export default class XRoom extends EventEmitter {
+  constructor(s) {
+    super();
+    this.disableAutoTurn = !1;
+    this.options = null;
+    this._currentNetworkOptions = null;
+    this.lastSkinId = null;
+    this.debug = null;
+    this.bypasser = null;
+    this.isFirstDataUsed = !1;
+    this.userId = null;
+    this.pathManager = new PathManager;
+    this.networkController = null;
+    this._startTime = Date.now();
+    this.canvas = null;
+    this.modelManager = null;
+    this.eventsController = null;
+    this.panorama = null;
+    this.engineProxy = null;
+    this._id = null;
+    this.skinList = [];
+    this.isHost = !1;
+    this.avatarManager = new XverseAvatarManager(this);
+    this.effectManager = new XverseAvatarManager(this);
+    this.sceneManager = null;
+    this.scene = null;
+    this.breathPointManager = null;
+    this._currentState = null;
+    this.joined = !1;
+    this.disableRotate = !1;
+    this.isPano = !1;
+    this.movingByClick = !1;
+    this.camera = new Camera(this);
+    this.stats = new Stats(this);
+    this.isUpdatedRawYUVData = !1;
+    this.actionsHandler = new ActionsHandler(this);
+    this._currentClickingState = null;
+    this.signal = new Signal(this);
+    this.allowRender = !0;
+    this.firstFrameTimestamp = null;
+    this.receiveRtcData = async()=>{
+        logger.info("Invoke receiveRtcData");
+        let s = !1
+          , c = !1
+          , _ = !1
+          , b = !1;
+        return this.viewMode === "serverless" ? (logger.warn("set view mode to serverless"),
+        this.setViewMode("observer").then(()=>this)) : new Promise((k,j)=>{
+            const $ = this.networkController.rtcp.workers;
+            $.registerFunction("signal", _e=>{
+                this.signal.handleSignal(_e, j)
+            }
+            ),
+            $.registerFunction("stream", _e=>{
+                var et;
+                if (this.emit("streamTimestamp", {
+                    timestamp: Date.now()
+                }),
+                c || (c = !0,
+                logger.info("Invoke stream event")),
+                _e.stream) {
+                    _ || (_ = !0,
+                    logger.info("Invoke updateRawYUVData")),
+                    this.isUpdatedRawYUVData = !1;
+                    const tt = (et = this._currentState.skin) == null ? void 0 : et.fov;
+                    this.sceneManager.materialComponent.updateRawYUVData(_e.stream, _e.width, _e.height, tt),
+                    this.isUpdatedRawYUVData = !0
+                }
+                s || (logger.info("Invoke isAfterRenderRegistered"),
+                s = !0,
+                this.scene.registerAfterRender(()=>{
+                    this.engineProxy.frameRenderNumber >= 2 && (b || (b = !0,
+                    logger.info("Invoke registerAfterRender")),
+                    this.isFirstDataUsed || (logger.info("Invoke isStreamAvailable"),
+                    this.isFirstDataUsed = !0,
+                    this.firstFrameTimestamp = Date.now(),
+                    k(this),
+                    this.afterJoinRoom()))
+                }
+                ))
+            }
+            ),
+            this.panorama.bindListener(()=>{
+                k(this),
+                this.afterJoinRoom()
+            }
+            ),
+            $.registerFunction("reconnectedFrame", ()=>{}
+            ),
+            logger.info("Invoke decoderWorker.postMessage"),
+            $.decoderWorker.postMessage({
+                t: 5
+            })
+        }
+        )
+    }
+    this.moveToExtra = "";
+    this.options = s,
+    this.options.wsServerUrl || (this.options.wsServerUrl = SERVER_URLS.DEV),
+    this.modelManager = ModelManager.getInstance(s.appId, s.releaseId);
+    const c = s.nicknameOptions;
+    c && (s.extra = Object.assign({}, s.extra, {
+        nicknameOptions: c
+    })),
+    this.updateReporter();
+    const {canvas: _, ...b} = s;
+    logger.infoAndReportMeasurement({
+        metric: "startJoinRoomAt",
+        startTime: Date.now(),
+        group: "joinRoom",
+        extra: b,
+        value: 0
+    }),
+    this.bypasser = new ByPasser(s.bypassTag || 0)
+  }
+  get currentNetworkOptions() {
+      return this._currentNetworkOptions
+  }
+  get viewMode() {
+      var s;
+      return ((s = this._currentState) == null ? void 0 : s.viewMode) || "full"
+  }
+  get id() {
+      return this._id
+  }
+  get skinId() {
+      return this._currentState.skinId
+  }
+  get skin() {
+      return this._currentState.skin
+  }
+  get sessionId() {
+      return this.currentNetworkOptions.sessionId
+  }
+  get pictureQualityLevel() {
+      return this.currentState.pictureQualityLevel
+  }
+  get avatars() {
+      return Array.from(this.avatarManager.avatars.values())
+  }
+  get currentState() {
+      var s;
+      return {
+          ...this._currentState,
+          state: (s = this.networkController) == null ? void 0 : s._state
+      }
+  }
+  get _userAvatar() {
+      return this.avatars.find(s=>s.userId === this.userId)
+  }
+  get userAvatar() {
+      return this.avatars.find(s=>s.userId === this.userId)
+  }
+  get tvs() {
+      return this.engineProxy._tvs
+  }
+  get tv() {
+      return this.tvs[0]
+  }
+  get currentClickingState() {
+      return this._currentClickingState
+  }
+  afterJoinRoomHook() {}
+  beforeJoinRoomResolveHook() {}
+  afterReconnectedHook() {}
+  handleSignalHook(s) {}
+  skinChangedHook() {}
+  async beforeStartGameSendHook() {}
+  async beforeStartGameHook(s) {}
+  afterLoadAssetsHook() {}
+  afterUserAvatarLoadedHook() {}
+  audienceViewModeHook(s) {}
+  setViewModeToObserver() {}
+  handleVehicleHook(s) {}
+  updateReporter() {
+      const {avatarId: s, skinId: c, userId: _, roomId: b, role: k, appId: j, wsServerUrl: $} = this.options;
+      reporter.updateHeader({
+          userId: _
+      }),
+      reporter.updateBody({
+          roomId: b,
+          role: k,
+          skinId: c,
+          avatarId: s,
+          appId: j,
+          wsServerUrl: $
+      }),
+      tracker.updateHeader({
+          userId: _,
+          roomId: b,
+          role: k,
+          skinId: c,
+          appId: j,
+          wsServerUrl: $
+      })
+  }
+  async initRoom() {
+      const {timeout: s=DEFAULT_JOINROOM_TIMEOUT} = this.options;
+      return util.isSupported() ? this._initRoom()._timeout(s, new TimeoutError("initRoom timeout")) : Promise.reject(new UnsupportedError)
+  }
+  async _initRoom() {
+      const s = this.validateOptions(this.options);
+      if (s)
+          return logger.error("initRoom param error", s),
+          Promise.reject(s);
+      const {canvas: c, avatarId: _, skinId: b, pathId: k, userId: j, wsServerUrl: $, role: _e, token: et, pageSession: tt, appId: rt, camera: it, player: nt, avatarComponents: at, nickname: ot, avatarScale: st, viewMode: lt="full", roomId: ut, roomTypeId: ct, hasAvatar: ht=!1, syncToOthers: dt=!1, prioritySync: ft=!1, removeWhenDisconnected: pt=!0, avatarURL: gt, extra: _t} = this.options;
+      this.setCurrentNetworkOptions({
+          avatarId: _,
+          skinId: b,
+          roomId: ut,
+          userId: j,
+          wsServerUrl: $,
+          role: _e,
+          token: et,
+          pageSession: tt,
+          appId: rt,
+          camera: it,
+          player: nt,
+          avatarComponents: at,
+          nickname: ot,
+          avatarScale: st,
+          roomTypeId: ct,
+          hasAvatar: ht,
+          syncToOthers: dt,
+          prioritySync: ft,
+          extra: _t,
+          avatarURL: gt,
+          removeWhenDisconnected: pt,
+          pathId: k
+      }),
+      this.userId = j,
+      this.canvas = c,
+      this.networkController = new NetworkController(this),
+      this.setCurrentState({
+          speed: 0,
+          viewMode: lt,
+          state: this.networkController._state,
+          skinId: b
+      });
+      try {
+          await Promise.all([this.initNetwork(), this.initConfig(), this.initWasm()]),
+          logger.info("network config wasm all ready, start to create game");
+          const mt = await this.requestCreateRoom({
+              skinId: b
+          });
+          await this.initEngine(mt)
+      } catch (mt) {
+          return Promise.reject(mt)
+      }
+      return this.beforeJoinRoomResolve(),
+      this.receiveRtcData()
+  }
+  beforeJoinRoomResolve() {
+      this.setupStats(),
+      this.eventsController = new EventsController(this),
+      this.eventsController.bindEvents(),
+      this.panorama = new Panorama(this),
+      this.beforeJoinRoomResolveHook()
+  }
+  afterJoinRoom() {
+      this.joined = !0,
+      this.viewMode === "observer" && this.setViewModeToObserver(),
+      logger.infoAndReportMeasurement({
+          tag: this.viewMode,
+          value: (this.firstFrameTimestamp || Date.now()) - this._startTime,
+          startTime: Date.now(),
+          metric: "joinRoom",
+          reportOptions: {
+              immediate: !0
+          }
+      }),
+      tracker.trackEvent("joinRoom", {
+          code: Codes.Success,
+          viewMode: this.viewMode
+      }),
+      this.stats.on("stats", ({stats: s})=>{
+          reporter.report("stats", {
+              ...s
+          })
+      }
+      ),
+      this.debug = new Debug(this),
+      this.afterJoinRoomHook(),
+      setInterval(()=>{
+          this.currentState.state === "connected" && this.actionsHandler.getNewUserState(NewUserStateType.NUST_Undefined).then(s=>{
+              this.avatarManager.handleAvatar(s)
+          }
+          ).catch(()=>{}
+          )
+      }
+      , 2e3)
+  }
+  afterReconnected() {
+      this.avatarManager.clearOtherUsers(),
+      this.afterReconnectedHook()
+  }
+  leave() {
+      var s, c;
+      return logger.info("Invoke room.leave"),
+      (s = this.eventsController) == null || s.clearEvents(),
+      (c = this.networkController) == null || c.quit(),
+      this
+  }
+  validateOptions(s) {
+      const {canvas: c, avatarId: _, skinId: b, userId: k, role: j, roomId: $, token: _e, appId: et, avatarComponents: tt} = s || {}
+        , rt = [];
+      return c instanceof HTMLCanvasElement || rt.push(new ParamError("`canvas` must be instanceof of HTMLCanvasElement")),
+      (!k || typeof k != "string") && rt.push(new ParamError("`userId` must be string")),
+      (!_e || typeof _e != "string") && rt.push(new ParamError("`token` must be string")),
+      (!et || typeof et != "string") && rt.push(new ParamError("`appId` must be string")),
+      j == "audience" || (!_ || !b) && rt.push(new ParamError("`avatarId` and `skinId` is required when create room")),
+      rt[0]
+  }
+  async initNetwork() {
+      if (this.viewMode === "serverless")
+          return Promise.resolve();
+      const s = Date.now();
+      try {
+          await this.networkController.connect()._timeout(8e3, new InitNetworkTimeoutError),
+          logger.infoAndReportMeasurement({
+              metric: "networkInitAt",
+              startTime: this._startTime,
+              group: "joinRoom"
+          }),
+          logger.infoAndReportMeasurement({
+              metric: "networkInitCost",
+              startTime: s,
+              group: "joinRoom"
+          })
+      } catch (c) {
+          throw logger.infoAndReportMeasurement({
+              metric: "networkInitAt",
+              startTime: s,
+              group: "joinRoom",
+              error: c
+          }),
+          c
+      }
+  }
+  async initConfig() {
+      const s = Date.now();
+      try {
+          await this.modelManager.getApplicationConfig()._timeout(8e3, new InitConfigTimeoutError),
+          logger.infoAndReportMeasurement({
+              metric: "configInitAt",
+              startTime: this._startTime,
+              group: "joinRoom"
+          }),
+          logger.infoAndReportMeasurement({
+              metric: "configInitCost",
+              startTime: s,
+              group: "joinRoom"
+          })
+      } catch (c) {
+          throw logger.infoAndReportMeasurement({
+              metric: "configInitAt",
+              startTime: s,
+              group: "joinRoom",
+              error: c
+          }),
+          c
+      }
+  }
+  async initEngine(s) {
+      const c = Date.now();
+      try {
+          logger.debug("GEngine.init bypass is:", this.options.bypassTag);
+          const _ = new XEngineOption(this.options.bypassTag);
+          GEngine.init(this.options.canvas, _),
+          logger.debug("GEngine.init options is:", _),
+          this.engineProxy = new EngineProxy(this),
+          await this.engineProxy.initEngine(s)._timeout(8e3, new InitEngineError("init engine timeout in 8s")),
+          logger.infoAndReportMeasurement({
+              metric: "webglInitAt",
+              startTime: this._startTime,
+              group: "joinRoom"
+          }),
+          logger.infoAndReportMeasurement({
+              metric: "webglInitCost",
+              startTime: c,
+              group: "joinRoom"
+          });
+          return
+      } catch (_) {
+          let b = _;
+          return _.code !== Codes.InitEngineTimeout && (b = new InitEngineError(_)),
+          logger.error(_),
+          logger.infoAndReportMeasurement({
+              metric: "webglInitAt",
+              startTime: c,
+              group: "joinRoom",
+              error: b
+          }),
+          Promise.reject(b)
+      }
+  }
+  async initWasm() {
+      if (this.viewMode === "serverless")
+          return Promise.resolve();
+      const s = Date.now();
+      try {
+          await this.networkController.rtcp.workers.init({
+              width: 1920,
+              height: 1080,
+              userID: this.userId,
+              pageSession: this.options.pageSession,
+              serverSession: "",
+              bypasserList: this.bypasser.getSwitches("decode")
+          })._timeout(8e3, new InitDecoderTimeoutError),
+          this.networkController.rtcp.workers.registerFunction("error", c=>{
+              logger.error("decode error", c);
+              const {code: _, message: b} = c;
+              this.emit("error", {
+                  code: _,
+                  msg: b
+              })
+          }
+          ),
+          logger.infoAndReportMeasurement({
+              metric: "wasmInitAt",
+              group: "joinRoom",
+              startTime: this._startTime
+          }),
+          logger.infoAndReportMeasurement({
+              metric: "wasmInitCost",
+              group: "joinRoom",
+              startTime: s
+          }),
+          eventsManager.on("traceId", c=>{
+              this.networkController.rtcp.workers.onTraceId(c)
+          }
+          )
+      } catch (c) {
+          throw logger.infoAndReportMeasurement({
+              metric: "wasmInitAt",
+              group: "joinRoom",
+              startTime: s,
+              error: c
+          }),
+          c
+      }
+  }
+  async requestCreateRoom({skinId: s}) {
+      await this.beforeStartGameHook(this.options);
+      let c;
+      if (s) {
+          c = await this.getSkin(s),
+          this.updateCurrentState({
+              skin: c
+          });
+          const _ = await this.modelManager.findPath(s, this.options.pathId);
+          this.updateCurrentNetworkOptions({
+              versionId: c.versionId
+          });
+          const {camera: b, player: k} = getRandomItem(_.birthPointList) || this.options;
+          this.options.camera || this.updateCurrentNetworkOptions({
+              camera: b
+          }),
+          this.options.player || this.updateCurrentNetworkOptions({
+              player: k
+          })
+      }
+      if (this.viewMode === "serverless")
+          return c;
+      try {
+          await this.beforeStartGameSendHook();
+          const {room_id: _, data: b, session_id: k} = await this.networkController.startGame();
+          this._id = _;
+          const j = JSON.parse(b);
+          this.isHost = j.IsHost,
+          s = j.SkinID || s;
+          const $ = await this.getSkin(s);
+          this.updateCurrentNetworkOptions({
+              roomId: _,
+              sessionId: k
+          }),
+          reporter.updateBody({
+              roomId: _,
+              skinId: s,
+              serverSession: k
+          }),
+          tracker.updateHeader({
+              roomId: _,
+              skinId: s,
+              serverSession: k
+          });
+          const _e = $.pathList.find(tt=>tt.id === this.options.pathId)
+            , et = ((_e == null ? void 0 : _e.step) || 7.5) * 30;
+          return this.updateCurrentState({
+              skin: $,
+              skinId: $.id,
+              versionId: $.versionId,
+              speed: et
+          }),
+          $
+      } catch (_) {
+          return logger.error("requestCreateRoom error:", _),
+          Promise.reject(_)
+      }
+  }
+  pause() {
+      return this.engineProxy.pause()
+  }
+  resume() {
+      return this.engineProxy.resume()
+  }
+  reconnect() {
+      this.networkController.reconnect()
+  }
+  async setViewMode(s) {}
+  handleRepetLogin() {
+      logger.infoAndReportMeasurement({
+          metric: "repeatLogin",
+          startTime: Date.now(),
+          code: Codes.RepeatLogin,
+          reportOptions: {
+              immediate: !0
+          }
+      }),
+      this.emit("repeatLogin"),
+      reporter.disable(),
+      this.networkController.quit()
+  }
+  setPictureQualityLevel(s) {
+      const c = {
+          high: EImageQuality.high,
+          low: EImageQuality.low,
+          average: EImageQuality.mid
+      };
+      return this.updateCurrentState({
+          pictureQualityLevel: s
+      }),
+      this.sceneManager.setImageQuality(c[s])
+  }
+  async getSkin(s) {
+      let c = null;
+      if (c = (this.skinList = await this.modelManager.getSkinsList()).find(b=>b.id === s || b.id === s),
+      c)
+          return c;
+      {
+          const b = `skin is invalid: skinId: ${s}`;
+          return Promise.reject(new ParamError(b))
+      }
+  }
+  setupStats() {
+      this.stats.assign({
+          roomId: this.id,
+          userId: this.userId
+      }),
+      setInterval(this.engineProxy.updateStats, 1e3)
+  }
+  proxyEvents(s, c) {
+      this.emit(s, c)
+  }
+  setCurrentNetworkOptions(s) {
+      this._currentNetworkOptions = s
+  }
+  updateCurrentNetworkOptions(s) {
+      Object.assign(this._currentNetworkOptions, s),
+      Object.assign(this.options, s)
+  }
+  setCurrentState(s) {
+      this._currentState = s
+  }
+  updateCurrentState(s) {
+      logger.infoAndReportMeasurement({
+          metric: "updateCurrentState",
+          startTime: Date.now(),
+          extra: s
+      }),
+      s.skinId && (this.lastSkinId = this.currentState.skinId,
+      this.updateCurrentNetworkOptions({
+          skinId: s.skinId
+      })),
+      s.versionId && this.updateCurrentNetworkOptions({
+          versionId: s.versionId
+      }),
+      Object.assign(this._currentState, s)
+  }
+  afterSetUrlHook() {}
+  afterTvStopedHook() {}
+  afterTvPlayedHook() {}
+  pageShowHandler() {
+      var s;
+      (s = this.engineProxy) == null || s.setEnv(this.skin),
+      this.allowRender = !0,
+      this.avatars.forEach(async c=>{
+          var $, _e, et;
+          const _ = c.statusSyncQueue.queue.filter(tt=>tt.type === QueueType.Move)
+            , k = ((($ = c.statusSyncQueue.currentAction) == null ? void 0 : $.type) === QueueType.Move ? c.statusSyncQueue.currentAction : void 0) || _.slice(-1)[0]
+            , j = (et = (_e = k == null ? void 0 : k.userState) == null ? void 0 : _e.event) == null ? void 0 : et.points;
+          if (j) {
+              const tt = await this.modelManager.findPath(this.skinId, c.currentPathName)
+                , rt = ((tt == null ? void 0 : tt.step) || 7.5) * 25
+                , it = j[j.length - 1];
+              c.move({
+                  start: it,
+                  end: it,
+                  walkSpeed: rt
+              })
+          }
+          c.statusSyncQueue.reject()
+      }
+      )
+  }
+  pageHideHandler() {
+      this.allowRender = !1
+  }
+}

+ 205 - 0
src/XSceneComponent.js

@@ -0,0 +1,205 @@
+
+import XActorComponent from "./XActorComponent.js"
+import Logger from "./Logger.js"
+
+const logger = new Logger("XSceneComponent");
+
+export default class XSceneComponent extends XActorComponent{
+    constructor() {
+        super(),
+        this._billboardMode = 0,
+        this._castShadow = !0,
+        this.getBbox = (s={})=>{
+            const {isConst: c=!1, changeWithAvatar: _=!1} = s;
+            let {localCenter: b={
+                x: 0,
+                y: 0,
+                z: 75
+            }, width: k=1.32, height: j=1.5, depth: $=.44} = s;
+            if (_) {
+                const _e = this.scaling;
+                b = {
+                    x: b.x * _e.x,
+                    y: b.y * _e.y,
+                    z: b.z * _e.z
+                },
+                k *= _e.x,
+                j *= _e.y,
+                $ *= _e.z
+            }
+            if (this.rootNode) {
+                let _e = new BABYLON.Vector3(0,0,0)
+                  , et = new BABYLON.Vector3(0,0,0);
+                if (c) {
+                    const rt = ue4Position2Xverse(b);
+                    _e = _e.add(rt.add(new BABYLON.Vector3(-k / 2,-j / 2,-$ / 2))),
+                    et = et.add(rt.add(new BABYLON.Vector3(k / 2,j / 2,$ / 2)))
+                } else {
+                    _e = _e.add(new BABYLON.Vector3(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY)),
+                    et = et.add(new BABYLON.Vector3(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY)),
+                    this.rootNode.getChildMeshes().forEach(nt=>{
+                        const at = nt.getBoundingInfo().boundingBox.minimum
+                          , ot = nt.getBoundingInfo().boundingBox.maximum;
+                        _e.x = Math.min(_e.x, at.x),
+                        et.x = Math.max(et.x, ot.x),
+                        _e.y = Math.min(_e.y, at.y),
+                        et.y = Math.max(et.y, ot.y),
+                        _e.z = Math.min(_e.z, at.z),
+                        et.z = Math.max(et.z, ot.z)
+                    }
+                    );
+                    const rt = et.x - _e.x
+                      , it = et.z - _e.z;
+                    _e.x -= this.scaling.x * rt / 2,
+                    et.x += this.scaling.x * rt / 2,
+                    et.y *= this.scaling.y,
+                    _e.z -= this.scaling.z * it / 2,
+                    et.z += this.scaling.z * it / 2
+                }
+                const tt = this.rootNode.computeWorldMatrix(!0);
+                this.bbox ? this.bbox.reConstruct(_e, et, tt) : this.bbox = new BABYLON.BoundingBox(_e,et,tt)
+            }
+        }
+        ;
+        const o = BABYLON.EngineStore.LastCreatedScene;
+        this._bbox = null,
+        this._attachChildren = new Array,
+        this._attachParent = null,
+        this._asset = new BABYLON.AssetContainer(o),
+        this._rootNode = this._asset.GetRootNode()
+    }
+    getClassName() {
+        return "XSceneComponent"
+    }
+    set asset(o) {
+        !o || (this._asset = o,
+        this._asset.SetOwner(this),
+        this._rootNode = this._asset.GetRootNode())
+    }
+    get asset() {
+        return this._asset
+    }
+    set castShadow(o) {
+        !this._rootNode || (this._rootNode.getChildMeshes().forEach(s=>{}
+        ),
+        this._castShadow = o)
+    }
+    get castShadow() {
+        return this._castShadow
+    }
+    set position(o) {
+        if (!this.rootNode || !o)
+            return;
+        const s = ue4Position2Xverse(o);
+        s && (this.rootNode.position = s)
+    }
+    get position() {
+        return this.rootNode ? xversePosition2Ue4(this.rootNode.position) : {
+            x: 0,
+            y: 0,
+            z: 0
+        }
+    }
+    set rotation(o) {
+        if (!this.rootNode || !o)
+            return;
+        const s = ue4Rotation2Xverse(o);
+        s && (this.rootNode.rotation = s)
+    }
+    get rotation() {
+        return this.rootNode ? xverseRotation2Ue4(this.rootNode.rotation) : {
+            pitch: 0,
+            yaw: 0,
+            roll: 0
+        }
+    }
+    set scaling(o) {
+        if (!this.rootNode || !o)
+            return;
+        const s = ue4Scaling2Xverse(o);
+        s && (this.rootNode.scaling = s)
+    }
+    get scaling() {
+        if (!this.rootNode)
+            return {
+                x: 0,
+                y: 0,
+                z: 0
+            };
+        const o = this.rootNode.scaling;
+        return {
+            x: o.x,
+            y: -o.z,
+            z: o.y
+        }
+    }
+    setEnabled(o) {
+        !this.rootNode || (this.rootNode.setEnabled(o),
+        this._attachChildren.forEach(s=>{
+            s.setEnabled(o)
+        }
+        ))
+    }
+    isEnabled() {
+        return this.rootNode ? this.rootNode.isEnabled : null
+    }
+    get billboardMode() {
+        return this._billboardMode
+    }
+    set bllboardMode(o) {
+        this._billboardMode !== o && (!this.rootNode || this._rootNode.getChildMeshes().forEach(s=>{
+            s.billboardMode = o
+        }
+        ))
+    }
+    set name(o) {
+        !this.rootNode || (this.rootNode.name = o)
+    }
+    get name() {
+        return this.rootNode ? this.rootNode.name : ""
+    }
+    get bbox() {
+        return this._bbox
+    }
+    set bbox(o) {
+        this._bbox = o
+    }
+    get rootNode() {
+        return this._rootNode
+    }
+    postLoad() {
+        var o;
+        this._asset && (this.asset = this._asset,
+        this._rootNode = (o = this._asset) == null ? void 0 : o.GetRootNode())
+    }
+    dispose() {
+        var o, s;
+        (o = this._asset) == null || o.dispose(),
+        (s = this._bbox) == null || s.dispose(),
+        this._attachChildren = [],
+        this._attachParent = null
+    }
+    DetachFromComponent(o) {
+        !this.rootNode || (this.rootNode.parent = null,
+        o._attachChildren.splice(o._attachChildren.indexOf(this), 1),
+        this._attachParent = null)
+    }
+    AttachToComponent(o, s={
+        x: 0,
+        y: 0,
+        z: 0
+    }) {
+        if (!this.asset || !this.rootNode)
+            return;
+        const c = this.rootNode;
+        this.asset.scene;
+        const _ = ue4Position2Xverse(s);
+        c.setParent(o.rootNode),
+        c.position = _,
+        o._attachChildren.push(this),
+        this._attachParent = o
+    }
+}
+
+__decorateClass([xProperty("xAsset")], XSceneComponent.prototype, "_asset", 2);
+RegisterXObjectClass("XSceneComponent", XSceneComponent);

+ 209 - 0
src/XSequence.js

@@ -0,0 +1,209 @@
+export default class XSequence {
+    constructor(o, s, c="test", _=DefaultUrlTransformer) {
+        this.init = async()=>new Promise(b=>{
+            this.urlTransformer(this._abosoluteUrl).then(k=>{
+                const j = new XMLHttpRequest;
+                j.open("get", k),
+                j.send(null),
+                j.onload = ()=>{
+                    if (j.status == 200) {
+                        const $ = JSON.parse(j.responseText);
+                        this.load($).then(()=>{
+                            b()
+                        }
+                        )
+                    }
+                }
+            }
+            )
+        }
+        ),
+        this.getRootOfSubSeqs = ()=>{
+            const b = new Array;
+            return this._subSeqs.forEach(k=>{
+                b.push(k.root)
+            }
+            ),
+            b
+        }
+        ,
+        this.play = async(b=!0)=>new Promise(k=>{
+            this._animGroup.play(b),
+            b ? this._animGroup.onAnimationGroupLoopObservable.addOnce(()=>{
+                k()
+            }
+            ) : this._animGroup.onAnimationGroupEndObservable.addOnce(()=>{
+                k()
+            }
+            )
+        }
+        ),
+        this.goToFrame = b=>{
+            this._animGroup.goToFrame(b)
+        }
+        ,
+        this.hide = ()=>{
+            this._subSeqs.forEach(b=>{
+                b.hide()
+            }
+            )
+        }
+        ,
+        this.show = ()=>{
+            this._subSeqs.forEach(b=>{
+                b.show()
+            }
+            )
+        }
+        ,
+        this.pause = ()=>{
+            this._animGroup.pause()
+        }
+        ,
+        this.reset = ()=>{
+            this._animGroup.reset()
+        }
+        ,
+        this._scene = o,
+        this._abosoluteUrl = s,
+        this._rootDir = s.split("/").slice(0, -1).join("/") + "/",
+        this._name = c,
+        this._speedRatio = 1,
+        this._subSeqs = new Map,
+        this._animGroup = new AnimationGroup("Seq_" + c,o),
+        this._targetSubSeqs = new Map,
+        this._animGroup.onAnimationGroupPlayObservable.add(()=>{
+            this._subSeqs.forEach(b=>{
+                b.show()
+            }
+            )
+        }
+        ),
+        this._animGroup.onAnimationGroupEndObservable.add(()=>{
+            this._subSeqs.forEach(b=>{
+                b.hide()
+            }
+            )
+        }
+        ),
+        this.urlTransformer = _
+    }
+    get animGroup() {
+        return this._animGroup
+    }
+    serialize() {
+        const o = {};
+        return o.SubSequence = new Array,
+        o.TimeLine = new Array,
+        this._subSeqs.forEach(s=>{
+            const c = {
+                name: s.name,
+                uri: s.path
+            };
+            o.SubSequence.push(c);
+            const _ = this._targetSubSeqs.get(s);
+            _ && o.TimeLine.push({
+                frame: _ == null ? void 0 : _.frame,
+                position: _.position,
+                rotation: _.rotation,
+                scaling: _.scaling,
+                name: s.name
+            })
+        }
+        ),
+        o
+    }
+    get isPlaying() {
+        return this._animGroup.isPlaying
+    }
+    get isStarted() {
+        return this._animGroup.isStarted
+    }
+    get loaded() {
+        let o = !0;
+        return this._subSeqs.forEach(s=>{
+            o = o && s.loaded
+        }
+        ),
+        o
+    }
+    dispose() {
+        this._subSeqs.forEach(o=>{
+            o.dispose()
+        }
+        ),
+        this.animGroup.dispose()
+    }
+    setFrame(o, s) {
+        const c = this._subSeqs.get(o);
+        if (c) {
+            const _ = this._targetSubSeqs.get(c);
+            _ && (_.frame = s),
+            _ && this.update(c, _)
+        }
+    }
+    get name() {
+        return this._name
+    }
+    update(o, s) {
+        if (s) {
+            const c = {
+                frame: s.frame,
+                scaling: new BABYLON.Vector3(s.scaling[0],s.scaling[1],s.scaling[2]),
+                position: new BABYLON.Vector3(s.position[0],s.position[1],s.position[2]),
+                rotation: new BABYLON.Vector3(s.rotation[0] / 180 * Math.PI,s.rotation[1] / 180 * Math.PI,s.rotation[2] / 180 * Math.PI),
+                name: s.name
+            }
+              , _ = this._subSeqs.get(c.name);
+            _ && (_.setPositionVector(c.position),
+            _.setRotationVector(c.rotation),
+            _.setScalingVector(c.scaling),
+            _.setStartFrame(c.frame),
+            this._targetSubSeqs.set(_, s),
+            _.onSubSequenceTransformationChangeObservable.add(()=>{
+                const b = this._targetSubSeqs.get(_);
+                b && (b.position = [_.pos.x, _.pos.y, _.pos.z]),
+                b && (b.rotation = [_.rot.x, _.rot.y, _.rot.z]),
+                b && (b.scaling = [_.scal.x, _.scal.y, _.scal.z])
+            }
+            ))
+        }
+    }
+    load(o) {
+        return new Promise((s,c)=>{
+            const _ = new Array
+              , b = o.SubSequence
+              , k = o.TimeLine
+              , j = o.SpeedRatio;
+            j && (this._speedRatio = j);
+            for (const $ of b) {
+                $.uri.indexOf("./") == 0 && ($.uri = $.uri.slice(2));
+                const _e = new XSubSequence(this._scene,this._rootDir + $.uri,this.urlTransformer);
+                this._subSeqs.set($.name, _e),
+                _.push(_e.init())
+            }
+            Promise.all(_).then(()=>{
+                k.forEach($=>{
+                    const _e = this._subSeqs.get($.name);
+                    _e && this.update(_e, $)
+                }
+                ),
+                this._subSeqs.forEach($=>{
+                    $.animGroup.targetedAnimations.forEach(_e=>{
+                        this._animGroup.addTargetedAnimation(_e.animation, _e.target)
+                    }
+                    )
+                }
+                ),
+                this._animGroup.normalize(),
+                this._animGroup.speedRatio = this._speedRatio,
+                s()
+            }
+            , ()=>{
+                c()
+            }
+            )
+        }
+        )
+    }
+}

+ 113 - 0
src/XStream.js

@@ -0,0 +1,113 @@
+
+import Logger from "./Logger.js"
+
+const logger = new Logger('audio')
+
+export default class XStream {
+    constructor(o) {
+        this.audioPlayer = null;
+        this.localTrack = null;
+        this.mediaRecorder = null;
+        this.connection = o,
+        this.localStream = new MediaStream,
+        this.remoteStream = new MediaStream,
+        this.connection.ontrack = s=>{
+            try {
+                if (logger.debug("event.track", s.track),
+                !s.track.id.startsWith("audio-")) {
+                    logger.debug("not my track, return");
+                    return
+                }
+                this.remoteStream.addTrack(s.track),
+                this.audioPlayer = document.createElement("audio"),
+                this.audioPlayer.srcObject = this.remoteStream,
+                this.audioPlayer.onerror = function(c) {
+                    logger.debug("audio player play error: ", c)
+                }
+                ,
+                document.body.appendChild(this.audioPlayer)
+            } catch (c) {
+                logger.debug("+++++++++++++on track error++++++++++", c)
+            }
+        }
+    }
+    pauseRecorder() {
+        var o;
+        (o = this.mediaRecorder) == null || o.stop()
+    }
+    playStream() {
+        if (!this.audioPlayer) {
+            logger.debug("audio player is ", this.audioPlayer);
+            return
+        }
+        this.audioPlayer.play(),
+        logger.debug("audio element paused status is ", this.audioPlayer.paused),
+        this.audioPlayer.paused && (logger.debug("audio elment start next round"),
+        setTimeout(()=>{
+            this.playStream()
+        }
+        , 1e3))
+    }
+    playStream_back() {
+        if (!!this.audioPlayer)
+            try {
+                logger.debug("playStream", this.remoteStream.getTracks(), this.audioPlayer),
+                logger.debug("audio element paused status is ", this.audioPlayer.paused),
+                this.audioPlayer.play(),
+                logger.debug("audio element paused status is ", this.audioPlayer.paused)
+            } catch {
+                logger.error("playStream error")
+            }
+    }
+    getRemoteStream() {
+        return this.remoteStream
+    }
+    quitLocalStream() {
+        this.localTrack != null && this.connection.removeTrack(this.localTrack)
+    }
+    setLocalStream(o) {
+        for (const s of this.localStream.getTracks())
+            s.kind == "audio" && (logger.debug("add track is triggered ", s),
+            this.localTrack = this.connection.addTrack(s, o));
+        return 0
+    }
+    muteAll() {
+        for (const o of this.remoteStream.getTracks())
+            o.kind == "audio" && (o.enabled = !1)
+    }
+    unmuteAll() {
+        for (const o of this.remoteStream.getTracks())
+            o.kind == "audio" && (o.enabled = !0)
+    }
+    muteTrack(o) {
+        for (const s of this.remoteStream.getTracks())
+            if (s.id == o)
+                return s.enabled = !1,
+                !0;
+        return !1
+    }
+    unmuteTrack(o) {
+        for (const s of this.remoteStream.getTracks())
+            if (s.id == o)
+                return s.enabled = !0,
+                !0;
+        return !1
+    }
+    switchMic() {
+        for (const o of this.localStream.getTracks())
+            if (o.kind == "audio")
+                return logger.debug("switchMic is triggered!"),
+                o.enabled = !o.enabled;
+        return !1
+    }
+    getUserMedia() {
+        return navigator.mediaDevices.getUserMedia({
+            video: !1,
+            audio: !0
+        }).then(o=>(logger.debug("getUserMedia stream", o),
+        this.localStream = o,
+        this.setLocalStream(o),
+        Promise.resolve(!0))).catch(o=>(logger.error("getUserMedia error ", o),
+        Promise.reject(!1)))
+    }
+}

+ 32 - 0
src/XWorld.js

@@ -0,0 +1,32 @@
+import XObject from "./XObject.js";
+import WorldStore from "./WorldStore.js";
+
+export default class XWorld extends XObject {
+    constructor() {
+        super(),
+        XWorld.Instances.push(this),
+        this._persistentLevel = null,
+        this.Levels = new Array,
+        this.Components = new Array
+    }
+    static GetDefaultWorld() {
+        return WorldStore.DefaultWorld
+    }
+    static get Instances() {
+        return WorldStore.Instances
+    }
+    get persistentLevel() {
+        return this._persistentLevel == null && (this._persistentLevel = new XLevel),
+        this._persistentLevel
+    }
+    set persistentLevel(o) {
+        this._persistentLevel = o
+    }
+    dispose() {
+        const o = XWorld.Instances.indexOf(this);
+        XWorld.Instances.splice(o, 1),
+        this.Levels = [],
+        this.Components = [],
+        this._persistentLevel = null
+    }
+}

+ 146 - 0
src/XverseAvatarTools.js

@@ -0,0 +1,146 @@
+import Logger from "./Logger.js";
+import EDressType from "./enum/EDressType.js";
+
+const logger = new Logger("xverse-avatar-tools");
+
+export default class XverseAvatarTools{
+    isSuit=d=>d === EDressType.SUIT;
+    isPendant=d=>d === EDressType.PENDANT;
+    avatarComponentsParser = async(d=null,o,s=[],c)=>new Promise(async(_,b)=>{
+        var rt;
+        const k = Date.now();
+        o.find(it=>this.isSuit(it.type)) && ((rt = d == null ? void 0 : d.componentList) == null || rt.find(it=>this.isSuit(it.type)));
+        const $ = o.filter(it=>!s.some(nt=>nt.id === it.id));
+        $.length === 0 && _([]);
+        const _e = [];
+        $.forEach(async it=>{
+            var ot;
+            let nt = (ot = d == null ? void 0 : d.componentList) == null ? void 0 : ot.find(st=>st.type === it.type);
+            if (!nt) {
+                const st = `changeComponents, no such component with type: ${it.type}`;
+                logger.error(st),
+                b(st)
+            }
+            nt = JSON.parse(JSON.stringify(nt));
+            let at = nt == null ? void 0 : nt.unitList.find(st=>st.id === it.id);
+            at || (logger.warn(`changeComponents, no unit with type: ${it.type}, id: ${it.id}`),
+            at = nt == null ? void 0 : nt.unitList.find(st=>st.isDefault),
+            !at && logger.warn(`changeComponents, no default unit with type: ${it.type}`)),
+            at && _e.push({
+                id: at.id,
+                type: it.type
+            })
+        }
+        );
+        const et = [];
+        Promise.all(et).then(it=>{
+            _(_e)
+        }
+        ).catch(it=>{
+            b(it)
+        }
+        );
+        const tt = Date.now();
+        c == null || c.stats.functionTimeConsumingAdd("avatarComponentsParser", tt - k)
+    }
+    );
+    avatarComponentsModify = (d,o,s)=>new Promise((c,_)=>{
+        var tt;
+        const b = Date.now();
+        let k = [];
+        const j = []
+          , $ = [];
+        let _e = o.some(rt=>this.isSuit(rt.type));
+        (tt = d == null ? void 0 : d.componentList) == null || tt.forEach(rt=>{
+            var at;
+            const it = o.find(ot=>ot.type === rt.type)
+              , nt = it && ((at = d == null ? void 0 : d.componentList) == null ? void 0 : at.find(ot=>ot.type === it.type && ot.unitList.some(st=>st.id === it.id))) !== void 0;
+            if (it)
+                if (nt)
+                    k.push(it);
+                else {
+                    if (this.isPendant(rt.type))
+                        return;
+                    const ot = rt.unitList.find(st=>st.isDefault) || rt.unitList[0];
+                    ot ? k.push({
+                        type: rt.type,
+                        id: ot.id
+                    }) : j.push(`component with type: ${rt.type} without default and available unit`)
+                }
+            else if (this.isSuit(rt.type) || this.isPendant(rt.type)) {
+                const ot = rt.unitList.find(st=>st.isDefault);
+                ot && k.push({
+                    type: rt.type,
+                    id: ot.id
+                })
+            } else {
+                const ot = rt.unitList.find(st=>st.isDefault) || rt.unitList[0];
+                ot ? k.push({
+                    type: rt.type,
+                    id: ot.id
+                }) : j.push(`component with type: ${rt.type} without default and available unit`)
+            }
+        }
+        ),
+        _e = k.some(rt=>this.isSuit(rt.type)),
+        _e && (d == null || d.componentList.find(rt=>this.isSuit(rt.type)),
+        k = k.filter(rt=>rt.type !== EDressType.CLOTHES && rt.type !== EDressType.PANTS)),
+        j.length > 0 && (logger.error(j.join(", ")),
+        _(j.join(", "))),
+        $.length > 0 && logger.warn($.join(", ")),
+        c(k);
+        const et = Date.now();
+        s == null || s.stats.functionTimeConsumingAdd("avatarComponentsModify", et - b)
+    }
+    );
+    positionPrecisionProtect = d=>{
+        const {x: o, y: s, z: c} = d;
+        return {
+            x: +o.toFixed(2),
+            y: +s.toFixed(2),
+            z: +c.toFixed(2)
+        }
+    };
+
+    rotationPrecisionProtect = d=>{
+        const {pitch: o, yaw: s, roll: c} = d;
+        return {
+            pitch: +o.toFixed(2),
+            yaw: +s.toFixed(2),
+            roll: +c.toFixed(2)
+        }
+    };
+    
+    avatarComponentsValidate = (d,o)=>{
+        d = d.filter(_=>_.type !== "effect");
+        const s = []
+          , c = {};
+        return Array.isArray(d) ? (d.forEach(_=>{
+            c[_.type] ? c[_.type].num++ : c[_.type] = {
+                num: 1,
+                isSuit: this.isSuit(_.type)
+            }
+        }
+        ),
+        Object.keys(c).forEach(_=>{
+            c[_].num > 1 && !this.isPendant(_) && s.push(new ParamError(`avatarComponent with type: ${_} repeated`))
+        }
+        ),
+        s[0]) : (s.push(new ParamError("avatarComponents must be array")),
+        s[0])
+    };
+    
+    safeParseComponents = d=>{
+        let o = [];
+        try {
+            o = JSON.parse(d || "[]")
+        } catch {
+            o = [],
+            logger.error(`avatarComponents parse error: ${d}`)
+        }
+        return o
+    };
+};
+
+const xverseAvatarTools = new XverseAvatarTools();
+export { xverseAvatarTools };

+ 104 - 0
src/XverseEffect.js

@@ -0,0 +1,104 @@
+import Logger from "./Logger.js"
+import InternalError from "./error/InternalError.js"
+
+const logger = new Logger('effectManager')
+export default class XverseEffect extends EventEmitter{
+    constructor({id: s, jsonPath: c, type: _, room: b, scale: k=1, effect: j}) {
+        super();
+        this._isLoading = !0;
+        this._failed = !1;
+        this.isFromClone = !1;
+        this._room = b,
+        this._id = s,
+        this.type = _,
+        this._scale = k,
+        this.jsonPath = c,
+        j ? this.effect = j : this.effect = s === "Rain" || s === "Boom" ? new XRain(this._room.scene,c,urlTransformer) : _ === IEffectType.Sequence ? new XSequence(this._room.scene,c,"",urlTransformer) : new XSubSequence(this._room.scene,c,urlTransformer)
+    }
+    get failed() {
+        return this._failed
+    }
+    get position() {
+        if (this.type !== IEffectType.Sequence)
+            return this.effect.position
+    }
+    get rotation() {
+        if (this.type !== IEffectType.Sequence)
+            return this.effect.rotation
+    }
+    get isLoading() {
+        return this._isLoading
+    }
+    get id() {
+        return this._id
+    }
+    get name() {
+        return this.effect.name
+    }
+    get isPlaying() {
+        var s;
+        return !!((s = this.effect) != null && s.isPlaying)
+    }
+    clone() {
+        if (this.type !== IEffectType.SubSequence)
+            throw new InternalError("clone failed, only support XubSequence");
+        const s = this.effect.clone()
+          , c = new gr({
+            id: this._id + "_clone" + gr.INDEX++,
+            jsonPath: this.jsonPath,
+            type: this.type,
+            scale: this._scale,
+            effect: s,
+            room: this._room
+        });
+        return c.isFromClone = !0,
+        c
+    }
+    async init() {
+        try {
+            await this.effect.init()._timeout(1e4, new TimeoutError("effect init timeout(10s)")),
+            this._isLoading = !1,
+            this._failed = !1
+        } catch (s) {
+            throw this._isLoading = !1,
+            this._failed = !0,
+            logger.error(`effect: ${this.id} init error`, s),
+            s
+        }
+    }
+    play(s=!1) {
+        return new Promise((c,_)=>{
+            this.effect.play(s),
+            c()
+        }
+        )
+    }
+    hide() {
+        return this.effect.hide()
+    }
+    show() {
+        return this.effect.show()
+    }
+    setRotation(s) {
+        var c;
+        return this.type === IEffectType.Sequence ? Promise.reject("setRotation failed, sequence unSuported") : (c = this.effect) == null ? void 0 : c.setRotation(s)
+    }
+    setPosition(s) {
+        var c;
+        return this.type === IEffectType.Sequence ? Promise.reject("setPosition failed, sequence unSuported") : (c = this.effect) == null ? void 0 : c.setPosition(s)
+    }
+    setScaling(s) {
+        var c;
+        return this.type === IEffectType.Sequence ? Promise.reject("setScaling failed, sequence unSuported") : (this._scale = s,
+        (c = this.effect) == null ? void 0 : c.setScaling({
+            x: s,
+            y: -s,
+            z: s
+        }))
+    }
+    dispose() {
+        this.effect.dispose()
+    }
+}
+
+XverseEffect.INDEX = 0;

+ 17 - 0
src/XverseEngine.js

@@ -0,0 +1,17 @@
+import Singleton from "./Singleton.js";
+import XEngineOption from "./XEngineOption.js";
+
+export default class XverseEngine extends Singleton{
+    constructor() {
+        super(...arguments),
+        this._engineOption = new XEngineOption
+    }
+    get engineOption() {
+        return this._engineOption
+    }
+    init(o, s) {
+        s && (this._engineOption = s)
+    }
+}
+
+window.GEngine = XverseEngine.getInstance()

+ 6 - 0
src/enum/ChangeComponentsMode.js

@@ -0,0 +1,6 @@
+var ChangeComponentsMode = {
+    Preview:0,
+    Confirm:1,
+    Cancel:2
+}
+export default ChangeComponentsMode

+ 21 - 0
src/enum/ClickTargetName.js

@@ -0,0 +1,21 @@
+
+var ClickTargetName = {
+    OfficeQiantai:'OfficeQiantai',
+    OfficeZhanting:'OfficeZhanting',
+    OfficeXingyunmanghe:'OfficeXingyunmanghe',
+    OfficeZixunqiang: 'OfficeZixunqiang',
+    OfficeHr: 'OfficeHr',
+    OfficeInterview:'OfficeInterview',
+    OfficeXingzheng:'OfficeXingzheng',
+    OfficeBangongqu:'OfficeBangongqu',
+    OfficeMeishu:'OfficeMeishu',
+    OfficeJishu:'OfficeJishu',
+    OfficeChanpin:'OfficeChanpin',
+    OfficeZhineng:'OfficeZhineng',
+    OfficeZhaopin:'OfficeZhaopin',
+    OfficeZixunlan:'OfficeZixunlan',
+    OfficeTuring:'OfficeTuring',
+    OfficeTuringlife:'OfficeTuringlife'
+}
+export default ClickTargetName
+

+ 14 - 0
src/enum/ComponentItemType.js

@@ -0,0 +1,14 @@
+
+var ComponentItemType = {
+    SKELETON:'SKELETON',
+    BODY:'BODY',
+    HEAD:'HEAD',
+    CLOTHES:'CLOTHES',
+    PANTS:'PANTS',
+    SHOES:'SHOES',
+    SUIT:'SUIT',
+    PENDANT:'PENDANT',
+    ANIMATION:'ANIMATION',
+    HAIR:'HAIR'
+}
+export default ComponentItemType

+ 6 - 0
src/enum/EAllNicknameStatus.js

@@ -0,0 +1,6 @@
+var EAllNicknameStatus = {
+    HIDE_ALL:0,
+    SHOW_ALL:1,
+    SHOW_USER_ONLY:2
+}
+export default EAllNicknameStatus

+ 11 - 0
src/enum/EDressType.js

@@ -0,0 +1,11 @@
+var EDressType = {
+    BODY:'BODY',
+    CLOTHES:'CLOTHES',
+    HEAD:'HEAD',
+    HAIR:'HAIR',
+    PANTS:'PANTS',
+    SUIT:'SUIT',
+    SHOES:'SHOES',
+    PENDANT:'PENDANT'
+}
+export default EDressType

+ 7 - 0
src/enum/EMotionType.js

@@ -0,0 +1,7 @@
+var EMotionType = {
+    Idle:'idle',
+    Walk:'walk',
+    Run:'run',
+    Fly:'fly'
+}
+export default EMotionType

+ 10 - 0
src/enum/FeatureSwitchEnum.js

@@ -0,0 +1,10 @@
+var FeatureSwitchEnum = {
+    DisableRemoteAvatar:3,
+    DisableNickName:4,
+    DisableSkeletonAnim:5,
+    SimpleMaterialAvatar:6,
+    DisableCloudRender:7,
+    DisableLocalRender:8,
+    Max:9
+}
+export default FeatureSwitchEnum

+ 5 - 0
src/enum/IEffectType.js

@@ -0,0 +1,5 @@
+var IEffectType = {
+    Sequence:'sequence',
+    SubSequence:'subSequence'
+}
+export default IEffectType

+ 8 - 0
src/enum/MotionAnimtion.js

@@ -0,0 +1,8 @@
+var MotionAnimtion = {
+    walk:'Walking',
+    run:'Running',
+    swim:'Swim02',
+    idle:'Idle',
+    swimIdle:'Swim01'
+}
+export default MotionAnimtion

+ 7 - 0
src/enum/PathType.js

@@ -0,0 +1,7 @@
+var PathType = {
+    SequentialPath:'SequentialPath',
+    RoamingPath:'RoamingPath',
+    ViewingPointPath:'ViewingPointPath',
+    FixedPath:'FixedPath'
+}
+export default PathType

+ 10 - 0
src/enum/PointerEventTypes.js

@@ -0,0 +1,10 @@
+var PointerEventTypes = {
+    POINTERDOWN:1,
+    POINTERUP:2,
+    POINTERMOVE:4,
+    POINTERWHEEL:8,
+    POINTERPICK:16,
+    POINTERTAP:32,
+    POINTERDOUBLETAP:64
+}
+export default PointerEventTypes

+ 6 - 0
src/enum/TransferType.js

@@ -0,0 +1,6 @@
+
+var TransferType = {
+    TF_Undefine:0,
+    TF_AcceptLocation:1
+}
+export default TransferType