-
Notifications
You must be signed in to change notification settings - Fork 308
/
BabylonExporter.CustomAttributes.cs
184 lines (169 loc) · 8.38 KB
/
BabylonExporter.CustomAttributes.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
using Autodesk.Max;
using BabylonExport.Entities;
using System;
using System.Collections.Generic;
namespace Max2Babylon
{
partial class BabylonExporter
{
/// <summary>
/// Return the custom attributes of a material
/// </summary>
/// <param name="materialNode"></param>
/// <param name="babylonScene"></param>
/// <param name="excludeAttributes">Attribute names to not export</param>
public Dictionary<string, object> ExportExtraAttributes(IIGameMaterial gameMaterial, BabylonScene babylonScene, List<string> excludeAttributes = null)
{
// Retreive the max object
#if MAX2022 || MAX2023 || MAX2024
ManagedServices.MaxscriptSDK.ExecuteMaxscriptCommand("obj = sceneMaterials[\"" + gameMaterial.MaterialName + "\"];", ManagedServices.MaxscriptSDK.ScriptSource.NotSpecified);
#else
ManagedServices.MaxscriptSDK.ExecuteMaxscriptCommand("obj = sceneMaterials[\"" + gameMaterial.MaterialName + "\"];");
#endif
return _ExportExtraAttributes(gameMaterial.IPropertyContainer, babylonScene, excludeAttributes);
}
/// <summary>
/// Return the custom attributes of a material
/// </summary>
/// <param name="materialNode"></param>
/// <param name="babylonScene"></param>
/// <param name="excludeAttributes">Attribute names to not export</param>
public Dictionary<string, object> ExportExtraAttributes(IIGameNode gameNode, BabylonScene babylonScene, List<string> excludeAttributes = null)
{
// Retreive the max object
#if MAX2022 || MAX2023 || MAX2024
ManagedServices.MaxscriptSDK.ExecuteMaxscriptCommand("obj = maxOps.getNodeByHandle " + gameNode.MaxNode.Handle + ";", ManagedServices.MaxscriptSDK.ScriptSource.NotSpecified);
#else
ManagedServices.MaxscriptSDK.ExecuteMaxscriptCommand("obj = maxOps.getNodeByHandle " + gameNode.MaxNode.Handle + ";");
#endif
return _ExportExtraAttributes(gameNode.IGameObject.IPropertyContainer, babylonScene, excludeAttributes);
}
/// <summary>
/// Return custom attributes retreive from a max object named "obj"
/// </summary>
/// <param name="metadata"></param>
/// <param name="propertyContainer"></param>
/// <param name="babylonScene"></param>
/// <param name="excludeAttributes">Attribute names to not export</param>
private Dictionary<string, object> _ExportExtraAttributes(IIPropertyContainer propertyContainer, BabylonScene babylonScene, List<string> excludeAttributes = null)
{
RaiseMessage("ExportExtraAttributes", 2);
// Return a string encoded with 2 separators
// Parameter separator: _$€PParam_
// Name/Type separator: _$€PType_
string cmd = "s = \"\""
+ "\r\n" + "for objDef in (custAttributes.getDefs obj) do"
+ "\r\n" + "("
+ "\r\n" + "pbArray = custAttributes.getPBlockDefs objdef"
+ "\r\n" + "for indexPBlock = 1 to pbArray.count do"
+ "\r\n" + "("
+ "\r\n" + "itms = pbArray[indexPBlock]"
+ "\r\n" + "for y = 5 to itms.Count do"
+ "\r\n" + "("
+ "\r\n" + "s = s + \"_$€PParam_\" + itms[y][1]"
+ "\r\n" + "for z = 1 to itms[y][2].Count by 2 do"
+ "\r\n" + "("
+ "\r\n" + "key = itms[y][2][z] as string"
+ "\r\n" + "if (findString key \"type\") != undefined then"
+ "\r\n" + "("
+ "\r\n" + "s = s + \"_$€PType_\" + itms[y][2][z+1]"
+ "\r\n" + ")"
+ "\r\n" + ")"
+ "\r\n" + ")"
+ "\r\n" + ")"
+ "\r\n" + ")"
+ "\r\n" + "s";
#if MAX2022 || MAX2023 || MAX2024
string result = ManagedServices.MaxscriptSDK.ExecuteStringMaxscriptQuery(cmd, ManagedServices.MaxscriptSDK.ScriptSource.NotSpecified);
#else
string result = ManagedServices.MaxscriptSDK.ExecuteStringMaxscriptQuery(cmd);
#endif
if (result == null || result == "")
{
return null;
}
// Parse the result into a dictionary
string[] parameters = result.Split(new string[] { "_$€PParam_" }, StringSplitOptions.RemoveEmptyEntries);
Dictionary<string, string> customAttributesTypeByName = new Dictionary<string, string>();
foreach (string parameter in parameters)
{
string[] customAttribute = parameter.Split(new string[] { "_$€PType_" }, StringSplitOptions.RemoveEmptyEntries);
string key = customAttribute[0];
if (customAttributesTypeByName.ContainsKey(key) == false)
{
customAttributesTypeByName.Add(key, customAttribute[1]);
}
}
// Remove preset custom attributes
customAttributesTypeByName.Remove("presetName_str");
customAttributesTypeByName.Remove("preset_str");
customAttributesTypeByName.Remove("rampOn");
// Remove specified attributes
if (excludeAttributes != null)
{
foreach (string excludeAttribute in excludeAttributes)
{
customAttributesTypeByName.Remove(excludeAttribute);
}
}
// Handle each attribute type
Dictionary<string, object> metadata = new Dictionary<string, object>();
foreach (KeyValuePair<string, string> entry in customAttributesTypeByName)
{
object obj = null;
RaiseMessage(entry.Key + "=" + entry.Value, 2);
switch (entry.Value.ToLowerInvariant())
{
case "float":
case "angle": // in rad units
case "worldunits":
obj = propertyContainer.GetFloatProperty(entry.Key);
break;
case "percent": // in base 1 (80% => 0.8)
obj = propertyContainer.GetFloatProperty(entry.Key) / 100f;
break;
case "boolean":
obj = propertyContainer.GetBoolProperty(entry.Key);
break;
case "integer":
case "array": // selected enum value expressed as int starting from 1
obj = propertyContainer.GetIntProperty(entry.Key);
break;
case "string":
obj = propertyContainer.GetStringProperty(entry.Key);
break;
case "color": // Color RGB in base 1 (not 255)
obj = propertyContainer.GetPoint3Property(entry.Key).ToArray();
break;
case "frgba": // Color RGBA in base 1 (not 255)
obj = propertyContainer.GetPoint4Property(entry.Key).ToArray();
break;
case "texturemap":
IIGameProperty gameProperty = propertyContainer.QueryProperty(entry.Key);
ITexmap texmap = gameProperty.MaxParamBlock2.GetTexmap(gameProperty.ParamID, 0, 0);
obj = ExportTexture(texmap, babylonScene);
break;
case "node":
// Currently not exported
break;
case "material":
// Currently not exported
break;
default:
RaiseWarning("Unknown type '" + entry.Value + "' for custom attribute named '" + entry.Key + "'", 2);
break;
}
if (obj != null)
{
metadata.Add(entry.Key, obj);
}
}
// Print all extra attributes
foreach (KeyValuePair<string, object> entry in metadata)
{
RaiseVerbose(entry.Key + "=" + entry.Value, 2);
}
return metadata;
}
}
}