4 minute read

Nos adentramos en la septima semana del blog. Este blog estará dedicado al modelado 3D y concretamente se utilizará Blender.

Modelado

Los siguientes automóviles han sido modelados mediante Blender.

Auto 1

Back

Coche

Front

Coche

Left

Coche

Top

Coche

Auto 2

Back

Coche

Front

Coche

Left

Coche

Top

Coche

Texturizado

El siguiente texturizado ha sido realizado mediante Blender.

Auto 2

Back

Coche

Front

Coche

Left

Coche

Top

Coche

Colisiones

Sencilla
Compleja

Me encuentro ante el siguiente problema. Siguiendo los pasos para poner mallas de colisión en Blender (UCX_Name_Number) para que funcione en A-frame no se obtienen resultado, es más, se observa el objeto que ha sido definido como la malla de colisión en Blender.

error

Es cierto que los tutoriales observados exportan el modelo como .fbx, pero no logro importarlo con esta extensión en nuestra escena A-frame. Finalmente, ha sido importado con esta extensión y sigue sin dar el resultado deseado.

Por otro lado, he observado que en formas geometricas sencillas funciona el siguiente código, por tanto, probablemente en caso de tener el objeto en si mismo una malla ese código permitiría integrarla en nuestra escena.

    ammo-body="type: dynamic; 
    emitCollisionEvents: true;" 
    ammo-shape="fit: all" * fit: all

ammo-shape

  • type: sphere

ammo-shape

Por tanto, el gran problema ante el que me encuentro es que siguiendo los tutoriales que hablan sobre la creación de una malla de colisión en Blender no me es posible hacer que funcionen correctamente en A-frame. Una posible solución sería introducir diversas entidades, invisibles, en nuestro modelo 3D para acercarnos lo máximo posible a su geometría. A continuación, se encuentra la escena correspondiente al siguiente código:

<a-scene physics="driver: ammo; 
debug: true; 
debugDrawMode: 1;"
background="color: pink">
    <a-entity camera position="0 3 5" look-controls wasd-controls></a-entity>
    <!-- Suelo -->
    <a-plane 
    ammo-body="type: static" 
    ammo-shape="type: box"
    position="0 -3 -10" rotation="-90 0 0" width="30" height="12"
    color="yellow"></a-plane>

    <!-- Bola -->
    <a-entity geometry="primitive: box" material="color: red" position="0 5 -10"
    ammo-body="type: dynamic; 
    emitCollisionEvents: true;" 
    ammo-shape="type: box"
    >
        <a-entity geometry="primitive: box" material="opacity: 0.0" scale="2 0.5 1" position="0 -0.5 0"
        ammo-body="type: dynamic; 
        emitCollisionEvents: true;" 
        ammo-shape="type: box"
        ></a-entity>
        <a-entity geometry="primitive: box" material="color: blue" scale="2 0.5 1" position="0 0.5 0"
        ammo-body="type: dynamic; 
        emitCollisionEvents: true;" 
        ammo-shape="type: box"
        ></a-entity>
    </a-entity>

</a-scene>

idea

La conclusión a la que llego es que puede tratarse de una solución para entidades estaticas con formas poco convencionales, como un sofá, ya que a pesar de ser entidades padre-hijo pueden separarse por las físicas de la escena. Ya que en aquellas que hay movimiento se pierden las referencias debido a las físicas, es decir, los movimientos de las entidades depende de las físicas siempre que las haya, ya que aunque pongamos una condición esta deja de cumplirse. Además, si usamos diversas entidades para crear nuestra malla de colisión, en caso de ser dinamicas, chocarán entre sí.

Duda: ¿Los coches sufren las físicas convencionales en nuestro juego?

Exportación del modelo 3D

Se ha de modificar el sufijo del archivo a .gltf y de este modo podrá ser utilizado en A-frame.

Exportar

Exportar

Nota:

La opción Selection only permite almacenar el objeto seleccionado y en caso de no tener seleccionada la casilla se guardaran todos los objetos de la escena.

Importación del modelo 3D a A-frame

El siguiente código permite importar modelos 3D a escenas de A-frame de manera sencilla.

<!DOCTYPE html>
<html>
  <head>
    <script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
  </head>
  <body>
    <a-scene>
        <a-assets>
            <a-asset-item id="car" src="assets/car.gltf"></a-asset-item>
        </a-assets>
        <a-entity position="0 0 -10" gltf-model="#car"></a-entity>
    </a-scene>
  </body>
</html>

El resultado del código anterior puede observarse en la siguiente imagen.

Importar

¿Cómo es la malla de colisión del objeto?

A continuación, va a observarse la malla de colisión del modelo 3D creado anteriormente. Es importante tener en cuenta como otorgamos la malla de colisión, ya que es al indicar ammo-shape cuando la determinamos. El ‘problema’ es que no nos encontramos ante una primitiva sencilla, sino a un modelo 3D complejo.

    ammo-body="type: dynamic; 
    emitCollisionEvents: true;" 
    ammo-shape="type: box;fit: manual"

Fallo

Entre las posibles preguntas encuentro si podemos determinar una malla de colisión perfecta para nuestro objeto, pero no encuentro el modo de hacerlo. Por ello, considero que la solución adecuada es encapsular nuestros elementos en la forma geometria que mas convenga. Como podemos observar en la siguiente imagen la malla de colisión no es perfecta, pero se ajusta a nuestro coche bastante.

    ammo-body="type: dynamic; 
    emitCollisionEvents: true;" 
    ammo-shape="type: box;fit: manual; halfExtents: 1.5 2 3.7; offset: 0 0 -0.3"

Fallo

Nota:

He observado que Blender puede realizar mallas de colisión, pero no veo la posibilidad de introducirla en ammo-shape Opciones:

Hull (hull) – Wraps a model in a convex hull, like a shrink-wrap. Not quite as performant as primitives, but still very fast. Hull Approximate Convex Decomposition (hacd) – This is an experimental feature that generates multiple convex hulls to approximate any convex or concave shape. Volumetric Hull Approximate Convex Decomposition (vhacd) – Also experimental, this is hacd with a different algorithm. See: http://kmamou.blogspot.com/2014/11/v-hacd-v20-is-here.html for more information. Mesh (mesh) – Creates a 1:1 concave collision shape with the triangles of the meshes of the entity. May only be used on static bodies. This is the least performant shape, however they can work very well for static environments if the following is observed:

Avoid using meshes with very high triangle density relative to size of convex objects (primitives and hulls) colliding with the mesh. E.g. avoid meshes where an object could collide with dozens or more triangles in a single spot.
Avoid very high poly meshes in general and use mesh decimation (simplification) if possible.

Heightfield (heightfield) – Similar to a mesh shape, but you must provide an array of heights and the distance between those values. E.g. heightfieldData: [[0, 0, 0], [0, 1, 0], [0, 0, 0]] and heightfieldDistance: 1 will create a 3x3 meter heightfield with a height of 0 except for the center with a height of 1.

Importación del modelo 3D a A-frame

El siguiente código permite importar modelos 3D a escenas de Networked A-frame de manera sencilla.

    <a-asset-item id="car" src="own_asset/car.glb"></a-asset-item>

    <template id="car-template">
      <a-entity 
      class="raycastable" 
      gltf-model="#car"
      material="color: red" 
      position="0 10 -10" 
      ></a-entity>
    </template>

Importar