Hola de nuevo, la semana pasada me metí a intentar crear una aplicación que funcionara en Windows Phone 7 y manejara el uso de la realidad aumentada, así que al terminar y después de leer un buen rato este post es el resultado del trabajo de la semana pasada.
Si no sabes que es la realidad aumentada, un buen inicio sería comenzar desde leyendo el siguiente link acerca de qué es la realidad aumentada.
Bien, ahora si podrás comenzar, pero en esta ocasión no iniciaremos desde un proyecto nuevo, hay que ir un poco mas allá, para poder tener acceso a la cámara del teléfono.
Comienza descargando una librería desde aquí, esta librería es Windows.Phone.Media.Extended, y servirá para poder acceder al uso de la cámara.
Ya que la tienes, extrae la .dll y colócala en la siguiente ruta
C:\Program Files\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0\Profile\WindowsPhone
Abre el archivo FrameworkList.xml que esta dentro de la carpeta RedistList (recuerda que seguimos dentro de la ubicación anterior), e inserta la siguiente línea.
Imagino que como buen desarrollador tienes un editor algo mas avanzado que el Bloc de notas, de lo contrario yo recomiendo enfáticamente Notepadd++, me encanta desde la primera vez que lo usé.
Ya que terminaste con esto ahora si, ve a Visual Studio, pero antes de iniciar con cualquier proyecto, debes comenzar por descargar el complemento para ejecutar una consola desde Visual Studio.
Ok, entonces ahora si, ya con tu .dll añadida y tu complemento inicia un nuevo proyecto en Windows Phone 7 y vete por la opción Landscape, será la mas adecuada, después de eso añade la librería, que como verás ya está dentro de las preestablecidas.
Si te tomas la libertad de compilar tu proyecto, es muy posible que tu IDE no haya reconocido tu librería recién incorporada, para ello da click derecho sobre tu proyecto y ahí selecciona la opción de abrir una consola.
Y ahí en tu consola, ve primero a la ruta siguiente (por medio del comando “cd”).
C:\Program Files\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0\Profile\WindowsPhone
y ahora si escribe el siguiente comando.
sn -Vr Microsoft.Phone.Media.Extended dll
esto dará “de alta” definitivamente a tu librería para poder usarla dentro de tu proyecto.
Por último para terminar debes agregar dos librerías mas las cuales son:
SlarToolkit.dll (librería diseñada para el manejo y reconocimiento de patrones)
Matrix3DEx.dll (librería que extiende la funcionalidad del elemento PlaneProjection de Silverlight)
Puedes obtener las dos desde aquí aunqque te recomiendo que les des un vistazo para comprender un poco mas de su funcionalidad.
De acuerdo, hemos terminado con la parte de configuración y requerimientos del proyecto, ahora si, al fin, a escribir el código, primero ve por el XAML
En donde simplemente colocas el espacio para visualizar la cámara y después un contenedor para la imagen que quieres ver, no es la gran ciencia, hasta aquí puedes compilar sin mayor problema, ahora podremos pasar al lado de C#.
Comienza declarando dos objetos globales
private VideoCamera camara; private BitmapMarkerDetector detectorRealidad; |
Y después utilizarás los eventos OnNavigatedTo y OnNavigatedFrom que se ejecutan al aparecer la página en cuestión y al salir.
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { base.OnNavigatedTo(e); IniciarDetectorRealidad(); IniciarCamara(); } protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e) { base.OnNavigatedFrom(e); camara.Dispose(); camara = null; } |
Como puedes ver en una función solo inicias dos funciones, y en el otro eliminas el uso de la cámara, las funciones en uso son las siguientes.
private void IniciarDetectorRealidad() { detectorRealidad = new BitmapMarkerDetector(); var marker = Marker.LoadFromResource("Materiales/probando.pat", 16, 16, 80); detectorRealidad.Initialize(640, 480, 1, 4000, marker); } private void IniciarCamara() { camara = new VideoCamera(); camara.Initialized += OnCameraInitialized; visorCamara.SetSource(camara); } |
El detector de realidad manda llamar a un archivo de tipo .pat, es un patrón, ese patrón lo puedes crear por diferentes métodos, por ahora no te preocupes por ello y descarga el patrón que usamos aquí.
Al momento de añadir ese patrón a tu proyecto, es bien importante que además de añadirlo, modifiques sus propiedades para que quede añadido como un recurso.
Así también puedes notar que usas un event handler para la inicialización de la cámara, el cual incluirá lo siguiente.
void OnCameraInitialized(object sender, EventArgs e) { camara.Initialized -= OnCameraInitialized; Dispatcher.BeginInvoke(() => { GrabFrame(); }); } |
Lo primero que hacemos es eliminar el manejador, para después al momento de invocar el reconocimiento de elementos llamemos a nuestra última función.
private void GrabFrame() { if (camara != null) { Debug.WriteLine("GrabFrame"); WriteableBitmap wb = new WriteableBitmap(640, 480); camara.GetCurrentFrame(wb); wb.Invalidate(); var sw = new Stopwatch(); sw.Start(); var results = detectorRealidad.DetectAllMarkers(wb); Debug.WriteLine("Has results: {0}", results.HasResults); if (results.HasResults) { img.Opacity = 1; var centerAtOrigin = Matrix3DFactory.CreateTranslation(-img.ActualWidth * 0.5, -img.ActualHeight * 0.5, 0); var scale = Matrix3DFactory.CreateScale(0.5, -0.5, 0.5); var world = centerAtOrigin * scale * results[0].Transformation; var vp = Matrix3DFactory.CreateViewportTransformation(visorCamara.ActualWidth, visorCamara.ActualHeight); var m = Matrix3DFactory.CreateViewportProjection(world, Matrix3D.Identity, detectorRealidad.Projection, vp); img.Projection = new Matrix3DProjection { ProjectionMatrix = m }; } sw.Stop(); Debug.WriteLine("Time to scan frame: {0}ms", sw.ElapsedMilliseconds); } Dispatcher.BeginInvoke(() => { GrabFrame(); }); } |
Aquí me declaro un completo ignorante en la materia, simplemente aprendí lo necesario, pero fue sencillo, usando la librería de Matriz 3DEx vas a darle la posición al elemento (en este caso una imagen) basándote en la posición del patrón, es así de sencillo en este caso particularmente.
Ahora si, a probarlo (aclaro que solo he podido probarlo en un dispositivo real, en el emulador solo me aparece un cuadro en blanco).
Listo!!! Ahora a disfrutar de tu nueva aplicación
El código fuente lo puedes descargar desde aquí.
El patrón en su versión para imprimir es este.
NOTA: Hay que mencionar que esta librería NO forma parte de la API para el entorno de desarrollo de Windows Phone 7, por lo mismo, cualquier intento por publicar una aplicación de este tipo en el Marketplace será rechazado por violar los términos del contrato de publicación de aplicaciones.