Unity Spain

Post Antiguos => General (Antiguo) => Mensaje iniciado por: ftejada en Noviembre 05, 2018, 06:36:54 PM

Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: ftejada en Noviembre 05, 2018, 06:36:54 PM
Hola a todos,
 
Sabemos que la escala de un gameObjet es totalmente independiente de su Tamaño real en nuestras escenas. Por ejemplo un Cubo con la malla por defecto de Unity con la escala (1,1,1) tiene un Tamaño Real en cada uno de sus EjesLocales de 1 (metro). Pero otro cubo que tenga otra malla modelada en otro programa con escala de su gameObject (1,1,1), puede tener cualquier tamaño Real en cada uno de sus EjesLocales... por ejemplo 2 (metros). Lo que nos daria un Cubo el doble de grande que el que tiene la malla por defecto de Unity
 
En la escena tengo un cubo y una esfera (con malla por defecto de Unity) y necesito darles el mismo tamaño "Real" en el mundo que un cubo y una esfera con mallas de otro programa. Pero no encuentro una manera totalmente precisa de hacerlo, ya que la escala de sus gameObjects en ambas parejas, (Cubo y Esfera con malla por defecto de Unity) y (Cubo y Esfera con mallas importadas "con tamaño indeterminado), sería de (1,1,1).
 
¿Existe alguna manera de poder saber el tamaño Real exacto dentro de nuestra escena de un objeto independientemente de la escala que tenga? mediante script, claro está!
 
 
 
Saludos y gracias de antemano.
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: francoe1 en Noviembre 05, 2018, 07:06:19 PM
Se me ocurre para una esfera tomar x vértice y luego calcular las distancias con todos los vértices y obtener el de mayor distancia, en una esfera funcionaria correctamente, en un cubo tendrías que limitar el valor de x & z para que se tome el vértice más lejano en line recta.
 
¿Se entiende?
 
Al final tendrás la distancia desde el primer punto al último y esa será tu escala real.
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: ftejada en Noviembre 05, 2018, 08:24:04 PM
Cita de: francoe1 date=1541441179Se me ocurre para una esfera tomar x vértice y luego calcular las distancias con todos los vértices y obtener el de mayor distancia, en una esfera funcionaria correctamente, en un cubo tendrías que limitar el valor de x & z para que se tome el vértice más lejano en line recta.
   
   
      ¿Se entiende?
   
   
      Al final tendrás la distancia desde el primer punto al último y esa será tu escala real.
   


mmmm Parece buena idea... Voy a tantearla en estos días a ver que saco en claro.
 
Gracias @francoe1
 
 
 
Si a alguien se le ocurre más ideas estoy abierto a más sugerencias
 
 
 
Saludos
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: Igor en Noviembre 05, 2018, 09:57:57 PM
el componente meshFilter contine el "mesh" que contiene los vertices del modelo... cada vertice es un verctor3 con su posicion "real" respecto a su pivot o gizmo...
 
puedes pedir la "magnitude" de los verrtices para ver como de lejos estan del centro...
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: lightbug en Noviembre 06, 2018, 02:17:32 AM
Lo que dice @francoe1 es lo que iba a decir, para agregar si querés podés normalizar todo a la unidad (como Unity por default) en base a la componente máxima del arreglo podés hacer, para el cubo Por ej:
 

* Cubo
Sin normalizar:
(Por ej en X)
X_min = - 2.75
X_max = 2.75
Lado = 5.5
Con |X_max|=|X_min| = 2.75

 
Si querés dejar al x max y min en 0.5 vas a terminar normalizar al vértice, osea dividir por 2 * |X_max|
 

v_n = v / ( 2 * |X_max|  )
Normalizado:
x_min_n = - 2.75 / 5.5 = - 0.5
x_max_n = 2.75 / 5.5 = 0.5

 
Con la esfera es más facil todavía.
 
: )
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: juanma_teso en Noviembre 06, 2018, 02:21:40 PM
Has mirado ya la propiedad bounds? Creo recordar que podías sacar un cubo que envuelve la malla fácilmente...
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: Igor en Noviembre 06, 2018, 10:49:41 PM
Cita de: juanma_teso date=1541510500Has mirado ya la propiedad bounds? Creo recordar que podías sacar un cubo que envuelve la malla fácilmente...
   


eso de los bounds es buena... no se me habia ocurrido...
 
