1/****************************************************************************************
2
3 Copyright (C) 2015 Autodesk, Inc.
4 All rights reserved.
5
6 Use of this software is subject to the terms of the Autodesk license agreement
7 provided at the time of installation or download, or which otherwise accompanies
8 this software in either electronic or hard copy form.
9
10****************************************************************************************/
11
12//! \file fbxlodgroup.h
13#ifndef _FBXSDK_SCENE_GEOMETRY_LOD_GROUP_H_
14#define _FBXSDK_SCENE_GEOMETRY_LOD_GROUP_H_
15
16#include <fbxsdk/fbxsdk_def.h>
17
18#include <fbxsdk/scene/geometry/fbxnodeattribute.h>
19
20#include <fbxsdk/fbxsdk_nsbegin.h>
21
22/** Defines a LOD (Level of Detail) group.
23 * This LodGroup node is a group node that can be used to detect how
24 * close a group of objects is to a camera. Typically this node is
25 * used for controlling "Level of Detail" visibility.
26 *
27 * Properties in the class are designed according to Maya implementation.
28 * So these properties may be incompatible with other software, like 3ds Max.
29 *
30 * In Maya, with "Level of Detail",the visibility of the children of this
31 * transform are controlled by the distance of a group to the camera and the
32 * threshold values.
33 *
34 * For example, under a LOD group node, there are three children:
35 * ship_detailed, ship_medium, and ship_rough. There are 2 threshold
36 * values: 5, 10. When the camera is less than 5 units away of the group
37 * bounding box, only ship_detailed is visible. When the view is zoomed out and
38 * the camera is between 5 and 10 units away from the group, only ship_medium is
39 * visible. Finally, when the view is zoomed out more and the camera is 10 or
40 * more units away from the group, only ship_rough is visible.
41 *
42 * This node attribute contains the properties of a null node.
43 *
44 * Example code to create LODGroup:
45 * \code
46 * FbxNode *lLodGroup = FbxNode::Create(pScene, "LODNode");
47 * FbxLODGroup *lLodGroupAttr = FbxLODGroup::Create(pScene, "LODGroup1");
48 * // Array lChildNodes contains geometries of all LOD levels
49 * for (int j = 0; j < lChildNodes.GetCount(); j++)
50 * {
51 * lLodGroup->AddChild(lChildNodes.GetAt(j));
52 * }
53 * \endcode
54 *
55 * This object can also be configured to define thresholds as percentage values.
56 * Typically, these percentage values represent the ratio between the group bounding
57 * box height (in screen space) and the viewing screen height.
58 *
59 * To switch to this mode, the client application must set the value of the
60 * ThresholdsUsedAsPercentage property to "true" before the calls to the AddThreshold/
61 * SetThreshold methods. Client applications should always check the return value of
62 * these methods to validate that the action was successful.
63 *
64 * Note that, for backward compatibility, the data is always stored as FbxDistance type.
65 * The client application should always check the return value of this method to validate
66 * that the argument contains a meaningful value (see GetThreshold for more details).
67 *
68 * Example code to create LODGroup that store percentage values:
69 * \code
70 * FbxNode *lLodGroup = FbxNode::Create(pScene, "LODNode");
71 * FbxLODGroup *lLodGroupAttr = FbxLODGroup::Create(pScene, "LODGroup1");
72 * lLodGroupAttr->ThresholdsUsedAsPercentage.Set(true);
73 * FBX_ASSERT(lLodGroupAttr->AddThreshold(33.3)) == true);
74 * FBX_ASSERT(lLodGroupAttr->AddThreshold(66.6)) == true);
75 * FBX_ASSERT(lLodGroupAttr->AddThreshold(FbxDistance(0.6f, "cm")) == false);
76 *
77 * FbxDistance dval;
78 * FbxDouble val = 0.0;
79 * bool res;
80 * res = lLodGroupAttr->GetThreshold(0, val); // res = true, val = 33.3
81 * res = lLodGroupAttr->GetThreshold(0, dval); // res = false, dval.value()=33.3
82 * res = lLodGroupAttr->GetThreshold(2, val); // res = false, val = 1.0
83 * \nosubgrouping
84 */
85class FBXSDK_DLL FbxLODGroup : public FbxNodeAttribute
86{
87 FBXSDK_OBJECT_DECLARE(FbxLODGroup, FbxNodeAttribute);
88
89public:
90 //! Return the type of node attribute which is EType::eLODGroup.
91 virtual FbxNodeAttribute::EType GetAttributeType() const;
92
93 /** \enum EDisplayLevel types to determine how to display nodes in LODGroup.
94 * - \e eUseLOD Display the node according LOD threshold
95 * - \e eShow Always show this node
96 * - \e eHide Always hide this node
97 */
98 enum EDisplayLevel
99 {
100 eUseLOD,
101 eShow,
102 eHide
103 };
104
105 //////////////////////////////////////////////////////////////////////////
106 //
107 // Properties
108 //
109 //////////////////////////////////////////////////////////////////////////
110 /** Specifies if the threshold values stored by this LOD object are defining
111 * a distance to the camera (by default) or a percentage value.
112 *
113 * \remarks This property needs to be set before any call to the Add\SetThreshold
114 * methods since its value is used to validate that the correct method is
115 * called.
116 *
117 * To access this property do: ThresholdsUsedAsPercentage.Get().
118 * To set this property do: ThresholdsUsedAsPercentage.Set(bool).
119 *
120 * Default value is false
121 */
122 FbxPropertyT<FbxBool> ThresholdsUsedAsPercentage;
123
124 /**
125 * \name Distance Mode
126 * The properties in this block are meaningful only if ThresholdsUsedAsPercentage
127 * is set to false and should be ignored otherwise.
128 */
129 //@{
130 /** This property handles the use of the Min/Max distances.
131 * Enables the minimum and maximum distance to take effect.
132 * For example, if the distance between the group and the camera is smaller
133 * than the minimum distance, then the whole group disappears.
134 *
135 * To access this property do: MinMaxDistance.Get().
136 * To set this property do: MinMaxDistance.Set(bool).
137 *
138 * Default value is false.
139 */
140 FbxPropertyT<FbxBool> MinMaxDistance;
141
142 /** The minimum distance at which the group is displayed.
143 *
144 * To access this property do: MinDistance.Get().
145 * To set this property do: MinDistance.Set(double).
146 *
147 * Default value is -100
148 */
149 FbxPropertyT<FbxDouble> MinDistance;
150
151 /** The maximum distance at which the group is displayed.
152 *
153 * To access this property do: MaxDistance.Get().
154 * To set this property do: MaxDistance.Set(double).
155 *
156 * Default value is 100
157 */
158 FbxPropertyT<FbxDouble> MaxDistance;
159
160 /** Work in world space of transform or local space If true,
161 * the camera distance to the LOD group will be computed in world space.
162 * This means it is possible to parent the LOD transform below other transforms
163 * and still have it work as expected. If this attribute is set to false,
164 * the distance computation ignores any parent transforms of the LOD transform.
165 *
166 * To access this property do: WorldSpace.Get().
167 * To set this property do: WorldSpace.Set(bool).
168 *
169 * Default value is false
170 */
171 FbxPropertyT<FbxBool> WorldSpace;
172 //@}
173
174 //////////////////////////////////////////////////////////////////////////
175 //
176 // Methods
177 //
178 //////////////////////////////////////////////////////////////////////////
179
180 /** Get the number of elements in the threshold list.
181 * In correct situations, the size of this list is one less than the LOD node
182 * children objects count.
183 * \return The current size of the threshold list.
184 */
185 int GetNumThresholds() const;
186
187 /** Add a new threshold.
188 * \param pThreshValue Threshold value (distance).
189 * \return true if successful and false otherwise.
190 * \remarks The thresholds list can only expand. Removing items is not
191 * possible unless a new FbxLODGroup is created to replace this one.
192 * \remarks This method does not check the received value and blindly adds it
193 * to the list. Identical values can exist in different positions in
194 * the list.
195 * \remarks This method will fail if ThresholdsUsedAsPercentage=true.
196 */
197 bool AddThreshold(const FbxDistance& pThreshValue);
198
199 /** Add a new threshold.
200 * \param pThreshValue Threshold value (percentage).
201 * \return true if successful and false otherwise.
202 * \remarks The thresholds list can only expand. Removing items is not
203 * possible unless a new FbxLODGroup is created to replace this one.
204 * \remarks This method does not check the received value and blindly adds it
205 * to the list. Identical values can exist in different positions in
206 * the list.
207 * \remarks This method will fail if ThresholdsUsedAsPercentage=false.
208 */
209 bool AddThreshold(FbxDouble pThreshValue);
210
211 /** Replace the value of the specified threshold.
212 * \param pEl Element index in the thresholds list.
213 * \param pThreshValue New threshold value (distance).
214 * \return true if successful and false otherwise.
215 * \remarks This method will fail if ThresholdsUsedAsPercentage=true.
216 */
217 bool SetThreshold(int pEl, const FbxDistance& pThreshValue);
218
219 /** Replace the value of the specified threshold.
220 * \param pEl Element index in the thresholds list.
221 * \param pThreshValue New threshold value (percentage).
222 * \return true if successful and false otherwise.
223 * \remarks This method will fail if ThresholdsUsedAsPercentage=false.
224 */
225 bool SetThreshold(int pEl, FbxDouble pThreshValue);
226
227 /** Get the value of the specified threshold.
228 * \param pEl Element index in the thresholds list.
229 * \param pThreshValue The current threshold value.
230 * \return true if successful and false otherwise.
231 * \remarks pThreshValue is left unchanged if a bad index is provided,
232 * else the value stored in the list is returned in pThreshValue
233 * but may be irrelevant if ThresholdsUsedAsPercentage=true. In
234 * this case, the return of this function will also be \c false.
235 */
236 bool GetThreshold(int pEl, FbxDistance& pThreshValue) const;
237
238 /** Get the value of the specified threshold.
239 * \param pEl Element index in the thresholds list.
240 * \param pThreshValue The current threshold value.
241 * \return true if successful and false otherwise.
242 * \remarks pThreshValue is left unchanged if a bad index is provided,
243 * else the value stored in the list is returned in pThreshValue
244 * but may be irrelevant if ThresholdsUsedAsPercentage=false. In
245 * this case, the return of this function will also be \c false.
246 */
247 bool GetThreshold(int pEl, FbxDouble& pThreshValue) const;
248
249 /** Get the number of elements in the displayLevel list.
250 * In correct situations, the size of this list equals the LOD node
251 * children objects count.
252 * \return The current size of the displayLevel list.
253 */
254 int GetNumDisplayLevels() const;
255
256 /** Add a new displayLevel value to the current list.
257 *
258 * The value overrides the display of any level and can force it to hide
259 * or show the object at that level. For example, if the distance between
260 * the group and the camera is smaller than the first threshold, then the
261 * object at level 0 is visible. If the display level for the object at
262 * level 2 is changed to eShow, ie. if the attribute displayLevel[2] is
263 * set to eShow, then the object at level 2 will show regardless of
264 * the current active level.
265 *
266 * \param pValue Display level value
267 * \return true if successful and false if any error occurred.
268 * \remarks Removing items is not possible unless a new FbxLODGroup is
269 * created to replace this one.
270 * \remarks This method does not check the received value and blindly adds it
271 * to the list. Identical values can exist in different positions in
272 * the list.
273 */
274 bool AddDisplayLevel(FbxLODGroup::EDisplayLevel pValue);
275
276 /** Set the display level value for the specified child object.
277 * \param pEl The index of the object.
278 * \param pValue New display level value.
279 * \return true if successful and false otherwise.
280 */
281 bool SetDisplayLevel(int pEl, FbxLODGroup::EDisplayLevel pValue);
282
283 /** Get the display level value for the specified child object.
284 * \param pEl The index of the object.
285 * \param pValue the current display level value.
286 * \return true if successful and false otherwise.
287 * \remarks In case of failure, the pValue is left unchanged.
288 */
289 bool GetDisplayLevel(int pEl, FbxLODGroup::EDisplayLevel& pValue) const;
290
291/*****************************************************************************************************************************
292** WARNING! Anything beyond these lines is for internal use, may not be documented and is subject to change without notice! **
293*****************************************************************************************************************************/
294#ifndef DOXYGEN_SHOULD_SKIP_THIS
295 virtual FbxObject& Copy(const FbxObject& pObject);
296
297protected:
298 virtual void Construct(const FbxObject* pFrom);
299 virtual void ConstructProperties(bool pForceSet);
300
301private:
302 int mNbThresholds;
303 FbxProperty mThresholds;
304
305 bool RetrieveThreshold(int pEl, FbxDistance& pThreshValue) const;
306 bool StoreThreshold(int pEl, const FbxDistance& pThreshValue);
307
308 int mNbDisplayLevels;
309 FbxProperty mDisplayLevels;
310
311 bool DisplayLevel(int pEl, FbxLODGroup::EDisplayLevel pValue);
312
313public:
314 virtual FbxStringList GetTypeFlags() const;
315#endif /* !DOXYGEN_SHOULD_SKIP_THIS *****************************************************************************************/
316};
317
318inline EFbxType FbxTypeOf(const FbxLODGroup::EDisplayLevel&){ return eFbxEnum; }
319
320#include <fbxsdk/fbxsdk_nsend.h>
321
322#endif /* _FBXSDK_SCENE_GEOMETRY_LOD_GROUP_H_ */
323