This repository has no description
3.9 kB
107 lines
1// SPDX-License-Identifier: MIT
2// SPDX-FileCopyrightText: 2023 MizunagiKB <mizukb@live.jp>
3using Godot;
4using Godot.NativeInterop;
5using System;
6
7#pragma warning disable CA1050
8#pragma warning disable IDE1006
9
10
11public partial class demo_effect_custom_02 : Node2D
12{
13 private const System.String DEFAULT_ASSET = "res://addons/gd_cubism/example/res/live2d/mao_pro_jp/runtime/mao_pro.model3.json";
14
15 private GDCubismUserModelCS cubism_model;
16 private GDCubismEffectCustomCS cubism_efx;
17
18 private bool first_time = true;
19 private float counter = 0.0f;
20 private Vector2 base_vct;
21 private Vector2 base_scale;
22
23 [Export]
24 private String art_mesh_name = "ArtMesh278";
25 [Export]
26 private int vector_index_0 = 0;
27 [Export]
28 private int vector_index_1 = 1;
29
30
31 private void recalc_model_position(GDCubismUserModelCS model)
32 {
33 if(model.Assets == "") return;
34
35 Godot.Collections.Dictionary canvas_info = model.GetCanvasInfo();
36
37 if(canvas_info.Count > 0)
38 {
39 Vector2 vct_viewport_size = new(GetViewportRect().Size.X, GetViewportRect().Size.Y);
40 Vector2 size_in_pixels = (Vector2)canvas_info["size_in_pixels"];
41 float scale = vct_viewport_size.Y / Math.Max(size_in_pixels.X, size_in_pixels.Y);
42 model.GetInternalObject().Position = new(vct_viewport_size.X * 0.5f, vct_viewport_size.Y * 0.5f);
43 model.GetInternalObject().Scale = new(scale, scale);
44 }
45 }
46
47 public override void _Ready()
48 {
49 this.cubism_efx = new(GetNode<Node>("GDCubismUserModel/GDCubismEffectCustom"));
50 // this.cubism_efx.CubismPrologue += this._on_cubism_prologue;
51 // this.cubism_efx.CubismEpilogue += this._on_cubism_epilogue;
52 // this.cubism_efx.CubismInit += this._on_cubism_init;
53 // this.cubism_efx.CubismTerm += this._on_cubism_term;
54 this.cubism_efx.CubismProcess += this._on_cubism_process;
55
56 this.cubism_model = new(GetNode<Node2D>("GDCubismUserModel"));
57 if (this.cubism_model.Assets == "") this.cubism_model.Assets = DEFAULT_ASSET;
58
59 Godot.Collections.Dictionary<String, int> dict_motion = this.cubism_model.GetMotions();
60
61 foreach (var (k, item_count) in dict_motion)
62 {
63 this.cubism_model.StartMotionLoop(k, 0, GDCubismUserModelCS.PriorityEnum.PriorityForce, true, true);
64 break;
65 }
66 }
67
68 public override void _Process(double delta)
69 {
70 recalc_model_position(this.cubism_model);
71 }
72
73 private void _on_cubism_process(Node2D model, double delta)
74 {
75 const int ARRAY_VERTEX = (int)ArrayMesh.ArrayType.Vertex;
76
77 var ref_sprite = GetNode<Sprite2D>("GDCubismUserModel/GDCubismEffectCustom/Sprite2D");
78
79 Godot.Collections.Dictionary dict_mesh = this.cubism_model.GetMeshes();
80
81 if (dict_mesh.ContainsKey(this.art_mesh_name) == false) return;
82
83 MeshInstance2D ary_mesh = (dict_mesh[this.art_mesh_name]).AsGodotObject() as MeshInstance2D;
84 Godot.Collections.Array ary_surface = ary_mesh.Mesh.SurfaceGetArrays(0);
85 Godot.Collections.Array<Vector2> mesh_vertex = (Godot.Collections.Array<Vector2>)ary_surface[ARRAY_VERTEX];
86
87 if (this.first_time == true)
88 {
89 var _fr = mesh_vertex[this.vector_index_0];
90 var _to = mesh_vertex[this.vector_index_1];
91
92 this.base_vct = (_to - _fr);
93 this.base_scale = ref_sprite.Scale;
94 this.first_time = false;
95 }
96
97 var fr = mesh_vertex[this.vector_index_0];
98 var to = mesh_vertex[this.vector_index_1];
99
100 var calc_vct = (to - fr);
101 var scale = calc_vct.Length() / base_vct.Length();
102
103 ref_sprite.Position = this.cubism_model.GetInternalObject().ToGlobal(fr);
104 ref_sprite.Rotation = base_vct.Normalized().Cross(calc_vct.Normalized());
105 ref_sprite.Scale = base_scale * scale;
106 }
107}