Skip to content

Commit eb5074d

Browse files
committed
refactor so functions return values and make use of dicts
1 parent 1d411df commit eb5074d

File tree

1 file changed

+163
-95
lines changed

1 file changed

+163
-95
lines changed

Assets/FbxExporters/Editor/FbxPropertyChannelPair.cs

Lines changed: 163 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,55 @@ struct FbxPropertyChannelPair
1414
public string Property { get; private set; }
1515
public string Channel { get; private set; }
1616

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+
1762
/// <summary>
1863
/// Map of Unity transform properties to their FBX equivalent.
1964
/// </summary>
20-
private static Dictionary<string, string> TransformProperties = new Dictionary<string, string>()
65+
private static Dictionary<string, string> MapTransformPropToFbxProp = new Dictionary<string, string>()
2166
{
2267
{ "m_LocalScale", "Lcl Scaling" },
2368
{ "Motion S", "Lcl Scaling" },
@@ -31,63 +76,38 @@ struct FbxPropertyChannelPair
3176
/// <summary>
3277
/// Map of Unity Aim constraint properties to their FBX equivalent.
3378
/// </summary>
34-
private static Dictionary<string, string> AimConstraintProperties = new Dictionary<string, string>()
79+
private static Dictionary<string, string> MapAimConstraintPropToFbxProp = new Dictionary<string, string>()
3580
{
3681
{ "m_AimVector", "AimVector" },
3782
{ "m_UpVector", "UpVector" },
3883
{ "m_WorldUpVector", "WorldUpVector" },
3984
{ "m_RotationOffset", "RotationOffset" }
4085
};
4186

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-
5287
/// <summary>
5388
/// Map of Unity color properties to their FBX equivalent.
5489
/// </summary>
55-
private static Dictionary<string, string> ColorProperties = new Dictionary<string, string>()
90+
private static Dictionary<string, string> MapColorPropToFbxProp = new Dictionary<string, string>()
5691
{
5792
{ "m_Color", "Color" }
5893
};
5994

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-
7095
/// <summary>
7196
/// Map of Unity properties to their FBX equivalent.
7297
/// </summary>
73-
private static Dictionary<string, string> OtherProperties = new Dictionary<string, string>()
98+
private static Dictionary<string, string> MapPropToFbxProp = new Dictionary<string, string>()
7499
{
75100
{ "m_Intensity", "Intensity" },
76101
{ "field of view", "FieldOfView" },
77102
{ "m_Weight", "Weight" }
78103
};
79104

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-
85105
/// <summary>
86106
/// Map of Unity constraint source property name as a regular expression to the FBX property as a string format.
87107
/// This is necessary because the Unity property contains an index in to an array, and the FBX property contains
88108
/// the name of the source object.
89109
/// </summary>
90-
private static Dictionary<string, string> ConstraintSourceProperties = new Dictionary<string, string>()
110+
private static Dictionary<string, string> MapConstraintSourcePropToFbxProp = new Dictionary<string, string>()
91111
{
92112
{ @"m_Sources\.Array\.data\[(\d+)\]\.weight", "{0}.Weight" }
93113
};
@@ -97,39 +117,66 @@ struct FbxPropertyChannelPair
97117
/// This is necessary because the Unity property contains an index in to an array, and the FBX property contains
98118
/// the name of the source object.
99119
/// </summary>
100-
private static Dictionary<string, string> ConstraintSourceTransformProperties = new Dictionary<string, string>()
120+
private static Dictionary<string, string> MapConstraintSourceTransformPropToFbxProp = new Dictionary<string, string>()
101121
{
102122
{ @"m_TranslationOffsets\.Array\.data\[(\d+)\]", "{0}.Offset T" },
103123
{ @"m_RotationOffsets\.Array\.data\[(\d+)\]", "{0}.Offset R" }
104124
};
105125

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+
};
111147

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)
113160
{
114-
outChannel = null;
115-
foreach (var channel in channels)
161+
int index = fullPropertyName.LastIndexOf('.');
162+
if (index < 0)
116163
{
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);
124165
}
125-
return false;
166+
167+
var property = fullPropertyName.Substring(0, index);
168+
var channel = fullPropertyName.Substring(index + 1);
169+
return new UnityPropertyChannelPair(property, channel);
126170
}
127171

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)
129173
{
130174
// 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.
131175
// If the property name is just "property" then the channel is null.
132176

177+
var properties = propertyChannelMap.MapUnityPropToFbxProp;
178+
var channels = propertyChannelMap.MapUnityChannelToFbxChannel;
179+
133180
// First handle case where there's no channels.
134181
if (channels == null)
135182
{
@@ -141,14 +188,15 @@ private static FbxPropertyChannelPair[] GetChannelPairs(string uniPropertyName,
141188
return null;
142189
}
143190

144-
int index = uniPropertyName.LastIndexOf('.');
145-
if (index < 0)
191+
var uniPropChannelPair = GetUnityPropertyChannelPair(uniPropertyName);
192+
if(uniPropChannelPair.channel == null)
146193
{
194+
// We've already checked the case where there are no channels
147195
return null;
148196
}
149197

150-
var property = uniPropertyName.Substring(0, index);
151-
var channel = uniPropertyName.Substring(index + 1);
198+
var property = uniPropChannelPair.property;
199+
var channel = uniPropChannelPair.channel;
152200

153201
string fbxProp;
154202
if(!properties.TryGetValue(property, out fbxProp))
@@ -165,9 +213,12 @@ private static FbxPropertyChannelPair[] GetChannelPairs(string uniPropertyName,
165213
return new FbxPropertyChannelPair[] { new FbxPropertyChannelPair(fbxProp, fbxChannel) };
166214
}
167215

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)
169217
{
170-
foreach (var prop in properties)
218+
var properties = propertyChannelMap.MapUnityPropToFbxProp;
219+
var channels = propertyChannelMap.MapUnityChannelToFbxChannel;
220+
221+
foreach(var prop in properties)
171222
{
172223
var match = System.Text.RegularExpressions.Regex.Match(uniPropertyName, prop.Key);
173224
if (match.Success && match.Groups.Count > 0)
@@ -180,16 +231,32 @@ private static bool TryGetConstraintSourceChannelPairs(string uniPropertyName, F
180231
}
181232
var source = constraint.GetConstraintSource(index);
182233
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)
186237
{
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) };
189240
}
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) };
190256
}
191257
}
192-
return false;
258+
259+
return null;
193260
}
194261

