// Wormhout10.pde // OuvertureXml.pde // // Gerard Paresys Guy Kayser // 3 1 2015 // Processing 2.0.3 // // A partir de http://www.openprocessing.org/sketch/77718 // "Worm" de Adam Lastowka // "A worm, building a landscape by "tunneling" all over it, raising and lowering the terrain. // Somewhat like the sandworms in "Dune" by Frank Herbert, // except for the rainbows and strange fading trails." // en remplacant Maker[] Worm = new Maker[1]; // par Maker Worm = new Maker(); (1 seul worm) // // Utilise la library minim incluse dans Processing 2 // http://code.compartmental.net/minim/ // // Utilise la "contributed library" peasycam by Jonathan Feinberg // http://mrfeinberg.com/peasycam/ // // PeasyCam: Souris Molette : Zoom // Souris Clic droit + Drag : Zoom // Souris Clic + Drag : Rotation // Souris 2 x Clic : Reset position // Souris cmd + Clic + Drag : Translate (MacOS) // Touche Clavier: // E Erosion Lissage // R Reset // C Couleur Worm // S Sauve l'ecran (format png) // L Lumiere // // Si le dossier data contient 5 fichiers nommés: // XXX.xml (format Praat TextGrid sauve en UTF8) // XXX.mp3 // XXX_Pitch.txt // XXX_Intensity.txt // XXX256.png 256x256 pixels // le sketch les ouvre // sinon un selecteur de fichiers s'ouvre, choisir alors un fichier XXX.xml... // // Modifier la ligne 53 au besoin // // Le dossier data doit contenir le fichier ArialMT-12.vlw // import ddf.minim.*; // pour AudioPlayer import peasy.*; String NomFichierXML = "maore.xml"; // les 5 fichiers "maore..." doivent etre dans le dossier data boolean Lumiere = true; // boolean AfficheT = false; // Chrono Boolean Couleur = false; boolean Verbose = false; XML[] Traduction, Transcription; int NombreSegment; String[] LignesPitch; String[] LignesIntensity; float[] LignePitch, LigneIntensity; boolean FichierOuvert = false; Minim minim; AudioPlayer player; PeasyCam pcam; float[][] hm = new float[256][256]; // hm[x][y] = brightness(Image) float[][] hm2 = new float[256][256]; int hmlengthdemi = hm.length / 2; float M = 2; // M = diametre du worm boolean Pause = false; float Temps, TempsPause = 0, TempsDebutPause = 0; PFont maFonte; Maker Worm = new Maker(); float wormTemp; int x, y, Alea; float Distance, h; PImage Image1; color MonPixel; int IndexXML = 0, Segment; float xmin, xmax; // Temps en seconde String Content1 = "", Content2 = "", Content = "", Nom = ""; float Intensite; float Facteur; void setup() { size(800, 600, P3D); // P3D OPENGL // Image1 = loadImage(NomFichierCarte); // background(Image1); // image(Image1, 0, 0, width, height); pcam = new PeasyCam(this, width/2, height/2, 0, 500); // PeasyCam(PApplet parent, double lookAtX, double lookAtY, double lookAtZ, double distance); pcam.setMinimumDistance(50); pcam.setMaximumDistance(1000); pcam.rotateX(-PI/4); noStroke(); // generateLandscape(); // colorMode(HSB); // RGB HSB frameRate(60); // frameRate(2); // A mettre pour mieux comprendre // maFonte = createFont("AdventPro-Thin", 12); // maFonte = createFont("Georgiazut", 18); maFonte = loadFont("ArialMT-12.vlw"); println("hm.length = " + hm.length); File Fichier = new File(dataPath(NomFichierXML)); if (Fichier.exists()) { Ouverture(NomFichierXML); Nom = split(Fichier.getName(), '.')[0]; } else selectInput("select the XML File (format Praat textGrid):", "fileSelected"); } void draw() { background(255, 0, 0); // image(Image1, 0, 0); // image(Image1, 0, 0, width, height); if (Lumiere) lights(); if (! Pause) Temps = (millis() - TempsPause) / 1000.0; //temps en ms if (FichierOuvert) { if (IndexXML < (NombreSegment-1)) { if (Temps > xmax) { // Passage au segment suivant IndexXML = IndexXML + 1; Content = Traduction[IndexXML].getContent(); Content2 = Transcription[IndexXML].getContent(); if (Verbose) println(); if (Verbose) println("IndexXML = " + IndexXML); if (Content == null) IndexXML = IndexXML + 1; else if (Content.equals("_") == true) IndexXML = IndexXML + 1;//Elimination des caracteres _ qui separe les segments // else if ((Temps > xmin) && ! Pause) { else if (! Pause) { Segment = Traduction[IndexXML].getInt("n"); xmin = Traduction[IndexXML].getFloat("xmin"); xmax = Traduction[IndexXML].getFloat("xmax"); Content1 = trim(Content); Content2 = trim(Content2); println(Content1); println(Content2); } } } else Pause = true; if (Temps < LignesIntensity.length) { LigneIntensity = float(split(LignesIntensity[int(Temps * Facteur)], " ")); Intensite = LigneIntensity[1]; Intensite = (Intensite - 40) / 12; Intensite = max(Intensite, 0); // println("Temps = " + Temps + " Intensite = " + Intensite); } translate(width/2, height/2); if (! Pause) { temGen(); } paintLandscape(); // Lissage(); textFont(maFonte, 12); fill(0, 255, 0); // Texte vert textAlign(CENTER); // text(Content1, 0, 170, 60 ); // Traduction translate(-200,0,60); // text(Content1, 0, 220, 400, 100 ); // Traduction text(Content2, 0, 220, 400, 100 ); // Transcription } // if (AfficheT) AfficheTemps(Temps); frame.setTitle(Nom + " " + int(Temps * 10) / 10.0 + " sec " + int(10 * frameRate) / 10.0 + " fps"); } void keyPressed() { if ( key == ' ' ) temGen(); // barre d'espace else if ( key == 'e' || key == 'E' ) Lissage(); // Erosion Lissage else if ( key == 'r' || key == 'R' ) { generateLandscape(); xmax = 0; IndexXML = -1; Pause = false; TempsPause = millis(); PlayerAudioDebut(); } else if ( key == 'c' || key == 'C' ) Couleur = !Couleur; // Touche C Worm rouge // else if ( key == 's' || key == 'S' ) saveFrame("Screen" + frameCount + ".png"); else if ( key == 's' || key == 'S' ) saveFrame(Nom + "-" + frameCount + ".png"); else if ( key == 'l' || key == 'L' ) Lumiere = !Lumiere; // Touche L Lumiere // else if ( key == 't' || key == 'T' ) AfficheT = !AfficheT; // Touche T Affiche Temps en bas a droite } void generateLandscape() { Image1 = loadImage(NomFichierCarte); Image1.loadPixels(); HeightMap(); // for (int i = 0; i < 600; i++) temGen(); } void HeightMap() { for ( x = 0; x < hm.length; x++) { for ( y = 0; y < hm.length; y++) { // hm[x][y] = 0; // hm[x][y] = brightness(Image1.pixels[x + (y * hm.length)])/ 255.f; // hm[x][y] = brightness(Image1.pixels[x*4 + (y*4*3 * hm.length)])/ 25.f; hm[x][y] = brightness(Image1.pixels[x + (y * hm.length)])/ 8.f; // println(brightness(Image1.pixels[x*4 + (y*4*3 * hm.length)])/ 25.f); // if (x == 128) { // println("generateLandscape hm[128][" + y + "] = " + hm[128][y] + " Distance = " + Distance); // } } } // for (int i = 0; i < 600; i++) temGen(); } void temGen() { // - hmlengthdemi < Worm.x < + hmlengthdemi // - hmlengthdemi < Worm.yx < + hmlengthdemi // Worm.x += sin(Worm.wormTheta)*2; // Worm.y += cos(Worm.wormTheta)*2; Worm.x += sin(Worm.wormTheta); Worm.y += cos(Worm.wormTheta); Worm.wormTheta += Worm.wormThetaDelta; Worm.wormThetaDelta += random(-0.1, 0.1); // Worm.wormThetaDelta /= 1.05; Worm.wormThetaDelta /= 1.30; // 1.05 le worm tourne beaucoup 1.25 tourne peu Mettre 1.20 if (Worm.x > hmlengthdemi - 10) Worm.wormTheta = Worm.wormTheta - HALF_PI; else if (Worm.x < - hmlengthdemi + 10) Worm.wormTheta = Worm.wormTheta - HALF_PI; else if (Worm.y > hmlengthdemi - 10) Worm.wormTheta = Worm.wormTheta - HALF_PI; else if (Worm.y < - hmlengthdemi + 10) Worm.wormTheta = Worm.wormTheta - HALF_PI; // Alea = int(random(hm.length)); x = int(Worm.x + hmlengthdemi); y = int(Worm.y + hmlengthdemi); h = Intensite * 3.0; // h = 20; hm[x][y] = hm[x][y] + h*1.5; x = x - 1; hm[x][y] = hm[x][y] + h; x = x + 2; hm[x][y] = hm[x][y] + h; x = x - 1; y = y - 1; hm[x][y] = hm[x][y] + h; y = y + 2; hm[x][y] = hm[x][y] + h; if (false) { for ( x = 1; x < hm.length-1; x++) { for ( y = 1; y < hm.length-1; y++) { Distance = dist((x-hm.length/2)/M, (y-hm.length/2)/M, Worm.x/M, Worm.y/M); // if (Distance != 0) hm[x][y] = hm[x][y] + sin(TWO_PI / (Distance * Distance)) * 4.5 * sin(Worm.wormTheta); // if (Distance != 0) hm[x][y] = hm[x][y] + sin(TWO_PI / (Distance * Distance)) * 4.5 * sin(Worm.wormTheta); // if (Distance != 0) hm[x][y] = hm[x][y] + (sin(TWO_PI / (Distance * Distance)) + 0) * 4.5 * (sin(Worm.wormTheta) + 0.5); // +1 pour que le worm soit toujours a la surface // if (Distance != 0) hm[x][y] = hm[x][y] + (sin(TWO_PI / (Distance * Distance)) + 0) * 4.5 * (sin(Worm.wormTheta) + 0.5); // +1 pour que le worm soit toujours a la surface // if ((Distance != 0) && (Distance < 1)) hm[x][y] = hm[x][y] + (sin(TWO_PI / (Distance * Distance)) + 0) * 4.5 ; // if (Distance != 0) hm[x][y] = hm[x][y] + (sin(TWO_PI / (Distance * Distance)) + 0) * 4.5 ; // if (Distance != 0) hm[x][y] = hm[x][y] + min((1 / (Distance * Distance)), 10) ; // if ((Distance != 0) && (Distance < 1)) hm[x][y] = hm[x][y] + min((1 / (Distance * Distance)), 10) ; // if ((Distance != 0) && (Distance < 1)) hm[x][y] = hm[x][y] + min((1 / (Distance)), 10) ; // // else if ((Distance == 0) && (Distance < 1)) hm[x][y] = hm[x][y] + 10 ; // // if (Distance < 1) hm[x][y] = hm[x][y] + 3 ; // // Intensite = -3; if (Distance < Intensite) { hm[x][y] = hm[x][y] + 3; // // hm[x][y] = brightness(Image1.pixels[x + (y * hm.length)])/ 8.f; // Image1.pixels[x + (y * hm.length)] = color(hm[x][y] * 8); Image1.pixels[x + (y * hm.length)] = color(hm[x][y] * 8); } if (Distance < Intensite) hm[x][y] = (hm[x][y]*2 + hm[x+1][y] + hm[x-1][y] + hm[x][y+1] + hm[x][y-1])/6; // if (Distance < 0.4) Image1.pixels[x + (y * hm.length)] = Image1.pixels[x + (y * hm.length)] + color(100, 0, 0, 150); // if ((Distance < 0.2) && Couleur ) Image1.pixels[x + (y * hm.length)] = color(red(Image1.pixels[x + (y * hm.length)])+255, green(Image1.pixels[x + (y * hm.length)])+255, blue(Image1.pixels[x + (y * hm.length)])+255); // if ((Distance < Intensite / 2) && Couleur ) { // MonPixel = Image1.pixels[x + (y * hm.length)]; // Image1.pixels[x + (y * hm.length)] = color(red(MonPixel)+255, green(MonPixel), blue(MonPixel)); // hm[x][y] = brightness(Image1.pixels[x + (y * hm.length)])/ 8.f; // } // if (Distance != 0) { // hm[x][y] = hm[x][y] - min((1 / (Distance)), 15) ; // +1 pour que le worm soit toujours a la surface // if (x > 1) hm[x-1][y] = hm[x-1][y] - min((0.1 / (Distance)), 15) ; // +1 pour que le worm soit toujours a la surface // if (x < hm.length-1) hm[x+1][y] = hm[x+1][y] - min((0.1 / (Distance)), 15) ; // +1 pour que le worm soit toujours a la surface // if (y > 1) hm[x][y-1] = hm[x][y-1] - min((0.1 / (Distance)), 15) ; // +1 pour que le worm soit toujours a la surface // if (y < hm.length-1) hm[x][y+1] = hm[x][y+1] - min((0.1 / (Distance)), 15) ; // +1 pour que le worm soit toujours a la surface // } // if (x == 128) hm[x][y] = 0; // Creuse ligne verticale // if (y == 138) hm[x][y] = max( hm[x][y] - 5, 0); // Creuse ligne horizontale // if (y == Alea-1) hm[x][y] = max( hm[x][y] - 5, 0); // Creuse ligne horizontale // if (y == Alea) hm[x][y] = max( hm[x][y] + 5, 0); // Creuse ligne horizontale // if (y == Alea+1) hm[x][y] = max( hm[x][y] - 5, 0); // Creuse ligne horizontale // if (x == 128) println("hm[128][" + y + "] = " + hm[128][y] + " Distance = " + Distance); } } } for ( x = 1; x < hm.length-1; x++) { for ( y = 1; y < hm.length-1; y++) { Distance = dist((x-hm.length/2)/M, (y-hm.length/2)/M, Worm.x/M, Worm.y/M); if (Distance < 3) { hm2[x][y] = (hm[x][y]*2 + hm[x+1][y] + hm[x-1][y] + hm[x][y+1] + hm[x][y-1])/6; // Image1.pixels[x + (y * hm.length)] = color(hm2[x][y] * 8); // Image1.pixels[x + (y * hm.length)] = color((hm2[x][y] * 8)+255, (hm2[x][y] * 8), (hm2[x][y] * 8)); // Image1.pixels[x + (y * hm.length)] = color((hm2[x][y] *8), 0, 0); // Image1.pixels[x + (y * hm.length)] = color((hm2[x][y] * 16), (hm2[x][y] * 8), (hm2[x][y] * 8)); if (Couleur) Image1.pixels[x + (y * hm.length)] = color((hm2[x][y] *8), 0, 0); else Image1.pixels[x + (y * hm.length)] = color(hm2[x][y] * 8); } } } for ( x = 1; x < hm.length-1; x++) { for ( y = 1; y < hm.length-1; y++) { Distance = dist((x-hm.length/2)/M, (y-hm.length/2)/M, Worm.x/M, Worm.y/M); if (Distance < 3) { hm[x][y] = hm2[x][y]; } } } // HeightMap(); // Image1.updatePixels(); // Lissage(); } void paintLandscape() { // stroke(128); noStroke(); // fill(0,0,255); scale(2); for ( x = 3; x < hm.length-5; x++) { beginShape(QUADS); for ( y = 3; y < hm.length-5; y++) { // fill(abs(4*hm[x][y]), 255, 255);//origin fill(Image1.pixels[x + (y * hm.length)]); vertex(x - hmlengthdemi, y - hmlengthdemi, hm[x] [y]); vertex(x + 1 - hmlengthdemi, y - hmlengthdemi, hm[x+1][y]); vertex(x + 1 - hmlengthdemi, y + 1 - hmlengthdemi, hm[x+1][y+1]); vertex(x - hmlengthdemi, y + 1 - hmlengthdemi, hm[x] [y+1]); } endShape(CLOSE); } scale(0.5); } void Lissage() { // for(float x = 1; x < hm.length-1; x++) { // for(float y = 1; y < hm.length-1; y++) { // hm[(int)x][(int)y] = (hm[(int)x][(int)y]*2 + hm[(int)x+1][(int)y] + hm[(int)x-1][(int)y] + hm[(int)x][(int)y+1] + hm[(int)x][(int)y-1])/6; // } // } for ( x = 1; x < hm.length-1; x++) { for ( y = 1; y < hm.length-1; y++) { hm2[x][y] = (hm[x][y]*2 + hm[x+1][y] + hm[x-1][y] + hm[x][y+1] + hm[x][y-1])/6; } } for ( x = 1; x < hm.length-1; x++) { for ( y = 1; y < hm.length-1; y++) { hm[x][y] = hm2[x][y]; } } println("Lissage"); } class Maker { float x; float y; float wormTheta; float wormThetaDelta; } void FinOuverture() { minim = new Minim(this); player = minim.loadFile(NomFichierAudio, 1024); FichierOuvert = true; xmax = 0; IndexXML = -1; Facteur = LignesIntensity.length / LigneIntensity[0]; //Nombre de lignes / Duree totale fichier XXX_Intensity.txt Lissage(); Lissage(); player.play(); TempsPause = millis(); } void PlayerAudioDebut() { player.close(); player = minim.loadFile(NomFichierAudio, 1024); player.play(); TempsPause = millis(); } //void AfficheTemps(float T) { // fill(255); // textFont(maFonte, 12); // textAlign(LEFT); // text(int(T * 10) / 10.0 + " sec frameRate = "+ (int(10 * frameRate)) / 10.0 + "/sec", -200, 150, 60); //}