2 * Copyright(c) 2023 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 using System.Collections.Generic;
20 using System.Runtime.InteropServices;
21 using System.ComponentModel;
23 using Tizen.NUI.Binding;
24 using Tizen.NUI.BaseComponents;
26 namespace Tizen.NUI.Scene3D
29 /// ModelNode is a class for representing the Node of Model in Scene3D.
33 /// ModelNode contains multiple ModelPrimitives and allows easy access and
34 /// modification of Material information that ModelPrimitive has. If a 3D
35 /// format file is loaded by Model, ModelNode is created internally to
36 /// construct the model. In addition, you can create a Custom ModelNode
37 /// using ModelPrimitive and Material directly and add it to Model.
40 /// ModelNode modelNode = new ModelNode();
41 /// ModelPrimitive modelPrimitive = new ModelPrimitive();
42 /// modelNode.AddModelPrimitive(modelPrimitive);
44 /// Material material = new Material;
45 /// modelPrimitive.Material = material;
48 [EditorBrowsable(EditorBrowsableState.Never)]
49 public class ModelNode : View
51 internal ModelNode(global::System.IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, cMemoryOwn)
55 internal ModelNode(global::System.IntPtr cPtr, bool cMemoryOwn, bool cRegister) : base(cPtr, cMemoryOwn, true, cRegister)
60 /// Create an initialized ModelNode.
62 [EditorBrowsable(EditorBrowsableState.Never)]
63 public ModelNode() : this(Interop.ModelNode.ModelNodeNew(), true)
65 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
66 this.PositionUsesPivotPoint = true;
72 /// <param name="modelNode">Source object to copy.</param>
73 [EditorBrowsable(EditorBrowsableState.Never)]
74 public ModelNode(ModelNode modelNode) : this(Interop.ModelNode.NewModelNode(ModelNode.getCPtr(modelNode)), true, false)
76 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
80 /// Assignment operator.
82 /// <param name="modelNode">Source object to be assigned.</param>
83 /// <returns>Reference to this.</returns>
84 internal ModelNode Assign(ModelNode modelNode)
86 ModelNode ret = new ModelNode(Interop.ModelNode.ModelNodeAssign(SwigCPtr, ModelNode.getCPtr(modelNode)), false);
87 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
88 ret.PositionUsesPivotPoint = modelNode.PositionUsesPivotPoint;
93 /// Get the number of ModelPrimitive of this ModelNode.
95 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
96 [EditorBrowsable(EditorBrowsableState.Never)]
97 public uint ModelPrimitiveCount
101 return GetModelPrimitiveCount();
106 /// Adds a ModelPrimitive object to the ModelNode object.
108 /// <param name="modelPrimitive">The ModelPrimitive object to add.</param>
109 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
110 [EditorBrowsable(EditorBrowsableState.Never)]
111 public void AddModelPrimitive(ModelPrimitive modelPrimitive)
113 Interop.ModelNode.AddModelPrimitive(SwigCPtr, ModelPrimitive.getCPtr(modelPrimitive));
114 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
118 /// Removes a ModelPrimitive object from the ModelNode object.
120 /// <param name="modelPrimitive">The ModelPrimitive object to remove.</param>
121 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
122 [EditorBrowsable(EditorBrowsableState.Never)]
123 public void RemoveModelPrimitive(ModelPrimitive modelPrimitive)
125 Interop.ModelNode.RemoveModelPrimitive(SwigCPtr, ModelPrimitive.getCPtr(modelPrimitive));
126 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
130 /// Removes a ModelPrimitive object from the ModelNode object at the specified index.
132 /// <param name="index">The index of the ModelPrimitive object to remove.</param>
133 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
134 [EditorBrowsable(EditorBrowsableState.Never)]
135 public void RemoveModelPrimitive(uint index)
137 Interop.ModelNode.RemoveModelPrimitive(SwigCPtr, index);
138 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
142 /// Gets the ModelPrimitive object at the specified index.
144 /// <param name="index">The index of the ModelPrimitive object to get.</param>
145 /// <returns>The ModelPrimitive object at the specified index.</returns>
146 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
147 [EditorBrowsable(EditorBrowsableState.Never)]
148 public ModelPrimitive GetModelPrimitive(uint index)
150 global::System.IntPtr cPtr = Interop.ModelNode.GetModelPrimitive(SwigCPtr, index);
151 ModelPrimitive ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as ModelPrimitive;
154 // Register new animatable into Registry.
155 ret = new ModelPrimitive(cPtr, true);
159 // We found matched NUI animatable. Reduce cPtr reference count.
160 HandleRef handle = new HandleRef(this, cPtr);
161 Tizen.NUI.Interop.BaseHandle.DeleteBaseHandle(handle);
162 handle = new HandleRef(null, IntPtr.Zero);
164 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
169 /// Returns a child ModelNode object with a name that matches nodeName.
171 /// <param name="nodeName">The name of the child ModelNode object you want to find.</param>
172 /// <returns>Child ModelNode that has nodeName as name.</returns>
173 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
174 [EditorBrowsable(EditorBrowsableState.Never)]
175 public ModelNode FindChildModelNodeByName(string nodeName)
177 global::System.IntPtr cPtr = Interop.Model.FindChildModelNodeByName(SwigCPtr, nodeName);
178 ModelNode ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as ModelNode;
181 // Store the value of PositionUsesAnchorPoint from dali object (Since View object automatically change PositionUsesPivotPoint value as false, we need to keep value.)
182 HandleRef handle = new HandleRef(this, cPtr);
184 // Use original value as 'true' if we got invalid ModelNode.
185 bool originalPositionUsesAnchorPoint = (cPtr == global::System.IntPtr.Zero || !Tizen.NUI.Interop.BaseHandle.HasBody(handle)) || Object.InternalGetPropertyBool(handle, View.Property.PositionUsesAnchorPoint);
186 handle = new HandleRef(null, IntPtr.Zero);
188 // Register new animatable into Registry.
189 ret = new ModelNode(cPtr, true);
192 ret.PositionUsesPivotPoint = originalPositionUsesAnchorPoint;
197 // We found matched NUI animatable. Reduce cPtr reference count.
198 HandleRef handle = new HandleRef(this, cPtr);
199 Tizen.NUI.Interop.BaseHandle.DeleteBaseHandle(handle);
200 handle = new HandleRef(null, IntPtr.Zero);
202 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
207 /// Sets collider mesh on current node
209 /// <param name="vertexList">List of vertices</param>
210 /// <param name="normalList">List of vertex normals</param>
211 /// <param name="indexList">List of mesh indices</param>
212 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
213 [EditorBrowsable(EditorBrowsableState.Never)]
214 public void SetColliderMesh(List<Vector3> vertexList, List<Vector3> normalList, List<int> indexList)
216 var vertices = new Interop.ModelNode.Vec3[vertexList.Count];
218 foreach (var vertex in vertexList)
220 vertices[idx].x = vertex.X;
221 vertices[idx].y = vertex.Y;
222 vertices[idx].z = vertex.Z;
226 var normals = new Interop.ModelNode.Vec3[normalList.Count];
228 foreach (var normal in normalList)
230 normals[idx].x = normal.X;
231 normals[idx].y = normal.Y;
232 normals[idx].z = normal.Z;
236 Interop.ModelNode.SetColliderMesh(SwigCPtr,vertices, normals, vertexList.Count, indexList.ToArray(), indexList.Count);
237 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
241 /// Sets whether this Model casts shadow or not.
242 /// If it is true, this model is drawn on Shadow Map.
243 /// Note: This method affects all of the child ModelNode.
244 /// However, same property of each child ModelNode can be changed respectively and it not changes parent's property.
246 /// <param name="castShadow">Whether this Model casts shadow or not.</param>
247 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
248 [EditorBrowsable(EditorBrowsableState.Never)]
249 public void CastShadow(bool castShadow)
251 Interop.ModelNode.CastShadow(SwigCPtr, castShadow);
252 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
256 /// Retrieves whether the Model casts shadow or not for Light.
257 /// Note: IBL does not cast any shadow.
259 /// <returns>True if this model casts shadow.</returns>
260 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
261 [EditorBrowsable(EditorBrowsableState.Never)]
262 public bool IsShadowCasting()
264 var isShadowCasting = Interop.ModelNode.IsShadowCasting(SwigCPtr);
265 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
266 return isShadowCasting;
270 /// Sets whether this Model receives shadow or not.
271 /// If it is true, shadows are drawn on this model.
272 /// Note: This method affects all of the child ModelNode.
273 /// However, same property of each child ModelNode can be changed respectively and it not changes parent's property.
275 /// <param name="receiveShadow">Whether this Model receives shadow or not.</param>
276 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
277 [EditorBrowsable(EditorBrowsableState.Never)]
278 public void ReceiveShadow(bool receiveShadow)
280 Interop.ModelNode.ReceiveShadow(SwigCPtr, receiveShadow);
281 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
285 /// Retrieves whether the Model receives shadow or not for Light
286 /// If it is true, this model is drawn on Shadow Map.
288 /// <returns>True if this model receives shadow.</returns>
289 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
290 [EditorBrowsable(EditorBrowsableState.Never)]
291 public bool IsShadowReceiving()
293 var isShadowReceiving = Interop.ModelNode.IsShadowReceiving(SwigCPtr);
294 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
295 return isShadowReceiving;
299 /// Gets the number of ModelPrimitive objects in the ModelNode object.
301 /// <returns>The number of ModelPrimitive objects in the ModelNode object.</returns>
302 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
303 [EditorBrowsable(EditorBrowsableState.Never)]
304 private uint GetModelPrimitiveCount()
306 uint ret = Interop.ModelNode.GetModelPrimitiveCount(SwigCPtr);
307 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
312 /// Build C# ModelNode Tree
314 [EditorBrowsable(EditorBrowsableState.Never)]
315 internal void Build()
317 List<ModelNode> childModelNodes = new List<ModelNode>();
318 uint childModelNodeCount = GetChildModelNodeCount();
319 for (uint i = 0; i < childModelNodeCount; ++i)
321 ModelNode modelNode = GetChildModelNodeAt(i);
322 if (modelNode != null)
324 childModelNodes.Add(modelNode);
329 foreach (ModelNode node in childModelNodes)
336 /// Gets the number of child objects in the ModelNode object.
338 /// <returns>The number of childchild objects in the ModelNode object.</returns>
339 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
340 [EditorBrowsable(EditorBrowsableState.Never)]
341 private uint GetChildModelNodeCount()
343 uint ret = Interop.ModelNode.GetChildModelNodeCount(SwigCPtr);
344 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
349 /// Returns a child ModelNode object at the index.
351 /// <param name="index">The index of child ModelNode object you want to find.</param>
352 /// <returns>Child ModelNode</returns>
353 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
354 [EditorBrowsable(EditorBrowsableState.Never)]
355 private ModelNode GetChildModelNodeAt(uint index)
357 global::System.IntPtr cPtr = Interop.ModelNode.GetChildModelNodeAt(SwigCPtr, index);
358 ModelNode ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as ModelNode;
361 // Store the value of PositionUsesAnchorPoint from dali object (Since View object automatically change PositionUsesPivotPoint value as false, we need to keep value.)
362 HandleRef handle = new HandleRef(this, cPtr);
364 // Use original value as 'true' if we got invalid ModelNode.
365 bool originalPositionUsesAnchorPoint = (cPtr == global::System.IntPtr.Zero || !Tizen.NUI.Interop.BaseHandle.HasBody(handle)) || Object.InternalGetPropertyBool(handle, View.Property.PositionUsesAnchorPoint);
366 handle = new HandleRef(null, IntPtr.Zero);
368 // Register new animatable into Registry.
369 ret = new ModelNode(cPtr, true);
372 ret.PositionUsesPivotPoint = originalPositionUsesAnchorPoint;
377 // We found matched NUI animatable. Reduce cPtr reference count.
378 HandleRef handle = new HandleRef(this, cPtr);
379 Tizen.NUI.Interop.BaseHandle.DeleteBaseHandle(handle);
380 handle = new HandleRef(null, IntPtr.Zero);
382 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
387 /// Release swigCPtr.
389 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
390 [EditorBrowsable(EditorBrowsableState.Never)]
391 protected override void ReleaseSwigCPtr(global::System.Runtime.InteropServices.HandleRef swigCPtr)
393 Interop.ModelNode.DeleteModelNode(swigCPtr);