[EXaml] Fix build erro of Array/Extents in EXaml
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Scene3D / src / public / Controls / Model.cs
1 /*
2  * Copyright(c) 2022 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     /// <summary>
28     /// Model is a Class to show 3D mesh objects.
29     /// Model supports glTF 2.0 and DLI model formats.
30     /// Physically Based Rendering with Image Based Lighting is also supported.
31     /// </summary>
32     ///
33     /// <remarks>
34     /// Since NUI uses a left-handed coordinate system, loaded models are transformed into a left-handed coordinate system with Y pointing down.
35     /// The Animations defined in the glTF or DLI are also loaded and can be retrieved by using <see cref="GetAnimation(uint)"/> and <see cref="GetAnimation(string)"/> methods.
36     /// The number of animation is also retrieved by GetAnimationCount() method.
37     ///
38     /// Model also supports Physically Based Rendering(PBR) with Image Based Lighting(IBL).
39     /// For the IBL, two cube map textures(diffuse and specular) are required.
40     /// Model supports 4 types layout for Cube Map: Vertical/Horizontal Cross layouts, and Vertical/Horizontal Array layouts.
41     /// And also, ktx format with cube map is supported.
42     ///
43     /// The model and IBL textures start to be loaded asynchronously when the Model object is on Window.
44     /// ResourcesLoaded signal notifies that the loading of the model and IBL resources have been completed.
45     /// If Model or IBL is requested to be loaded before the other loading is completed, the ResourcesLoaded signal is called after all resources are loaded.
46     /// <see cref="GetAnimation(uint)"/> and <see cref="GetAnimation(string)"/> methods can be used after the model loading is finished.
47     ///
48     /// By default, the loaded mesh has its own size and <see cref="PivotPoint"/> inferred from position of vertices.
49     /// The <see cref="PivotPoint"/> can be modified after model loading is finished.
50     /// If user set size property, the mesh will be scaled to the input size.
51     /// Default value of <see cref="ParentOrigin"/> of the Model is Center.
52     /// </remarks>
53     ///
54     /// <example>
55     /// <code>
56     /// Model model = new Model(modelUrl)
57     /// {
58     ///     Size = new Size(width, height),
59     /// };
60     /// model.ResourcesLoaded += (s, e) =>
61     /// {
62     ///     model.PivotPoint = new Vector3(0.5f, 0.5f, 0.5f); // Use center as a Pivot.
63     ///
64     ///     int animationCount = model.GetAnimationCount();
65     ///     if(animationCount > 0)
66     ///     {
67     ///         // Play an Animation of index 0.
68     ///         model.GetAnimation(0).Play();
69     ///     }
70     /// };
71     /// model.SetImageBasedLightSource(diffuseUrl, specularUrl, scaleFactor);
72     /// window.Add(model);
73     ///
74     /// </code>
75     /// </example>
76     /// <since_tizen> 10 </since_tizen>
77     public class Model : View
78     {
79         internal Model(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
80         {
81             // Currenly, Model don't have API to access it's child. So, we make it false.
82             this.ChildrenSensitive = false;
83             this.FocusableChildren = false;
84         }
85
86         /// <summary>
87         /// Create an initialized Model.
88         /// </summary>
89         /// <param name="modelUrl">model file url.(e.g. glTF, and DLI).</param>
90         /// <param name="resourceDirectoryUrl"> The url to derectory containing resources: binary, image etc.</param>
91         /// <remarks>
92         /// If resourceDirectoryUrl is empty, the parent directory url of modelUrl is used for resource url.
93         ///
94         /// http://tizen.org/privilege/mediastorage for local files in media storage.
95         /// http://tizen.org/privilege/externalstorage for local files in external storage.
96         /// </remarks>
97         /// <since_tizen> 10 </since_tizen>
98         public Model(string modelUrl, string resourceDirectoryUrl = "") : this(Interop.Model.ModelNew(modelUrl, resourceDirectoryUrl), true)
99         {
100             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
101             this.PositionUsesAnchorPoint = true;
102         }
103
104         /// <summary>
105         /// Copy constructor.
106         /// </summary>
107         /// <param name="model">Source object to copy.</param>
108         /// <since_tizen> 10 </since_tizen>
109         public Model(Model model) : this(Interop.Model.NewModel(Model.getCPtr(model)), true)
110         {
111             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
112         }
113
114         /// <summary>
115         /// Assignment operator.
116         /// </summary>
117         /// <param name="model">Source object to be assigned.</param>
118         /// <returns>Reference to this.</returns>
119         internal Model Assign(Model model)
120         {
121             Model ret = new Model(Interop.Model.ModelAssign(SwigCPtr, Model.getCPtr(model)), false);
122             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
123             return ret;
124         }
125
126         /// <summary>
127         /// Set/Get whether allow this model's children allow to use touch events.
128         /// This property doesn't change Model itself's Sensitive info.
129         /// If this property is true, event can traversal this models children.
130         /// If this property is false, event traversal blocked.
131         /// Default is false.
132         /// </summary>
133         /// <remarks>
134         /// If ChildrenSensitive is true, it could decrease performance but we can connect events into it's children.
135         /// If ChildrenSensitive is false, the performance becomes better but we cannot connect events into it's children.
136         ///
137         /// Currenly, Model don't have API to access it's child. So, we make it as private.
138         /// </remarks>
139         private bool ChildrenSensitive
140         {
141             set
142             {
143                 SetChildrenSensitive(value);
144             }
145             get
146             {
147                 return GetChildrenSensitive();
148             }
149         }
150
151         /// <summary>
152         /// Set/Get the ImageBasedLight ScaleFactor.
153         /// Scale factor controls light source intensity in [0.0f, 1.0f]
154         /// </summary>
155         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
156         [EditorBrowsable(EditorBrowsableState.Never)]
157         public float ImageBasedLightScaleFactor
158         {
159             set
160             {
161                 SetImageBasedLightScaleFactor(value);
162             }
163             get
164             {
165                 return GetImageBasedLightScaleFactor();
166             }
167         }
168
169         /// <summary>
170         /// Changes Image Based Light according to the given input textures.
171         /// </summary>
172         /// <param name="diffuseUrl">The path of Cube map image that will be used as a diffuse IBL source.</param>
173         /// <param name="specularUrl">The path of Cube map image that will be used as a specular IBL source.</param>
174         /// <param name="scaleFactor">Scale factor that controls light source intensity in [0.0f, 1.0f]. Default value is 1.0f.</param>
175         /// <remarks>
176         /// http://tizen.org/privilege/mediastorage for local files in media storage.
177         /// http://tizen.org/privilege/externalstorage for local files in external storage.
178         /// </remarks>
179         /// <since_tizen> 10 </since_tizen>
180         public void SetImageBasedLightSource(string diffuseUrl, string specularUrl, float scaleFactor = 1.0f)
181         {
182             Interop.Model.SetImageBasedLightSource(SwigCPtr, diffuseUrl, specularUrl, scaleFactor);
183             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
184         }
185
186         /// <summary>
187         /// Gets number of animations that has been loaded from model file.
188         /// </summary>
189         /// <remarks>
190         /// This method should be called after Model load has been finished.
191         /// </remarks>
192         /// <returns>The number of loaded animations.</returns>
193         /// <since_tizen> 10 </since_tizen>
194         public uint GetAnimationCount()
195         {
196             uint ret = Interop.Model.GetAnimationCount(SwigCPtr);
197             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
198             return ret;
199         }
200
201         /// <summary>
202         /// Gets animation at the index.
203         /// </summary>
204         /// <remarks>
205         /// This method should be called after Model load has been finished.
206         /// </remarks>
207         /// <param name="index">Index of animation to be retrieved.</param>
208         /// <returns>Animation at the index.</returns>
209         /// <since_tizen> 10 </since_tizen>
210         public Animation GetAnimation(uint index)
211         {
212             Animation ret = new Animation(Interop.Model.GetAnimation(SwigCPtr, index), false);
213             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
214             return ret;
215         }
216
217         /// <summary>
218         /// Retrieves animation with the given name.
219         /// Note: This method should be called after Model load finished.
220         /// </summary>
221         /// <param name="name">String name of animation to be retrieved.</param>
222         /// <returns>Animation that has the given name.</returns>
223         /// <since_tizen> 10 </since_tizen>
224         public Animation GetAnimation(string name)
225         {
226             Animation ret = new Animation(Interop.Model.GetAnimation(SwigCPtr, name), false);
227             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
228             return ret;
229         }
230
231         /// <summary>
232         /// Retrieves model root Actor.
233         /// </summary>
234         /// <returns>Root View of the model.</returns>
235         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
236         [EditorBrowsable(EditorBrowsableState.Never)]
237         private View GetModelRoot()
238         {
239             View ret = new View(Interop.Model.GetModelRoot(SwigCPtr), false);
240             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
241             return ret;
242         }
243
244         internal void SetChildrenSensitive(bool enable)
245         {
246             Interop.Model.SetChildrenSensitive(SwigCPtr, enable);
247             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
248         }
249
250         internal bool GetChildrenSensitive()
251         {
252             bool result = Interop.Model.GetChildrenSensitive(SwigCPtr);
253             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
254             return result;
255         }
256
257         /// <summary>
258         /// Set the ImageBasedLight ScaleFactor.
259         /// </summary>
260         /// <param name="scaleFactor">Scale factor that controls light source intensity in [0.0f, 1.0f].</param>
261         private void SetImageBasedLightScaleFactor(float scaleFactor)
262         {
263             Interop.Model.SetImageBasedLightScaleFactor(SwigCPtr, scaleFactor);
264             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
265         }
266
267         /// <summary>
268         /// Get the ImageBasedLight ScaleFactor.
269         /// </summary>
270         /// <returns>ImageBasedLightScaleFactor that controls light source intensity.</returns>
271         private float GetImageBasedLightScaleFactor()
272         {
273             float scaleFactor = Interop.Model.GetImageBasedLightScaleFactor(SwigCPtr);
274             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
275             return scaleFactor;
276         }
277
278         /// <summary>
279         /// Release swigCPtr.
280         /// </summary>
281         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
282         [EditorBrowsable(EditorBrowsableState.Never)]
283         protected override void ReleaseSwigCPtr(global::System.Runtime.InteropServices.HandleRef swigCPtr)
284         {
285             Interop.Model.DeleteModel(swigCPtr);
286         }
287     }
288 }