[NUI.Scene3D] Make API to apply ModelMotion
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Scene3D / src / internal / Controls / Model.cs
1 /*
2  * Copyright(c) 2023 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 using System;
19 using System.Runtime.InteropServices;
20 using System.ComponentModel;
21 using Tizen.NUI;
22 using Tizen.NUI.Binding;
23 using Tizen.NUI.BaseComponents;
24
25 namespace Tizen.NUI.Scene3D
26 {
27     public partial class Model
28     {
29         internal Animation InternalGenerateMotionDataAnimation(MotionData motionData, int durationMilliSeconds)
30         {
31             if (motionData == null || motionData.MotionValues == null)
32             {
33                 Tizen.Log.Error("NUI", $"MotionData was null\n");
34                 return null;
35             }
36
37             Lazy<Animation> ret = new Lazy<Animation>(() => new Animation(durationMilliSeconds));
38
39             foreach (var indexValuePair in motionData.MotionValues)
40             {
41                 var motionIndex = indexValuePair.Item1;
42                 var motionValue = indexValuePair.Item2;
43
44                 if (motionIndex == null || motionValue == null || motionValue.Type == MotionValue.ValueType.Invalid)
45                 {
46                     continue;
47                 }
48
49                 // TODO : Make we use ModelNode instead of Animatable. Currently, ModelNode have some problem.
50                 if (motionIndex.ModelNodeId != null)
51                 {
52                     Animatable modelNode = null;
53                     if (motionIndex.ModelNodeId.Type == PropertyKey.KeyType.String)
54                     {
55                         modelNode = FindChildAnimatableByName(motionIndex.ModelNodeId.StringKey);
56                     }
57                     else if (motionIndex.ModelNodeId.Type == PropertyKey.KeyType.Index)
58                     {
59                         // TODO : Not implement yet.
60                     }
61
62                     if (modelNode != null)
63                     {
64                         KeyFrames keyFrames = null;
65                         if (motionValue.Type == MotionValue.ValueType.KeyFrames)
66                         {
67                             keyFrames = motionValue.KeyFramesValue;
68                         }
69                         else if (motionValue.Type == MotionValue.ValueType.Property)
70                         {
71                             // Generate stable keyframe animation here.
72                             keyFrames = new KeyFrames();
73                             keyFrames.Add(0.0f, motionValue.Value);
74                             keyFrames.Add(1.0f, motionValue.Value);
75                         }
76
77                         if (keyFrames != null)
78                         {
79                             string animatedPropertyName = motionIndex.GetPropertyName(modelNode as ModelNode);
80                             if (!string.IsNullOrEmpty(animatedPropertyName))
81                             {
82                                 ret.Value.AnimateBetween(modelNode, animatedPropertyName, keyFrames);
83                             }
84                         }
85                     }
86                 }
87                 else
88                 {
89                     if (motionIndex is BlendShapeIndex)
90                     {
91                         var blendShapeIndex = motionIndex as BlendShapeIndex;
92                         if (blendShapeIndex.BlendShapeId?.Type == PropertyKey.KeyType.String)
93                         {
94                             // TODO : Not implement yet. (Set all blendshapes by string)
95                         }
96                     }
97                 }
98             }
99
100             return ret.IsValueCreated ? ret.Value : null;
101         }
102
103         internal void InternalSetMotionData(MotionData motionData)
104         {
105             if (motionData == null || motionData.MotionValues == null)
106             {
107                 Tizen.Log.Error("NUI", $"MotionData was null\n");
108                 return;
109             }
110
111             foreach (var indexValuePair in motionData.MotionValues)
112             {
113                 var motionIndex = indexValuePair.Item1;
114                 var motionValue = indexValuePair.Item2;
115
116                 if (motionIndex == null || motionValue == null || motionValue.Type == MotionValue.ValueType.Invalid)
117                 {
118                     continue;
119                 }
120
121                 if (motionIndex.ModelNodeId != null)
122                 {
123                     // TODO : Make we use ModelNode instead of Animatable. Currently, ModelNode have some problem.
124                     Animatable modelNode = null;
125                     if (motionIndex.ModelNodeId.Type == PropertyKey.KeyType.String)
126                     {
127                         modelNode = FindChildAnimatableByName(motionIndex.ModelNodeId.StringKey);
128                     }
129                     else if (motionIndex.ModelNodeId.Type == PropertyKey.KeyType.Index)
130                     {
131                         // TODO : Not implement yet.
132                     }
133
134                     if (modelNode != null)
135                     {
136                         PropertyValue value = null;
137                         if (motionValue.Type == MotionValue.ValueType.KeyFrames)
138                         {
139                             // TODO : Not implement yet.
140                         }
141                         else if (motionValue.Type == MotionValue.ValueType.Property)
142                         {
143                             value = motionValue.Value;
144                         }
145
146                         if (value != null)
147                         {
148                             string propertyName = motionIndex.GetPropertyName(modelNode as ModelNode);
149                             if (!string.IsNullOrEmpty(propertyName))
150                             {
151                                 modelNode.SetProperty(propertyName, value);
152                             }
153                         }
154                     }
155                 }
156                 else
157                 {
158                     if (motionIndex is BlendShapeIndex)
159                     {
160                         var blendShapeIndex = motionIndex as BlendShapeIndex;
161                         if (blendShapeIndex.BlendShapeId?.Type == PropertyKey.KeyType.String)
162                         {
163                             // TODO : Not implement yet. (Set all blendshapes by string)
164                         }
165                     }
166                 }
167             }
168         }
169     }
170 }