private void LoadModel(string path) { if (!File.Exists(path)) { return; } if (Path.GetExtension(path).ToLower() != ".vrm") { LogOutput.Instance.Write($"unknown file type: {path}"); return; } TryWithoutException(() => { var context = new VRMImporterContext(); var file = File.ReadAllBytes(path); context.ParseGlb(file); context.Load(); context.EnableUpdateWhenOffscreen(); context.ShowMeshes(); SetModel(context.Root); }); }
private void LoadModel(string path) { if (!File.Exists(path)) { return; } if (Path.GetExtension(path).ToLower() != ".vrm") { LogOutput.Instance.Write($"unknown file type: {path}"); return; } try { var context = new VRMImporterContext(); var file = File.ReadAllBytes(path); context.ParseGlb(file); var meta = context.ReadMeta(false); context.Load(); context.EnableUpdateWhenOffscreen(); context.ShowMeshes(); _sender.SendCommand(MessageFactory.Instance.ModelNameConfirmedOnLoad("VRM File: " + meta.Title)); SetModel(context.Root); } catch (Exception ex) { HandleLoadError(ex); } }
IEnumerator Loading(Camera mainCamera, int defaultCullingMask, VrmMeta vrmMeta) { //Loading表示に切り替えるために1フレーム待つ yield return(null); var bytes = File.ReadAllBytes(GlobalPath.VrmHomePath + "/" + vrmMeta.VrmFileName); var vrmImporterContext = new VRMImporterContext(); vrmImporterContext.ParseGlb(bytes); vrmImporterContext.Load(); vrmImporterContext.Root.transform.SetParent(vrmRoot, false); var vrmAnimationController = vrmImporterContext.Root.AddComponent <VrmAnimationController>(); vrmAnimationController.Play(defaultAnimation); //BlendShapeProxyの初期化を待つ。 yield return(null); var vrmBlendShapeProxy = vrmImporterContext.Root.GetComponent <VRMBlendShapeProxy>(); vrmBlendShapeProxy.ImmediatelySetValue(defaultBlendShapePreset, defaultBlendShapeValue); vrmImporterContext.EnableUpdateWhenOffscreen(); vrmImporterContext.ShowMeshes(); poolingVrmImporterContexts.Add(new KeyValuePair <string, VRMImporterContext>(vrmMeta.VrmFileName, vrmImporterContext)); mainCamera.cullingMask = defaultCullingMask; }
//ファイルからモデルを読み込む public void LoadVRMFromData(byte[] VRMdata) { if (isLoading) { Debug.LogError("Now Loading! load request is rejected."); return; } DestroyModel(); //読み込み VRMImporterContext vrmImporter = new VRMImporterContext(); vrmImporter.ParseGlb(VRMdata); isLoading = true; vrmImporter.LoadAsync(() => { isLoading = false; Model = vrmImporter.Root; //ExternalReceiverの下にぶら下げる LoadedModelParent = new GameObject(); LoadedModelParent.transform.SetParent(transform, false); LoadedModelParent.name = "LoadedModelParent"; //その下にモデルをぶら下げる Model.transform.SetParent(LoadedModelParent.transform, false); vrmImporter.EnableUpdateWhenOffscreen(); vrmImporter.ShowMeshes(); //カメラなどの移動補助のため、頭の位置を格納する animator = Model.GetComponent <Animator>(); HeadPosition = animator.GetBoneTransform(HumanBodyBones.Head).position; }); }
public void LoadModel(string path) { if (!File.Exists(path)) { return; } Debug.LogFormat("{0}", path); string ext = Path.GetExtension(path).ToLower(); if (ext != ".vrm") { Debug.LogWarning($"unknown file type: {path}"); return; } var context = new VRMImporterContext(); var file = File.ReadAllBytes(path); context.ParseGlb(file); m_texts.UpdateMeta(context); context.Load(); context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); context.ShowMeshes(); SetModel(context.Root); }
void LoadModel(string path) { if (!File.Exists(path)) { return; } Debug.LogFormat("{0}", path); var ext = Path.GetExtension(path).ToLower(); switch (ext) { case ".vrm": { var context = new VRMImporterContext(); var file = File.ReadAllBytes(path); context.ParseGlb(file); m_texts.UpdateMeta(context); context.Load(); context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); context.ShowMeshes(); SetModel(context.Root); break; } case ".glb": { var context = new UniGLTF.ImporterContext(); var file = File.ReadAllBytes(path); context.ParseGlb(file); context.Load(); context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); context.ShowMeshes(); SetModel(context.Root); break; } case ".gltf": case ".zip": { var context = new UniGLTF.ImporterContext(); context.Parse(path); context.Load(); context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); context.ShowMeshes(); SetModel(context.Root); break; } default: Debug.LogWarningFormat("unknown file type: {0}", path); break; } }
private void LoadModel(string path) { try { // If BVH trigger is still on if (_bvhLoadingTrigger == true) { LoadMotion(_bvhPathSaved); } if (!File.Exists(path)) { return; } Debug.LogFormat("{0}", path); var bytes = File.ReadAllBytes(path); var context = new VRMImporterContext(); // GLB形式でJSONを取得しParseします context.ParseGlb(bytes); // GLTFにアクセスできます Debug.LogFormat("{0}", context.GLTF); // Call License Update function _licensePanel.LicenseUpdatefunc(context); // GLTFからモデルを生成します try { context.Load(); context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); context.ShowMeshes(); _vrmModel = context.Root; Debug.LogFormat("loaded {0}", _vrmModel.name); } catch (Exception ex) { Debug.LogError(ex); } // Set up Model SetModel(_vrmModel); } catch (Exception e) { _errorMessagePanel.SetMessage(MultipleLanguageSupport.VrmLoadErrorMessage + "\nError message: " + e.Message); throw; } }
void OnLoaded(VRMImporterContext context) { if (m_model != null) { GameObject.Destroy(m_model.gameObject); } m_model = context.Root; m_model.transform.rotation = Quaternion.Euler(0, 180, 0); context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); }
public void Load() { var path = Environment.GetFolderPath(Environment.SpecialFolder.Personal) + "/avatar.vrm"; if (!File.Exists(path)) { throw new Exception("no file found"); } var data = File.ReadAllBytes(path); var importerContext = new VRMImporterContext(); importerContext.ParseGlb(data); importerContext.Load(); var root = importerContext.Root; importerContext.EnableUpdateWhenOffscreen(); root.GetComponentsInChildren <Renderer>().ToList().ForEach(e => { e.shadowCastingMode = ShadowCastingMode.Off; e.receiveShadows = false; }); var lookAt = root.GetComponent <VRMLookAtHead>(); _humanPoseTransferTarget = root.AddComponent <HumanPoseTransfer>(); _humanPoseTransferTarget.SourceType = HumanPoseTransfer.HumanPoseTransferSourceType.None; lookAt.UpdateType = UpdateType.LateUpdate; //Spring boneのスケジュール SetIK(root, loadSetting); var animator = root.GetComponent <Animator>(); animator.runtimeAnimatorController = animatorController; settingAdjuster.AssignModelRoot(root.transform); var info = new VrmLoadedInfo() { context = importerContext, vrmRoot = root.transform, animator = animator, blendShape = root.GetComponent <VRMBlendShapeProxy>(), }; PreVrmLoaded?.Invoke(info); VrmLoaded?.Invoke(info); }
IEnumerator Loading(Camera mainCamera, int defaultCullingMask, VrmMeta vrmMeta) { //Loading表示に切り替えるために1フレーム待つ yield return(null); var bytes = File.ReadAllBytes(GlobalPath.VrmHomePath + "/" + vrmMeta.VrmFileName); var vrmImporterContext = new VRMImporterContext(); vrmImporterContext.ParseGlb(bytes); vrmImporterContext.Load(); vrmImporterContext.Root.transform.SetParent(vrmRoot, false); vrmImporterContext.EnableUpdateWhenOffscreen(); vrmImporterContext.ShowMeshes(); poolingVrmImporterContexts.Add(new KeyValuePair <string, VRMImporterContext>(vrmMeta.VrmFileName, vrmImporterContext)); mainCamera.cullingMask = defaultCullingMask; }
public void MeshCopyTest() { var path = AliciaPath; var context = new VRMImporterContext(); context.ParseGlb(File.ReadAllBytes(path)); context.Load(); context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); foreach (var mesh in context.Meshes) { var src = mesh.Mesh; var dst = src.Copy(true); MeshTests.MeshEquals(src, dst); } }
void OnLoaded(VRMImporterContext context) { if (_model != null) { GameObject.Destroy(_model.gameObject); } _model = context.Root; _model.transform.position = new Vector3(-10, 0, 0); _model.transform.rotation = Quaternion.Euler(0, 270, 0); context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); // VR化用に追記 _model.AddComponent <VRIK>(); _model.GetComponent <VRIK>().solver.spine.headTarget = GameObject.Find("Head_Target").transform; _model.GetComponent <VRIK>().solver.leftArm.target = GameObject.Find("Hand_L_Target").transform; _model.GetComponent <VRIK>().solver.rightArm.target = GameObject.Find("Hand_R_Target").transform; // akiraさんのQiitaよりがに股を直すように設定 _model.GetComponent <VRIK>().solver.leftLeg.swivelOffset = 15f; _model.GetComponent <VRIK>().solver.rightLeg.swivelOffset = -15f; _model.GetComponent <VRIK>().solver.locomotion.footDistance = 0.4f; _model.GetComponent <VRIK>().solver.locomotion.stepThreshold = 0.3f; _model.GetComponent <VRIK>().solver.locomotion.maxVelocity = 0.3f; _model.GetComponent <VRIK>().solver.locomotion.rootSpeed = 30f; _model.GetComponent <VRIK>().solver.plantFeet = false; //自分のカメラに頭が映らないように VRMFirstPerson の設定 _model.GetComponent <VRM.VRMFirstPerson>().Setup(); foreach (var renderer in GetComponentsInChildren <SkinnedMeshRenderer>(true)) { renderer.updateWhenOffscreen = true; } // リップシンクのターゲット指定 var aniLipSync = GameObject.Find("AniLipSync-VRM"); aniLipSync.GetComponent <AnimMorphTarget>().blendShapeProxy = _model.GetComponent <VRMBlendShapeProxy>(); // まばたきをする設定 _model.AddComponent <VRM.Blinker>(); }
//モデルを読み込む private void LoadVRM(string path) { //存在すれば即破壊(異常顔防止) if (Model != null) { Destroy(Model); Model = null; } if (LoadedModelParent != null) { Destroy(LoadedModelParent); LoadedModelParent = null; } //バイナリの読み込み if (File.Exists(path)) { byte[] VRMdata = File.ReadAllBytes(path); //読み込み VRMImporterContext vrmImporter = new VRMImporterContext(); vrmImporter.ParseGlb(VRMdata); vrmImporter.LoadAsync(() => { Model = vrmImporter.Root; //ExternalReceiverの下にぶら下げる LoadedModelParent = new GameObject(); LoadedModelParent.transform.SetParent(transform, false); LoadedModelParent.name = "LoadedModelParent"; //その下にモデルをぶら下げる Model.transform.SetParent(LoadedModelParent.transform, false); vrmImporter.EnableUpdateWhenOffscreen(); vrmImporter.ShowMeshes(); }); } else { Debug.LogError("VRM load failed."); } }
public async Task LoadModel(string path) { if (!File.Exists(path)) { Debug.LogError("file not found path = " + path); return; } //VRMファイルの読み込み var bytes = File.ReadAllBytes(path); var context = new VRMImporterContext(); context.ParseGlb(bytes); var meta = context.ReadMeta(false); await context.LoadAsyncTask(); //VRMファイルの表示 context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); context.ShowMeshes(); model = GameObject.Find("VRM"); //VRMオブジェクトへの動的アタッチ model.AddComponent <AvatarController>(); this.GetComponent <KinectManager>().ResetAvatarControllers(); //thisをKinectManagerをアタッチしたGameObjectに変更 //BoneSendへのVRMオブジェクト代入 this.GetComponent <SampleBonesSend>().Model = model; //thisをSampleBonesSendをアタッチしたGameObjectに変更 //BoneReceiveへのVRMオブジェクト代入 this.GetComponent <SampleBonesReceive>().Model = model; //thisをSampleBonesSendをアタッチしたGameObjectに変更 //Blinker追加 var lookAt = model.GetComponent <VRMLookAtHead>(); if (lookAt != null) { model.AddComponent <Blinker>(); blinker = model.GetComponent <Blinker>(); } //AniLipSync-VRMへのVRMオブジェクト代入 LipSync.blendShapeProxy = model.GetComponent <VRMBlendShapeProxy>(); //thisをSampleBonesSendをアタッチしたGameObjectに変更 }
// Start is called before the first frame update async void Start() { var path = GameObject.Find("SceneController").GetComponent <SceneController>().path; Debug.Log("start" + path); // VRMを読み込む機能の提供 var context = new VRMImporterContext(); // ファイルをByte配列に読み込みファイルを閉じる var bytes = File.ReadAllBytes(path); // GLB形式でJSONを取得しParseする context.ParseGlb(bytes); // metaデータの取得 // 引数にサムネイルの取得設定を行える var meta = context.ReadMeta(false); Debug.LogFormat("meta_title: {0}", meta.Title); // LoadAsync後に引数のメソッドが呼び出されるように登録 // context.LoadAsync(_ => OnLoaded(context)); // 今UnityのVersionだとObsoleteになっている try { // awaitを使いたいのでメソッドにasyncを付ける await context.LoadAsyncTask(); // context.EnableUpdateWhenOffscreen(); OnLoaded(context); } catch (Exception e) { Debug.LogError(e); // 関連するリソースを破棄する context.Dispose(); throw; } }
//ファイルからモデルを読み込む public void LoadVRMFromData(byte[] VRMdata) { DestroyModel(); //読み込み VRMImporterContext vrmImporter = new VRMImporterContext(); vrmImporter.ParseGlb(VRMdata); vrmImporter.LoadAsync(() => { Model = vrmImporter.Root; //ExternalReceiverの下にぶら下げる LoadedModelParent = new GameObject(); LoadedModelParent.transform.SetParent(transform, false); LoadedModelParent.name = "LoadedModelParent"; //その下にモデルをぶら下げる Model.transform.SetParent(LoadedModelParent.transform, false); vrmImporter.EnableUpdateWhenOffscreen(); vrmImporter.ShowMeshes(); }); }
public void ImportExportTest() { var path = AliciaPath; var parser = new GltfParser(); parser.ParseGlb(File.ReadAllBytes(path)); using (var context = new VRMImporterContext(parser)) { context.Load(); context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); var importedJson = JsonParser.Parse(context.Json); importedJson.SetValue("/extensions/VRM/exporterVersion", VRMVersion.VRM_VERSION, (f, x) => f.Value(x)); importedJson.SetValue("/asset/generator", UniGLTF.UniGLTFVersion.UNIGLTF_VERSION, (f, x) => f.Value(x)); importedJson.SetValue("/scene", 0, (f, x) => f.Value(x)); importedJson.SetValue("/materials/*/doubleSided", false, (f, x) => f.Value(x)); //importJson.SetValue("/materials/*/pbrMetallicRoughness/roughnessFactor", 0); //importJson.SetValue("/materials/*/pbrMetallicRoughness/baseColorFactor", new float[] { 1, 1, 1, 1 }); importedJson.SetValue("/accessors/*/normalized", false, (f, x) => f.Value(x)); importedJson.RemoveValue(Utf8String.From("/nodes/*/extras")); /* * importJson.SetValue("/bufferViews/12/byteStride", 4); * importJson.SetValue("/bufferViews/13/byteStride", 4); * importJson.SetValue("/bufferViews/14/byteStride", 4); * importJson.SetValue("/bufferViews/15/byteStride", 4); * importJson.SetValue("/bufferViews/22/byteStride", 4); * importJson.SetValue("/bufferViews/29/byteStride", 4); * importJson.SetValue("/bufferViews/45/byteStride", 4); * importJson.SetValue("/bufferViews/46/byteStride", 4); * importJson.SetValue("/bufferViews/47/byteStride", 4); * importJson.SetValue("/bufferViews/201/byteStride", 4); * importJson.SetValue("/bufferViews/202/byteStride", 4); * importJson.SetValue("/bufferViews/203/byteStride", 4); * importJson.SetValue("/bufferViews/204/byteStride", 4); * importJson.SetValue("/bufferViews/211/byteStride", 4); * importJson.SetValue("/bufferViews/212/byteStride", 4); * importJson.SetValue("/bufferViews/213/byteStride", 4); * importJson.SetValue("/bufferViews/214/byteStride", 4); * importJson.SetValue("/bufferViews/215/byteStride", 4); * importJson.SetValue("/bufferViews/243/byteStride", 4); * importJson.SetValue("/bufferViews/247/byteStride", 64); * importJson.SetValue("/bufferViews/248/byteStride", 64); * importJson.SetValue("/bufferViews/249/byteStride", 64); * importJson.SetValue("/bufferViews/250/byteStride", 64); * importJson.SetValue("/bufferViews/251/byteStride", 64); * importJson.SetValue("/bufferViews/252/byteStride", 64); * importJson.SetValue("/bufferViews/253/byteStride", 64); */ importedJson.RemoveValue(Utf8String.From("/bufferViews/*/byteStride")); var vrm = VRMExporter.Export(UniGLTF.MeshExportSettings.Default, context.Root); // TODO: Check contents in JSON /*var exportJson = */ JsonParser.Parse(vrm.ToJson()); // TODO: Check contents in JSON /*var newExportedJson = */ // JsonParser.Parse(JsonSchema.FromType<glTF>().Serialize(vrm)); /* * foreach (var kv in importJson.Diff(exportJson)) * { * Debug.Log(kv); * } * * Assert.AreEqual(importJson, exportJson); */ } }
private void Server_Received(object sender, DataReceivedEventArgs e) { synchronizationContext.Post(async(arg) => { //-----------システム系---------------- if (e.CommandType == typeof(PipeCommands.Hello)) { //Helloが来たらHelloを返す。すると初期値が送られてくる。 await server.SendCommandAsync(new PipeCommands.Hello { startTime = this.startTime }); Debug.Log(">Hello"); } else if (e.CommandType == typeof(PipeCommands.Bye)) { //Unity側終了処理 /* #if UNITY_EDITOR * UnityEditor.EditorApplication.isPlaying = false; #else * Application.Quit(); #endif */ Debug.Log(">Bye"); } //-----------基本設定---------------- //===========探索=========== else if (e.CommandType == typeof(PipeCommands.DiscoverRequest)) { var d = (PipeCommands.DiscoverRequest)e.Data; //探索開始 var req = GetComponent <EasyDeviceDiscoveryProtocolClient.Requester>(); req.servicePort = port; req.StartDiscover(() => { //次のデバイスに更新されないうちに取得しておく string ip = req.responseIpAddress; int port = req.responseServicePort; string name = req.deivceName; int found = req.foundDevices; //探索完了 synchronizationContext.Post(async(a) => { Debug.Log("DiscoverResponse"); await server.SendCommandAsync(new PipeCommands.DiscoverResponse { ip = ip, port = port, name = name, found = found, }); }, null); }); } //===========VRMライセンス応答=========== else if (e.CommandType == typeof(PipeCommands.VRMLicenceAnser)) { var d = (PipeCommands.VRMLicenceAnser)e.Data; if (d.Agree) { loader.Agree(); } else { loader.DisAgree(); } } //===========VRM読み込み=========== else if (e.CommandType == typeof(PipeCommands.LoadVRM)) { var d = (PipeCommands.LoadVRM)e.Data; Debug.Log("LoadVRM: " + d.filepath); //許諾画面を出す if (File.Exists(d.filepath)) { loader.LoadRequest(d.filepath, (path, bytes) => { synchronizationContext.Post((args) => { Debug.Log("Load start"); externalReceiver.LoadVRMFromData(bytes); hidePanel.SetActive(d.hide); }, null); }); //許諾応答要求を出す await server.SendCommandAsync(new PipeCommands.VRMLicenceCheck { skip = d.skip }); } } //===========DVRConnect Login=========== else if (e.CommandType == typeof(PipeCommands.LoginDVRConnect)) { var d = (PipeCommands.LoginDVRConnect)e.Data; Debug.Log("LoginDVRConnect"); synchronizationContext.Post(async(args) => { var config = new DVRAuthConfiguration(TokenManager.DVRSDK_ClientId, new UnitySettingStore(), new UniWebRequest(), new NewtonsoftJsonSerializer()); Authentication.Instance.Init(config); Authentication.Instance.Authorize( openBrowser: async(OpenBrowserResponse url) => { Application.OpenURL(url.VerificationUri); //KEYを応答する await server.SendCommandAsync(new PipeCommands.LoginDVRConnectResult { key = url.UserCode }); }, onAuthSuccess: async isSuccess => { if (isSuccess) { Debug.Log("AUTHENTICATION_OK"); await server.SendCommandAsync(new PipeCommands.LoginDVRConnectResult { key = "LOGIN OK" }); await GetAvatarsList(); } else { Debug.Log("AUTHENTICATION_FAILED"); await server.SendCommandAsync(new PipeCommands.LoginDVRConnectResult { key = "LOGIN ERROR" }); } }, onAuthError: async exception => { Debug.Log("AUTHENTICATION_FAILED"); Debug.LogError(exception); await server.SendCommandAsync(new PipeCommands.LoginDVRConnectResult { key = "LOGIN ERROR" }); }); }, null); } //===========DVRConnect Logout=========== else if (e.CommandType == typeof(PipeCommands.LogoutDVRConnect)) { var d = (PipeCommands.LogoutDVRConnect)e.Data; Debug.Log("LogoutDVRConnect"); synchronizationContext.Post(async(args) => { var config = new DVRAuthConfiguration(TokenManager.DVRSDK_ClientId, new UnitySettingStore(), new UniWebRequest(), new NewtonsoftJsonSerializer()); Authentication.Instance.Init(config); await Authentication.Instance.DoLogout(); await server.SendCommandAsync(new PipeCommands.LoginDVRConnectResult { key = "LOGOUT" }); }, null); } //===========DVRConnect Load=========== else if (e.CommandType == typeof(PipeCommands.LoadDVRConnect)) { var d = (PipeCommands.LoadDVRConnect)e.Data; Debug.Log("LoadDVRConnect : " + d.index.ToString()); synchronizationContext.Post(async(args) => { var avatars = await Authentication.Instance.Okami.GetAvatarsAsync(); var currentAvatar = avatars[d.index]; await LoadAvatarFromDVRSDK(currentAvatar); }, null); } //===========DVRConnect GetAvatar=========== else if (e.CommandType == typeof(PipeCommands.GetAvatarDVRConnect)) { Debug.Log("GetAvatarDVRConnect"); synchronizationContext.Post(async(args) => { await GetAvatarsList(); }, null); } //===========背景読み込み=========== else if (e.CommandType == typeof(PipeCommands.LoadBackground)) { var d = (PipeCommands.LoadBackground)e.Data; Debug.Log("LoadBackground: " + d.filepath); //TODO: 背景読み込み処理 if (d.filepath != null && d.filepath != "") { uWC.gameObject.SetActive(false); //VRMの場合 if (d.filepath.ToLower().EndsWith(".vrm")) { Destroy(backgroundObject); bgtexture = null; backgroundObject = null; //ファイルからモデルを読み込む //バイナリの読み込み if (File.Exists(d.filepath)) { //許諾画面を出す loader.LoadRequest(d.filepath, (path, bytes) => { //読み込み VRMImporterContext vrmImporter = new VRMImporterContext(); vrmImporter.ParseGlb(bytes); vrmImporter.LoadAsync(() => { GameObject Model = vrmImporter.Root; //backgroundObjectの下にぶら下げる backgroundObject = new GameObject(); backgroundObject.transform.SetParent(rootLockerTransform, false); backgroundObject.name = "backgroundObject"; //最後に設定されていた位置に設定 if (lastBackgroundPos != null) { if (lastBackgroundPos.cameraTaget) { //カメラターゲット時は、カメラアームに backgroundObject.transform.SetParent(cameraArm, false); } else { //そうでないときは独立した位置に backgroundObject.transform.SetParent(rootLockerTransform, false); } backgroundObject.transform.localPosition = new Vector3(lastBackgroundPos.Px, lastBackgroundPos.Py, lastBackgroundPos.Pz); backgroundObject.transform.localRotation = Quaternion.Euler(lastBackgroundPos.Rx, lastBackgroundPos.Ry, lastBackgroundPos.Rz); backgroundObject.transform.localScale = new Vector3(lastBackgroundPos.scale, lastBackgroundPos.scale, lastBackgroundPos.scale); } //その下にモデルをぶら下げる Model.transform.SetParent(backgroundObject.transform, false); vrmImporter.EnableUpdateWhenOffscreen(); vrmImporter.ShowMeshes(); }); }); //許諾応答要求を出す await server.SendCommandAsync(new PipeCommands.VRMLicenceCheck { }); } else { Debug.LogError("VRM load failed."); } } //画像の場合 else if (d.filepath.ToLower().EndsWith(".png")) { Destroy(backgroundObject); bgtexture = null; backgroundObject = null; if (File.Exists(d.filepath)) { backgroundObject = GameObject.CreatePrimitive(PrimitiveType.Quad); backgroundObject.transform.SetParent(rootLockerTransform, false); //最後に設定されていた位置に設定 if (lastBackgroundPos != null) { if (lastBackgroundPos.cameraTaget) { //カメラターゲット時は、カメラアームに backgroundObject.transform.SetParent(cameraArm, false); } else { //そうでないときは独立した位置に backgroundObject.transform.SetParent(rootLockerTransform, false); } backgroundObject.transform.localPosition = new Vector3(lastBackgroundPos.Px, lastBackgroundPos.Py, lastBackgroundPos.Pz); backgroundObject.transform.localRotation = Quaternion.Euler(lastBackgroundPos.Rx, lastBackgroundPos.Ry, lastBackgroundPos.Rz); } backgroundObjectUrl = "file://" + d.filepath; StartCoroutine("LoadTexture"); } } else { await server.SendCommandAsync(new PipeCommands.SendMessage { Message = "その背景は対応していません" }); } } } else if (e.CommandType == typeof(PipeCommands.RemoveBackground)) { Destroy(backgroundObject); backgroundObject = null; } //===========カメラ位置=========== else if (e.CommandType == typeof(PipeCommands.CameraControl)) { var d = (PipeCommands.CameraControl)e.Data; lookAtModel.zaxis = d.Rz; lookAtModel.height = d.Height; cameraArm.localPosition = new Vector3(0, d.Height, 0); cameraArm.localRotation = Quaternion.Euler(d.Rx, d.Ry, 0); camera_comp.transform.localPosition = new Vector3(0, 0, d.Zoom); camera_comp.fieldOfView = d.Fov; //ライト連動 //カメラのを持ってくる lightArm.localPosition = new Vector3(0, lookAtModel.height, 0); lightLookAtModel.height = lookAtModel.height; light_comp.transform.localPosition = new Vector3(0, 0, light_comp.transform.localPosition.z); } //===========ライト位置=========== else if (e.CommandType == typeof(PipeCommands.LightControl)) { var d = (PipeCommands.LightControl)e.Data; lightLookAtModel.height = lookAtModel.height; //カメラのを持ってくる lightLookAtModel.zaxis = d.Rz; lightArm.localPosition = new Vector3(0, lookAtModel.height, 0); light_comp.transform.localPosition = new Vector3(0, 0, d.Distance); light_comp.range = d.Range; light_comp.spotAngle = d.SpotAngle; switch (d.Type) { case PipeCommands.LightType.Directional: lightArm.localRotation = Quaternion.Euler(0, 0, 0); light_comp.transform.localRotation = Quaternion.Euler(d.Rx, d.Ry, d.Rz); lightLookAtModel.enabled = false; light_comp.type = LightType.Directional; break; case PipeCommands.LightType.Point: lightArm.localRotation = Quaternion.Euler(d.Rx, d.Ry, 0); lightLookAtModel.enabled = true; light_comp.type = LightType.Point; break; case PipeCommands.LightType.Spot: lightArm.localRotation = Quaternion.Euler(d.Rx, d.Ry, 0); lightLookAtModel.enabled = true; light_comp.type = LightType.Spot; break; default: lightArm.localRotation = Quaternion.Euler(0, 0, 0); light_comp.transform.localRotation = Quaternion.Euler(d.Rx, d.Ry, d.Rz); lightLookAtModel.enabled = false; light_comp.type = LightType.Directional; break; } } //===========背景オブジェクト位置=========== else if (e.CommandType == typeof(PipeCommands.BackgroundObjectControl)) { var d = (PipeCommands.BackgroundObjectControl)e.Data; lastBackgroundPos = d; uWC.partialWindowTitle = d.windowTtitle; if (d.windowCapture) { if (!uWC.gameObject.activeSelf) { uWC.gameObject.SetActive(true); if (backgroundObject != null) { Destroy(backgroundObject); backgroundObject = null; } } if (d.cameraTaget) { //カメラターゲット時は、カメラアームに uWC.transform.SetParent(cameraArm, false); } else { //そうでないときは独立した位置に uWC.transform.SetParent(rootLockerTransform, false); } uWC.transform.localPosition = new Vector3(d.Px, d.Py, d.Pz); uWC.transform.localRotation = Quaternion.Euler(d.Rx, d.Ry, d.Rz); uWC.scalePer1000Pixel = d.scale; } else { uWC.gameObject.SetActive(false); if (backgroundObject != null) { if (d.cameraTaget) { //カメラターゲット時は、カメラアームに backgroundObject.transform.SetParent(cameraArm, false); } else { //そうでないときは独立した位置に backgroundObject.transform.SetParent(rootLockerTransform, false); } backgroundObject.transform.localPosition = new Vector3(d.Px, d.Py, d.Pz); backgroundObject.transform.localRotation = Quaternion.Euler(d.Rx, d.Ry, d.Rz); if (bgtexture != null) { backgroundObject.transform.localScale = new Vector3(d.scale, d.scale * (float)bgtexture.height / (float)bgtexture.width, d.scale); } else { backgroundObject.transform.localScale = new Vector3(d.scale, d.scale, d.scale); } } } } //-----------詳細設定---------------- //===========EVMC4U=========== else if (e.CommandType == typeof(PipeCommands.EVMC4UControl)) { var d = (PipeCommands.EVMC4UControl)e.Data; var uosc = externalReceiver.gameObject.GetComponent <uOSC.uOscServer>(); //uOSCのポートを書き換え FieldInfo fieldInfo = typeof(uOSC.uOscServer).GetField("port", BindingFlags.NonPublic | BindingFlags.Instance); fieldInfo.SetValue(uosc, d.Port); port = d.Port; uosc.enabled = d.Enable; externalReceiver.Freeze = d.Freeze; externalReceiver.BoneFilter = d.BoneFilterValue; externalReceiver.BonePositionFilterEnable = d.BoneFilterEnable; externalReceiver.BoneRotationFilterEnable = d.BoneFilterEnable; externalReceiver.BlendShapeFilter = d.BlendShapeFilterValue; externalReceiver.BlendShapeFilterEnable = d.BlendShapeFilterEnable; } else if (e.CommandType == typeof(PipeCommands.EVMC4UTakePhotoCommand)) { var d = (PipeCommands.EVMC4UTakePhotoCommand)e.Data; GetComponent <HiResolutionPhotoCamera>().shot = true; } //===========Window=========== else if (e.CommandType == typeof(PipeCommands.WindowControl)) { var d = (PipeCommands.WindowControl)e.Data; windowManagerEx.SetThroughMouseClick(d.Transparent); windowManagerEx.SetWindowBackgroundTransparent(d.Transparent, backgroundColor); windowManagerEx.SetWindowBorder(d.NoBorder); windowManagerEx.SetWindowAlwaysTopMost(d.ForceForeground); } //===========Root位置=========== else if (e.CommandType == typeof(PipeCommands.RootPositionControl)) { var d = (PipeCommands.RootPositionControl)e.Data; cameraRootLocker.Lock = d.CameraLock; lookAtModel.enabled = d.CameraLock; lightRootLocker.Lock = d.LightLock; backgroundRootLocker.Lock = d.BackgroundLock; } //===========外部連携=========== else if (e.CommandType == typeof(PipeCommands.ExternalControl)) { var d = (PipeCommands.ExternalControl)e.Data; //TODO: OBS連動など } //===========仮想Webカメラ=========== else if (e.CommandType == typeof(PipeCommands.VirtualWebCamera)) { var d = (PipeCommands.VirtualWebCamera)e.Data; unityCapture.enabled = d.Enable; } //===========SEDSSサーバー=========== /* * else if (e.CommandType == typeof(PipeCommands.SEDSSServerControl)) * { * var d = (PipeCommands.SEDSSServerControl)e.Data; * * sedss_server.SetPassword(d.Password); * * //サーバー起動終了 * if (d.Enable) * { * ServerExchangePath = d.ExchangeFilePath; * sedss_server.StartServer(); * Debug.Log("[SEDSS Server] サーバー起動"); * } * else { * ServerExchangePath = null; * sedss_server.StopServer(); * Debug.Log("[SEDSS Server] サーバー停止"); * } * * sedss_server.OnDataUploaded = (bytes, id) => { * Debug.Log("[SEDSS Server] アップロードを受けました"); * externalReceiver.LoadVRMFromData(bytes); * return; * }; * sedss_server.OnDownloadRequest = (id) => * { * if (File.Exists(d.ExchangeFilePath)) * { * Debug.Log("[SEDSS Server] ダウンロード要求を受けました"); * byte[] data = File.ReadAllBytes(ServerExchangePath); * return data; * } * else { * Debug.LogError("[SEDSS Server] ダウンロード要求を受けましたがファイルが存在しません"); * return new byte[0]; * } * }; * } */ //===========SEDSSクライアント=========== else if (e.CommandType == typeof(PipeCommands.SEDSSClientRequestCommand)) { var d = (PipeCommands.SEDSSClientRequestCommand)e.Data; sedss_client.SetPassword(d.Password); sedss_client.SetAddress(d.Address); int port = 0; if (int.TryParse(d.Port, out port)) { sedss_client.port = port; if (d.RequestType == PipeCommands.SEDSS_RequestType.Downdload) { sedss_client.Download(d.ID, (bytes, id) => { Debug.Log("[SEDSS Client] ダウンロード完了"); externalReceiver.LoadVRMFromData(bytes); synchronizationContext.Post(async(a) => { await server.SendCommandAsync(new PipeCommands.SEDSSResult { ok = true }); hidePanel.SetActive(false); }, null); }, (err, id) => { Debug.LogError("[SEDSS Client] ダウンロード失敗(waidayoを再起動してもう一度お試しください)"); synchronizationContext.Post(async(a) => { await server.SendCommandAsync(new PipeCommands.SEDSSResult { ok = false }); hidePanel.SetActive(false); }, null); }); } else if (d.RequestType == PipeCommands.SEDSS_RequestType.Upload) { if (File.Exists(d.UploadFilePath)) { byte[] data = File.ReadAllBytes(d.UploadFilePath); sedss_client.Upload(data, d.ID, (id) => { Debug.Log("[SEDSS Client] アップロード完了"); synchronizationContext.Post(async(a) => { await server.SendCommandAsync(new PipeCommands.SEDSSResult { ok = true }); hidePanel.SetActive(false); }, null); }, (err, id) => { Debug.LogError("[SEDSS Client] アップロード失敗(waidayoを再起動してもう一度お試しください)"); synchronizationContext.Post(async(a) => { await server.SendCommandAsync(new PipeCommands.SEDSSResult { ok = false }); hidePanel.SetActive(false); }, null); }); } else { Debug.LogError("アップロードファイルが存在しません"); synchronizationContext.Post(async(a) => { await server.SendCommandAsync(new PipeCommands.SEDSSResult { ok = false }); }, null); } } else { Debug.LogError("不正なリクエスト"); synchronizationContext.Post(async(a) => { await server.SendCommandAsync(new PipeCommands.SEDSSResult { ok = false }); }, null); } } else { Debug.LogError("不正なポート番号"); synchronizationContext.Post(async(a) => { await server.SendCommandAsync(new PipeCommands.SEDSSResult { ok = false }); }, null); } } //-----------色設定---------------- //===========背景色=========== else if (e.CommandType == typeof(PipeCommands.BackgrounColor)) { var d = (PipeCommands.BackgrounColor)e.Data; Color c = new Color(d.r / 255f, d.g / 255f, d.b / 255f); backgroundColor = c; windowManagerEx.SetWindowBackgroundTransparent(false, c); } //===========ライト色=========== else if (e.CommandType == typeof(PipeCommands.LightColor)) { var d = (PipeCommands.LightColor)e.Data; light_comp.color = new Color(d.r / 255f, d.g / 255f, d.b / 255f); } //===========環境光=========== else if (e.CommandType == typeof(PipeCommands.EnvironmentColor)) { var d = (PipeCommands.EnvironmentColor)e.Data; RenderSettings.ambientLight = new Color(d.r / 255f, d.g / 255f, d.b / 255f); } //===========PostProcessing=========== else if (e.CommandType == typeof(PipeCommands.PostProcessingControl)) { var d = (PipeCommands.PostProcessingControl)e.Data; //アンチエイリアス if (d.AntiAliasingEnable) { PPSLayer.antialiasingMode = PostProcessLayer.Antialiasing.SubpixelMorphologicalAntialiasing; } else { PPSLayer.antialiasingMode = PostProcessLayer.Antialiasing.None; } var p = PPSVolume.sharedProfile; //ブルーム var bloom = p.GetSetting <Bloom>(); bloom.active = true; bloom.enabled.value = d.BloomEnable; bloom.intensity.value = d.BloomIntensity; bloom.threshold.value = d.BloomThreshold; //DoF var dof = p.GetSetting <DepthOfField>(); dof.active = true; dof.enabled.value = d.DoFEnable; dof.focusDistance.value = d.DoFFocusDistance; dof.aperture.value = d.DoFAperture; dof.focalLength.value = d.DoFFocusLength; switch (d.DoFMaxBlurSize) { case 1: dof.kernelSize.value = KernelSize.Small; break; case 2: dof.kernelSize.value = KernelSize.Medium; break; case 3: dof.kernelSize.value = KernelSize.Large; break; case 4: dof.kernelSize.value = KernelSize.VeryLarge; break; default: dof.kernelSize.value = KernelSize.Medium; break; } //CG var cg = p.GetSetting <ColorGrading>(); cg.active = true; cg.enabled.value = d.CGEnable; cg.temperature.value = d.CGTemperature; cg.saturation.value = d.CGSaturation; cg.contrast.value = d.CGContrast; var v = p.GetSetting <Vignette>(); v.active = true; v.enabled.value = d.VEnable; v.intensity.value = d.VIntensity; v.smoothness.value = d.VSmoothness; v.roundness.value = d.VRounded; var ca = p.GetSetting <ChromaticAberration>(); ca.active = true; ca.enabled.value = d.CAEnable; ca.intensity.value = d.CAIntensity; PPSVolume.sharedProfile = p; } else { //未対応のなにか } }, null); }
private bool ExecuteVRMCommand(string command, string subCommand, string[] parameters) { UnityEngine.Debug.Log($"{command} {subCommand} {(string.Join(" ", parameters))}"); subCommand = subCommand.ToLower(); //小文字として比較 bool handled = true; List <string> values = new List <string>(); //コマンドのフォーマットエラー等 bool parseError = false; if (subCommand == "test") { //アセンブリは Craftopia_Data\Managed に入れる必要はない模様 // Craftopia\BepInEx\plugins\TestVRMPlugin\MToon.dll 等の配置でも読み込まれている foreach (var a in AppDomain.CurrentDomain.GetAssemblies()) { values.Add(a.FullName); } } OcCharacter target = null; if (subCommand == "npc") { //近くのNPCの検索 var cs = new CraftopiaSharp() { Trace = true }; var instPl = OcPlMng.Inst; var pos = instPl?.getPlPos(0); if (pos != null) { target = cs.SearchEnemy(pos.Value, "NPC"); if (target == null) { UnityEngine.Debug.Log($"NPC not found"); } } if (target != null) { //コマンドをずらすことで共通化 if (parameters.Length >= 1) { subCommand = parameters[0]; parameters = parameters.Skip(1).ToArray(); } } } else if (subCommand == "load") { //プレーヤーを対象 var instPl = OcPlMng.Inst; target = instPl?.getPl(0); } if (subCommand == "load" && target != null) { //TODO すでに適用済みの場合のチェック // 専用のComponentでも追加して確認するのが良い。 // 暫定的にSyncHumanPoseのチェック if (target.gameObject.GetComponentInChildren <SyncHumanPose>() == null) { values.Add($"{this.GetType().Assembly.Location}"); string dir = Path.GetDirectoryName(this.GetType().Assembly.Location); //values.Add(dir); dir = Path.Combine(dir, "Models"); //values.Add(dir); var di = new DirectoryInfo(dir); foreach (var fi in di.GetFiles()) { values.Add(fi.Name); } if (parameters.Length == 0) { parameters = new string[] { "AliciaSolid.vrm" }; } if (parameters.Length >= 1) { string path = Path.Combine(dir, parameters[0]); //読み込み var context = new VRMImporterContext(); var file = File.ReadAllBytes(path); context.ParseGlb(file); context.Load(); context.EnableUpdateWhenOffscreen(); //このまま読み込んでも、 // shader VRM/MToon not found. set Assets/VRM/Shaders/VRMShaders to Edit - project setting - Graphics - preloaded shaders //のエラーが出ます。 //そのため、別途、shaderをAssetBundlesにして読み込めるようにして、 //Shaderの検索部分に割り込んで、Shaderを渡す必要があります。 // AssetBundleの作成はUnityプロジェクト上で行う必要があります。作成補助用に、BuildAssetBundle.cs を用意してあるので参照してください。 //ShaderPatch で Shader.Find();にパッチしています。 var o = context.Root; var animator = target.Animator; #if false o.transform.SetParent(animator.transform, false); //テスト用に横にずらしてわかりやすくする o.transform.position = o.transform.position + o.transform.right * 1.5f; //アニメーション動作を使用可能とする o.GetComponent <Animator>().runtimeAnimatorController = animator.runtimeAnimatorController; #endif //プレイヤーへの追随やポーズの同期等を含めて別コンポーネントとします var sync = o.AddComponent <SyncHumanPose>(); sync.Setup(animator); context.ShowMeshes(); } } } if (parseError) { values.Add($"コマンドエラー : {command} {subCommand} {(string.Join(" ", parameters))}"); } if (values.Any()) { //改行も有効 string message = string.Join(Environment.NewLine, values); PopMessage(message); } return(handled); }
public void ImportExportTest() { var path = AliciaPath; var parser = new GltfParser(); parser.ParseGlb(File.ReadAllBytes(path)); using (var context = new VRMImporterContext(parser)) { context.Load(); context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); var destroyer = context.DisposeOnGameObjectDestroyed(); try { // mesh { foreach (var renderer in destroyer.GetComponentsInChildren <Renderer>()) { Mesh mesh = default; if (renderer is MeshRenderer) { var f = renderer.GetComponent <MeshFilter>(); mesh = f.sharedMesh; } else if (renderer is SkinnedMeshRenderer smr) { mesh = smr.sharedMesh; } var gltfMesh = parser.GLTF.meshes.Find(x => x.name == mesh.name); Assert.AreEqual(gltfMesh.name, mesh.name); // materials foreach (var material in renderer.sharedMaterials) { var gltfMaterial = parser.GLTF.materials.Find(x => x.name == material.name); Assert.AreEqual(gltfMaterial.name, material.name); var materialIndex = parser.GLTF.materials.IndexOf(gltfMaterial); var vrmMaterial = context.VRM.materialProperties[materialIndex]; // Debug.Log($"shaderName: '{vrmMaterial.shader}'"); if (vrmMaterial.shader == "VRM/MToon") { // MToon // Debug.Log($"{material.name} is MToon"); foreach (var kv in vrmMaterial.textureProperties) { var texture = material.GetTexture(kv.Key); // Debug.Log($"{kv.Key}: {texture}"); Assert.NotNull(texture); } } else if (glTF_KHR_materials_unlit.IsEnable(gltfMaterial)) { // Unlit // Debug.Log($"{material.name} is unlit"); throw new NotImplementedException(); } else { // PBR // Debug.Log($"{material.name} is PBR"); throw new NotImplementedException(); } } } } // meta { var meta = destroyer.GetComponent <VRMMeta>(); } // humanoid { var animator = destroyer.GetComponent <Animator>(); } // blendshape { var blendshapeProxy = destroyer.GetComponent <VRMBlendShapeProxy>(); for (int i = 0; i < context.VRM.blendShapeMaster.blendShapeGroups.Count; ++i) { var gltfBlendShapeClip = context.VRM.blendShapeMaster.blendShapeGroups[i]; var unityBlendShapeClip = blendshapeProxy.BlendShapeAvatar.Clips[i]; Assert.AreEqual(Enum.Parse(typeof(BlendShapePreset), gltfBlendShapeClip.presetName, true), unityBlendShapeClip.Preset); } } var importedJson = JsonParser.Parse(context.Json); importedJson.SetValue("/extensions/VRM/exporterVersion", VRMVersion.VRM_VERSION, (f, x) => f.Value(x)); importedJson.SetValue("/asset/generator", UniGLTF.UniGLTFVersion.UNIGLTF_VERSION, (f, x) => f.Value(x)); importedJson.SetValue("/scene", 0, (f, x) => f.Value(x)); importedJson.SetValue("/materials/*/doubleSided", false, (f, x) => f.Value(x)); //importJson.SetValue("/materials/*/pbrMetallicRoughness/roughnessFactor", 0); //importJson.SetValue("/materials/*/pbrMetallicRoughness/baseColorFactor", new float[] { 1, 1, 1, 1 }); importedJson.SetValue("/accessors/*/normalized", false, (f, x) => f.Value(x)); importedJson.RemoveValue(Utf8String.From("/nodes/*/extras")); /* * importJson.SetValue("/bufferViews/12/byteStride", 4); * importJson.SetValue("/bufferViews/13/byteStride", 4); * importJson.SetValue("/bufferViews/14/byteStride", 4); * importJson.SetValue("/bufferViews/15/byteStride", 4); * importJson.SetValue("/bufferViews/22/byteStride", 4); * importJson.SetValue("/bufferViews/29/byteStride", 4); * importJson.SetValue("/bufferViews/45/byteStride", 4); * importJson.SetValue("/bufferViews/46/byteStride", 4); * importJson.SetValue("/bufferViews/47/byteStride", 4); * importJson.SetValue("/bufferViews/201/byteStride", 4); * importJson.SetValue("/bufferViews/202/byteStride", 4); * importJson.SetValue("/bufferViews/203/byteStride", 4); * importJson.SetValue("/bufferViews/204/byteStride", 4); * importJson.SetValue("/bufferViews/211/byteStride", 4); * importJson.SetValue("/bufferViews/212/byteStride", 4); * importJson.SetValue("/bufferViews/213/byteStride", 4); * importJson.SetValue("/bufferViews/214/byteStride", 4); * importJson.SetValue("/bufferViews/215/byteStride", 4); * importJson.SetValue("/bufferViews/243/byteStride", 4); * importJson.SetValue("/bufferViews/247/byteStride", 64); * importJson.SetValue("/bufferViews/248/byteStride", 64); * importJson.SetValue("/bufferViews/249/byteStride", 64); * importJson.SetValue("/bufferViews/250/byteStride", 64); * importJson.SetValue("/bufferViews/251/byteStride", 64); * importJson.SetValue("/bufferViews/252/byteStride", 64); * importJson.SetValue("/bufferViews/253/byteStride", 64); */ importedJson.RemoveValue(Utf8String.From("/bufferViews/*/byteStride")); var vrm = VRMExporter.Export(UniGLTF.MeshExportSettings.Default, context.Root, new EditorTextureSerializer()); // TODO: Check contents in JSON /*var exportJson = */ JsonParser.Parse(vrm.ToJson()); // TODO: Check contents in JSON /*var newExportedJson = */ // JsonParser.Parse(JsonSchema.FromType<glTF>().Serialize(vrm)); /* * foreach (var kv in importJson.Diff(exportJson)) * { * Debug.Log(kv); * } * * Assert.AreEqual(importJson, exportJson); */ } finally { UnityEngine.Object.DestroyImmediate(destroyer.gameObject); } } }
async void LoadModelAsync(string path) { if (!File.Exists(path)) { return; } Debug.LogFormat("{0}", path); var ext = Path.GetExtension(path).ToLower(); switch (ext) { case ".vrm": { var file = File.ReadAllBytes(path); var parser = new GltfParser(); parser.ParseGlb(file); using (var context = new VRMImporterContext(parser)) { await m_texts.UpdateMetaAsync(context); await context.LoadAsync(); context.EnableUpdateWhenOffscreen(); context.ShowMeshes(); context.DisposeOnGameObjectDestroyed(); SetModel(context.Root); } break; } case ".glb": { var file = File.ReadAllBytes(path); var parser = new GltfParser(); parser.ParseGlb(file); var context = new UniGLTF.ImporterContext(parser); context.Load(); context.EnableUpdateWhenOffscreen(); context.ShowMeshes(); context.DisposeOnGameObjectDestroyed(); SetModel(context.Root); break; } case ".gltf": case ".zip": { var parser = new GltfParser(); parser.ParsePath(path); var context = new UniGLTF.ImporterContext(parser); context.Load(); context.EnableUpdateWhenOffscreen(); context.ShowMeshes(); context.DisposeOnGameObjectDestroyed(); SetModel(context.Root); break; } default: Debug.LogWarningFormat("unknown file type: {0}", path); break; } }
private void LoadModel(string path) { try { // If BVH trigger is still on if (_bvhLoadingTrigger == true) { LoadMotion(_bvhPathSaved); } if (!File.Exists(path)) { return; } Debug.LogFormat("{0}", path); var bytes = File.ReadAllBytes(path); var context = new VRMImporterContext(); // GLB形式でJSONを取得しParseします context.ParseGlb(bytes); // GLTFにアクセスできます Debug.LogFormat("{0}", context.GLTF); // Call License Update function _licensePanel.LicenseUpdatefunc(context); // GLTFからモデルを生成します try { context.Load(); context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); context.ShowMeshes(); _vrmModel = context.Root; Debug.LogFormat("loaded {0}", _vrmModel.name); } catch (Exception ex) { Debug.LogError(ex); } // Set up Model SetModel(_vrmModel); _facialExpressionPanel.CreateDynamicObject(_vrmModel); // Check the model's LookAt type if (_vrmModel.GetComponent <VRMLookAtBoneApplyer>() != null) { _leftEyeSaved = _vrmModel.GetComponent <VRMLookAtBoneApplyer>().LeftEye.Transform; _rightEyeSaved = _vrmModel.GetComponent <VRMLookAtBoneApplyer>().RightEye.Transform; _lookAtBoneFlag = true; // Send information _informationUpdate.SetVRM(_vrmModel); _informationUpdate.SetBoneEyeTransform(_leftEyeSaved, _rightEyeSaved); _informationUpdate.SetLookAtType(_lookAtBoneFlag); } else if (_vrmModel.GetComponent <VRMLookAtBlendShapeApplyer>() != null) { _lookAtBoneFlag = false; // Send information _informationUpdate.SetVRM(_vrmModel); _informationUpdate.SetLookAtType(_lookAtBoneFlag); } // VRMFirstPerson initialization var m_firstPerson = _vrmModel.GetComponent <VRMFirstPerson>(); if (m_firstPerson != null) { m_firstPerson.Setup(); } if (_freeViewpointToggle.isOn) { _closeGameObject.EnableFirstPersonModeOption(); } } catch (Exception e) { _errorMessagePanel.SetMessage(MultipleLanguageSupport.VrmLoadErrorMessage + "\nError message: " + e.Message); throw; } }
// Called by ObjectSync when become ready async void OnSyncReady() { Debug.Log("OnSyncReady"); SyncObject obj = GetComponent <ObjectSync>().SyncObject; SyncNode node = GetComponent <ObjectSync>().Node; obj.BeforeSync += OnBeforeSync; obj.AfterSync += OnAfterSync; obj.RegisterFieldUpdateHandler("leftHand", OnLeftHandUpdated); obj.RegisterFieldUpdateHandler("rightHand", OnRightHandUpdated); obj.RegisterFieldUpdateHandler("mouseGrabber", OnMouseGrabberUpdated); OnLeftHandUpdated(); OnRightHandUpdated(); OnMouseGrabberUpdated(); Blob vrmBlob; if (GetComponent <ObjectSync>().IsOriginal) { byte[] vrmData = File.ReadAllBytes(Settings.Instance.AvatarPath); // Use MIME type for GLTF binary https://www.iana.org/assignments/media-types/model/gltf-binary vrmBlob = new Blob(vrmData, "model/gltf-binary"); BlobHandle vrmHandle = vrmBlob.GenerateHandle(); node.WriteBlob(vrmHandle, vrmBlob); obj.SetField("vrm", vrmHandle); } else { while (!obj.HasField("vrm") || !(obj.GetField("vrm") is BlobHandle)) { obj.WriteDebugLog("PlayerAvatar", "Field vrm not ready"); await UniTask.WaitForFixedUpdate(); } BlobHandle blobHandle = (BlobHandle)obj.GetField("vrm"); vrmBlob = await node.ReadBlob(blobHandle); } // Disable collision detection (and character control) during VRM load // When the avatar collides with something during creation, // it goes to wrong position (e.g. floating). // Note: CharacterController inherits Collider. // (See https://docs.unity3d.com/2019.3/Documentation/ScriptReference/CharacterController.html ) GetComponent <CharacterController>().enabled = false; // Load VRM from byte array // https://github.com/vrm-c/UniVRM/wiki/Runtime-import // https://qiita.com/sh_akira/items/8155e4b69107c2a7ede6 ctx = new VRMImporterContext(); ctx.Root = new GameObject(); // VRM is loaded as a separate object ctx.ParseGlb(vrmBlob.Data); var meta = ctx.ReadMeta(); obj.WriteLog("PlayerAvatar", $"Loading VRM {meta.Title} created by {meta.Author} ({meta.ContactInformation})"); obj.WriteLog("PlayerAvatar", $"AllowedUser={meta.AllowedUser}, ViolentUsage={meta.ViolentUssage}"); obj.WriteLog("PlayerAvatar", $"SexualUsage={meta.SexualUssage}, CommercialUsage={meta.CommercialUssage}"); obj.WriteLog("PlayerAvatar", $"OtherPermissionUrl={meta.OtherPermissionUrl}"); obj.WriteLog("PlayerAvatar", $"LicenseType={meta.LicenseType}"); obj.WriteLog("PlayerAvatar", $"OtherLicenseUrl={meta.OtherLicenseUrl}"); await ctx.LoadAsyncTask(); ctx.EnableUpdateWhenOffscreen(); ctx.ShowMeshes(); // Enable collision (and character controller) again (see the disabling line above) GetComponent <CharacterController>().enabled = true; // Move VRM avatar inside this gameObject ctx.Root.transform.SetParent(transform); ctx.Root.transform.localPosition = Vector3.zero; ctx.Root.transform.localRotation = Quaternion.identity; GetComponent <Animator>().avatar = ctx.Root.GetComponent <Animator>().avatar; obj.WriteLog("PlayerAvatar", $"VRM loaded"); if (GetComponent <ObjectSync>().IsOriginal) { // Set up first person view (do not display avatar of the player) // https://vrm.dev/en/univrm/components/univrm_firstperson/ // https://vrm.dev/en/dev/univrm-0.xx/programming/univrm_use_firstperson/ var fp = GetComponentInChildren <VRMFirstPerson>(); fp.Setup(); if (XRRig != null) { XRRig.transform.position = fp.FirstPersonBone.position + fp.FirstPersonBone.rotation * fp.FirstPersonOffset; XRRig.transform.rotation = transform.rotation; // face forward // Do not render layer "VRMThirdPersonOnly" on first person camera xrCamera.cullingMask &= ~LayerMask.GetMask("VRMThirdPersonOnly"); SetHeadShadow(); } if (ThirdPersonCamera != null) { // Do not render layer "VRMFirstPersonOnly" on third person camera ThirdPersonCamera.cullingMask &= ~LayerMask.GetMask("VRMFirstPersonOnly"); } // Left hand if (leftController.HasValue) { // If left hand device is present var leftId = await node.CreateObject(); leftHandObj = node.Objects[leftId]; leftHandObj.SetField("parent", obj.GetObjectRef()); leftHandObj.SetField("tags", new Sequence(new IValue[] { new Primitive <string>("constantVelocity"), new Primitive <string>("collider") })); obj.SetField("leftHand", leftHandObj.GetObjectRef()); } // Right hand if (rightController.HasValue) { // If right hand device is present var rightId = await node.CreateObject(); rightHandObj = node.Objects[rightId]; rightHandObj.SetField("parent", obj.GetObjectRef()); rightHandObj.SetField("tags", new Sequence(new IValue[] { new Primitive <string>("constantVelocity"), new Primitive <string>("collider") })); obj.SetField("rightHand", rightHandObj.GetObjectRef()); } // Mouse var mouseGrabberId = await node.CreateObject(); mouseGrabberObj = node.Objects[mouseGrabberId]; mouseGrabberObj.SetField("parent", obj.GetObjectRef()); mouseGrabberObj.SetField("tags", new Sequence(new IValue[] { new Primitive <string>("constantVelocity"), new Primitive <string>("collider") })); obj.SetField("mouseGrabber", mouseGrabberObj.GetObjectRef()); } }