195262
/// <summary>
@@ -198,62 +265,63 @@ private static bool TryGetConstraintSourceChannelPairs(string uniPropertyName, F
198265
/// </summary>
199266
public static bool TryGetValue(string uniPropertyName, out FbxPropertyChannelPair[] prop, FbxConstraint constraint = null)
200267
{
201-
System.StringComparison ct = System.StringComparison.CurrentCulture;
202-
203268
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+
}
205280

281+
// Try get constraint specific channel pairs first as we know this is a constraint
206282
if (constraint != null)
207283
{
208284
// Aim constraint shares the RotationOffset property with RotationConstraint, so make sure that the correct FBX property is returned
209285
if (constraint.GetConstraintType() == FbxConstraint.EType.eAim)
210286
{
211-
prop = GetChannelPairs(uniPropertyName, AimConstraintProperties, TransformChannels);
212-
if(prop != null)
287+
prop = GetChannelPairs(uniPropertyName, AimConstraintPropertyMap);
288+
if (prop != null)
213289
{
214290
return true;
215291
}
216292
}
217293

218-
prop = GetChannelPairs(uniPropertyName, ConstraintSourceProperties);
219-
if(prop != null)
294+
var constraintPropertyMaps = new List<PropertyChannelMap>()
220295
{
221-
return true;
222-
}
296+
ConstraintSourcePropertyMap,
297+
ConstraintSourceTransformPropertyMap
298+
};
223299

224-
prop = GetChannelPairs(uniPropertyName, ConstraintSourceTransformProperties, TransformChannels);
225-
if(prop != null)
300+
foreach(var propMap in constraintPropertyMaps)
226301
{
227-
return true;
302+
prop = GetConstraintSourceChannelPairs(uniPropertyName, constraint, propMap);
303+
if(prop != null)
304+
{
305+
return true;
306+
}
228307
}
229308
}
230309

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>()
245312
{
246-
return true;
247-
}
313+
TransformPropertyMap,
314+
ColorPropertyMap,
315+
OtherPropertyMap
316+
};
248317

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)
251319
{
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+
}
257325
}
258326

259327
return false;

0 commit comments

Comments
 (0)