[NUI.Scene3D] Add CastShadow and ReceiveShadow for Model and ModelNode (#5987)
[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         /// Sets whether this Model casts shadow or not.
599         /// If it is true, this model is drawn on Shadow Map.
600         /// Note: This method affects all of the child ModelNode.
601         /// However, same property of each child ModelNode can be changed respectively and it not changes parent's property.
602         /// </summary>
603         /// <param name="castShadow">Whether this Model casts shadow or not.</param>
604         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
605         [EditorBrowsable(EditorBrowsableState.Never)]
606         public void CastShadow(bool castShadow)
607         {
608             Interop.Model.CastShadow(SwigCPtr, castShadow);
609             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
610         }
611
612         /// <summary>
613         /// Retrieves whether the Model casts shadow or not for Light.
614         /// Note: IBL does not cast any shadow.
615         /// </summary>
616         /// <returns>True if this model casts shadow.</returns>
617         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
618         [EditorBrowsable(EditorBrowsableState.Never)]
619         public bool IsShadowCasting()
620         {
621             var isShadowCasting = Interop.Model.IsShadowCasting(SwigCPtr);
622             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
623             return isShadowCasting;
624         }
625
626         /// <summary>
627         /// Sets whether this Model receives shadow or not.
628         /// If it is true, shadows are drawn on this model.
629         /// Note: This method affects all of the child ModelNode.
630         /// However, same property of each child ModelNode can be changed respectively and it not changes parent's property.
631         /// </summary>
632         /// <param name="receiveShadow">Whether this Model receives shadow or not.</param>
633         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
634         [EditorBrowsable(EditorBrowsableState.Never)]
635         public void ReceiveShadow(bool receiveShadow)
636         {
637             Interop.Model.ReceiveShadow(SwigCPtr, receiveShadow);
638             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
639         }
640
641         /// <summary>
642         /// Retrieves whether the Model receives shadow or not for Light
643         /// If it is true, this model is drawn on Shadow Map.
644         /// </summary>
645         /// <returns>True if this model receives shadow.</returns>
646         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
647         [EditorBrowsable(EditorBrowsableState.Never)]
648         public bool IsShadowReceiving()
649         {
650             var isShadowReceiving = Interop.Model.IsShadowReceiving(SwigCPtr);
651             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
652             return isShadowReceiving;
653         }
654
655         /// <summary>
656         /// Retrieves model root Actor.
657         /// </summary>
658         /// <returns>Root View of the model.</returns>
659         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
660         [EditorBrowsable(EditorBrowsableState.Never)]
661         private ModelNode GetModelRoot()
662         {
663             global::System.IntPtr cPtr = Interop.Model.GetModelRoot(SwigCPtr);
664             ModelNode ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as ModelNode;
665             if (ret == null)
666             {
667                 // Store the value of PositionUsesAnchorPoint from dali object (Since View object automatically change PositionUsesPivotPoint value as false, we need to keep value.)
668                 HandleRef handle = new HandleRef(this, cPtr);
669
670                 // Use original value as 'true' if we got invalid ModelNode.
671                 bool originalPositionUsesAnchorPoint = (cPtr == global::System.IntPtr.Zero || !Tizen.NUI.Interop.BaseHandle.HasBody(handle)) || Object.InternalGetPropertyBool(handle, View.Property.PositionUsesAnchorPoint);
672                 handle = new HandleRef(null, IntPtr.Zero);
673
674                 // Register new animatable into Registry.
675                 ret = new ModelNode(cPtr, true);
676                 if (ret != null)
677                 {
678                     ret.PositionUsesPivotPoint = originalPositionUsesAnchorPoint;
679                 }
680             }
681             else
682             {
683                 // We found matched NUI animatable. Reduce cPtr reference count.
684                 HandleRef handle = new HandleRef(this, cPtr);
685                 Tizen.NUI.Interop.BaseHandle.DeleteBaseHandle(handle);
686                 handle = new HandleRef(null, IntPtr.Zero);
687             }
688             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
689             return ret;
690         }
691
692         /// <summary>
693         /// Set the ImageBasedLight ScaleFactor.
694         /// </summary>
695         /// <param name="scaleFactor">Scale factor that controls light source intensity in [0.0f, 1.0f].</param>
696         private void SetImageBasedLightScaleFactor(float scaleFactor)
697         {
698             Interop.Model.SetImageBasedLightScaleFactor(SwigCPtr, scaleFactor);
699             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
700         }
701
702         /// <summary>
703         /// Get the ImageBasedLight ScaleFactor.
704         /// </summary>
705         /// <returns>ImageBasedLightScaleFactor that controls light source intensity.</returns>
706         private float GetImageBasedLightScaleFactor()
707         {
708             float scaleFactor = Interop.Model.GetImageBasedLightScaleFactor(SwigCPtr);
709             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
710             return scaleFactor;
711         }
712
713         private void OnResourcesLoaded(object sender, EventArgs e)
714         {
715             if (!isBuilt && this.ModelRoot != null)
716             {
717                 this.ModelRoot.Build();
718                 isBuilt = true;
719                 this.modelPivotPoint.X = this.PivotPoint.X;
720                 this.modelPivotPoint.Y = this.PivotPoint.Y;
721                 this.modelPivotPoint.Z = this.PivotPoint.Z;
722             }
723         }
724
725         /// <summary>
726         /// To make transitionSet instance be disposed.
727         /// </summary>
728         protected override void Dispose(DisposeTypes type)
729         {
730             if (disposed)
731             {
732                 return;
733             }
734
735             ResourcesLoaded -= OnResourcesLoaded;
736             base.Dispose(type);
737         }
738
739         /// <summary>
740         /// Release swigCPtr.
741         /// </summary>
742         // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
743         [EditorBrowsable(EditorBrowsableState.Never)]
744         protected override void ReleaseSwigCPtr(global::System.Runtime.InteropServices.HandleRef swigCPtr)
745         {
746             Interop.Model.DeleteModel(swigCPtr);
747         }
748         
749         
750         private EventHandler<MeshHitEventArgs> meshHitEventHandler;
751         private MeshHitCallbackType meshHitCallback;
752         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
753         private delegate void MeshHitCallbackType(IntPtr motionData);
754
755         /// <summary>
756         /// MeshHitEventArgs
757         /// Contains arguments when MeshHitSignal called
758         /// </summary>
759         [EditorBrowsable(EditorBrowsableState.Never)]
760         public class MeshHitEventArgs : EventArgs
761         {
762             private ModelNode modelNode;
763             
764             /// <summary>
765             /// ModelNode that's been hit
766             /// </summary>
767             [EditorBrowsable(EditorBrowsableState.Never)]
768             public ModelNode ModelNode
769             {
770                 get
771                 {
772                     return modelNode;
773                 }
774                 set
775                 {
776                     modelNode = value;
777                 }
778             }
779         }
780         
781         /// <summary>
782         /// EventHandler event.
783         /// It will be invoked when collider mesh is hit.
784         /// </summary>
785         [EditorBrowsable(EditorBrowsableState.Never)]
786         public event EventHandler<MeshHitEventArgs> ColliderMeshHitted
787         {
788             add
789             {
790                 if (meshHitEventHandler == null)
791                 {
792                     meshHitCallback = MeshHitCollision;
793                     Interop.Model.MeshHitSignalConnect(SwigCPtr, meshHitCallback.ToHandleRef(this));
794                     NDalicPINVOKE.ThrowExceptionIfExists();
795                 }
796                 meshHitEventHandler += value;
797             }
798             remove
799             {
800                 meshHitEventHandler -= value;
801                 if (meshHitEventHandler == null && meshHitCallback != null)
802                 {
803                     Interop.Model.MeshHitSignalDisconnect(SwigCPtr, meshHitCallback.ToHandleRef(this));
804                     NDalicPINVOKE.ThrowExceptionIfExists();
805                     meshHitCallback = null;
806                 }
807             }
808         }
809
810         private void MeshHitCollision(IntPtr modelNode)
811         {
812             if (meshHitEventHandler != null)
813             {
814                 var args = new MeshHitEventArgs();
815                 args.ModelNode = new ModelNode(modelNode, false);
816                 meshHitEventHandler(this, args);
817             }
818         }
819     }
820 }