Saltar al contenido principal

W - I -React Native 3D

React Native

React Native es un framework JavaScript para crear aplicaciones reales nativas para iOS y Android, basado en la librearía de JavaScript React para la creación de componentes visuales

Expo vs Cli

Las aplicaciones React Native CLI requieren macOS para crear aplicaciones iOS, lo que significa que los usuarios de Windows no pueden desarrollar aplicaciones iOS sin algunas soluciones provisionales.

Expo evita por completo esta limitación al ofrecer un servicio alojado llamado EAS Build para crear binarios de aplicaciones para sus proyectos Expo y React Native. Esto abre un mercado completamente nuevo para los usuarios de Windows y Linux.

También automatiza y facilita el proceso de creación al proporcionar valores predeterminados configurados para proyectos Expo y React Native, así como también maneja las credenciales de firma de su aplicación, proporcionando la forma más rápida de implementar en las tiendas de aplicaciones. Puede enviar aplicaciones directamente desde su CLI usando EAS Enviar.

Requisitos

  • Node
  • Expo
  • React native
  • Cuenta en expo

Uso de 3D

Uso de opengl

Para el uso de open gl, a diferencia de web que es webgl, necesitamos un visor que muestre objectos en 3D, en react native existe la herramienta la cual es gl-view

https://docs.expo.dev/versions/latest/sdk/gl-view/

La cual nos ayuda a mostrar objetos en 3d, lo cual esta limitado a figuras geometricas, y no a modelos

Uso de modelos

Para el uso de modelos, se usan una herramienta que puede ayudarnos las cuales son threejs, pero no funciona todos sus puntos de manera efectiva.

Para poder agregarlo se puede con expo-three

https://github.com/expo/expo-three

de esta manera puedes agregar modelos

Advertencia

Algunas paginas o videos te diran que ocupes react three fiber

https://docs.pmnd.rs/react-three-fiber/getting-started/introduction

si se puede ocupar hasta un punto, es mejor ocuparlo como lo marca expo-three, dado que en desarrollo funciona correctamente, porque es un servidor, pero en producción las apk no funcionan de la misma manera, dado que ya no es un servidor, y se rompe cuando llega al modelo, asi que tal vez funcione si se manden a llamadar desde algun space los modelos y texturas, pero de manera local no funciona.

Carga de modelos

Cuando se cargan modelos, movil, se puede ocupar cualquier tipo solo que es muy dificil hacer que funcione, con glb, gltf y fbx, es recomendable usar obj

Configurar metro

Primeramente necesitas modificar lo que es metro, que es indicar como leer otro tipo de extensiones mas información en https://docs.expo.dev/guides/customizing-metro/

const { getDefaultConfig } = require('expo/metro-config');

const config = getDefaultConfig(__dirname)

config.resolver.assetExts.push("obj", "mtl", "xpng", "xjpg");

module.exports = config;

Expo assets

Para cargar algunos assets se necesita expo assets, para generar un ulr de donde se encuentra tu assets como file//archivo.

https://docs.expo.dev/versions/latest/sdk/asset/

Codigo three

Para acceder a glview, llamas al componente react, y en onContextCreate agregar un method, no acepta clases solo methods

<GLView

style={{ height: "100%", width: "100%" }}

onContextCreate={onContextCreate}

/>

Codigo de three, a diferencia de web, que se usa el windows, con las propiedades clientHeight y clientWidth, en gl, viene drawingBufferWidth y drawingBufferHeight

// importaciones
import ExpoTHREE, { Renderer, TextureLoader } from "expo-three";
const onContextCreate = async (gl) => {
 // Scene
 const scene = new Scene();
 // Camara
const camera = new PerspectiveCamera(
75,
gl.drawingBufferWidth / gl.drawingBufferHeight,
0.1,
1000
);

gl.canvas = {
width: gl.drawingBufferWidth,
height: gl.drawingBufferHeight,
};

camera.position.z = 2;
const ambientLight = new AmbientLight(0xffffff);
ambientLight.intensity = 1;
 scene.add(ambientLight);

 // renderer
const renderer = new Renderer({ gl });
renderer.setSize(gl.drawingBufferWidth, gl.drawingBufferHeight);
 // -- codigo que sigue --
 // - va al final

 const render = () => {
requestAnimationFrame(render);
renderer.render(scene, camera);
gl.endFrameEXP();
 };

// call render
render();
}

