Hola a todos!
Una vez mas vengo a recurrir a vosotros!
Vereis, tengo un problema con el 3DStudio. Tengo una malla que tiene 5007 TVertices y 4003 caras. Bien, el problema esta en que cuando recorro todas las TVFaces me encuentro con que hay TVertices que no son usados por ninguna cara, y esto me jode mucho para exportar. Alguien sabe el porque de esto? Hay alguna forma para decirle al MAX que 'limpie' toda la info que no usa?
Muchisimas gracias!!!
No conocía este problema así que no sé la solución pero mirando en la ayuda de MAXScript encontré estos dos métodos:
meshop.buildMapFaces <Mesh mesh> <Integer mapChannel> <Boolean keep>
Sets the number of map faces to the number of mesh faces, retaining existing mapping data if keep is true. Deletes any map vertices that are not used by the map faces.
meshop.defaultMapFaces <Mesh mesh> <Integer mapChannel> <Integer count>
Sets the number of map faces to the number of mesh faces, and the number of map vertices to the number of mesh vertices. The map face vertices are set to the same vertex index as the corresponding mesh face vertices (i.e., there will be a 1-to-1 correspondence between map faces/vertices and the mesh faces/vertices). The map vertex UVW coordinates are set to the normalized (0 to 1) position of the corresponding mesh vertex in the mesh's bounding box.
Parece que el primero de ellos podría ser lo que buscas...
Precisamente yo estoy metido de lleno en la creación de algunas herramientas para mi motor para exportar escenas. Estoy utilizando MAXScript y la verdad, sería bueno saber si eso soluciona tu problema...
Saludos
¿Quién ha hecho el modelo? Puede que haya copiado vértices sin querer y todo lo que haya que hacer sea seleccionar toda la malla a nivel de vértice y aplicar el "fusionar" vértices con el valor de tolerancia mínimo, 0,1. Esto servirá si el problema es de duplicación de vértices.
Ya que estamos hablando del tema de la exportación de modelos a ver si me confirmáis lo siguiente.
Hay veces en el que el número de coordenadas de vértice no coincide con el número e coordenadas de textura, por lo que hay que reconstruir la lista de vértices y de índices. El caso más claro es el del cubo, para el cual MAX te devuelve 8 coordenadas de vértice y 12 de textura, por lo que tras el proceso de conversión quedarían 24 vértices.
Ahora bien, en el caso de que el número de coordenadas de vértice sea igual al de textura, siempre he dado por hecho que no hay que reconstruir la lista de vértices e índices (hasta ahora nunca he encontrado problema alguno). ¿Esto es así o sí hay que recalcular la geometría por si acaso?.
Saludos.
Hola!
Berserker, muchisimas gracias por mirarlo. Yo no supe encontrar nada : (
Ahora mismo no puedo probar lo que me dices. Mañana lo probare y te digo a ver si consigo algo, aunque no entiendo los parametros :b
Mars Attacks, ya he hecho lo que me dices, pero no me soluciono nada : (
Y sobre tu pregunta, Berserker, lo que pasa es que el MAX tiene un 'set' de indices por cada... no se como llamarlo. Me refiero a vertices, coordenadas de textura, vertices de color, etc. No es como en GL o D3D que tienes un solo indice para todo.
Creo que cuando te coinciden el numero de vertices y el de coordenadas de textura dara igual cual elijas, pero yo prefiero curarme en salud y leo siempre las coordenadas de textura, porque nunca van a haber menos que vertices ( me refiero a los indices ). Se que asi obligo a que toda la malla este texturizada, pero es que pienso que es un poco tonteria utilizar materiales sin textura.
Espero haberte ayudado. Para cualquier cosa, comentalo por aqui que estare al tanto. Yo tambien estoy muy puesto ahora con MaxScript. Creo que es la mejor eleccion para hacer herramientas para un juego.
Un saludote!!
El problema de regenerar la geometría es que consume bastante tiempo. Por ejemplo, ahí van unos numeritos recogidos con las escenas que Mars ha hecho para el test de motores:
Castillo3 (22648 vértices, 25476 triángulos)
-----------
Procesando malla sólo "cuando es necesario" -> 18 segundos
Procesando malla siempre -> 147 segundos
Castillo4 (9762 vértices, 8382 triángulos)
-----------
Procesando malla sólo "cuando es necesario" -> 12 segundos
Procesando malla siempre -> 306 segundos
La razón de que "Castillo4" tarde mucho más que "Castillo3" en procesar todos los meshes (a pesar de tener muchos menos triángulos) es que hay uno en concreto (el suelo) que tiene unos 5000 vértices y triángulos y como el tiempo crece exponencialmente pues se lleva casi todo el tiempo de proceso de la malla (unos 3 minutos o así) :D
Así que la cosa estaría en ver si realmente es necesario regenerar la malla cuando el número de vértices coincide con el de coordenadas de textura. En cuanto tenga el renderer programado lo veré (ni siquiera he empezado a programarlo aún) :)
De todas formas, si no recuerdo mal, en otras pruebas que hice hace tiempo, no regeneraba la geometría y las texturas salían bien aplicadas sobre los modelos...
Bueno, hasta aquí hemos llegado por hoy, ¡a dormiiiiiiiiiir! :P
Saludos
PD: por cierto, he estado mirando el método buildMapFaces y aunque no sé si será lo que necesitas, en la documentación da esta definición:
meshop.buildMapFaces
pero por lo que he podido comprobar, la sintaxis correcta es
meshop.buildMapFaces
y nada, utilizarlo es simplemente hacer
meshop.buildMapFaces el_nodo 1
donde el_nodo es el nodo que estas procesando (que tiene que ser un mesh editable) y 1 es el canal de mapeado de textura para las coordenadas de textura (normalmente será el 1, supongo).
Pero con 'regenerar la malla' a que te refieres? Yo no hago nada de eso y me va bien ( aunque tengo el problema que comente en el inicio de este post ). Luego probare con los castillos...
Gracias de nuevo por lo de la funcion esta : ) De aqui a poco voy a probarlo y digo algo : )
talogo!!
Pues con regenerar la malla me refiero a por ejemplo, en el caso de un cubo, tienes 8 vértices y 12 coordenadas de textura por lo que tienes que crear una nueva lista de vértices y una nueva lista de índices para que finalmente te de los 24 necesarios para poder renderizarlos con cualquier API 3D. Lo que pasa es que este caso, al parecer sólo se presenta con las primitivas estándar por que hasta ahora, todos los modelos (de personajes y objetos de juegos) que he cargado en MAX y he probado a exportar, coinciden el número de vértices con el de coordenadas de textura por lo que en teoría no sería necesario recalcular la geometría.
De todas formas, este mismo proceso lo hace flexporter y no tarda nada. La verdad es que no sé cómo lo hará (no sé si hará algún tipo de ordenación para descartar vértices más rápidamente...)
Saludos
PD: precisamente las escenas de Mars me parece que no contienen ningún mesh en el que tenga que regenerar la malla. Lo de regenerar la malla es algo que forcé para que vieras lo que me tardaría en caso de regenerar toda la escena.
Como te dije antes, no hace falta regenerar la malla. Utiliza tan solo los indices de las TVFace. Es mucho mas sencillo y sobretodo, mucho mas rapido!
Y me parece muy extraño que siempre te coincida el numero de vertices y el de coordenadas de textura. Que pasa si tienes una habitacion? Las paredes al fin y al cabo formaran un cubo... aunque no te pase nunca esto, mejor asegurarse. A mi me ha pasado mas de una vez el creer que ya tengo un exportador solido y luego verlo petar, y da mucho palo volver a ello : (
Flexporter no tarda nada porque esta hecho en C++ : ) Seguramente utilizara una tabla de hash para indexar la malla. Es lo que se suele hacer.
Ah! Ya he probado la funcion que me dijiste y parece ser que funciona!! Te quiero!! X***** :bbb Ahora mismo hare la prueba de fuego y te digo algo : )
tahora!!
¡¡Joder, tienes razón con respecto a lo de las coordenadas de textura, estoy empanaaaaaoooo!! :D
Espero que realmente fuera eso lo que buscas. La verdad es que no sabía que se podía dar el problema que mencionabas, así que si el buildMapFaces soluciona el problema, será cuestión de utilizarlo :)
Saludos
: ))))) Funcionaaaa!!! Prueba superada! :b
buildMapFaces era lo que buscaba, si : ) Muchas gracias de nuevo! Si quieres te paso mi script para que veas como 'desenrollo' la malla para utilizar un solo indice, sin necesidad de recomputar la malla. Si quieres, dame un mail y te lo envio ahora mismo.
Chaludotechs!!! :b
Bien, me alegro.
Yo aún sigo dándole vueltas al tema de las coordenadas de textura y es que no sé...tal vez no lo termino de pillar. A ver
Poniendo el caso del cubo que es el más simple.
MAX nos da:
- 8 vértices
- 12 faces
- 36 coordenadas de textura
Si yo creo la malla a partir de las faces de coordenadas de textura, ¿no me dará como resultado 36 vértices?. Cuando en realidad deberían ser 24, ¿no?.
Y es que hace un tiempo precisamente se habló de este tema en
otro thread y se hablaba de hacer lo que yo hago pero después de lo que me has dicho ya no estoy seguro :D
Te paso mi dirección por mensaje privado.
Saludos
Pues si! Tienes toda la razon x(( Pues menos mal que me lo has dicho... que putada :b
Pero sigue sin gustarme la idea de recomputar la malla... por ahora lo dejare como lo tengo, que funciona ( no todo lo bien que podria ser ), y pensare en ello. Si se te ocurre algo... :b
Gracias por tó!!
La verdad es que cuando me has dado tu solución lo he visto claro. Lo que pasa es que me ha extrañado mucho que después de haber pensado sobre el tema tanto tiempo, la cosa fuera tan "sencilla" (aunque a veces las mejores soluciones son las más simples y uno muchas veces no las ve :)). Así que cuando me he parado a pensar en lo que me has dicho he visto que algo no cuadraba...
De todas formas gracias por mandarme tu script. Siempre se aprende algo de los demás.
Saludos
En fin... me voy a poner ahora mismo a mirarlo. Si saco algo te lo digo : ) A ver si tu encuentras la solucion! Almenos hemos sacado en claro que hay que hacerlo de otra forma. Ni pa ti ni pa mi x(
Un saludote!!
Bueno, tal y como exporto yo en estos momentos, la malla queda totalmente limpia de vértices redundantes. Lo que pasa es que es un proceso lento. Por suerte, y como ya he dicho, la mayoría de las veces esta regeneración de la geometría no es necesaria por lo que en la mayoría de los casos la exportación se realiza de forma rápida.
Te he enviado la función que utilizo para regenerar la malla para que le eches un vistazo y a ver si se te ocurre alguna optimización que acelere el proceso.
Saludos
Hola Berserker!
Sorry por responder tan tarde pero últimamente estoy algo desconectado de los foros de stratos (desde el nuevo redesign, no se si tendrá algo que ver :) )
Yo he tenido bastantes peleas con lo de la consolidación de malla, y hasta hace un par de meses mi código tardaba mucho en construir la malla consolidada (lo de equiparar número de vértices a número de coordenadas de mapeado etc). Y era muy engorroso porque yo exporto bastantes canales de mapeado (3 en el peor caso). Eso unido a las normales, a los vertex colors y a los vértices en sí puede llegar a un caos tremendo.
La solución la tuve cuando implementé los smoothing groups de MAX para calcular correctamente los vertex normals (ya sabéis, un vértice puede tener varias normales según la cara desde la que se accede) y la escena queda totalmente distinta a hacerlo con o sin los smoothing groups. Mil veces mejor.
El caso es que una vez que implementé tener en cuenta el smoothing group de cada cara el hecho de luego procesar el mapeado etc para equiparar vértices salió 'gratis'. Y la consolidación de malla ahora es prácticamente instantánea aparte de optimizar mucho más la malla en cuanto a nº de vértices que antes.
Es un poco tarde para poner la explicación del algoritmo, pero no tengo problema en enviarte el código por mail si te interesa y que le eches un vistazo.
Saludos!
Ithaqua.
P.D Yo anduve durante bastante tiempo buscando solución a ésto y pensé en usar el IGameInterface o Flexporter pensando que realizaban esa tarea, pero el primero ya ví que no lo hace y el segundo creo que solamente tiene en cuenta el canal básico de mapeado, y no los demás que pueda haber. No se si tampoco calcula las normales teniendo en cuenta los smoothing groups...
Por cierto, ya se discutió un tema parecido hace bastante tiempo en
este post.
Hola Ithaqua:
Yo consegui hacer que me exportase verdaderamente rapido, pero ahora estoy intentando exportar dos juegos de coordenadas de texturas y es un coñazo. Y lo mismo con lo de las normales... no entiendo para que te sirven los smoothing groups. Lo entiendo para las normales, pero para el mapeado?? Yo si que te pediria, porfavor, algun codigo de ejemplo.
Muchas gracias!
Los smoothing groups valen para suavizar las normales de una zona de un objeto selectivamente, sin necesidad de ke todo este suavizado o no.
Citarno entiendo para que te sirven los smoothing groups. Lo entiendo para las normales, pero para el mapeado??
No era esa mi duda ; )
Hey Ithaqua. Te he dejado por mensaje privado mi dirección.
Gracias.
Mchiz: no tienen nada que ver pero resulta que el algoritmo que usé para reconstruir la malla según los smoothing groups (para que al calcular las normales hiciera las medias como debiera) permitía que introdujera sin problemas una parte de mesh consolidation.
El algoritmo funciona básicamente así:
---------------------------
Smoothing groups: Van por cara. A la hora de calcular las normales si un vértice pertenece a varias caras antes lo que hacíamos era que su vertex normal era el promediado de esas caras. Con smoothing groups se calcula la media _solamente_ para caras que tienen el mismo smoothing group.
---------------------------
Algoritmo
-Declarar los diferentes std::vector que contendrán la malla final procesada (vertices, normales, maps...).
-Declarar vector con la información de los smoothing groups.
Es una lista en la que cada elemento tiene a su vez otra lista con las distintas apariciones de ese vértice pero con diferente smoothing group. (vector<vector<struct{indicevertice, smoothingroup}>>)
Estos vértices deben ser los replicados para calcular correctamente las normales, ya que no intervienen en la media a la hora de promediar las face normals para el vértice.
for(caras)
{
smoothing group = cara.smoothinggroup.
int v[3]; // contendrá los índices de nuestra nueva cara
for(vertices en cara)
{
Para este vertice, buscar si ya está en la lista con este smoothing group.
if(no encontrado)
{
1-Añadir el vértice (indice) y su smoothing group a la lista de vectores.
2-Generar nuevo vértice en los vectores de la malla final procesada,
con su información de mapeado etc y meter el índice que ha ocupado en v[]
}
else
{
// Este vertice con su smoothing group ya ha sido procesado pero tenemos que comprobar
// si el resto de información (mapeado, vcolors, etc) es la misma.
bool mismo = true;
if(mapeado1 no es el mismo) mismo = false
if(mapeado2 no es el mismo) mismo = false
....
if(caracteristica n no es igual) mismo = false
if(mismo == true)
{
// Ya tenemos este vértice en nuestra lista, ahora se accede a él desde diferente cara
// Lo que hacemos es simplemente indexar el mismo en v[]
}
else
{
// El vértice es geométricamente el mismo, pero sus mapeados etc son distintos
// Generamos un nuevo vértice como en el paso 2 de if(no encontrado) y lo indexamos en v[].
}
}
Añadir cara(v) a la lista de caras.
}
-------------------
P.D Berserker: Te envío el código con la explicación por mail :)
Muchas gracias Ithaqua
Por cierto,
Mchiz: El esqueleto de ese código sirve para procesar los smoothing groups, pero como puedes ver en el if(encontrado) { } else { AQUI } se procesa el tema de que un vértice puede tener distintos mapeados según la cara. En caso de tenerlo hay que replicarlo, porque sino saldría mal.
En definitiva, MAX podría hacer ese curro por nosotros pero... :)
Y digo yo.
Si MAX tiene que trabajar internamente con uns lista de vértices, colores, normales, etc "compatible" con OpenGL o Direct3D (porque si no no podría renderizar los objetos correctamente, claro). ¿Por qué demonios no nos dan ya la lista "correcta"?. ¡O por lo menos que den las dos posibilidades!
Es que este tema es un coñazo, de verdad :D
Saludos
Muchas gracias Ithaqua! Tendre que mirar como 'estan hechos' los smoothing groups porque nunca los he tocado ;bbb
Gracias!!
Berseker, sobre los 36 vertices q salen en un cubo, la cosa es sencilla
6 caras* (2 triangulos/cara)* (3 vertices/triangulo) = 36 vertices, y esto te pasara siempre a menos q los vertices compartan uv's
Saludos,
Toni aka Tag
En realidad, lo normal es que un cubo esté formado por 24 vértices (6 caras * 4 vértices por cara) y 36 índices...
Esos 36 vértices sería si no utilizas índices, lo cual es poco recomendable (un cubo vale, pero un modelo con miles de vértices...)
Saludos