First implementation of L-System in 3D

This commit is contained in:
Quentin Legot 2021-03-10 11:51:06 +01:00
parent 4129724064
commit 6371082665
5 changed files with 42 additions and 42 deletions

View File

@ -6,17 +6,17 @@ public class Element {
public final ElementProperties property; public final ElementProperties property;
public final Element parent; public final Element parent;
public final float[] values; public final float[] rotation;
public final LinkedList<Element> children = new LinkedList<>(); public final LinkedList<Element> children = new LinkedList<>();
public Element(ElementProperties property, Element parent) { public Element(ElementProperties property, Element parent) {
this(property, parent, new float[]{0f, 0f, 0f}); this(property, parent, new float[]{0f, 0f, 0f});
} }
public Element(ElementProperties property, Element parent, float[] values) { public Element(ElementProperties property, Element parent, float[] rotation) {
this.property = property; this.property = property;
this.parent = parent; this.parent = parent;
this.values = values; this.rotation = rotation;
} }
} }

View File

@ -19,7 +19,7 @@ import java.util.List;
public abstract class AbstractCanvas { public abstract class AbstractCanvas {
private Element lsystem; private Element lSystem;
public State parsedState = State.FINISH_OR_NULL; public State parsedState = State.FINISH_OR_NULL;
public JFrame frame; public JFrame frame;
protected FPSAnimator animator; protected FPSAnimator animator;
@ -41,7 +41,7 @@ public abstract class AbstractCanvas {
public void windowClosing(WindowEvent e) { public void windowClosing(WindowEvent e) {
frame.dispose(); frame.dispose();
setVisible(false); setVisible(false);
lsystem = null; lSystem = null;
parsedState = State.FINISH_OR_NULL; parsedState = State.FINISH_OR_NULL;
System.gc(); System.gc();
} }
@ -61,9 +61,13 @@ public abstract class AbstractCanvas {
frame.setVisible(bl); frame.setVisible(bl);
} }
public void setLsystem(String axiom, List<Pair<String, String>> rules, int iterations) { public Element getLSystem() {
return lSystem;
}
public void setLSystem(String axiom, List<Pair<String, String>> rules, int iterations) {
parsedState = State.LOAD; parsedState = State.LOAD;
this.lsystem = Parser.parse(Rewrite.rewrite(axiom, rules, iterations)); this.lSystem = Parser.parse(Rewrite.rewrite(axiom, rules, iterations));
parsedState = State.FINISH_OR_NULL; parsedState = State.FINISH_OR_NULL;
} }

View File

@ -4,6 +4,7 @@ import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable; import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.glu.GLU; import com.jogamp.opengl.glu.GLU;
import com.jogamp.opengl.util.gl2.GLUT; import com.jogamp.opengl.util.gl2.GLUT;
import lsystem.engine.Element;
import lsystem.utils.Pair; import lsystem.utils.Pair;
import java.util.LinkedList; import java.util.LinkedList;
@ -18,8 +19,6 @@ public class GLEventListener implements com.jogamp.opengl.GLEventListener {
private final float[] light_0_position = {1000f, 1000f, 1000f, 1f}; private final float[] light_0_position = {1000f, 1000f, 1000f, 1f};
private final float[] material_specular = {0.8f, 0.8f, 0.8f, 0.8f}; private final float[] material_specular = {0.8f, 0.8f, 0.8f, 0.8f};
private float angle = 0f;
private final LinkedList<Pair<Integer, Integer>> prismPosition = new LinkedList<>(); private final LinkedList<Pair<Integer, Integer>> prismPosition = new LinkedList<>();
private final GLU glu; private final GLU glu;
@ -89,35 +88,33 @@ public class GLEventListener implements com.jogamp.opengl.GLEventListener {
gl.glTranslatef(0, 0, 0); gl.glTranslatef(0, 0, 0);
DrawHelper.placeCamera(gl, canvas); DrawHelper.placeCamera(gl, canvas);
glu.gluLookAt(canvas.camera[0], canvas.camera[1], canvas.camera[2], canvas.camera[0], canvas.camera[1], canvas.camera[2] - 1, 0f, 1f, 0f); glu.gluLookAt(canvas.camera[0], canvas.camera[1], canvas.camera[2], canvas.camera[0], canvas.camera[1], canvas.camera[2] - 1, 0f, 1f, 0f);
gl.glPushMatrix(); gl.glPushMatrix();
gl.glTranslatef(0f, 0f, -4f); gl.glRotatef(90f, -1f, 0f, 0f);
gl.glRotatef(angle, 0f, 1f, 0f); displayLSystem(gl, glut, canvas.getLSystem());
gl.glColor3f(1.0f, 0.0f, 1.0f);
glut.glutSolidSphere(2f, 20, 20);
gl.glPopMatrix(); gl.glPopMatrix();
gl.glPushMatrix();
gl.glTranslatef(2f, 0.75f, 1.25f);
gl.glRotatef(angle, 0f, 1f, 0f);
gl.glColor3f(0.5f, 0.0f, 1.0f);
glut.glutSolidSphere(0.75f, 20, 20);
gl.glPopMatrix();
gl.glPushMatrix();
gl.glColor3f(1f, 1f, 1f);
DrawHelper.drawRectangularPrism(gl, -3f, 0f, -2f, -2.5f, 1.5f, -1.5f);
glut.glutSolidCylinder(0.25f, 1.5f, 15, 2);
gl.glPopMatrix();
angle = (angle + 0.1f) % 360;
DrawHelper.drawAxes(gl, glut); DrawHelper.drawAxes(gl, glut);
DrawHelper.drawDebugInformation(gl, glut, canvas); DrawHelper.drawDebugInformation(gl, glut, canvas);
gl.glFlush(); gl.glFlush();
fps++; fps++;
} }
private void displayLSystem(GL2 gl, GLUT glut, Element element) {
gl.glPushMatrix();
gl.glRotatef(element.rotation[0] * 360 , 1f, 0f, 0f);
gl.glRotatef(element.rotation[1] * 360, 0f, 1f, 0f);
gl.glRotatef((element.rotation[0] + element.rotation[1]) * 360, 0f, 0f, 1f);
gl.glTranslated(-Math.sin(element.rotation[0]), -Math.sin(element.rotation[1]), -Math.sin(element.rotation[0] + element.rotation[1]));
gl.glBegin(GL2.GL_LINES);
glut.glutSolidCylinder(0.25f, 1f, 20, 20);
gl.glEnd();
gl.glTranslatef(0f, 0f, 1f);
for(Element child : element.children) {
displayLSystem(gl, glut, child);
}
gl.glPopMatrix();
}
@Override @Override
public void reshape(GLAutoDrawable glAutoDrawable, int x, int y, int width, int height) { public void reshape(GLAutoDrawable glAutoDrawable, int x, int y, int width, int height) {
GL2 gl = glAutoDrawable.getGL().getGL2(); GL2 gl = glAutoDrawable.getGL().getGL2();

View File

@ -17,6 +17,7 @@ public class Listener implements ActionListener, KeyListener {
Integer index; Integer index;
String type; String type;
Integer nbAxioms; Integer nbAxioms;
Thread parserThread = null;
public Listener(MainFrame frame, Integer index, String type, Tab tab){ public Listener(MainFrame frame, Integer index, String type, Tab tab){
this.tab = tab; this.tab = tab;
@ -25,6 +26,7 @@ public class Listener implements ActionListener, KeyListener {
this.type = type; this.type = type;
nbAxioms = 0; nbAxioms = 0;
} }
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
switch (type) { switch (type) {
@ -52,13 +54,15 @@ public class Listener implements ActionListener, KeyListener {
openDialog("Veuillez fermer la fenêtre 3D avant de lancer une nouvelle génération"); openDialog("Veuillez fermer la fenêtre 3D avant de lancer une nouvelle génération");
} else if(Main.joglFrame.parsedState == AbstractCanvas.State.LOAD) { } else if(Main.joglFrame.parsedState == AbstractCanvas.State.LOAD) {
openDialog("Une génération est actuellement en cours, impossible d'en relancer un autre"); openDialog("Une génération est actuellement en cours, impossible d'en relancer un autre");
openDialog("Une génération est actuellement en cours, impossible d'en relancer un autre");
} else if (!parser.isCorrect()) { } else if (!parser.isCorrect()) {
openDialog("Vos règles ou votre axiome ne sont pas correctement écrites, veuillez recommencer"); openDialog("Vos règles ou votre axiome ne sont pas correctement écrites, veuillez recommencer");
} else { } else {
new Thread(() -> { parserThread = new Thread(() -> {
Main.joglFrame.setLsystem(axiom, parser.parseRules(), tab.getNbIterations()); Main.joglFrame.setLSystem(axiom, parser.parseRules(), tab.getNbIterations());
Main.joglFrame.setVisible(true); Main.joglFrame.setVisible(true);
}).start(); });
parserThread.start();
} }
break; break;

View File

@ -2,8 +2,7 @@ package lsystem.screen.main;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.util.ArrayList; import java.util.Arrays;
import java.util.List;
public class Tab extends JPanel{ public class Tab extends JPanel{
@ -102,12 +101,12 @@ public class Tab extends JPanel{
public JTextField getTextField(byte i){ public JTextField getTextField(byte i){
return (i == 0) ? axiomeField : rulesField; return (i == 0) ? axiomeField : rulesField;
} }
public void changeList(String stringToAdd, JTextArea list,int nbAxioms) { public void changeList(String stringToAdd, JTextArea list, int nbAxioms) {
if(nbAxioms>0) if(nbAxioms > 0)
JOptionPane.showMessageDialog(null, "Nombre maximal d'axiomes créés"); JOptionPane.showMessageDialog(null, "Nombre maximal d'axiomes créés");
else { else {
list.append(stringToAdd); list.append(stringToAdd);
if (stringToAdd == ";") if (stringToAdd.equals(";"))
nbAxioms++; nbAxioms++;
} }
@ -118,14 +117,10 @@ public class Tab extends JPanel{
return str; return str;
} }
public java.util.List<String> getRules(){ public java.util.List<String> getRules(){
List<String> list = new ArrayList<>();
String str = rulesList.getText(); String str = rulesList.getText();
str = str.substring(10).replaceAll(";", ""); str = str.substring(10).replaceAll(";", "");
String[] strsplit = str.split("\n"); String[] strsplit = str.split("\n");
for(int y = 0;y<strsplit.length;y++){ return Arrays.asList(strsplit);
list.add(strsplit[y]);
}
return list;
} }
public int getNbIterations(){ public int getNbIterations(){
return (int) itSpinner.getValue(); return (int) itSpinner.getValue();