Iniciarse en el manejo de JME, Creación de un Cloth.

Primeros pasos con Jmonkey engine, crearemos una pequeña aplicación animada basada en un Cloth con colisiones

Iniciarse
en el manejo de JMonkeyEngine, Creación
de un Cloth.

Nos hemos embarcado en el  uso de JMonkey Engine, en este
tutorial nos iniciaremos viendo el uso de algunas clases sencillas,
para
ver un poco el manejo de este motor gráfico

Para
realizar este tutorial primero
tendremos que instalar el JMonkeyEngine, puede ver como se hace en:

https://adictosaltrabajo.com/tutoriales/tutoriales.php?pagina=BlenderavaMonkeyEngine

Creación
del proyecto

Una
vez creado, añadimos una clase al
paquete por defecto, en nuestro caso lo llamaremos Cloth.java

Una
vez creada, tendremos una pantalla
como la siguiente:

Borramos
todo el código que contiene y
le añadimos el siguiente código(este
código se puede encontrar en
los ejemplos de JavaMonkeyEngine, mirar el tutorial: Blender
y JmonkeyEngine
):

Las clases principales que se usan
son(toda la información sobre las clases las podemos
encontrar en
http://wiki.jmonkeyengine.org/doku.php/
):

CollidingClothPatch:
es una clase que
intenta simular un trozo de tela pero tiene la peculiaridad de que
puede interactuar con objetos, se puede reescribir el manejador que
colisiones para poder cambiar el comportamiento.
SpringPointForce:
es una clase
abstracta que define una fuerza externa para usarse con la clase
SpringSystem

import java.util.logging.Logger;

import com.jme.animation.SpatialTransformer;
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.bounding.CollisionTree;
import com.jme.bounding.CollisionTreeManager;
import com.jme.image.Texture;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.light.PointLight;
import com.jme.math.Vector3f;
import com.jme.math.spring.SpringPointForce;
import com.jme.scene.Controller;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.TextureState;
import com.jme.util.TextureManager;
import com.jmex.effects.cloth.ClothUtils;
import com.jmex.effects.cloth.CollidingClothPatch;

public class Cloth extends SimpleGame {
    private static final Logger logger = Logger.getLogger(Cloth.class
            .getName());

	private CollidingClothPatch cloth;
	private float windStrength =10f;
	private Vector3f windDirection = new Vector3f(0.3f, 1f, .8f);
	private SpringPointForce wind, gravity, drag;
	

	
	public static void main(String[] args) {
		Cloth app = new Cloth();
		app.setConfigShowMode(ConfigShowMode.AlwaysShow);
		app.start();
	}

	
    @Override
	public void simpleUpdate() {
		if (KeyBindingManager.getKeyBindingManager().isValidCommand("wind", false)) {
			wind.setEnabled(!wind.isEnabled());
            logger.info("wind is: "+(wind.isEnabled() ? "on" : "off"));
		}
	}

	
	protected void simpleInitGame() {
		display.setTitle("jME Cloth Demo");
		KeyBindingManager.getKeyBindingManager().set("wind", KeyInput.KEY_RETURN);

		((PointLight)lightState.get(0)).setLocation(new Vector3f(0, -30, 150));
		lightState.setTwoSidedLighting(true);
		cam.setLocation(new Vector3f(0, -30, 100));
		cam.update();

		cloth = new CollidingClothPatch("cloth", 50, 50, 2f, 1000); // name, nodesX, nodesY, springSize, nodeMass
		// Add a simple breeze with mild random eddies:
		wind = ClothUtils.createBasicWind(windStrength, windDirection, true);
		cloth.addForce(wind);
		// Add a simple gravitational force:
		gravity = ClothUtils.createBasicGravity();
		cloth.addForce(gravity);
		// Add a simple drag force.
		drag = ClothUtils.createBasicDrag(20f);
		cloth.addForce(drag);

		CollisionTreeManager.getInstance().setTreeType(CollisionTree.Type.AABB);

	
               

		
		TextureState ts = display.getRenderer().createTextureState();
		ts.setTexture(
			TextureManager.loadTexture(
			Cloth.class.getClassLoader().getResource(
			"images/Monkey.jpg"),
			Texture.MinificationFilter.Trilinear,
			Texture.MagnificationFilter.Bilinear));
		cloth.setRenderState(ts);
		rootNode.attachChild(cloth);
		for (int i = 0; i < 50; i++) {
			cloth.getSystem().getNode(i).position.x *= .8f;
			cloth.getSystem().getNode(i).setMass(Float.POSITIVE_INFINITY);
		}
  }

}

Añadimos
las librería necesarios de JME a nuestro proyecto( mirar el
tutorial: Blender
y JmonkeyEngine
) y nos debera
quedar asi:

Una
vez realizado todos los pasos
anteriores,Si ejecutamos el código anterior sin hacer
modificaciones
ocurrirá esto:

Para
evitar eso nos dirigimos a nuestra
carpeta de proyecto y en la carpeta src, añadimos una
carpeta llamada images:

Y
dentro de esa carpeta añadimos la
imagen que queramos en nuestro caso una de Autentia:

Una
vez hecho esto nos dirigimos al
código y modificamos las siguientes lineas:

