Exportador en Maxscript

darkwin - 19/07/2006 17:38
Pues eso, deseo hacer un script que me exporte la posición, rotación y escalado de todos los modelos de una escena. No se ESI esta es la rama más adecuada del foro para hacerlo, pero es que, no sabía dónde meterlo.

Es para hacer la composición de la escena de un juego en 3dsmax y luego exportar la posición exacta de todos los objetos a un fichero para cargarlos exactamente igual en el motor del juego. Algo, así como un editor de mapas, pero más sencillo.

No tengo ni idea de max script así que, no se ni cómo empezar. Se programar sin problemas en lenguajes como C++, etc así que, tampoco necesito explicaciones demasiado básicas.

A ver si alguien me puede ayudar, que parece que el Maxscript es ese gran desconocido.

Posdata: si nadie sabe cómo hacerlo me vendría bien al menos algún tutorial en español a ser posible.
alberizo - 19/07/2006 19:41
Si sabes C++ podrías hacerlo con el SDK del 3dsMax.
Fiz3d - 19/07/2006 19:52
Creo que Alberizo tiene razón, yo estoy aprendiendo a marchas forzadas Maxscript, y si ya sabes C++ no tendrías problemas, aun así creo que si le echas un vistazo rápido a la ayuda del Maxscript, te haces con el en dos patadas. Saludos.
alberizo - 19/07/2006 19:59
O también tienes la opción exportar cómo ase, y hacerte un lector conversor a tu formato, que sin duda es la opción más sencilla y que más gente usa.
HalfVector - 19/07/2006 20:47
Hola.

Pues eso, deseo hacer un script que me exporte la posición, rotación y escalado de todos los modelos de una escena.

Prueba con esta función:
[code]Fn exportprsdata nodes file = (tformat numobjects %\nNodes, count to: file tfor node in nodes do (t format \nName \%\\nNode, name to: file format position (% % %)\nNode, transform, row4.x node, transform, row4, y node, transform, row4.z to: file format rotation (% % % %)\nNode, transform, rotationpart.x node, transform, rotationpart, y node, transform, rotationpart, z node, transform, rotationpart.w to: file format scale (% % %)\nNode, transform, scalepart.x node, transform, scalepart, y node, transform, scalepart, z to: file t).
)[/code]

Luego, para utilizarla, pon algo así:
[code]filename = getsavefilename caption:save prs data types:prs data (*.prs)|*.prs.

If filename.= undefined do (tlocal file = createfile filename tif file.= undefined do (t exportprsdata $geometry file close file t).
)[/code]

Con eso escribiras en el archivo seleccionado la matriz de transformación (posición, rotación y escala) de todos los meshes en la escena.

Consulta la referencia de Maxscript para obtener más información.

Tienes que tener en cuenta que no he hecho ningún tipo de conversión a Direct3D o a OpenGL.

Posdata: si nadie sabe cómo hacerlo me vendría bien al menos algún tutorial en español a ser posible.

Espero sacar pronto la primera parte de la serie de tutoriales sobre Maxscript que tengo previsto escribir. Saludos.
darkwin - 20/07/2006 03:15
Alberizo gracias por tus comentarios, pero por lo que me han comentado el SDK del 3ds Max es un auténtico infierno y cambia en cada nueva versión de max, con lo cual aprender a desarrollar algo es muy difícil.

Me estudiare a fondo la referencia tomando como base el código de Halfvector, al que estoy realmente agradecido.

Espero ese tutorial con impaciencia y ánimo con él. Gracias a todos.
HalfVector - 20/07/2006 11:04

Por lo que me han comentado el SDK del 3ds Max es un auténtico infierno y cambia en cada nueva versión de max, con lo cual aprender a desarrollar algo es muy difícil.

Es cierto que es un infierno, pero no porque cambie en cada versión (yo lo conozco desde la versión 6 más o menos y para mí que mucho no ha cambiado) sino porque hay una maraña de clases impresionante. Pero es lógico. Estamos hablando de una aplicación mastodóntica como max.

En cualquier caso, para aplicaciones sencillas como ésta, sin duda la mejor opción es Maxscript. Como ves, en unas pocas líneas tienes lo que quieres. Saludos.
darkwin - 20/07/2006 11:19
Hola Halfvector, me queda una duda, el engine que estamos usando trabaja sobre DirectX, pero el max lo suelo tener con OpenGL. Para evitarme conversiones, bastaría con cambiar el max a DirectX?
HalfVector - 20/07/2006 12:29

