@@ -14,10 +14,55 @@ struct FbxPropertyChannelPair
14
14
public string Property { get ; private set ; }
15
15
public string Channel { get ; private set ; }
16
16
17
+ public FbxPropertyChannelPair ( string p , string c ) : this ( )
18
+ {
19
+ Property = p ;
20
+ Channel = c ;
21
+ }
22
+
23
+ struct UnityPropertyChannelPair
24
+ {
25
+ public string property ;
26
+ public string channel ;
27
+
28
+ public UnityPropertyChannelPair ( string p , string c )
29
+ {
30
+ property = p ;
31
+ channel = c ;
32
+ }
33
+ }
34
+
35
+ /// <summary>
36
+ /// Contains the two dictionaries that map Unity property to FBX property and Unity channel to Fbx channel
37
+ /// for a set of properties.
38
+ /// </summary>
39
+ struct PropertyChannelMap
40
+ {
41
+ public Dictionary < string , string > MapUnityPropToFbxProp ;
42
+ public Dictionary < string , string > MapUnityChannelToFbxChannel ;
43
+
44
+ public PropertyChannelMap ( Dictionary < string , string > propertyMap , Dictionary < string , string > channelMap )
45
+ {
46
+ MapUnityPropToFbxProp = propertyMap ;
47
+ MapUnityChannelToFbxChannel = channelMap ;
48
+ }
49
+ }
50
+
51
+ private static PropertyChannelMap TransformPropertyMap = new PropertyChannelMap ( MapTransformPropToFbxProp , MapTransformChannelToFbxChannel ) ;
52
+ private static PropertyChannelMap AimConstraintPropertyMap = new PropertyChannelMap ( MapAimConstraintPropToFbxProp , MapTransformChannelToFbxChannel ) ;
53
+ private static PropertyChannelMap ColorPropertyMap = new PropertyChannelMap ( MapColorPropToFbxProp , MapColorChannelToFbxChannel ) ;
54
+ private static PropertyChannelMap ConstraintSourcePropertyMap = new PropertyChannelMap ( MapConstraintSourcePropToFbxProp , null ) ;
55
+ private static PropertyChannelMap ConstraintSourceTransformPropertyMap = new PropertyChannelMap ( MapConstraintSourceTransformPropToFbxProp , MapTransformChannelToFbxChannel ) ;
56
+ private static PropertyChannelMap OtherPropertyMap = new PropertyChannelMap ( MapPropToFbxProp , null ) ;
57
+
58
+ // =========== Property Maps ================
59
+ // These are dictionaries that map a Unity property name to it's corresponding Fbx property name.
60
+ // Split up into multiple dictionaries as some are channel and object dependant.
61
+
17
62
/// <summary>
18
63
/// Map of Unity transform properties to their FBX equivalent.
19
64
/// </summary>
20
- private static Dictionary < string , string > TransformProperties = new Dictionary < string , string > ( )
65
+ private static Dictionary < string , string > MapTransformPropToFbxProp = new Dictionary < string , string > ( )
21
66
{
22
67
{ "m_LocalScale" , "Lcl Scaling" } ,
23
68
{ "Motion S" , "Lcl Scaling" } ,
@@ -31,63 +76,38 @@ struct FbxPropertyChannelPair
31
76
/// <summary>
32
77
/// Map of Unity Aim constraint properties to their FBX equivalent.
33
78
/// </summary>
34
- private static Dictionary < string , string > AimConstraintProperties = new Dictionary < string , string > ( )
79
+ private static Dictionary < string , string > MapAimConstraintPropToFbxProp = new Dictionary < string , string > ( )
35
80
{
36
81
{ "m_AimVector" , "AimVector" } ,
37
82
{ "m_UpVector" , "UpVector" } ,
38
83
{ "m_WorldUpVector" , "WorldUpVector" } ,
39
84
{ "m_RotationOffset" , "RotationOffset" }
40
85
} ;
41
86
42
- /// <summary>
43
- /// Map of Unity transform channels to their FBX equivalent.
44
- /// </summary>
45
- private static Dictionary < string , string > TransformChannels = new Dictionary < string , string > ( )
46
- {
47
- { "x" , Globals . FBXSDK_CURVENODE_COMPONENT_X } ,
48
- { "y" , Globals . FBXSDK_CURVENODE_COMPONENT_Y } ,
49
- { "z" , Globals . FBXSDK_CURVENODE_COMPONENT_Z }
50
- } ;
51
-
52
87
/// <summary>
53
88
/// Map of Unity color properties to their FBX equivalent.
54
89
/// </summary>
55
- private static Dictionary < string , string > ColorProperties = new Dictionary < string , string > ( )
90
+ private static Dictionary < string , string > MapColorPropToFbxProp = new Dictionary < string , string > ( )
56
91
{
57
92
{ "m_Color" , "Color" }
58
93
} ;
59
94
60
- /// <summary>
61
- /// Map of Unity color channels to their FBX equivalent.
62
- /// </summary>
63
- private static Dictionary < string , string > ColorChannels = new Dictionary < string , string > ( )
64
- {
65
- { "b" , Globals . FBXSDK_CURVENODE_COLOR_BLUE } ,
66
- { "g" , Globals . FBXSDK_CURVENODE_COLOR_GREEN } ,
67
- { "r" , Globals . FBXSDK_CURVENODE_COLOR_RED }
68
- } ;
69
-
70
95
/// <summary>
71
96
/// Map of Unity properties to their FBX equivalent.
72
97
/// </summary>
73
- private static Dictionary < string , string > OtherProperties = new Dictionary < string , string > ( )
98
+ private static Dictionary < string , string > MapPropToFbxProp = new Dictionary < string , string > ( )
74
99
{
75
100
{ "m_Intensity" , "Intensity" } ,
76
101
{ "field of view" , "FieldOfView" } ,
77
102
{ "m_Weight" , "Weight" }
78
103
} ;
79
104
80
- /// <summary>
81
- /// Map of empty string to null, used for properties that don't need a channel.
82
- /// </summary>
83
- private static Dictionary < string , string > NullChannel = new Dictionary < string , string > ( ) { { "" , null } } ;
84
-
85
105
/// <summary>
86
106
/// Map of Unity constraint source property name as a regular expression to the FBX property as a string format.
87
107
/// This is necessary because the Unity property contains an index in to an array, and the FBX property contains
88
108
/// the name of the source object.
89
109
/// </summary>
90
- private static Dictionary < string , string > ConstraintSourceProperties = new Dictionary < string , string > ( )
110
+ private static Dictionary < string , string > MapConstraintSourcePropToFbxProp = new Dictionary < string , string > ( )
91
111
{
92
112
{ @"m_Sources\.Array\.data\[(\d+)\]\.weight" , "{0}.Weight" }
93
113
} ;
@@ -97,39 +117,66 @@ struct FbxPropertyChannelPair
97
117
/// This is necessary because the Unity property contains an index in to an array, and the FBX property contains
98
118
/// the name of the source object.
99
119
/// </summary>
100
- private static Dictionary < string , string > ConstraintSourceTransformProperties = new Dictionary < string , string > ( )
120
+ private static Dictionary < string , string > MapConstraintSourceTransformPropToFbxProp = new Dictionary < string , string > ( )
101
121
{
102
122
{ @"m_TranslationOffsets\.Array\.data\[(\d+)\]" , "{0}.Offset T" } ,
103
123
{ @"m_RotationOffsets\.Array\.data\[(\d+)\]" , "{0}.Offset R" }
104
124
} ;
105
125
106
- public FbxPropertyChannelPair ( string p , string c ) : this ( )
107
- {
108
- Property = p ;
109
- Channel = c ;
110
- }
126
+ // ================== Channel Maps ======================
127
+
128
+ /// <summary>
129
+ /// Map of Unity transform channels to their FBX equivalent.
130
+ /// </summary>
131
+ private static Dictionary < string , string > MapTransformChannelToFbxChannel = new Dictionary < string , string > ( )
132
+ {
133
+ { "x" , Globals . FBXSDK_CURVENODE_COMPONENT_X } ,
134
+ { "y" , Globals . FBXSDK_CURVENODE_COMPONENT_Y } ,
135
+ { "z" , Globals . FBXSDK_CURVENODE_COMPONENT_Z }
136
+ } ;
137
+
138
+ /// <summary>
139
+ /// Map of Unity color channels to their FBX equivalent.
140
+ /// </summary>
141
+ private static Dictionary < string , string > MapColorChannelToFbxChannel = new Dictionary < string , string > ( )
142
+ {
143
+ { "b" , Globals . FBXSDK_CURVENODE_COLOR_BLUE } ,
144
+ { "g" , Globals . FBXSDK_CURVENODE_COLOR_GREEN } ,
145
+ { "r" , Globals . FBXSDK_CURVENODE_COLOR_RED }
146
+ } ;
111
147
112
- private static bool TryGetChannel ( string uniPropertyName , string uniName , string propFormat , Dictionary < string , string > channels , out string outChannel )
148
+ // =======================================================
149
+
150
+ /// <summary>
151
+ /// Separates and returns the property and channel from the full Unity property name.
152
+ ///
153
+ /// Takes what is after the last period as the channel.
154
+ /// In order to use this have to be certain that there are channels, as there are cases where what is after
155
+ /// the last period is still the property name. E.g. m_Sources.Array.data[0].weight has no channel.
156
+ /// </summary>
157
+ /// <param name="fullPropertyName"></param>
158
+ /// <returns></returns>
159
+ private static UnityPropertyChannelPair GetUnityPropertyChannelPair ( string fullPropertyName )
113
160
{
114
- outChannel = null ;
115
- foreach ( var channel in channels )
161
+ int index = fullPropertyName . LastIndexOf ( '.' ) ;
162
+ if ( index < 0 )
116
163
{
117
- var uniChannel = channel . Key ;
118
- var fbxChannel = channel . Value ;
119
- if ( uniPropertyName . EndsWith ( string . Format ( propFormat , uniName , uniChannel ) ) )
120
- {
121
- outChannel = fbxChannel ;
122
- return true ;
123
- }
164
+ return new UnityPropertyChannelPair ( fullPropertyName , null ) ;
124
165
}
125
- return false ;
166
+
167
+ var property = fullPropertyName . Substring ( 0 , index ) ;
168
+ var channel = fullPropertyName . Substring ( index + 1 ) ;
169
+ return new UnityPropertyChannelPair ( property , channel ) ;
126
170
}
127
171
128
- private static FbxPropertyChannelPair [ ] GetChannelPairs ( string uniPropertyName , Dictionary < string , string > properties , Dictionary < string , string > channels = null )
172
+ private static FbxPropertyChannelPair [ ] GetChannelPairs ( string uniPropertyName , PropertyChannelMap propertyChannelMap )
129
173
{
130
174
// Unity property name is of the format "property.channel". Split by the last '.' and search for the property in the property dict, and channel in the channel dict.
131
175
// If the property name is just "property" then the channel is null.
132
176
177
+ var properties = propertyChannelMap . MapUnityPropToFbxProp ;
178
+ var channels = propertyChannelMap . MapUnityChannelToFbxChannel ;
179
+
133
180
// First handle case where there's no channels.
134
181
if ( channels == null )
135
182
{
@@ -141,14 +188,15 @@ private static FbxPropertyChannelPair[] GetChannelPairs(string uniPropertyName,
141
188
return null ;
142
189
}
143
190
144
- int index = uniPropertyName . LastIndexOf ( '.' ) ;
145
- if ( index < 0 )
191
+ var uniPropChannelPair = GetUnityPropertyChannelPair ( uniPropertyName ) ;
192
+ if ( uniPropChannelPair . channel == null )
146
193
{
194
+ // We've already checked the case where there are no channels
147
195
return null ;
148
196
}
149
197
150
- var property = uniPropertyName . Substring ( 0 , index ) ;
151
- var channel = uniPropertyName . Substring ( index + 1 ) ;
198
+ var property = uniPropChannelPair . property ;
199
+ var channel = uniPropChannelPair . channel ;
152
200
153
201
string fbxProp ;
154
202
if ( ! properties . TryGetValue ( property , out fbxProp ) )
@@ -165,9 +213,12 @@ private static FbxPropertyChannelPair[] GetChannelPairs(string uniPropertyName,
165
213
return new FbxPropertyChannelPair [ ] { new FbxPropertyChannelPair ( fbxProp , fbxChannel ) } ;
166
214
}
167
215
168
- private static bool TryGetConstraintSourceChannelPairs ( string uniPropertyName , FbxConstraint constraint , Dictionary < string , string > properties , Dictionary < string , string > channels , ref FbxPropertyChannelPair [ ] channelPairs )
216
+ private static FbxPropertyChannelPair [ ] GetConstraintSourceChannelPairs ( string uniPropertyName , FbxConstraint constraint , PropertyChannelMap propertyChannelMap )
169
217
{
170
- foreach ( var prop in properties )
218
+ var properties = propertyChannelMap . MapUnityPropToFbxProp ;
219
+ var channels = propertyChannelMap . MapUnityChannelToFbxChannel ;
220
+
221
+ foreach ( var prop in properties )
171
222
{
172
223
var match = System . Text . RegularExpressions . Regex . Match ( uniPropertyName , prop . Key ) ;
173
224
if ( match . Success && match . Groups . Count > 0 )
@@ -180,16 +231,32 @@ private static bool TryGetConstraintSourceChannelPairs(string uniPropertyName, F
180
231
}
181
232
var source = constraint . GetConstraintSource ( index ) ;
182
233
var fbxName = string . Format ( prop . Value , source . GetName ( ) ) ;
183
- string channel ;
184
- // we've already matched with the property name, just get the channel
185
- if ( TryGetChannel ( uniPropertyName , "" , "{1}" , channels , out channel ) )
234
+
235
+ // Have the fbx name, now need the channel
236
+ if ( channels == null )
186
237
{
187
- channelPairs = new FbxPropertyChannelPair [ ] { new FbxPropertyChannelPair ( fbxName , channel ) } ;
188
- return true ;
238
+ // no channel, we have what we need
239
+ return new FbxPropertyChannelPair [ ] { new FbxPropertyChannelPair ( fbxName , null ) } ;
189
240
}
241
+
242
+ var uniPropChannelPair = GetUnityPropertyChannelPair ( uniPropertyName ) ;
243
+ if ( uniPropChannelPair . channel == null )
244
+ {
245
+ // We've already checked the case where there are no channels
246
+ return null ;
247
+ }
248
+
249
+ var channel = uniPropChannelPair . channel ;
250
+ string fbxChannel ;
251
+ if ( ! channels . TryGetValue ( channel , out fbxChannel ) )
252
+ {
253
+ return null ;
254
+ }
255
+ return new FbxPropertyChannelPair [ ] { new FbxPropertyChannelPair ( fbxName , fbxChannel ) } ;
190
256
}
191
257
}
192
- return false ;
258
+
259
+ return null ;
193
260
}
194
261
195
262
/// <summary>
@@ -198,62 +265,63 @@ private static bool TryGetConstraintSourceChannelPairs(string uniPropertyName, F
198
265
/// </summary>
199
266
public static bool TryGetValue ( string uniPropertyName , out FbxPropertyChannelPair [ ] prop , FbxConstraint constraint = null )
200
267
{
201
- System . StringComparison ct = System . StringComparison . CurrentCulture ;
202
-
203
268
prop = new FbxPropertyChannelPair [ ] { } ;
204
- var propFormat = "{0}.{1}" ;
269
+
270
+ // spot angle is a special case as it returns two channel pairs instead of one
271
+ System . StringComparison ct = System . StringComparison . CurrentCulture ;
272
+ if ( uniPropertyName . StartsWith ( "m_SpotAngle" , ct ) )
273
+ {
274
+ prop = new FbxPropertyChannelPair [ ] {
275
+ new FbxPropertyChannelPair ( "OuterAngle" , null ) ,
276
+ new FbxPropertyChannelPair ( "InnerAngle" , null )
277
+ } ;
278
+ return true ;
279
+ }
205
280
281
+ // Try get constraint specific channel pairs first as we know this is a constraint
206
282
if ( constraint != null )
207
283
{
208
284
// Aim constraint shares the RotationOffset property with RotationConstraint, so make sure that the correct FBX property is returned
209
285
if ( constraint . GetConstraintType ( ) == FbxConstraint . EType . eAim )
210
286
{
211
- prop = GetChannelPairs ( uniPropertyName , AimConstraintProperties , TransformChannels ) ;
212
- if ( prop != null )
287
+ prop = GetChannelPairs ( uniPropertyName , AimConstraintPropertyMap ) ;
288
+ if ( prop != null )
213
289
{
214
290
return true ;
215
291
}
216
292
}
217
293
218
- prop = GetChannelPairs ( uniPropertyName , ConstraintSourceProperties ) ;
219
- if ( prop != null )
294
+ var constraintPropertyMaps = new List < PropertyChannelMap > ( )
220
295
{
221
- return true ;
222
- }
296
+ ConstraintSourcePropertyMap ,
297
+ ConstraintSourceTransformPropertyMap
298
+ } ;
223
299
224
- prop = GetChannelPairs ( uniPropertyName , ConstraintSourceTransformProperties , TransformChannels ) ;
225
- if ( prop != null )
300
+ foreach ( var propMap in constraintPropertyMaps )
226
301
{
227
- return true ;
302
+ prop = GetConstraintSourceChannelPairs ( uniPropertyName , constraint , propMap ) ;
303
+ if ( prop != null )
304
+ {
305
+ return true ;
306
+ }
228
307
}
229
308
}
230
309
231
- // Transform Properties
232
- if ( TryGetChannelPairs ( uniPropertyName , propFormat , TransformProperties , TransformChannels , ref prop ) )
233
- {
234
- return true ;
235
- }
236
-
237
- // Color Properties
238
- if ( TryGetChannelPairs ( uniPropertyName , propFormat , ColorProperties , ColorChannels , ref prop ) )
239
- {
240
- return true ;
241
- }
242
-
243
- // Other Properties
244
- if ( TryGetChannelPairs ( uniPropertyName , "{0}" , OtherProperties , NullChannel , ref prop ) )
310
+ // Check if this is a transform, color, or other property and return the channel pairs if they match.
311
+ var propertyMaps = new List < PropertyChannelMap > ( )
245
312
{
246
- return true ;
247
- }
313
+ TransformPropertyMap ,
314
+ ColorPropertyMap ,
315
+ OtherPropertyMap
316
+ } ;
248
317
249
- // spot angle is a special case as it returns two channel pairs instead of one
250
- if ( uniPropertyName . StartsWith ( "m_SpotAngle" , ct ) )
318
+ foreach ( var propMap in propertyMaps )
251
319
{
252
- prop = new FbxPropertyChannelPair [ ] {
253
- new FbxPropertyChannelPair ( "OuterAngle" , null ) ,
254
- new FbxPropertyChannelPair ( "InnerAngle" , null )
255
- } ;
256
- return true ;
320
+ prop = GetChannelPairs ( uniPropertyName , propMap ) ;
321
+ if ( prop != null )
322
+ {
323
+ return true ;
324
+ }
257
325
}
258
326
259
327
return false ;
0 commit comments