TextureState ts = display.getRenderer().createTextureState();
ts.setTexture( TextureManager.loadTexture( Cloth.class.getClassLoader().getResource("images/Monkey.jpg"),

Se modificarían por:

TextureState ts = display.getRenderer().createTextureState();
ts.setTexture( TextureManager.loadTexture( Cloth.class.getClassLoader().getResource( "images/Autentia.jpg"),//Hemos sustituido la foto predeterminada por la nuestra

Después
de realizar esta modificación
si ejecutamos, veremos lo siguiente(con la imagen que decidamos
poner):

Si
jugamos con los variables, cambiando
sus valores, con la primera variable cambiaremos la fuerza del viento
y con la segunda la dirección(como estamos en un mundo 3D la
dirección se define por los ejes de coordenadas XYZ):

private float windStrength =10f;
private Vector3f windDirection = new Vector3f(0.3f, 1f, .8f);

Con
esto ya tendríamos nuestra primera
aplicación utilizando JME, pero si queremos complementarlo
un poco,
podemos añadir una esfera para que interactue con el cloth.

Para
esto solo tenemos que añadir una
variable de la clase Sphere:

private CollidingClothPatch cloth;
private float windStrength =10f;
private Vector3f windDirection = new Vector3f(0.3f, 1f, .8f);
private SpringPointForce wind, gravity, drag;
private Sphere sphere;//Se añade la variable sphere

Una
vez añadida esa variable tenemos que añadir un
manejador de
colisiones, que lo podemos añadir detrás de la
definición de las
propiedades del Cloth:

drag = ClothUtils.createBasicDrag(20f);
cloth.addForce(drag);
CollisionTreeManager.getInstance().setTreeType CollisionTree.Type.AABB);//Se añade el manejador de colisiones

Luego
tenemos que crear la esfera y definir sus propiedades, y se lo
añadimos al cloth:


CollisionTreeManager.getInstance().setTreeType CollisionTree.Type.AABB);

//Inico de código añadido
sphere = new Sphere("sphere", 10, 10, 4);//Define la forma y el
tamaño de la esfera
<sphere.setModelBound(new BoundingBox());
sphere.updateModelBound();
rootNode.attachChild(sphere);
SpatialTransformer st = new SpatialTransformer(1);//se define un objeto para concretar la rotación,translación y escala a un objeto en distintos tiempos.
st.setObject(sphere,0, -1);
st.setPosition(0,0, new Vector3f(10, 10, 30));
st.setPosition(0,2, new Vector3f(-10, -10, -30));
st.interpolateMissing();
st.setRepeatType(Controller.RT_CYCLE)
sphere.addController(st);//Se le añade este objeto al conjunto de controles de la esfera
cloth.addCollider(sphere); 
//fin de código añadido
TextureState ts = display.getRenderer().createTextureState();
ts.setTexture( TextureManager.loadTexture(Cloth.class.getClassLoader().getResource "images/Autentia.jpg"),texture.MinificationFilter.Trilinear,Texture.MagnificationFilter.Bilinear));
cloth.setRenderState(ts);

Si
ejecutamos ahora el código se nos mostrara por pantalla el
cloth
y
ademas la esfera que estara en movimiento, colisionando contra
nuestro cloth:

Podemos añadir las
bolas que queramos, repitiendo los pasos anteriores de la esfera
(renombrando evidentemente las variables)y tocando en la
posición de
las lineas:

st.setPosition(0,0, new
Vector3f(10, 10, 30));
st.setPosition(0,2, new Vector3f(-10, -10, -30));

Conseguiremos algo como esto:

Esperemos que les haya sido
útil este tutorial, seguiremos haciendo más tutoriales
sobre esta
tecnología analizando más ejemplos algo más
complicados, todo el que quiera hacer una aportación séra
bien recibida.

Para comunicarme cualquier problema o sugerencia de mejora
podeís utilizar la
zona de comentarios, de este modo todo el mundo se podrá
aprovechar de
las respuestas.

Saludos.

Comentarios

Un comentario

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

He leído y acepto la política de privacidad

Información básica acerca de la protección de datos

  • Responsable: IZERTIS S.A.
  • Finalidad: Envío información de carácter administrativa, técnica, organizativa y/o comercial sobre los productos y servicios sobre los que se nos consulta.
  • Legitimación: Consentimiento del interesado
  • Destinatarios: Otras empresas del Grupo IZERTIS. Encargados del tratamiento.
  • Derechos: Acceso, rectificación, supresión, cancelación, limitación y portabilidad de los datos.
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad

Consultor tecnológico de desarrollo de proyectos informáticos. Ingeniero en Informática por la Universidad de Alcalá de Henares.

¿Quieres publicar en Adictos al trabajo?

Te puede interesar

22/06/2026

Juan Antonio Jiménez Torres

Vamos a instrumentalizar un SDD para un microservicio bancario. En este artículo sobre SDD - Spec Driven Development, instrumentalizado sobre OpenSpec vamos a construir una PoC de algo más serio que una tabla periódica. Un microservicio bancario muy simplificado que gestione cuentas y permita hacer transferencias

16/06/2026

Juan Antonio Jiménez Torres

Este es el segundo artículo sobre SDD, Spec Driven Development, instrumentalizado sobre OpenSpec. Pero esta vez nos acercaremos usando softwere gratuito. Por un lado OpenCode en lugar de ClaudeCode y usando el modelo gratuito Gemma4 de Google en lugar de otros de pago.

08/06/2026

Juan Antonio Jiménez Torres

Aprenderemos sobre SDD – Spec Driven Development instrumentalizado sobre OpenSpec. Haremos un primer acercamiento usando ClaudeCode con Sonnet, para luego, en un artículo posterior pasarnos a la versión gratuita de OpenCode con Gemma4