This repository has been archived by the owner on Jul 6, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
TgcSceneImporter.ms
352 lines (282 loc) · 10.5 KB
/
TgcSceneImporter.ms
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
/*
##############################################################
TgcSceneImporter
--------------------------------------------------------------
Importador de escenario estatico con format TgcScene.xml
##############################################################
General e Instalacion
---------------------
Autor: Matias Leone
Plataforma: 3ds Max 2011
Instalacion: Copiar archivo TgcSceneImporter.ms en "..\Autodesk\3ds Max 2011\Scripts\Startup\"
Tambien necesita el archivo MaxScriptUtils.ms. Copiarlo a la carpeta anterior.
Ejecucion:
Abrir 3ds Max
Ir a la seccion de Scripts de la barra de herramientas de la derecha (Utilities: icono del Martillo)
Elegir "MAXScript"
De la lista inferior de "Utilities" elegir "TGC-Scene Importer"
Aparecera abajo todo el conjunto de herramientas del Plugin.
Uso del Plugin
--------------
El plugin levanta archivos XML de formato "-TgcScene.xml" y crea todos los modelos de MAX.
Actualmente no soporta:
- Lightmaps
- Normales
- Portales
- Instancias de modelos
No soporta que el XML tenga caracteres UTF-8
*/
--Incluir utilidades generales
include "MaxScriptUtils.ms"
utility TgcSceneImporter "TGC-Scene Importer"
(
--######### GLOBALS ###########
local FILE_EXT = "-TgcScene.xml"
---------------------------------------------------------------------------------------------------------------------------------------------------------------
/*
* Cargar un Bitmap de DiffuseMap y aplicarlo a un Material.
* Carga tambien su OpacityMap si corresponde
*/
function loadBitmapInMaterial mat bitmapFileName aphaBlendEnable = (
local matBitmap = bitmapTexture filename:bitmapFileName
mat.diffuseMap = matBitmap
--mat.mapEnables[2] = true
--showTextureMap mat bmpTex true
--Ver si tiene OpacityMap
if aphaBlendEnable == true then (
matBitmap.monoOutput = 1 --Alpha
mat.opacityMap = matBitmap
)
)
---------------------------------------------------------------------------------------------------------------------------------------------------------------
/*
* Parsea el contenido en string de un tag de la forma: 11.1305 0.0 9.03702 -2.26105 0.0 14.1578 -13.3915 0.0 5.12076
* y lo convierte en un array de floats
* plusOne en true suma 1 a todos los valores para convertir indices de DirectX a MAX
*/
function parseFloatArray content plusOne = (
local floatArray = #()
local strArray = filterString content " "
for s in strArray do (
local f = s as float
if plusOne == true then (
f = f + 1
)
append floatArray f
)
floatArray
)
---------------------------------------------------------------------------------------------------------------------------------------------------------------
/*
* Parsea el contenido en string de un tag de la forma: 11.1305 0.0 9.03702 -2.26105 0.0 14.1578 -13.3915 0.0 5.12076
* y lo convierte en un array de point3 tomado de a 3 valores.
* plusOne en true suma 1 a todos los valores para convertir indices de DirectX a MAX
* invertYZ en true invierte Y por Z
*/
function convertToPoint3Array content plusOne invertYZ= (
local point3Array = #()
local strArray = filterString content " "
local i = 1
while i <= strArray.count do (
local x = strArray[i] as float
local y = strArray[i + 1] as float
local z = strArray[i + 2] as float
if plusOne == true then (
x = x + 1
y = y + 1
z = z + 1
)
if invertYZ == true then (
local aux = y
y = z
z = aux
)
append point3Array (point3 x y z)
i = i + 3
)
point3Array
)
---------------------------------------------------------------------------------------------------------------------------------------------------------------
/*
* FUNCION PRINCIPAL
*
* Importa todos los meshes del XML "-TgcScene.xml" y crea objetos de MAX
*/
function importScene = (
--Obtener path de archivo "-TgcScene.xml"
local fileName = getOpenFileName caption:"Open Scene file" types:"-TgcScene.xml|*-TgcScene.xml"
if fileName == undefined then (
return 0
)
--Cargar XML
local doc = XmlDocument()
doc.loadFromFile fileName
--Llamar garbage collector para limpiar todas las variables temporales del parseo de XML
gc
--Obtener directorio de texturas
local texturesExportNode = doc.root.getChild "texturesExport"
local texturesDir = (substring filename 1 (Utils_lastIndexOf filename "\\")) + (texturesExportNode.getAttributeValue "dir") + "\\"
--Leer Materials
local materialsNode = doc.root.getChild "materials"
local mNodes = materialsNode.getChildren "m"
local createdMaterials = #()
for mNode in mNodes do (
local matName = mNode.getAttributeValue "name"
local matType = mNode.getAttributeValue "type"
--Crear Standardmaterial
local mat = undefined
if matType == "Standardmaterial" then (
--Crear material de MAX
mat = standardmaterial name:matName showInViewport:true
--Cargar Bitmap
local matBitmapNode = mNode.getChild "bitmap"
if matBitmapNode != undefined then (
local matBitmapFileName = texturesDir + matBitmapNode.content
local alphaBlendEnableString = mNode.getChildContent "alphaBlendEnable"
local matAlphaBlendEnable = false
if alphaBlendEnableString != undefined then (
matAlphaBlendEnable = alphaBlendEnableString as booleanClass
)
loadBitmapInMaterial mat matBitmapFileName matAlphaBlendEnable
)
)
--Crear Multimaterial
else if matType == "Multimaterial" then (
--Crear SubMaterials
local subMNodes = mNode.getChildren "subM"
local subMaterials = #()
for subMNode in subMNodes do (
local subMatName = subMNode.getAttributeValue "name"
local subMatType = subMNode.getAttributeValue "type"
if subMatType != "Standardmaterial" then (
messagebox subMatType
messagebox ("The SubMaterial: " + subMatName + " is not a StandardMaterial")
return 0
)
--Crear material de MAX
local subMat = standardmaterial name:subMatName showInViewport:true
--Cargar Bitmap
local subMatBitmapNode = subMNode.getChild "bitmap"
if subMatBitmapNode != undefined then (
local subMatBitmapFileName = texturesDir + subMatBitmapNode.content
local alphaBlendEnableString = subMNode.getChildContent "alphaBlendEnable"
if alphaBlendEnableString != undefined then (
matAlphaBlendEnable = alphaBlendEnableString as booleanClass
)
loadBitmapInMaterial subMat subMatBitmapFileName subMatAlphaBlendEnable
)
append subMaterials subMat
)
--Crear material de MAX
mat = multimaterial name:matName showInViewport:true numsubs:(subMaterials.count)
mat.materialList = subMaterials
)
append sceneMaterials mat
append createdMaterials mat
)
--Leer Meshes
local meshesNode = doc.root.getChild "meshes"
local meshNodes = meshesNode.getChildren "mesh"
local createdMeshes = #()
for meshNode in meshNodes do (
--Obtener atributos generales
local meshName = meshNode.getAttributeValue "name"
local meshLayerName = meshNode.getAttributeValue "layer"
local meshType = meshNode.getAttributeValue "type"
local meshMatId = (meshNode.getAttributeValue "matId" as integer)
local meshColor = meshNode.getAttributeValue "color"
--Type
if meshType == "Instance" then (
messagebox ("Instance meshes are not supported yet. Mesh name: " + meshName)
return 0
)
--Craer mesh de MAX y aplicar vertices y coordinatesIdx
local meshFaces = convertToPoint3Array (meshNode.getChildContent "coordinatesIdx") true false
local meshVertices = convertToPoint3Array (meshNode.getChildContent "vertices") false true
local meshMAX = mesh name:meshName vertices:meshVertices faces:meshFaces
--Material, tverts y materialIDs
if meshMatId != -1 then (
local meshMaterial = createdMaterials[meshMatId + 1]
local matClass = classof meshMaterial
--Obtener texCoords y crear array con UVW tverts
local texCoords = parseFloatArray (meshNode.getChildContent "texCoords") false
local meshTVerts = #()
local texCoordsCount = (texCoords.count / 2 - 1)
for i = 0 to texCoordsCount do (
local u = texCoords[i * 2 + 1]
local v = texCoords[i * 2 + 2]
v = 1 - v --Invertimos V
local w = 0
append meshTVerts (point3 u v w)
)
--StandardMaterial
local meshMaterialIDs
if matClass == StandardMaterial then (
--Crear array con todos matID = 1
meshMaterialIDs = #()
for i = 1 to meshFaces.count do (
append meshMaterialIDs 1
)
--MultiMaterial
) else (
--Tomar matIds de mesh
meshMaterialIDs = parseFloatArray (meshNode.getChildContent "matIds") true
)
--Aplicar materialIDs y tverts
setMesh meshMAX materialIDs:meshMaterialIDs tverts:meshTVerts
--Cargar TVFaces con textCoordsIdx
buildTVFaces meshMAX
local textCoordsIdx = convertToPoint3Array (meshNode.getChildContent "textCoordsIdx") true false
for i = 1 to textCoordsIdx.count do (
setTVFace meshMAX i textCoordsIdx[i]
)
--Aplicar material
meshMAX.material = meshMaterial
--Si no tiene Material
) else (
--Crear igual las TV Faces, de forma generica
meshMAX.numtverts = meshMAX.numverts
buildTVFaces meshMAX
)
--Aplicar color
meshColor = substring meshColor 2 (meshColor.count - 2)
local meshColorArray = filterString meshColor ","
meshMax.wireColor = color (meshColorArray[1] as float) (meshColorArray[2] as float) (meshColorArray[3] as float)
--Crear layer si es necesario y aplicar a mesh
if meshLayerName != undefined then (
local layer = LayerManager.getLayerFromName meshLayerName
if layer == undefined then (
layer = LayerManager.newLayer()
layer.setName meshLayerName
)
layer.addnode meshMax
)
/*
--Aplicar normales PENDIENTE!!!
local meshNormals = convertToPoint3Array (meshNode.getChildContent "normals") false true
for i = 1 to meshNormals.count do (
setNormal meshMAX i meshNormals[i]
)
*/
--Actualizar estado de mesh
update meshMAX
append createdMeshes meshMAX
)
--Seleccionar meshes creados
select createdMeshes
messagebox "Scene imported OK"
)
---------------------------------------------------------------------------------------------------------------------------------------------------------------
--############################################################
--####################### USER INTERFACE #########################
--############################################################
--######### GENERAL SETTINGS ###########
--Widgets
button w_importScene "Import Scene" width:150 height:20
--Event: button Import
on w_importScene pressed do
(
--importar
importScene()
)
)