Mas sobre GLScene escena basica (continuacion) [Delphi 7]

Buenas noches a todos! este post es de seguimiento inmediato del post anterior, y veremos mas cosas basicas de GLScene, como poner un skyBox, mas objetos y poder seleccionarlos.

Agregando mas figuras basicas

Lo que vamos a hacer es agregar unas cuantas figuras mas, para poder interactuar con ellas, poder seleccionarlas y moverlas con las flechas del teclado. Nuestro editor GLScene quedara de la siguiente manera:

1

Agregamos un GLPlane,GLSphere y un GLCone, en la imagen podemos encontrar las coordenadas que les asignamos a cada uno en la propiedad Position. Ademas al Plano le cambiamos mas propiedades, en direction le ponemos 1 en Y, como es un vector normalizado si le cambiamos los valores talvez se cambien a numeros extraños, simplemente si se cambian 2ponemos un 0 a los demas (X y Z), el tamaño le cambiamos a 10 en Width y en Height, ademas en la propiedad Material la expandimos y expandimos FrontProperties y en diffuse elegimos cualquier color que queramos ( esto se puede hacer con cualquier objeto, pero al momento solo al plano)

 

 

Seleccion de objetos

Ahora que ya tenemos la escena lista para su uso, vamos a hacer que el programa reaccione cuando seleccionemos uno de los objetos. De momento queremos hacer que, al dar clic sobre uno de los objetos, éste quede seleccionado, cambiando su color a naranja.
La detección de sobre qué objeto ha dado clic el usuario requiere utilizar un evento del tipo MouseDown o MouseMove, que nos proporcione las coordenadas del visor sobre las que ha dado clic el usuario. Vamos a permitir que, sea cual sea el botón que pinche el usuario, el objeto quede seleccionado, así que utilizaremos el MouseDown del visor(GLSceneViewer). El código necesario para este comportamiento es el siguiente:

1

Declarando un TGLCustomSceneObject podemos manejar cualquiera de las figuras que hemos creado; con un TGLCube sólo podríamos manejar cubos, con TGLCone sólo conos, etc.

GetPickedObject devuelve el objeto que se encuentra en las coordenadas (x,y) de pantalla; el as TGLCustomSceneObject hace que ese objeto se vea como de tipo TGLCustomSceneObject(un poco de polimorfismo), para que todo esto junto funcione. Si en la posición (x,y) no había ningún objeto, nuevaSeleccion queda con valor None, o sea, sin asignar, así que antes de intentar cambiar el color del objeto comprobamos que, en efecto, se ha seleccionado alguno.

veremos que el nombre del color, clrCoral, produce un error porque no está definido, ya que los colores están definidos en la unidad GLTexture. Simplemente hay que añadir esta unidad al final de la lista de uses que hay al principio del código:

2

Si todo salio bien, el resultado sera el siguiente:

3

Al dar clic en cualquier objeto de nuestra escena este se pintara de color naranja, incluso hasta el plano claramente eso debemos de evitarlo y entre otras cosas deberiamos de mejorar:

  • Hay que evitar que el suelo se pueda seleccionar.
  • Al seleccionar un segundo objeto, hay que hacer que el anteriormente seleccionado vuelva a su color gris habitual, si no se van quedando todos naranja.
    Para evitar que el piso se seleccione es muy simple, en la condicion donde tenemos if Assigned(nuevaSeleccion) then solo hay que cambiarlo por:

image

El otro aspecto del programa que hay que mejorar es la deselección de objectos previamente seleccionados; es necesario recordar cuál era el objeto previamente seleccionado para deseleccionarlo y devolverle su color original. Como el programa debe recordar una información entre eventos, es necesario crear una variable global seleccion en la sección private del Form:

image

Inicialmente esa variable deberá tomar el valor Nil (nil significa nada) para indicar que no hay ningún objecto seleccionado (ya sabran dónde hay que darle ese valor, ¿no?), y al seleccionar un nuevo objeto hay que deseleccionar el objeto anterior, si es que lo había. El código que hay en el MouseDown anterior queda así:

image

Manipulacion de los objetos

Ahora que ya sabemos seleccionar los objetos de la escena, vamos a aplicarles algunos cambios, permitiendo que el usuario cambie el tamaño del objeto seleccionado y lo mueva.

Ahora lo que haremos es crear un evento “onMouseWheel” de nuestro form, y en este eveneto pondremos el siguiente codigo:

image

Lo que estamos haciendo aqui, es de que cuando el usuario gire la rueda de su mouse, dependiendo si es arriba o abajo, la figura se encogera o se agrandara.