...creo que el box collider se "setupea" asi al asignarlo... creo que coje las medidas de los bounds...
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: lightbug en Noviembre 06, 2018, 11:36:16 PM
Cita de: juanma_teso date=1541510500Has mirado ya la propiedad bounds? Creo recordar que podías sacar un cubo que envuelve la malla fácilmente...
   


Es buena, siempre y cuando tengas un collider asociado, no se si podés obtener algo parecido con Mesh.
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: ftejada en Noviembre 07, 2018, 07:14:13 PM
Gracias a todos por las ideas!
 
Voy a probar que tal va... de todos modos me surgen algunas dudas acerca del consumo que requeriria calcular la distancia entre muchisimos vertices ( por ejemplo los de una esfera que tiene unos cuantos)... Tengo entendido que calcular la distancia es bastante costoso en terminos de rendimiento debido a la raiz cuadrada.
 
Por Bound he estado haciendo unas pequeñas pruebas y parece que en cuanto rotas un objeto los valores cambian ya que la caja delimitadora nunca gira con los ejes y la Api de Unity no provee de unas variables con la posicion exacta de cada Bound para poder calcular todo manualmente ayudandonos con el centro...
 
Parece que la mejor via de conseguirlo es mediante lo que dijo francoe1... voy a seguir tanteando...
 
 
 
Saludos
 
 
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: Igor en Noviembre 07, 2018, 09:54:52 PM
los vertex de un mesh son directamente Vector3... si les pides la "magnitude" es la distancia...
 

//la distancia es directamente:
vertices[numeroDeVertice].magnitude;
//haces un bucle for...
Vector3 vertices = mesh.vertices;
float maxDistance = 0;
for (int i=0; i<vertices.Lentgth; i++) {
    if (vertices[i].magnitude > maxDistance) {
        maxDistance = vertices[i].magnitude;
    }
}
Debug.Log("distancia"+maxDistance);//mostrar en consola
  
//con eso encontrarias la distancia del vertice mas lejano del centro del objeto...

 
 
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: francoe1 en Noviembre 07, 2018, 11:30:25 PM
Cita de: Igor date=1541624092los vertex de un mesh son directamente Vector3... si les pides la "magnitude" es la distancia...
   
   

//la distancia es directamente:
vertices[numeroDeVertice].magnitude;
//haces un bucle for...
Vector3 vertices = mesh.vertices;
float maxDistance = 0;
for (int i=0; i<vertices.Lentgth; i++) {
    if (vertices[i].magnitude > maxDistance) {
        maxDistance = vertices[i].magnitude;
    }
}
Debug.Log("distancia"+maxDistance);//mostrar en consola
  
//con eso encontrarias la distancia del vertice mas lejano del centro del objeto...

   
       
   


En una esfera esto funciona, el problema se presenta en 1 cubo o formas irregulares donde la distancia perpendicular es mayor que la distancia recta.
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: lightbug en Noviembre 08, 2018, 01:45:33 AM
Cita de: ftejada date=1541614453Voy a probar que tal va... de todos modos me surgen algunas dudas acerca del consumo que requeriria calcular la distancia entre muchisimos vertices ( por ejemplo los de una esfera que tiene unos cuantos)... Tengo entendido que calcular la distancia es bastante costoso en terminos de rendimiento debido a la raiz cuadrada.
   


No para nada, es una relativamente una papita por sí solo, dependerá del número de vértices y de la arquitectura del CPU (ya hablando más hardcore) que calcule esas distancias, pero no es preocupante ...además lo vas a hacer una sola vez (supongo). Y como todo, lo mejor es probar y sacarte la duda.
 
Igual no es necesario calcular las distancias de todos los puntos, tenés que encontrar el valor más alto del arreglo de vértices, una vez tengas eso y sepas que el objeto originalmente está (y va) centrado lo que te resta es hacer un escalamiento manual o modificar su localScale si quisieras.
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: J Montes en Noviembre 09, 2018, 03:31:19 PM
Explorar todos los vértices puede ser un poco excesivo. Si lo vas a usar a menudo yo creo que deberías precalcular el tamaño en tu MonoBehavior. Por ejemplo implementando la medida de tamaño como una Editor Tool.
 