Hola Halfvector, me queda una duda, el engine que estamos usando trabaja sobre DirectX, pero el max lo suelo tener con OpenGL. Para evitarme conversiones, bastaría con cambiar el max a DirectX?

No, el hecho de tener activado OpenGL o Direct3D no cambia el sistema de coordenadas. Max utiliza el suyo propio (right-handed, como OpenGL, pero con +z apuntando hacia arriba y +y hacia dentro de la pantalla).

Así que, para Direct3D, al exportar tendrás que hacer algunas cosas. Por ejemplo, en la posición y en la escala tendrás que intercambiar la y por la z y en la rotación también tendrás que hacer unos cambios. En el script que te he puesto la rotación se especifica como cuaternión, pero para hacer la conversión a Direct3D de forma más sencilla yo lo haría en formato axis-angle o Euler y entonces sería cuestión de intercambiar la y por la z. Y no me acuerdo si también había que negar el ángulo. Eso ya es cuestión de que vayas probando hasta que salga. Saludos.
darkwin - 24/07/2006 22:16
Hola Halfvector, he estado probando el script y va perfecto. Ahora solo quería añadirle ciertos datos y me he atascado en una cosa, a ver si me puedes echar una mano.

Cuando monte la escena me gustaría añadir algunos datos a cada modelo mediante un plugin (por ejemplo, categoría del objeto (string) o ruta de la malla dónde está ese obeto exportado (string), o cualquier otro que se me ocurra).

He aprendido a crear mediante un script un nuevo modificador, pero no sé cómo sacar esos datos para incluirlos en tu script. Muchas gracias por tu ayuda, esto del Maxscript es todo un mundo.
HalfVector - 25/07/2006 01:34
Si puedes pon el modificador ese para que pueda ver cómo sacar los datos. Otra opción que tienes para asignar valores a un objeto es utilizar las user properties. Un ejemplo:
[code]setuserprop $ renderable true.

Setuserprop $ Path /base/objects[/code]

Con eso asignas una propiedad isrenderable de tipo bolean y otra de tipo string, Path, al objeto seleccionado.

Luego, para recoger los valores, haces algo así:
[code]isrenderable = getuserprop $ renderable.

Format isrenderable: %\n(if isrenderable.= undefined then isrenderable else propiedad no definida).

Objpath = getuserprop $ Path.

Format Path: %\n(if objpath.= undefined then objpath else propiedad no definida)[/code]

Para más información sobre esos métodos consulta la referencia.

De todas formas, si me pones el modificador que has hecho, te podre decir cómo acceder a sus propiedades. Saludos.
darkwin - 25/07/2006 13:24
Hola Halfvector. Una vez más gracias por tu ayuda. Te copio el script con el que añado un modificador propio: Plugin modifier mygames.

Name:mygames identifier.

Classid:#(0 por 133067, 0 por 54374).

Versión:1.

Parameters main ut:parámetros.

Archivo type: #string -desesperados parámetros aún no sé cómo se usan).

Rollout parámetros general.

Edittext narchivo nombre de archivo: labelontop:true).
).

Mi idea es correr este script cuando lo termine y luego ir montando la escena, rellenando los datos que necesite para cada objeto. Cuando termine tendré que correr el otro script para exportar los datos básicos de la geometría y los que introduzca en ese modificador.

Como ves estoy un poco atascado, me gustaría mejorar el modificador que te he puesto y terminar el otro script. Muchas gracias por tu ayuda.
HalfVector - 25/07/2006 17:13
Ese bloque de parámetros sirve para que el plugin sepa que parámetros y con que valor tiene que guardar en disco. Lo único que te ha faltado es asociar ese parámetro archivo con el control de edición de texto del ut narchivo:
[code]plugin modifier mygames.

Name:mygames identifier.

Classid:#(0 por 133067, 0 por 54374).

Versión:1.
(Tparameters main ut:parámetros t(t archivo type:#string ui:narchivo -desesperados parámetros aún no sé cómo se usan t) trollout parámetros general t(t edittext narchivo nombre de archivo: labelontop:true t).
)[/code]

Luego, si al objeto seleccionado le añadiste ese modificador, puedes acceder a la propiedad archivo de la siguiente forma:
[code]$.modifiers[mygames identifier"].archivo[/code]

Con eso debería bastar. Saludos.
darkwin - 25/07/2006 18:29
Perfecto, gracias. Ya he robado los dos scripts y funcionan. Eres un crack.