Delphi incorpora FMX Linux




Esta semana Embarcadero ha anunciado la incorporación de FMX Linux a todos los clientes de Delphi Enterprise y Architect, por lo que ahora las aplicaciones desarrolladas con Firemonkey pueden ejecutarse en plataformas Linux, de una forma parecida a como se hace en un Mac, instalando en Linux el agente PAServer que será el encargado  de hacer de puente entre nuestro equipo de desarrollo y Linux (Ubuntu)
Para instalar fmxlinux hay que abrir Delphi y acceder al menú Tools - Getit Package Manager,  buscar FmxLinux y pulsar el botón Install


Para continuar creando nuestro primer programa deben seguir las instrucciones del siguiente post de Marco Cantú

17 años después de Kylix, Embarcadero ha vuelto a apostar por Linux.   
FmxLinux fue desarrollado por un tercero, Eugene Kryukov y ha sido licenciado bajo "un acuerdo de distribución a largo plazo"
FmxLinux no se incorporará de momento en la edición gratuita y comunitaria de Delphi, aunque desde Embarcadero dicen que lo están considerando.
Tienen un documento de ayuda en la docwiki de FmxLinux 

En el siguiente post de Germán Estévez (MVP Embarcadero) tienen una guía paso a paso de configuración de FMXLinux desde cero.







Modelando en 3D con Firemonkey

Firemonkey proporciona la capacidad de utilizar modelos de alambre en 3D en los formatos OBJ, DAE y ASE, que son los más utilizados por el software diseñado para ese fin (p.ej blender...)
Para ahorrar tiempo, en vez de crear los modelos nosotros mismos, hay sitios web que los ofrecen de forma gratuita y sin pagar royalties.
Uno de los muchos sites que hay en la red  es www.turbosquid.com



En esa página hay miles de modelos que podremos utilizar en nuestro programa.
Para empezar tenemos que abrir RAD Studio y crear una nueva Multi-Device Application 3D (tienen los pasos a seguir en este post)
La estructura de los componentes será la siguiente:



El componente tModel3D (Model3D1) deberá colgar de un tDummy (DummyScene) y el objeto de malla en formato OBJ lo tendremos que indicar desde la propiedad MeshCollection (lo indico en color amarillo en la imagen superior).
Nos encontraremos con el incoveniente que el componente tModel3D no tiene asignada la propiedad "MaterialSource" por defecto, por lo que la tenemos que asignar en el evento OnCreate:


procedure TForm1.FormCreate(Sender: TObject);
var mesh : TMesh;
begin
  for mesh in Model3D1.MeshCollection do
    mesh.MaterialSource := LightMaterialSource1;
end;




También tendremos que añadir un manejador de eventos para conseguir que la figura de malla se mueva según la dirección del ratón y haga un zoom cuando se mueva la rueda del ratón:


procedure TForm1.FormGesture(Sender: TObject;
  const EventInfo: TGestureEventInfo; var Handled: Boolean);
var delta: integer;
begin
  if EventInfo.GestureID = igiZoom then
  begin
    if (not (TInteractiveGestureFlag.gfBegin in EventInfo.Flags))
      and (not (TInteractiveGestureFlag.gfEnd in EventInfo.Flags)) then
    begin
      delta := EventInfo.Distance - UltimaDistancia;
      DoZoom(delta > 0);
    end;
    UltimaDistancia := EventInfo.Distance;
  end;
end;



Igualmente hay que manejar los eventos OnMouseDown, OnMouseMove y OnMouseWheel del componente ViewPort3D1


procedure TForm1.MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
  Punto := PointF(X, Y);
end;

procedure TForm1.MouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Single);
begin
  if (ssLeft in Shift) then
  begin
    DummyCamera.RotationAngle.X := DummyCamera.RotationAngle.X - ((Y - Punto.Y) * ROTATION_STEP);
    DummyCamera.RotationAngle.Y := DummyCamera.RotationAngle.Y + ((X - Punto.X) * ROTATION_STEP);
    Punto := PointF(X, Y);
  end;
end;

procedure TForm1.MouseWheel(Sender: TObject;
  Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean);
begin
  DoZoom(WheelDelta > 0);
end;


Después ejecutaremos la aplicación y podremos ver la figura en 3D desde todos los ángulos posibles,
se puede rotar, ampliar, girar, etc... realmente es espectacular lo que hemos conseguido con unas pocas líneas de código.







Descargar el programa




También te puede interesar

Simular el movimiento de burbujas


Simular el movimiento de electrones en un campo eléctrico

App para visualizar moléculas en 3D

Diseñando hypercubos de N dimensiones

Creando aplicaciones en 3D con Firemonkey

En este post vamos a ver lo fácil que es realizar una aplicación simple en 3D con Firemonkey.
Comenzamos desde el menú File - New - Multi Device Application Delphi - 3D Application