De todas formas, Unity ya hace ese trabajo.  Yo intentaría usar los bounds como dijo @juanma_teso. De la documentación de Mesh.bounds: 
 
 
 



   
      This is the axis-aligned bounding box of the mesh in its local space (that is, not affected by the transform). Note that the Renderer.bounds (https://docs.unity3d.com/ScriptReference/Mesh-bounds.html) property is similar but returns the bounds in world space.
   

[/quote]
 
Y si sabes que se trata de un cubo o una esfera, puedes obtener el tamaño de la propiedad mesh.bounds.size. Como la matriz de transformación no está aplicada a los bounds (esto lo hace el Renderer en cada ciclo), tendrás que multiplicar ese vector por transform.lossyScale (https://docs.unity3d.com/ScriptReference/Transform.html) para tener las dimensiones en world coordinates.
 
Cita de: ftejada date=1541614453Por Bound he estado haciendo unas pequeñas pruebas y parece que en cuanto rotas un objeto los valores cambian ya que la caja delimitadora nunca gira con los ejes y la Api de Unity no provee de unas variables con la posicion exacta de cada Bound para poder calcular todo manualmente ayudandonos con el centro...
   


Los bounds de un Mesh nunca cambian, porque son los bounds axis-aligned, esto es, siempre ortogonales, en sus coordenadas locales. Estos bounds se usan para calcular en "grueso" las colisiones, el clipping... pero se transforman a través de la matriz de transformación del objeto para realizar estos cálculos. Después, la GPU usa esa misma transformación para proyectar cada vértice del objeto a sus coordenadas en word space. 
 
Y esto debería servirte si lo que necesitas es la escala del objeto, que para una esfera o cubo se puede deducir de su AABB (axis-aligned bounding box).
 
Pero las esferas son un caso un poco especial. Al estar trianguladas, el tamaño de su AABB varía levemente en función de su orientación. Y en función de cómo esté modelada, la medida de su Mesh.bounds podría ser menor que su radio real. Si no puedes predecir este efecto, tendrías efectivamente que evaluar cada vértice para saber cuál es el más alejado.
 
Dependiendo de tu caso de uso, podría interesarte usar Renderer.bounds en lugar de Mesh.bounds, pero Renderer.bounds sí irá cambiando de tamaño a medida que el objeto rota, sea un cubo o una esfera triangulada (de hecho sólo una esfera perfecta no cambiaría su Renderer.bounds al rotar, y no hay esferas perfectas en un rasterizador de triángulos). De nuevo, depende de tu caso de uso, pero si se trata de escalarlos para que tengan el mismo tamaño, yo creo que podrías usar los bounds.
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: Igor en Noviembre 09, 2018, 04:14:34 PM
no sabia que los mesh bounds eran diferentes a los renderer bounds... 
 
esta bien saberlo... quizas pueda ser util alguna vez...
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: ftejada en Noviembre 12, 2018, 07:49:29 AM
Hola a todos y muchas gracias por los aportes!!!
 
Cita de: Igor date=1541624092los vertex de un mesh son directamente Vector3... si les pides la "magnitude" es la distancia...
   


respecto a lo que dijo Igor, concuerdo con francoe1, la magnitud de la posición de cada vertice, solo serviría para esferas "totalmente redondas". En cuanto la esfera tuviese una escala distinta en alguno de sus ejes o en otras figuras irregulares... no parece ser una solución
 
 
 
Cita de: J Montes date=1541773879Y si sabes que se trata de un cubo o una esfera, puedes obtener el tamaño de la propiedad mesh.bounds.size. Como la matriz de transformación no está aplicada a los bounds (esto lo hace el Renderer en cada ciclo), tendrás que multiplicar ese vector por transform.lossyScale (https://docs.unity3d.com/ScriptReference/Transform.html) para tener las dimensiones en world coordinates.
   


 J Montes he estado probando lo que dijiste y va perfecto para los cubos... no tenia ni idea de que multiplicandolo por su lossyScale podría conseguirlo, por eso cuando estuve probando no me servia esta solución ya que no lo estaba haciendo bien. Siguiendo tu información he hecho algo así.
 
 


targetMeshBounds = gameObjectTarget.GetComponent<MeshFilter>().mesh;
 
//....
 
Vector3 sizeBoundsTarget = targetMeshBound.bounds.size;
Vector3 nSize;
nSize.x = Target.transform.lossyScale.x * size.x;
nSize.y = Target.transform.lossyScale.y * size.y;
nSize.z = Target.transform.lossyScale.z * size.z;
 
transform.localScale = nSize;

 
También lo he estado probando con esferas y parece ir perfecto también aunque la esferaTarget tenga escalas diferentes en cada eje X, Y, Z... Es cierto que he notado que la escala no es totalmente exacta, pero es más que suficiente para lo que necesito, ya que la perdida de precisión es como de 0.000001 o algo asi... supongo que es a esto a lo que te referias con si no dimelo pq con las prubas que he hecho parece bastante preciso y no representaría un problema para mi:
 
Cita de: J Montes date=1541773879Pero las esferas son un caso un poco especial. Al estar trianguladas, el tamaño de su AABB varía levemente en función de su orientación. Y en función de cómo esté modelada, la medida de su Mesh.bounds podría ser menor que su radio real. Si no puedes predecir este efecto, tendrías efectivamente que evaluar cada vértice para saber cuál es el más alejado.
   


 
 
 
 
Otro cantar parece ser con figuras como los cilindros, en los que la altura de este siempre se incrementa al doble ya que al final le estamos pasando el tamaño del bound.y a la escala del otro objeto... por lo que si es un cilindro conviene dividir el bound.y/2
 
¿Existe alguna manera de poder modificar el mesh.bounds.size de una malla para que cambie su tamaño en vez de andar tocando la escala de su transform?
 
Saludos
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: Igor en Noviembre 12, 2018, 12:15:46 PM
Cita de: ftejada date=1542005369 
   
   
      ¿Existe alguna manera de poder modificar el mesh.bounds.size de una malla para que cambie su tamaño en vez de andar tocando la escala de su transform?
   
   
       
   


si, tal como has puesto:
 

mesh.bounds = new Bounds(vector3 center, vector3 half_Extend);
le das el centro y la distancia a cada lado (la mitad del ancho, alto y largo.... como si fuese radio.... pero de un cubo...)

 
 
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: ftejada en Noviembre 12, 2018, 01:03:14 PM
Cita de: Igor date=1542021346si, tal como has puesto:
   
   

mesh.bounds = new Bounds(vector3 center, vector3 half_Extend);
le das el centro y la distancia a cada lado (la mitad del ancho, alto y largo.... como si fuese radio.... pero de un cubo...)

   
       
   


@Igor He probado a hacer lo que dices pero la malla no cambia de tamaño, al menos visiblemente en la pantalla:
 

   Vector3 size = meshTarget.bounds.size;      
Vector3 nSize;
        nSize.x = Target.transform.lossyScale.x * size.x;
        nSize.y = Target.transform.lossyScale.y * size.y;
        nSize.z = Target.transform.lossyScale.z * size.z;
        mesh.bounds = new Bounds(mesh.bounds.center, nSize / 2);

 
Supongo que no estaré utilizandolo bien... 
 
 
 
Saludos
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: Igor en Noviembre 12, 2018, 04:15:04 PM
los Bounds son una caja (cubo) imaginaria que envuelve el objeto... aumentar su tamaño no afectara al mesh....
 
para cambiar el tamaño del mesh usa:
 

transform.localScale = new Vector3(sizeX, sizeY, sizeZ);

 
 o tambien puedes alterar el mesh... con un bucle "for" que recorra los vertices...
 

void Start() {
  float scale = 1.5f;//por ejemplo
  Mesh mesh = GetComponent<MeshFilter>().mesh;
  Vector3[vert] = mesh.vertices;
  for (int i=0; i<mesh.vert.Length; i++){
     vert[i] *= scale;
  }
  mesh.vertices = vert;
  GetComponent<MeshFilter>().mesh = mesh;
}

 
 
 
pero lo que pasa es que no comprendo que quieres hacer exactamente....
 
...voy a volver a releer el post a ver si me he perdido algo...
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: J Montes en Noviembre 12, 2018, 11:24:48 PM
Cita de: ftejada date=1542005369También lo he estado probando con esferas y parece ir perfecto también aunque la esferaTarget tenga escalas diferentes en cada eje X, Y, Z... Es cierto que he notado que la escala no es totalmente exacta, pero es más que suficiente para lo que necesito, ya que la perdida de precisión es como de 0.000001 o algo asi... supongo que es a esto a lo que te referias con si no dimelo pq con las prubas que he hecho parece bastante preciso y no representaría un problema para mi:
   


No he entendido bien en qué casos tienes esferas modeladas con diferentes escalas X, Y y Z, pero si te funciona... vale :).  
 
Cita de: ftejada date=1542005369

Vector3 sizeBoundsTarget = targetMeshBound.bounds.size;
Vector3 nSize;
nSize.x = Target.transform.lossyScale.x * size.x;
nSize.y = Target.transform.lossyScale.y * size.y;
nSize.z = Target.transform.lossyScale.z * size.z;

   
       
   


Una nota: multiplicar un vector(x, y, z) por otro (a, b ,c) para obtener (x * a, y * b, z * c) es una operación común entre vectores (y siempre hay que pensar que en el tema vectores y matrices está todo inventado). Vector3.scale (https://docs.unity3d.com/ScriptReference/Vector3.Scale.html) multiplica dos Vector3 componente a componente. Ese fragmento queda más compacto y legible así:
 

Vector3 nSize = Vector3.scale(targetMeshBound.bounds.size, size);




   
      ¿Existe alguna manera de poder modificar el mesh.bounds.size de una malla para que cambie su tamaño en vez de andar tocando la escala de su transform?
   

[/quote]
 
Si lo que quieres es que cambie de tamaño, no puedes usar los bounds. Los bounds como te dice @Igor son la caja imaginaria, siempre alineada con los ejes, que comprende al objeto. Se usan para acelerar los cálculos de colisiones, para ordenar la cola del renderer para que las cosas más lejanas se dibujen antes, para  clipping (no dibujar objetos que están fuera de cámara), etc. 
 
En general no deberías modificar los bounds a mano, Unity los recalcula cuando es necesario en función del Mesh que contienen.
 
 
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: ftejada en Noviembre 17, 2018, 04:20:32 PM
Ok... Pensaba que al cambiar el tamaño de los bounds cambiaba el tamaño de la malla. @J Montes Gracias por la apreciación... con Vector3.scale el codigo está mas limpio...
 
Cita de: J Montes date=1542061488No he entendido bien en qué casos tienes esferas modeladas con diferentes escalas X, Y y Z, pero si te funciona... vale :).  
   


@J Montes Me refería a cuando una esfera no es totalmente redonda... por ejemplo  y alguno de sus ejes de (localScale) es de tamaño distinto
 
 
 
 
 
Cita de: Igor date=1542035704o tambien puedes alterar el mesh... con un bucle "for" que recorra los vertices...
   
   

void Start() {
  float scale = 1.5f;//por ejemplo
  Mesh mesh = GetComponent<MeshFilter>().mesh;
  Vector3[vert] = mesh.vertices;
  for (int i=0; i<mesh.vert.Length; i++){
     vert[i] *= scale;
  }
  mesh.vertices = vert;
  GetComponent<MeshFilter>().mesh = mesh;
}



Es posible que esto me pueda servir, aunque en principio solo para figuras donde el tamaño deba aumentar o disminuir por igual en todos sus lados... gracias @Igor
 
 
 
 
 
Saludos
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: francoe1 en Noviembre 17, 2018, 04:33:44 PM
@ftejada  ¿Estás buscando algo como Scale Factor de las propiedades de importación?
 
https://docs.unity3d.com/Manual/FBXImporter-Model.html (https://docs.unity3d.com/Manual/FBXImporter-Model.html)
Título: ¿Como puedo obtener el tamaño exacto de una esfera o cubo?
Publicado por: ftejada en Noviembre 19, 2018, 11:59:50 AM
Cita de: francoe1 date=1542468824@ftejada  ¿Estás buscando algo como Scale Factor de las propiedades de importación?
   
   
      https://docs.unity3d.com/Manual/FBXImporter-Model.html (https://docs.unity3d.com/Manual/FBXImporter-Model.html)
   


No. Esto lo estuve tanteando pero no sirve para lo que necesito. Esto lo reescalaria a nivel general y hay veces que necesito reescalar solo el tamaño de alguno de los ejes... Por no mencionar el hecho de que no sabría cuanto reescalarlo respecto a otra malla cuando vienen con distintos tamaños reales de otros programas 3d..
 
Por ejemp, si tengo un cubo con todos sus lados iguales y debo adaptarlo a otro cubo que tiene dos lados iguales (x, y) pero uno más grande (z) formando un rectangulo más que un cubo, no podría hacerlo. Aparte usar Scale Factor creo que me plantearia otros problemas...
 
Gracias por el aporte @francoe1