Cargar modelo

// react native lo pide los assets con require

let model = require("../../assets/model/model.obj");

// necesitamos el localUri que es file//assets, donde se encuentra guardado

const [{ localUri: localObj }] = await Asset.loadAsync(model);

// textura, tiene que tener xpng, mas adelante se explica, aqui se usa la

// textureLoader de expo-three no de three directamente

let textures = require("../../assets/texture/texture.xpng");

const texture1 = new TextureLoader().load(textures);

// se pasa por un mesh que quieras, la mayoria usa meshPong

texture1.magFilter = NearestFilter;

texture1.minFilter = NearestFilter;

material = new MeshPhongMaterial({
map: texture1,
flatShading: true,
emissiveIntensity: 0,
shininess: 0,
reflectivity: 0,
});

// viene de three
const loader = new OBJLoader();

loader.load(
localObj,
function (object) {

childFuntion(object, material, 0);
objectModel = object;
actionActiveButton(true);
scene.add(object);
},

function (xhr) {},
function (error) {}
);

Advertencia de codigo

Para poder cargar los modelos obj, consiste en varias cosas, como obj, mtl y una textura.

  1. obj => es importante
  2. mtl => no es tan relevante, cuidado con el mismo nombre
  3. texture => tiene que ser en png y luego cambiar la extension manualmente a xpng

Para poder cargar los modelos obj, consiste en varias cosas, como obj, mtl y una textura.

Extension xpng

La extension para cargar imagenes regulamente es png, pero cuando la guarda en la apk, la guarda de manera diferente entonces al final la apk, le el nombre de la imagen y no la ruta, de la imagen como file//assets, eso se debe a que android no guarda la ruta, para que lo haga, se necesita poner xpng que es una forma de decirle que lo guarde en el drawer que es el cache del apk, para mas información aqui https://github.com/expo/expo-three/issues/185#issuecomment-732161813

Cargar modelos glb, gltf, fbx

Es algo dificil porque sucede lo mismo, pero existe la manera de hacerlo, eso ya no lo pude probar, pero esta persona fue quien resolvio las dudas de xpng y el porque falla algunos modelos

https://github.com/expo/expo-three/issues/151#issuecomment-904532776

Mover un modelo sobre la pantalla

Es algo dificil porque no lo lograron como tal, dado que se sobre pone los gestos de pantalla contra los gestos de mover modelos, asi que logras mover el modelo, perderas la funcionalidad de dar tap, pero puedes poner los gestos de pantalla de expo gesture y con eso podrias aplicar el movimiento, pero atraves de orbit controls no se puede

Cuidado con nombres repetidos

Cuando se compila android pasa los assets a un metodo el cual, no pregunta el tipo solo lo guarda, entonces cuando son extensiones poco comunes como mtl, obj, android no entienden la diferencia por la extension entonces verifica el nombre, si encuentra texture.png y textura.jpg, el comprende que son dos imagenes, pero estas teniendo duplicado de assest y falla, entonces cuando te pasen el obj viene con un nombre que es mtl, y al compilar genera el duplicado. https://stackoverflow.com/questions/53239705/react-native-error-duplicate-resources-android

yarn

usarlo, porque en algunos puntos, cuando instalas algo yarn se encarga de hacer la instalación de dependencias, y npm no.

Link de proyectos de guia

https://github.com/kyaroru/RNExpoThree

https://github.com/aaronbesson/Space-Walker-3D

https://github.com/EvanBacon/Expo-Crossy-Road

El futuro del 3d nativo

Flutter

https://docs.flutter.dev/

React native

Muchos dicen que si se puede, usando open gl, pero no dicen que a un tiene muchas deficiencias y poco control a parte de poner un modelo y ya.

Librerias

https://github.com/BonnierNews/react-native-3d-model-view

https://github.com/rastapasta/react-native-gl-model-view

Existen muchas librerias que facilitan ese problema, pero sucede que son librerias pasadas entonces al usar react native nuevo, ya no es compatible y el pasado tiene muchos problemas de compatibilidad como el mas importante usar react native link, en las nuevas versiones ya no existe, y en las pasadas versiones react native tiene varios bugs.

Important: You only need to do this step if you're using React Native 0.59 or lower. Since v0.60, linking happens automatically.