Añadimos un componente llamado tDummy que se comportará como un contenedor de otros componentes en Firemonkey 3D. Este componente es el equivalente al tLayout en el mundo de Firemonkey 2D.
Con tDummy podremos mover, girar, rotar y escalar los objetos que le asociemos y será el objeto del que descenderán casi todos los que coloquemos en el form, esto nos dará una forma muy sencilla de manipular una escena.


Ahora tenemos que seleccionar el componente tSphere y colocarlo de tal forma que cuelgue del componente tDummy.
Seleccionamos tDummy y cambiamos la propiedad Scale X,Y,Z al valor 5.
Desde la vista Structure tiene que quedar así:

Seguidamente seleccionamos el componente tTextureMaterialSource y lo colocamos en el form.
Después hacemos clic en tSphere y asociamos la propiedad "MaterialSource" al componente tTextureMaterialSource.


Ahora tenemos que crear un bitmap para la textura. Este puede ser una imagen en formato jpg, png, bmp, un color sólido, etc.
Pero para crear un efecto espectacular vamos a cargar la imagen de la tierra vista desde el espacio.
Para ello hay que seleccionar el componente tTextureMaterialSource1 y dentro de él hacer clic en Texture - Edit y seleccionar la imagen en formato *.jpg


 Yo la he descargado desde aquí: http://visibleearth.nasa.gov/
Ahora ya podremos ejecutar la aplicación y veremos  el globo terráqueo en 3D,
 
Pero para dar más realismo y hacer que gire  en 3D lo que hay que hacer es crear una animación, que se hace de una forma muy sencilla, añadiendo el componente tFloatAnimation y teniendo la precaución de quede "colgado" del tShpere en la vista de Structure.

Dentro del componente tFloatAnimation modificamos las propiedades que os he marcado en amarillo:
-Duration = 2
-Enabled = True
-Loop = true
-PropertyName = RotationAngle.Y
-StartValue=1
-StopValue=-360







Cómo acelerar 10 veces los bucles "For" con Delphi





Para conseguir que los bucles for se ejecuten hasta 10 veces más rapido hay que utilizar PPI (Parallel Programming Library) y si no se lo creen, ejecuten el siguiente código:


Bucle for como se hace habitualmente:


uses
  System.Threading, // Parallel Programming Library
  System.Diagnostics; // TStopwatch

// ...




procedure TForm1.btnForLoopRegularClick(Sender: TObject);
var sw: TStopwatch; i: Integer;
begin
  sw := TStopwatch.StartNew;
  for i := 0 to 99 do
    Sleep(10);
  sw.Stop;
  Label1.Text := sw.ElapsedMilliseconds.ToString + 'ms';
end;

Ahora el mismo bucle utilizando PPI


procedure TForm1.btnForLoopParallelClick(Sender: TObject);
var sw: TStopwatch; i: Integer;
begin
  sw := TStopwatch.StartNew;
  TParallel.For(0, 99, procedure(i: integer)
  begin
    Sleep(10);
  end);
  sw.Stop;
  Label1.Text := sw.ElapsedMilliseconds.ToString + 'ms';
end;

En el primer caso el tiempo de ejecución es 1038 msegs y en el segundo caso de 117 msegs., como ven el incremento de velocidad está en un rango de 10 veces aproximadamente.
Espero que este truco les sea útil y que lo utilicen en sus programas. 


También te puede interesar

Ejemplos de programación paralela 
 

Midiendo el tiempo con Firemonkey




A continuación les presento una forma de medir el tiempo con Firemonkey, que nos va a proporcionar una alta precisión y que será muy útil en el caso de que tengamos que medir eventos físicos: la caída de una pelota , movimiento de bolas dentro de una caja, tiro parabólico, simulación de caída libre de un objeto, etc...
La solución es usar la clase tStopwatch de la unit system.Diagnostics, que proporciona una lectura precisa del temporizador del reloj del sistema operativo.
Se necesita inicializar el temporizador, por ejemplo en el evento OnCreate, llamando al método StartNew.
El método GetTimeStamp devuelve el número actual de tics del sistema.
Tambien podemos utilizar la propiedad Frecuency que nos da el número de tics por segundo.



uses
System.Diagnostics;


// ...
procedure TForm1.FormCreate(Sender: TObject);
begin
TStopwatch.StartNew;
Log('Frecuencia  = ' + TStopwatch.Frequency.ToString);
end;
function TForm1.GetRawReferenceTime: double;
begin
Result := TStopwatch.GetTimeStamp / TStopwatch.Frequency;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var t, elapsed: double;
begin
t := GetRawReferenceTime;
elapsed := t - FLastTime;
FLastTime := t;
Log('t=' + t.ToString + ' diferencia=' + elapsed.ToString);
end;



Tambien te puede interesar


Comandos que desconocías de Windows 8

Detener procesos y servicios con Delphi
Cerrar aplicaciones innecesarias en Windows
Cómo detectar inactividad en el sistema
Cómo proteger tu código