{"id":315,"date":"2016-01-08T07:07:45","date_gmt":"2016-01-08T07:07:45","guid":{"rendered":"http:\/\/multimedia.uoc.edu\/blogs\/rv\/?p=315"},"modified":"2016-01-08T07:09:47","modified_gmt":"2016-01-08T07:09:47","slug":"rubik-vr","status":"publish","type":"post","link":"http:\/\/multimedia.uoc.edu\/blogs\/rv\/es\/2016\/01\/08\/rubik-vr\/","title":{"rendered":"Rubik VR"},"content":{"rendered":"<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/blog.jpg\" alt=\"\" \/><\/p>\n<p><a href=\"https:\/\/www.youtube.com\/watch?v=EG4O4N33Yow\">V\u00eddeo<\/a> &#8211; <a href=\"http:\/\/www.adrianriera.com\/rubikvr\">Aplicaci\u00f3n<\/a><\/p>\n<h2>Autor<\/h2>\n<p>Adri\u00e1n Termen\u00f3n Riera<\/p>\n<h2>Introducci\u00f3n<\/h2>\n<p>Cuando me plante\u00e9 la tarea de hacer una aplicaci\u00f3n de Realidad Virtual me vinieron much\u00edsimas ideas a la cabeza, pero ten\u00eda claro que quer\u00eda desarrolar algo para Oculus. Esta decisi\u00f3n, no solo se debe a que ya cuento con cierta experiencia tanto con el dispositivo como con Unity, sino tambi\u00e9n a que considero que los visores de realidad virtual, ya sean de escritorio o port\u00e1tiles, actualmente se encuentran en esa fina l\u00ednea temporal que separa la tecnolog\u00eda que solamente usan unos pocos de la que se utiliza de manera manera masiva, tal como en su d\u00eda lo estuvieron los smartphones. En definitiva creo que tiene futuro.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/visores.jpg\" alt=\"\" \/><\/p>\n<p><a href=\"http:\/\/www.oculus.com\">Oculus<\/a> &#8211; <a href=\"https:\/\/www.google.com\/get\/cardboard\">Google Cardboard<\/a><\/p>\n<p>No obstante, la idea de jugar al cubo de Rubik puede parecer un poco aburrida, si se compara con lo que el usuario medio espera de la Realidad Virtual Inmersiva. Es decir, experiencias trepidantes y llenas de adrenalina. Pero opino que cuantos m\u00e1s contenidos haya disponibles, m\u00e1s r\u00e1pido se extender\u00e1 esta tecnolog\u00eda en la sociedad. Quiz\u00e1s por eso y porque hace bastante a\u00f1os que soy aficionado a los cubos me decid\u00ed por llevar este proyecto adelante.<\/p>\n<p>&nbsp;<\/p>\n<h2>Proceso de trabajo<\/h2>\n<h3>1. Modelar el cubo<\/h3>\n<p>La primera etapa del proyecto consisti\u00f3 en el modelado 3D del cubo, para lo cual utilic\u00e9 el software 3DS MAX 2014. Esto, supuso innumerables ventajas respecto al entorno Java Script en el que desarroll\u00e9 <a href=\"http:\/\/www.adrianriera.com\/rubik\">la primera aplicaci\u00f3n<\/a> debido, principalmente, a las herramientas que ofrece la interfaz de trabajo de MAX.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/cap00.jpg\" alt=\"\" \/><br \/>\n<a href=\"http:\/\/www.autodesk.es\/products\/3ds-max\/overview\">Autodesk 3DS Max<\/a><\/p>\n<h3>2. Dise\u00f1ar la interacci\u00f3n<\/h3>\n<p>Una vez modelado y texturizado, el siguiente paso fue dise\u00f1ar la interacci\u00f3n con el cubo en Unity 5. Lo primero que me plante\u00e9 al abordar esta tarea es que no quer\u00eda limitar el giro del cubo tal como hice en <a href=\"http:\/\/www.adrianriera.com\/rubik\">la primera aplicaci\u00f3n<\/a>. Despu\u00e9s de todo, algo m\u00e1s de un a\u00f1o de experiencia con Unity, me ha permitido familiarizarme con la clase Vector3, la cual ofrece infinidad de m\u00e9todos enfocados a la transformaci\u00f3n de objetos en un espacio euclideo, tal como es el entorno virtual en el cual se desarrolla la acci\u00f3n.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/vector3.jpg\" alt=\"\" \/><br \/>\n<a href=\"https:\/\/unity3d.com\/es\/5\">Unity 5<\/a> &#8211; <a href=\"http:\/\/docs.unity3d.com\/Manual\/index.html\">Unity Manual<\/a><\/p>\n<p>As\u00ed pues, en la primera aplicaci\u00f3n desarrollada en Java Script, el cubo siempre permanec\u00eda orientado en la misma direcci\u00f3n, y era la c\u00e1mara la que rotaba alrededor suyo cuando el usuario deseaba girarlo. Esto simplificaba bastante el manejo de las distintas caras pero, al mismo tiempo, supon\u00eda un problema. Era necesario escribir un c\u00f3digo espec\u00edfico pr\u00e1cticamente para cada pieza y cada giro. Es decir, si ahora quisiera hacer una versi\u00f3n del cubo de 4x4x4 o de 5x5x5, tendr\u00eda que reescribir pr\u00e1cticamente la totalidad del c\u00f3digo. Por el contrario, en Unity y gracias a sus herramientas vectoriales he conseguido que sea el cubo el que gira sobre si mismo mientras que la c\u00e1mara, es decir, el sujeto virtual, permanece est\u00e1tico en la misma posici\u00f3n.<\/p>\n<p>De esta manera, el gui\u00f3n de la interacci\u00f3n para el manejo del cubo es el siguiente:<\/p>\n<p>1 &#8211; seleccionar la pieza<\/p>\n<p>El usuario hace clic sobre una pieza, con lo que el programa guarda en la memoria la cara del cubo en cuesti\u00f3n y el vector normal de la misma.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/cap01.jpg\" alt=\"\" \/><\/p>\n<p>2 &#8211; seleccionar el conjunto de piezas<\/p>\n<p>El usuario arrastra el cursor sobre el plano de la cara, con lo que se guarda un nuevo vector que permite al programa saber que conjunto de piezas es el que se desea girar.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/cap02.jpg\" alt=\"\" \/><\/p>\n<p>3 &#8211; girar el conjunto de piezas<\/p>\n<p>Una vez guardados los datos necesarios, el programa calcula el eje y \u00e1ngulo de giro a partir del producto vectorial de la normal de la cara y la direcci\u00f3n del movimiento del cursor sobre la misma.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/cap03.jpg\" alt=\"\" \/><\/p>\n<p>4 &#8211; finalizar el giro<\/p>\n<p>Por \u00faltimo. cuando el usuario deja de presionar el bot\u00f3n del rat\u00f3n el programa restaura la rotaci\u00f3n de la cara en funci\u00f3n del \u00e1ngulo m\u00e1s pr\u00f3ximo.<\/p>\n<p>A parte de la interacci\u00f3n con el cubo est\u00e1 tambi\u00e9n la interacci\u00f3n con la propia aplicaci\u00f3n, cuyo gui\u00f3n es muy sencillo. Simplemente se basa en los posibles estados en los que se encuentra el cubo o el juego. Por un lado, si el cubo est\u00e1 resuelto o no y, por otro lado, si el jugador est\u00e1 tratando de resolverlo o simplemente esta jugando con \u00e9l sin ninguna finalidad en concreto.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/guion.jpg\" alt=\"\" \/><\/p>\n<h3>3. Dise\u00f1ar la interfaz l\u00f3gica<\/h3>\n<p>Llegado a este punto, lo que quer\u00eda evitar a toda costa respecto a la primera aplicaci\u00f3n es que el usuario realizase un giro no deseado por error. Para ello, me propuse delinear en todo momento los elementos susceptibles de ser modificados. De esta manera, el jugador dispone de la informaci\u00f3n visual necesaria para saber con exactitud que pieza o conjunto de piezas se dispone a girar.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/cap04.jpg\" alt=\"\" \/><\/p>\n<p>Por otro lado, me pareci\u00f3 buena idea incluir una consola para poder mostrar informaci\u00f3n sobre el estado de la aplicaci\u00f3n, es decir, si el cubo se esta desordenando, si el cron\u00f3metro esta activo o si el jugador ha logrado resolver el cubo.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/cap09.jpg\" alt=\"\" \/><\/p>\n<p>Por \u00faltimo, a\u00f1ad\u00ed unos sencillos controles para poder desordenar el cubo o resetearlo, conocer los atajos del teclado, regular la iluminaci\u00f3n de la escena o la intensidad de la m\u00fasica o poder cerrar la aplicaci\u00f3n sin necesidad de quitarse las Oculus.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/cap05.jpg\" alt=\"\" \/><\/p>\n<h3>4. Adaptar la interfaz f\u00edsica<\/h3>\n<p>Por suerte, esta parte del desarrollo no supuso ninguna complicaci\u00f3n, en parte debido a que Unity ya tiene las opciones de Realidad Virtual y Visi\u00f3n Estereosc\u00f3pica que automatizan completamente los procesos de mapeado entre el giro del visor, en este caso las Oculus DK2, y el giro de la c\u00e1mara en la escena.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/test.jpg\" alt=\"\" \/><\/p>\n<p>Un poco m\u00e1s peliaguda fue la parte de mapear el movimiento 2D del rat\u00f3n para adaptarlo al entorno tridimensional de la aplicaci\u00f3n. Sobre todo en determinadas circunstancias en las que el usuario deb\u00eda desplazar el cursor virtual a lo largo de un plano bastante perpendicular a su propia visi\u00f3n. Pero finalmente, no me encontr\u00e9 con ning\u00fan problema que no pudiese solucionar con trigonometr\u00eda b\u00e1sica.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/raton.jpg\" alt=\"\" \/><\/p>\n<h3>5. Dise\u00f1ar el concepto<\/h3>\n<p>Ya desde el principio ten\u00eda bastante claro que el entorno deb\u00eda ser lo m\u00e1s neutro posible. Finalmente y tras hacer varias pruebas me decante por integrar un plano a modo de suelo, que pudiese iluminarse u oscurecerse dependiendo de las preferencias del usuario. Tambi\u00e9n decid\u00ed a\u00f1adir unas part\u00edculas muy tenues situadas alrededor de la zona de acci\u00f3n, para aumentar la sensaci\u00f3n de profundidad del entorno y favorecer la sensaci\u00f3n de presencia del usuario.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/cap06.jpg\" alt=\"\" \/><\/p>\n<p>Por \u00faltimo, el sonido es un factor muy importante para potenciar esa misma sensaci\u00f3n de presencia tan indispensable en una aplicaci\u00f3n de realidad virtual. De modo que puse especial cari\u00f1o en esta parte, buscando una canci\u00f3n relajante y grabando sonidos de un cubo real para posteriormente, cortarlos e incluirlos de manera aleatoria cada vez que se llevase a cabo un giro en la aplicaci\u00f3n.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/sonido.jpg\" alt=\"\" \/><\/p>\n<p>&nbsp;<\/p>\n<h2>Dificultades<\/h2>\n<p>Probablemente, la mayor dificultad que me he encontrado es la manera en que Unity ejecuta el c\u00f3digo. Es decir \u00bfNunca os ha pasado cuando intent\u00e1is jugar a un videojuego muy antiguo en un ordenador nuevo que de repente todo va tan r\u00e1pido que no hay forma de manejarlo? Pues si no vais con cuidado, es muy probable que en Unity os pase lo mismo. Este problema surge principalmente al utilizar la funci\u00f3n Update() que b\u00e1sicamente es llamada por la aplicaci\u00f3n una vez por fotograma. Es bien sabido que, en funci\u00f3n de la potencia de la tarjeta gr\u00e1fica o del procesador, la cantidad de fotogramas que el juego muestra por segundo puede variar entre 30 o 300, lo cual influye s\u00ed o s\u00ed en la velocidad de ejecuci\u00f3n del c\u00f3digo. Por este motivo, hay que tener especial cuidado en como se escriben las diferentes instrucciones, sobre todo las que est\u00e1n relacionadas con el movimiento de los objetos virtuales.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/dificultad1.jpg\" alt=\"\" \/><\/p>\n<p>Otra dificultad que me encontr\u00e9 a medio camino de dise\u00f1ar la interacci\u00f3n con el cubo fue que el programa ten\u00eda que hacer much\u00edsimos procesos en muy poco tiempo para calcular que conjunto de piezas deb\u00edan ser afectadas por el giro, lo que deven\u00eda en que lo mismo el usuario se encontraba girando piezas que debieran quedarse est\u00e1ticas. Por suerte, este proyecto me ha servido para descubrir bastantes trucos de como gestionar el tiempo de ejecuci\u00f3n del c\u00f3digo en Unity, sin los cuales, no hubiese podido terminar el desarrollo de la aplicaci\u00f3n.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/dificultad2.jpg\" alt=\"\" \/><\/p>\n<p>Por \u00faltimo, est\u00e1 el tema de la escalabilidad. Como ya he comentado, la idea inicial era hacer un programa escalable que una vez terminado, me permitiese implementar el manejo de cubos de distintas dimensiones como el de 4 o el de 5 piezas. No obstante, cuando empec\u00e9 a dise\u00f1ar el c\u00f3digo encargado de detectar si el cubo esta resuelto me di cuenta de lo complicado que era hacer eso. Cada cubo, debido a su topolog\u00eda tiene sus particularidades, con lo que es realmente costoso hacer un c\u00f3digo escalable en ese sentido.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/dificultad3.jpg\" alt=\"\" \/><\/p>\n<p>&nbsp;<\/p>\n<h2>Posibles mejoras<\/h2>\n<p>Desde luego, la principal mejora ser\u00eda incluir cubos de distintas dimensiones o incluso modificaciones del propio cubo de 3 piezas. Aunque tambi\u00e9n me he planteado adaptar la aplicaci\u00f3n para otro tipo de interfaces f\u00edsicas que permitan el manejo del cubo prescindiendo del uso del rat\u00f3n. Algunos ejemplo pueden ser Leap Motion o MYO.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/dispositivos.jpg\" alt=\"\" \/><br \/>\n<a href=\"https:\/\/www.leapmotion.com\/\">Leap Motion<\/a> &#8211; <a href=\"https:\/\/www.myo.com\/\">MYO<\/a><\/p>\n<p>&nbsp;<\/p>\n<h2>Impacto de la aplicaci\u00f3n<\/h2>\n<p>Realmente no se que impacto puede llegar a tener esta aplicaci\u00f3n. Como ya mencionaba al principio, jugar al cubo de Rubik, no es precisamente lo que se espera de una experiencia de Realidad Virtual Inmersiva, lo cual no quita que haya muchos aficionados tanto del propio cubo como de la Realidad Virtual que encuentren interesante probar la aplicaci\u00f3n. Lo cierto es que buscando \u201cRubik Virtual Reality\u201d en Google aparecen resultados que poco o nada tienen que ver con este proyecto, de manera que no descarto publicar la aplicaci\u00f3n en la web de Oculus, intentar difundirla a trav\u00e9s de las redes sociales o incluso redactar una nota de prensa y enviarla a medios especializados en ocio y tecnolog\u00eda.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/google.jpg\" alt=\"\" \/><\/p>\n<p>&nbsp;<\/p>\n<h2>Usos no previstos<\/h2>\n<p>En cuanto a los posibles Hacks o usos no esperados que puedan darse en el manejo de la aplicaci\u00f3n solamente contemplo que alguien pueda utilizarla \u00fanicamente para escuchar el tema musical que por cierto es de libre difusi\u00f3n y se distribuye en la plataforma Jamendo bajo una licencia Creative Commons BY NC SA. Tanto el t\u00edtulo de la canci\u00f3n como su autora aparecen en todo momento en la consola de la interfaz.<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.adrianriera.com\/rubikvr\/img\/jamendo.jpg\" alt=\"\" \/><br \/>\n<a href=\"https:\/\/www.jamendo.com\/\">Jamendo<\/a> &#8211; <a href=\"https:\/\/www.jamendo.com\/track\/80704\/serakina\">Serakina<\/a><\/p>\n<p>&nbsp;<\/p>\n<h2>Conclusi\u00f3n<\/h2>\n<p>Como ya he comentado al principio, creo los visores de Realidad Virtual est\u00e1n a la vuelta de la esquina. Quiz\u00e1s, para que estos se conviertan en un producto de consumo masivo, todav\u00eda es necesaria la existencia de un contenido que sea indispensable para los usuarios, como por ejemplo lo fue el Whats App en los smartphones. Desde luego, Rubik VR no pretende ni de lejos ser ese tipo de contenido. Pero no cabe duda, de que cuantas m\u00e1s opciones y experiencias podamos ofrecer los desarrolladores, m\u00e1s cerca estaremos de iniciar de una vez por todas este nuevo y apasionante episodio en el mundo de la tecnolog\u00eda, el ocio, y la multimedia.<br \/>\nAdri\u00e1n Riera<br \/>\n12 de diciembre de 2015<\/p>","protected":false},"excerpt":{"rendered":"<p>V\u00eddeo &#8211; Aplicaci\u00f3n Autor Adri\u00e1n Termen\u00f3n Riera Introducci\u00f3n Cuando me plante\u00e9 la tarea de hacer una aplicaci\u00f3n de Realidad Virtual me vinieron much\u00edsimas ideas a la cabeza, pero ten\u00eda claro que quer\u00eda desarrolar algo para Oculus. Esta decisi\u00f3n, no solo se debe a que ya cuento con cierta experiencia tanto con el dispositivo como con &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/multimedia.uoc.edu\/blogs\/rv\/es\/2016\/01\/08\/rubik-vr\/\" class=\"more-link\">Seguir leyendo<span class=\"screen-reader-text\"> \u00abRubik VR\u00bb<\/span><\/a><\/p>\n","protected":false},"author":82,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[98,70,96,52],"class_list":["post-315","post","type-post","status-publish","format-standard","hentry","category-estudiants","tag-cubo-de-rubik","tag-oculus-rift","tag-realidad-virtual-inmersiva","tag-unity","entry"],"_links":{"self":[{"href":"http:\/\/multimedia.uoc.edu\/blogs\/rv\/es\/wp-json\/wp\/v2\/posts\/315","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/multimedia.uoc.edu\/blogs\/rv\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/multimedia.uoc.edu\/blogs\/rv\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/multimedia.uoc.edu\/blogs\/rv\/es\/wp-json\/wp\/v2\/users\/82"}],"replies":[{"embeddable":true,"href":"http:\/\/multimedia.uoc.edu\/blogs\/rv\/es\/wp-json\/wp\/v2\/comments?post=315"}],"version-history":[{"count":24,"href":"http:\/\/multimedia.uoc.edu\/blogs\/rv\/es\/wp-json\/wp\/v2\/posts\/315\/revisions"}],"predecessor-version":[{"id":612,"href":"http:\/\/multimedia.uoc.edu\/blogs\/rv\/es\/wp-json\/wp\/v2\/posts\/315\/revisions\/612"}],"wp:attachment":[{"href":"http:\/\/multimedia.uoc.edu\/blogs\/rv\/es\/wp-json\/wp\/v2\/media?parent=315"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/multimedia.uoc.edu\/blogs\/rv\/es\/wp-json\/wp\/v2\/categories?post=315"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/multimedia.uoc.edu\/blogs\/rv\/es\/wp-json\/wp\/v2\/tags?post=315"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}