En el que los cambios sólo se aplican si hay un objeto seleccionado, y en ese caso su escala se multiplica o divide por un factor 1.1. Hay que escribir Scale dos veces porque la primera es el atributo del objeto, su escala, que es un vector, y la segunda es la operación de multiplicar el vector por un escalar; lo único que ocurre es que los nombres coinciden.

image

La siguiente modificación consiste en permitir que el usuario coja un objeto y lo arrastre mientras mantenga el botón del ratón pulsado. Este problema resulta algo más complicado porque el programa debe saber a dónde está moviendo el ratón el usuario, en coordenadas de pantalla (x, y), y debe traducirlas a coordenadas (x, y, z). Además del código que realiza la operación, hay que añadir la unidad VectorGeometry en la lista uses que hay al principio del del unit. El código siguiente, correspondiente al MouseMove, explica paso a paso las instrucciones necesarias para mover los objetos al arrastrarlos con el ratón:

image

image

Como podran comprobar, sólo se pueden mover los objetos arrastrándolos con el botón izquierdo. Es fácil modificar el código para poder moverlos con cualquier botón.
También habran observado que los objetos sólo se mueven en el plano XZ; es posible extender el método anterior a otros planos, por ejemplo haciendo que al tocar Ctrl, Alt, etc., el objeto se mueva en otros planos.
Por último, quizá notéis un pequeño salto al coger los objetos; eso se debe a que aunque nosotros contamos con la posición desde la que los cogemos (por ejemplo una esquina), los cálculos los realizamos siempre respecto al centro del objeto; habría que tener en cuenta esta distancia para conseguir un movimiento más suave.

Agregando una esfera como SkyDome

Solo para hacer mas bonito este programa, le agregaremos un skydome, pero nosotros lo haremos ya que existen objetos que GLScene nos proporciona para hacer este tipo de objetos, lo primero que haremos es crear una esfera que llamaremos “skydome”(el nombre se cambia al dar clic en el objeto desde el editor glscene), igual como lo hemos creado antes,pero en la propiedad Radius le ponemos 50, y en la propedad NormalDirection le ponemos ndInside, para poder ver la esfera por dentro. Copiemos esta imagen y la guardamos en donde guardamos el proyecto, ahora solo resta escribir estas 2 lineas de codigo en el evento onCreate de nuestro form.

image

Es importante agregar al uses principal la unidad JPEG para poder cargar imagenes jpg en nuestro proyecto.

Si lo corren podran ver que el skydome tambien se puede seleccionar, al igual que le hicimos con el piso, lo hacemos con el skydome

Saludos y Code4Fun!.

Autor: Isaac Ojeda

Computer Systems Engineer. Full stack DotNet developer. Expert in Web technologies, and lifelong learner in all existing technologies for software development.

8 opiniones en “Mas sobre GLScene escena basica (continuacion) [Delphi 7]”

  1. Enhorabuena por los artículos de GLScene. Realmente son muy interesantes los artículos sobre GLScene. Cualquier ayuda sobre estos componentes es bienvenida ya que no hay prácticamente documentación. Te animo a seguir en la línea y publicar más artículos.

  2. Bien por tu aporte en Glscene.
    Soy programador de Delphi. Al igual me agrada el tema de Glscene con Delphi. He logrado instalarlo y crear pequeñas cosas.
    Pero la documentación es escasa y quisiera lograr el desplazamiento de un objeto por una construcción creada (un modelo 3d). Si tienes algo sobre eso o conoces donde descargar ejemplos para estudiar.

  3. hola brother… =)
    en la parte donde dices q no reconocera el color tienes razon, pero no debes de mandar llamar GLTexture sino q tienes q mandar llamar GLColor, porq a mi no me salia hasta q hoy en mi clase de graficacion vimos algo similar y vi q el prode puso eso y le funciono….
    UNA VEZ MAS UNA MUY GRATA, Q DIGO GRATA …. MERECIDICIMA FELICITACION Y AGRADECIMIENTO POR ESTOS TUTOS, LA VERDAD GRAX A TI APRENDI GLSENCE =)

    1. Gracias Jav! y respecto a lo de GLTexture, yo agregaba esas librería cuando tenia una versión vieja de GLScene ( eso quiero recordar ) yo creo que en la nueva versión de GLScene es con GLColor (como dices) ya que recuerdo que una vez intente hacer este ejemplo con una nueva versión de GLScene y no me sirvio con GLTexture y ya no supe como arreglarlo hehe.

      Y gracias por las felicitaciones jav! eso me inspira a seguir agregando tutoriales!

      Saludos!

Deja un comentario