70832216a3e1538804e0c77aa1a01c9f0ee31c51
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Scene3D / src / public / 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.Collections.Generic;
20 using System.Runtime.InteropServices;
21 using System.ComponentModel;
22 using Tizen.NUI;
23 using Tizen.NUI.Binding;
24 using Tizen.NUI.BaseComponents;
25
26 namespace Tizen.NUI.Scene3D
27 {
28     /// <summary>
29     /// Model is a Class to show 3D mesh objects.
30     /// Model supports glTF 2.0 and DLI model formats.
31     /// Physically Based Rendering with Image Based Lighting is also supported.
32     /// </summary>
33     ///
34     /// <remarks>
35     /// Since NUI uses a left-handed coordinate system, loaded models are transformed into a left-handed coordinate system with Y pointing down.
36     /// 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.
37     /// The number of animation is also retrieved by GetAnimationCount() method.
38     ///
39     /// Model also supports Physically Based Rendering(PBR) with Image Based Lighting(IBL).
40     /// For the IBL, two cube map textures(diffuse and specular) are required.
41     /// Model supports 4 types layout for Cube Map: Vertical/Horizontal Cross layouts, and Vertical/Horizontal Array layouts.
42     /// And also, ktx format with cube map is supported.
43     ///
44     /// The model and IBL textures start to be loaded asynchronously when the Model object is on Window.
45     /// ResourcesLoaded signal notifies that the loading of the model and IBL resources have been completed.
46     /// 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.
47     /// <see cref="GetAnimation(uint)"/> and <see cref="GetAnimation(string)"/> methods can be used after the model loading is finished.
48     ///
49     /// By default, the loaded mesh has its own size and <see cref="PivotPoint"/> inferred from position of vertices.
50     /// The <see cref="PivotPoint"/> can be modified after model loading is finished.
51     /// If user set size property, the mesh will be scaled to the input size.
52     /// Default value of <see cref="ParentOrigin"/> of the Model is Center.
53     /// </remarks>
54     ///
55     /// <example>
56     /// <code>
57     /// Model model = new Model(modelUrl)
58     /// {
59     ///     Size = new Size(width, height),
60     /// };
61     /// model.ResourcesLoaded += (s, e) =>
62     /// {
63     ///     model.PivotPoint = new Vector3(0.5f, 0.5f, 0.5f); // Use center as a Pivot.
64     ///
65     ///     int animationCount = model.GetAnimationCount();
66     ///     if(animationCount > 0)
67     ///     {
68     ///         // Play an Animation of index 0.
69     ///         model.GetAnimation(0).Play();
70     ///     }
71     /// };
72     /// model.SetImageBasedLightSource(diffuseUrl, specularUrl, scaleFactor);
73     /// window.Add(model);
74     ///
75     /// </code>
76     /// </example>
77     /// <since_tizen> 10 </since_tizen>
78     public partial class Model : View
79     {
80         private bool isBuilt = false;
81         private Position modelPivotPoint = new Position();
82         internal Model(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, cMemoryOwn)
83         {
84         }
85
86         internal Model(global::System.IntPtr cPtr, bool cMemoryOwn, bool cRegister) : base(cPtr, cMemoryOwn, true, cRegister)
87         {
88         }
89
90         /// <summary>
91         /// Create an initialized Model.
92         /// </summary>
93         /// <param name="modelUrl">model file url.(e.g. glTF, and DLI).</param>
94         /// <param name="resourceDirectoryUrl"> The url to derectory containing resources: binary, image etc.</param>
95         /// <remarks>
96         /// If resourceDirectoryUrl is empty, the parent directory url of modelUrl is used for resource url.
97         ///
98         /// http://tizen.org/privilege/mediastorage for local files in media storage.
99         /// http://tizen.org/privilege/externalstorage for local files in external storage.
100         /// </remarks>
101         /// <since_tizen> 10 </since_tizen>
102         public Model(string modelUrl, string resourceDirectoryUrl = "") : this(Interop.Model.ModelNew(modelUrl, resourceDirectoryUrl), true)
103         {
104             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
105             this.PositionUsesPivotPoint = true;
106             ResourcesLoaded += OnResourcesLoaded;
107         }
108
109         /// <summary>
110         /// Create an initialized Model.
111         /// </summary>
112         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
113         [EditorBrowsable(EditorBrowsableState.Never)]
114         public Model() : this(Interop.Model.ModelNew(), true)
115         {
116             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
117             this.PositionUsesPivotPoint = true;
118         }
119
120         /// <summary>
121         /// Copy constructor.
122         /// </summary>
123         /// <param name="model">Source object to copy.</param>
124         /// <since_tizen> 10 </since_tizen>
125         public Model(Model model) : this(Interop.Model.NewModel(Model.getCPtr(model)), true, false)
126         {
127             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
128             this.PositionUsesPivotPoint = model.PositionUsesPivotPoint;
129         }
130
131         /// <summary>
132         /// Assignment operator.
133         /// </summary>
134         /// <param name="model">Source object to be assigned.</param>
135         /// <returns>Reference to this.</returns>
136         internal Model Assign(Model model)
137         {
138             Model ret = new Model(Interop.Model.ModelAssign(SwigCPtr, Model.getCPtr(model)), false);
139             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
140             ret.PositionUsesPivotPoint = model.PositionUsesPivotPoint;
141             return ret;
142         }
143
144         /// <summary>
145         /// Get The original pivot point of the model
146         /// </summary>
147         /// <remarks>
148         /// This returns (0, 0, 0) before resources are loaded.
149         /// </remarks>
150         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
151         [EditorBrowsable(EditorBrowsableState.Never)]
152         public Position ModelPivotPoint
153         {
154             get
155             {
156                 return modelPivotPoint;
157             }
158         }
159
160         /// <summary>
161         /// Set/Get the ImageBasedLight ScaleFactor.
162         /// Scale factor controls light source intensity in [0.0f, 1.0f]
163         /// </summary>
164         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
165         [EditorBrowsable(EditorBrowsableState.Never)]
166         public float ImageBasedLightScaleFactor
167         {
168             set
169             {
170                 SetImageBasedLightScaleFactor(value);
171             }
172             get
173             {
174                 return GetImageBasedLightScaleFactor();
175             }
176         }
177
178         /// <summary>
179         /// Retrieves root ModelNode of this Model.
180         /// </summary>
181         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
182         [EditorBrowsable(EditorBrowsableState.Never)]
183         public ModelNode ModelRoot
184         {
185             get
186             {
187                 return GetModelRoot();
188             }
189         }
190
191         /// <summary>
192         /// Adds modelNode to this Model.
193         /// </summary>
194         /// <param name="modelNode">Root of a ModelNode tree</param>
195         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
196         [EditorBrowsable(EditorBrowsableState.Never)]
197         public void AddModelNode(ModelNode modelNode)
198         {
199             Interop.Model.AddModelNode(SwigCPtr, ModelNode.getCPtr(modelNode));
200             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
201         }
202
203         /// <summary>
204         /// Removes modelNode from this Model.
205         /// </summary>
206         /// <param name="modelNode">Root of a ModelNode tree to be removed</param>
207         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
208         [EditorBrowsable(EditorBrowsableState.Never)]
209         public void RemoveModelNode(ModelNode modelNode)
210         {
211             Interop.Model.RemoveModelNode(SwigCPtr, ModelNode.getCPtr(modelNode));
212             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
213         }
214
215         /// <summary>
216         /// Removes Returns a child ModelNode object with a name that matches nodeName.
217         /// </summary>
218         /// <param name="nodeName">The name of the child ModelNode object you want to find.</param>
219         /// <returns>Child ModelNode that has nodeName as name.</returns>
220         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
221         [EditorBrowsable(EditorBrowsableState.Never)]
222         public ModelNode FindChildModelNodeByName(string nodeName)
223         {
224             global::System.IntPtr cPtr = Interop.Model.FindChildModelNodeByName(SwigCPtr, nodeName);
225             ModelNode ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as ModelNode;
226             if (ret == null)
227             {
228                 // Store the value of PositionUsesAnchorPoint from dali object (Since View object automatically change PositionUsesPivotPoint value as false, we need to keep value.)
229                 HandleRef handle = new HandleRef(this, cPtr);
230
231                 // Use original value as 'true' if we got invalid ModelNode.
232                 bool originalPositionUsesAnchorPoint = (cPtr == global::System.IntPtr.Zero || !Tizen.NUI.Interop.BaseHandle.HasBody(handle)) || Object.InternalGetPropertyBool(handle, View.Property.PositionUsesAnchorPoint);
233                 handle = new HandleRef(null, IntPtr.Zero);
234
235                 // Register new animatable into Registry.
236                 ret = new ModelNode(cPtr, true);
237                 if (ret != null)
238                 {
239                     ret.PositionUsesPivotPoint = originalPositionUsesAnchorPoint;
240                 }
241             }
242             else
243             {
244                 // We found matched NUI animatable. Reduce cPtr reference count.
245                 HandleRef handle = new HandleRef(this, cPtr);
246                 Tizen.NUI.Interop.BaseHandle.DeleteBaseHandle(handle);
247                 handle = new HandleRef(null, IntPtr.Zero);
248             }
249             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
250             return ret;
251         }
252
253         /// <summary>
254         /// Changes Image Based Light according to the given input textures.
255         /// </summary>
256         /// <param name="diffuseUrl">The path of Cube map image that will be used as a diffuse IBL source.</param>
257         /// <param name="specularUrl">The path of Cube map image that will be used as a specular IBL source.</param>
258         /// <param name="scaleFactor">Scale factor that controls light source intensity in [0.0f, 1.0f]. Default value is 1.0f.</param>
259         /// <remarks>
260         /// http://tizen.org/privilege/mediastorage for local files in media storage.
261         /// http://tizen.org/privilege/externalstorage for local files in external storage.
262         /// </remarks>
263         /// <since_tizen> 10 </since_tizen>
264         public void SetImageBasedLightSource(string diffuseUrl, string specularUrl, float scaleFactor = 1.0f)
265         {
266             Interop.Model.SetImageBasedLightSource(SwigCPtr, diffuseUrl, specularUrl, scaleFactor);
267             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
268         }
269
270         /// <summary>
271         /// Gets number of animations that has been loaded from model file.
272         /// </summary>
273         /// <remarks>
274         /// This method should be called after Model load has been finished.
275         /// </remarks>
276         /// <returns>The number of loaded animations.</returns>
277         /// <since_tizen> 10 </since_tizen>
278         public uint GetAnimationCount()
279         {
280             uint ret = Interop.Model.GetAnimationCount(SwigCPtr);
281             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
282             return ret;
283         }
284
285         /// <summary>
286         /// Gets animation at the index.
287         /// </summary>
288         /// <remarks>
289         /// This method should be called after Model load has been finished.
290         /// </remarks>
291         /// <param name="index">Index of animation to be retrieved.</param>
292         /// <returns>Animation at the index.</returns>
293         /// <since_tizen> 10 </since_tizen>
294         public Animation GetAnimation(uint index)
295         {
296             global::System.IntPtr cPtr = Interop.Model.GetAnimation(SwigCPtr, index);
297             Animation ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Animation;
298             if (ret == null)
299             {
300                 // Register new animation into Registry.
301                 ret = new Animation(cPtr, true);
302             }
303             else
304             {
305                 // We found matched NUI animation. Reduce cPtr reference count.
306                 HandleRef handle = new HandleRef(this, cPtr);
307                 Tizen.NUI.Interop.Animation.DeleteAnimation(handle);
308                 handle = new HandleRef(null, IntPtr.Zero);
309             }
310             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
311             return ret;
312         }
313
314         /// <summary>
315         /// Retrieves animation with the given name.
316         /// Note: This method should be called after Model load finished.
317         /// </summary>
318         /// <param name="name">String name of animation to be retrieved.</param>
319         /// <returns>Animation that has the given name.</returns>
320         /// <since_tizen> 10 </since_tizen>
321         public Animation GetAnimation(string name)
322         {
323             global::System.IntPtr cPtr = Interop.Model.GetAnimation(SwigCPtr, name);
324             Animation ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Animation;
325             if (ret == null)
326             {
327                 // Register new animation into Registry.
328                 ret = new Animation(cPtr, true);
329             }
330             else
331             {
332                 // We found matched NUI animation. Reduce cPtr reference count.
333                 HandleRef handle = new HandleRef(this, cPtr);
334                 Tizen.NUI.Interop.Animation.DeleteAnimation(handle);
335                 handle = new HandleRef(null, IntPtr.Zero);
336             }
337             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
338             return ret;
339         }
340
341         /// <summary>
342         /// Gets number of camera parameters that has been loaded from model file.
343         /// </summary>
344         /// <remarks>
345         /// This method should be called after Model load has been finished.
346         /// </remarks>
347         /// <returns>The number of loaded camera parameters.</returns>
348         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
349         [EditorBrowsable(EditorBrowsableState.Never)]
350         public uint GetCameraCount()
351         {
352             uint ret = Interop.Model.GetCameraCount(SwigCPtr);
353             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
354             return ret;
355         }
356
357         /// <summary>
358         /// Generate Camera using camera parameters at the index.
359         /// If camera parameter is valid, create new Camera.
360         /// Else, return empty Handle.
361         /// </summary>
362         /// <remarks>
363         /// This method should be called after Model load has been finished.
364         /// </remarks>
365         /// <param name="index">Index of camera to be generated.</param>
366         /// <returns>Generated Camera by the index, or empty Handle if generation failed.</returns>
367         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
368         [EditorBrowsable(EditorBrowsableState.Never)]
369         public Camera GenerateCamera(uint index)
370         {
371             global::System.IntPtr cPtr = Interop.Model.GenerateCamera(SwigCPtr, index);
372             Camera ret = new Camera(cPtr, true); // Always create new camera.
373             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
374             return ret;
375         }
376
377         /// <summary>
378         /// Apply camera parameters at the index to inputed Camera.
379         /// If camera parameter is valid and camera is not empty, apply parameters.
380         /// It will change camera's transform and near / far / fov or orthographic size / aspect ratio (if defined)
381         /// </summary>
382         /// <remarks>
383         /// This method should be called after Model load has been finished.
384         /// </remarks>
385         /// <param name="index">Index of camera to be retrieved.</param>
386         /// <param name="camera">Camera to be applied parameter.</param>
387         /// <returns>True if Apply successed. False otherwise.</returns>
388         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
389         [EditorBrowsable(EditorBrowsableState.Never)]
390         public bool ApplyCamera(uint index, Camera camera)
391         {
392             bool ret = false;
393             if (camera?.HasBody() == true)
394             {
395                 ret = Interop.Model.ApplyCamera(SwigCPtr, index, Camera.getCPtr(camera));
396                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
397             }
398             return ret;
399         }
400
401         /// <summary>
402         /// Load bvh animation and assign to model.
403         /// Scale is additional scale factor of bvh animation. It is possible that
404         /// Model's scale may not matched with bvh animation scale.
405         /// If scale is null, default use as Vector3.ONE
406         /// </summary>
407         /// <param name="bvhFilename">Name of bvh format file.</param>
408         /// <param name="scale">Scale value of bvh animation match with model.</param>
409         /// <param name="translateRootFromModelNode">Whether we should translate the bvh root from it's ModelNode position or not.</param>
410         /// <returns>Animaion of bvh</returns>
411         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
412         [EditorBrowsable(EditorBrowsableState.Never)]
413         [Obsolete("Do not use this LoadBvhAnimation. Use MotionData.LoadMotionCaptureAnimation and GenerateMotionDataAnimation instead.")]
414         public Animation LoadBvhAnimation(string bvhFilename, Vector3 scale = null, bool translateRootFromModelNode = true)
415         {
416             global::System.IntPtr cPtr = Interop.Model.LoadBvhAnimation(SwigCPtr, bvhFilename, Vector3.getCPtr(scale), translateRootFromModelNode);
417             Animation ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Animation;
418             if (ret == null)
419             {
420                 // Register new animation into Registry.
421                 ret = new Animation(cPtr, true);
422             }
423             else
424             {
425                 // We found matched NUI animation. Reduce cPtr reference count.
426                 HandleRef handle = new HandleRef(this, cPtr);
427                 Tizen.NUI.Interop.Animation.DeleteAnimation(handle);
428                 handle = new HandleRef(null, IntPtr.Zero);
429             }
430             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
431             return ret;
432         }
433
434         /// <summary>
435         /// Load bvh animation and assign to model.
436         /// Scale is additional scale factor of bvh animation. It is possible that
437         /// Model's scale may not matched with bvh animation scale.
438         /// If scale is null, default use as Vector3.ONE
439         /// </summary>
440         /// <param name="bvhBuffer">Contents of bvh format file.</param>
441         /// <param name="scale">Scale value of bvh animation match with model.</param>
442         /// <param name="translateRootFromModelNode">Whether we should translate the bvh root from it's ModelNode position or not.</param>
443         /// <returns>Animaion of bvh</returns>
444         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
445         [EditorBrowsable(EditorBrowsableState.Never)]
446         [Obsolete("Do not use this LoadBvhAnimationFromBuffer. Use MotionData.LoadMotionCaptureAnimationFromBuffer and GenerateMotionDataAnimation instead.")]
447         public Animation LoadBvhAnimationFromBuffer(string bvhBuffer, Vector3 scale = null, bool translateRootFromModelNode = true)
448         {
449             global::System.IntPtr cPtr = Interop.Model.LoadBvhAnimationFromBuffer(SwigCPtr, bvhBuffer, bvhBuffer.Length, Vector3.getCPtr(scale), translateRootFromModelNode);
450             Animation ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Animation;
451             if (ret == null)
452             {
453                 // Register new animation into Registry.
454                 ret = new Animation(cPtr, true);
455             }
456             else
457             {
458                 // We found matched NUI animation. Reduce cPtr reference count.
459                 HandleRef handle = new HandleRef(this, cPtr);
460                 Tizen.NUI.Interop.Animation.DeleteAnimation(handle);
461                 handle = new HandleRef(null, IntPtr.Zero);
462             }
463             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
464             return ret;
465         }
466
467         /// <summary>
468         /// Load facial animation and assign to model.
469         /// </summary>
470         /// <param name="facialFilename">Name of json format file what we predefined.</param>
471         /// <returns>Animaion of facial</returns>
472         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
473         [EditorBrowsable(EditorBrowsableState.Never)]
474         [Obsolete("Do not use this LoadFacialAnimation. Use MotionData.LoadBlendShapeAnimation and GenerateMotionDataAnimation instead.")]
475         public Animation LoadFacialAnimation(string facialFilename)
476         {
477             return LoadBlendShapeAnimation(facialFilename);
478         }
479
480         /// <summary>
481         /// Load facial animation and assign to model.
482         /// </summary>
483         /// <param name="facialBuffer">Contents of json format file what we predefined.</param>
484         /// <returns>Animaion of facial</returns>
485         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
486         [EditorBrowsable(EditorBrowsableState.Never)]
487         [Obsolete("Do not use this LoadFacialAnimationFromBuffer. Use MotionData.LoadBlendShapeAnimationFromBuffer and GenerateMotionDataAnimation instead.")]
488         public Animation LoadFacialAnimationFromBuffer(string facialBuffer)
489         {
490             return LoadBlendShapeAnimationFromBuffer(facialBuffer);
491         }
492
493         /// <summary>
494         /// Load blendshape animation and assign to model from json file.
495         /// </summary>
496         /// <param name="jsonFilename">Name of json format file what we predefined.</param>
497         /// <returns>Animaion of facial</returns>
498         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
499         [EditorBrowsable(EditorBrowsableState.Never)]
500         [Obsolete("Do not use this LoadBlendShapeAnimation. Use MotionData.LoadBlendShapeAnimation and GenerateMotionDataAnimation instead.")]
501         public Animation LoadBlendShapeAnimation(string jsonFilename)
502         {
503             global::System.IntPtr cPtr = Interop.Model.LoadBlendShapeAnimation(SwigCPtr, jsonFilename);
504             Animation ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Animation;
505             if (ret == null)
506             {
507                 // Register new animation into Registry.
508                 ret = new Animation(cPtr, true);
509             }
510             else
511             {
512                 // We found matched NUI animation. Reduce cPtr reference count.
513                 HandleRef handle = new HandleRef(this, cPtr);
514                 Tizen.NUI.Interop.Animation.DeleteAnimation(handle);
515                 handle = new HandleRef(null, IntPtr.Zero);
516             }
517             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
518             return ret;
519         }
520
521         /// <summary>
522         /// Load morphing animation and assign to model from json string.
523         /// </summary>
524         /// <param name="jsonBuffer">Contents of json format file what we predefined.</param>
525         /// <returns>Animaion of facial</returns>
526         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
527         [EditorBrowsable(EditorBrowsableState.Never)]
528         [Obsolete("Do not use this LoadBlendShapeAnimationFromBuffer. Use MotionData.LoadBlendShapeAnimationFromBuffer and GenerateMotionDataAnimation instead.")]
529         public Animation LoadBlendShapeAnimationFromBuffer(string jsonBuffer)
530         {
531             global::System.IntPtr cPtr = Interop.Model.LoadBlendShapeAnimationFromBuffer(SwigCPtr, jsonBuffer, jsonBuffer.Length);
532             Animation ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Animation;
533             if (ret == null)
534             {
535                 // Register new animation into Registry.
536                 ret = new Animation(cPtr, true);
537             }
538             else
539             {
540                 // We found matched NUI animation. Reduce cPtr reference count.
541                 HandleRef handle = new HandleRef(this, cPtr);
542                 Tizen.NUI.Interop.Animation.DeleteAnimation(handle);
543                 handle = new HandleRef(null, IntPtr.Zero);
544             }
545             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
546             return ret;
547         }
548
549         /// <summary>
550         /// Generate animation by MotionData.
551         /// If there is no animatable item for MotionData, return null.
552         /// </summary>
553         /// <param name="motionData">Source motion data.</param>
554         /// <returns>Generated animation from then given motion data, or null if there is no animatable item in <paramref name="motionData"/></returns>
555         /// <since_tizen> 11 </since_tizen>
556         public Animation GenerateMotionDataAnimation(MotionData motionData)
557         {
558             global::System.IntPtr cPtr = Interop.Model.GenerateMotionDataAnimation(SwigCPtr, MotionData.getCPtr(motionData));
559             Animation ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Animation;
560             if (ret == null)
561             {
562                 // Register new animation into Registry.
563                 ret = new Animation(cPtr, true);
564             }
565             else
566             {
567                 // We found matched NUI animation. Reduce cPtr reference count.
568                 HandleRef handle = new HandleRef(this, cPtr);
569                 Tizen.NUI.Interop.Animation.DeleteAnimation(handle);
570                 handle = new HandleRef(null, IntPtr.Zero);
571             }
572             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
573
574             // It is possible if there is no animatable properties exist on inputed motionData.
575             // In this case, let we return null.
576             if (!ret.HasBody())
577             {
578                 ret.Dispose();
579                 ret = null;
580             }
581             return ret;
582         }
583
584         /// <summary>
585         /// Set values from MotionData.
586         /// Note that this method doesn not apply KeyFrames animation.
587         /// If you want to apply the animation, please use <see cref="GenerateMotionDataAnimation(MotionData)"/> and play the result.
588         /// </summary>
589         /// <param name="motionData">Source motion data.</param>
590         /// <since_tizen> 11 </since_tizen>
591         public void SetMotionData(MotionData motionData)
592         {
593             Interop.Model.SetMotionData(SwigCPtr, MotionData.getCPtr(motionData));
594             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
595         }
596
597         /// <summary>
598         /// Retrieves model root Actor.
599         /// </summary>
600         /// <returns>Root View of the model.</returns>
601         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
602         [EditorBrowsable(EditorBrowsableState.Never)]
603         private ModelNode GetModelRoot()
604         {
605             global::System.IntPtr cPtr = Interop.Model.GetModelRoot(SwigCPtr);
606             ModelNode ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as ModelNode;
607             if (ret == null)
608             {
609                 // Store the value of PositionUsesAnchorPoint from dali object (Since View object automatically change PositionUsesPivotPoint value as false, we need to keep value.)
610                 HandleRef handle = new HandleRef(this, cPtr);
611
612                 // Use original value as 'true' if we got invalid ModelNode.
613                 bool originalPositionUsesAnchorPoint = (cPtr == global::System.IntPtr.Zero || !Tizen.NUI.Interop.BaseHandle.HasBody(handle)) || Object.InternalGetPropertyBool(handle, View.Property.PositionUsesAnchorPoint);
614                 handle = new HandleRef(null, IntPtr.Zero);
615
616                 // Register new animatable into Registry.
617                 ret = new ModelNode(cPtr, true);
618                 if (ret != null)
619                 {
620                     ret.PositionUsesPivotPoint = originalPositionUsesAnchorPoint;
621                 }
622             }
623             else
624             {
625                 // We found matched NUI animatable. Reduce cPtr reference count.
626                 HandleRef handle = new HandleRef(this, cPtr);
627                 Tizen.NUI.Interop.BaseHandle.DeleteBaseHandle(handle);
628                 handle = new HandleRef(null, IntPtr.Zero);
629             }
630             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
631             return ret;
632         }
633
634         /// <summary>
635         /// Set the ImageBasedLight ScaleFactor.
636         /// </summary>
637         /// <param name="scaleFactor">Scale factor that controls light source intensity in [0.0f, 1.0f].</param>
638         private void SetImageBasedLightScaleFactor(float scaleFactor)
639         {
640             Interop.Model.SetImageBasedLightScaleFactor(SwigCPtr, scaleFactor);
641             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
642         }
643
644         /// <summary>
645         /// Get the ImageBasedLight ScaleFactor.
646         /// </summary>
647         /// <returns>ImageBasedLightScaleFactor that controls light source intensity.</returns>
648         private float GetImageBasedLightScaleFactor()
649         {
650             float scaleFactor = Interop.Model.GetImageBasedLightScaleFactor(SwigCPtr);
651             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
652             return scaleFactor;
653         }
654
655         private void OnResourcesLoaded(object sender, EventArgs e)
656         {
657             if (!isBuilt && this.ModelRoot != null)
658             {
659                 this.ModelRoot.Build();
660                 isBuilt = true;
661                 this.modelPivotPoint.X = this.PivotPoint.X;
662                 this.modelPivotPoint.Y = this.PivotPoint.Y;
663                 this.modelPivotPoint.Z = this.PivotPoint.Z;
664             }
665         }
666
667         /// <summary>
668         /// To make transitionSet instance be disposed.
669         /// </summary>
670         protected override void Dispose(DisposeTypes type)
671         {
672             if (disposed)
673             {
674                 return;
675             }
676
677             ResourcesLoaded -= OnResourcesLoaded;
678             base.Dispose(type);
679         }
680
681         /// <summary>
682         /// Release swigCPtr.
683         /// </summary>
684         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
685         [EditorBrowsable(EditorBrowsableState.Never)]
686         protected override void ReleaseSwigCPtr(global::System.Runtime.InteropServices.HandleRef swigCPtr)
687         {
688             Interop.Model.DeleteModel(swigCPtr);
689         }
690         
691         
692         private EventHandler<MeshHitEventArgs> meshHitEventHandler;
693         private MeshHitCallbackType meshHitCallback;
694         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
695         private delegate void MeshHitCallbackType(IntPtr motionData);
696
697         /// <summary>
698         /// MeshHitEventArgs
699         /// Contains arguments when MeshHitSignal called
700         /// </summary>
701         [EditorBrowsable(EditorBrowsableState.Never)]
702         public class MeshHitEventArgs : EventArgs
703         {
704             private ModelNode modelNode;
705             
706             /// <summary>
707             /// ModelNode that's been hit
708             /// </summary>
709             [EditorBrowsable(EditorBrowsableState.Never)]
710             public ModelNode ModelNode
711             {
712                 get
713                 {
714                     return modelNode;
715                 }
716                 set
717                 {
718                     modelNode = value;
719                 }
720             }
721         }
722         
723         /// <summary>
724         /// EventHandler event.
725         /// It will be invoked when collider mesh is hit.
726         /// </summary>
727         [EditorBrowsable(EditorBrowsableState.Never)]
728         public event EventHandler<MeshHitEventArgs> ColliderMeshHitted
729         {
730             add
731             {
732                 if (meshHitEventHandler == null)
733                 {
734                     meshHitCallback = MeshHitCollision;
735                     Interop.Model.MeshHitSignalConnect(SwigCPtr, meshHitCallback.ToHandleRef(this));
736                     NDalicPINVOKE.ThrowExceptionIfExists();
737                 }
738                 meshHitEventHandler += value;
739             }
740             remove
741             {
742                 meshHitEventHandler -= value;
743                 if (meshHitEventHandler == null && meshHitCallback != null)
744                 {
745                     Interop.Model.MeshHitSignalDisconnect(SwigCPtr, meshHitCallback.ToHandleRef(this));
746                     NDalicPINVOKE.ThrowExceptionIfExists();
747                     meshHitCallback = null;
748                 }
749             }
750         }
751
752         private void MeshHitCollision(IntPtr modelNode)
753         {
754             if (meshHitEventHandler != null)
755             {
756                 var args = new MeshHitEventArgs();
757                 args.ModelNode = new ModelNode(modelNode, false);
758                 meshHitEventHandler(this, args);
759             }
760         }
761     }
762 }