import processing.core.*; import processing.data.*; import processing.event.*; import processing.opengl.*; import java.util.*; import java.nio.file.*; import drop.*; import java.awt.Frame; import java.util.HashMap; import java.util.ArrayList; import java.io.File; import java.io.BufferedReader; import java.io.PrintWriter; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; public class BAconverter4_nomovie extends PApplet { //import controlP5.*; //import java.io.*; //import java.io.File; //import static java.nio.file.StandardOpenOption.*; //ControlP5 cp5; //import processing.video.*; //Movie bgmov; SDrop drop; int buttonCount = 10; Button buttons[]; PImage[] texture_pi = new PImage[7]; PImage render, kaff; int ts = 20; boolean waitForExport; int exporttimer, exportinc; int imgCount; public void setup() { frameRate(30); //cp5 = new ControlP5(this); //List l = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h"); // cp5.addScrollableList("dropdown") // .setPosition(100, 100) // .setSize(200, 100) // .setBarHeight(20) // .setItemHeight(20) // .addItems(l) //.setType(ScrollableList.LIST) // currently supported DROPDOWN and LIST // ; drop = new SDrop(this); PImage icon = loadImage("icon.png"); surface.setIcon(icon); surface.setTitle("Boreal Alyph pbr2vmt"); textSize(ts); sa = new SecondApplet(); buttons = new Button[buttonCount]; buttons[0] = new Button("flip metallic", 15, height/2-(ts+ts/10)); buttons[1] = new Button("flip roughness", 15, height/2); buttons[2] = new Button("flip ao", 15, height/2+(ts+ts/10)); buttons[3] = new Button("save", width/7*5, height/2+2*(ts+ts/10)); buttons[4] = new Button("restore", 15, height/2+2*(ts+ts/10)); buttons[5] = new Button("skip", width/2-19, height/2+2*(ts+ts/10)); buttons[6] = new Button("yes", width/2+15, height/2+2*(ts+ts/10)); buttons[7] = new Button("no", width/2-40, height/2+2*(ts+ts/10)); buttons[8] = new Button("back", 15, 20); buttons[9] = new Button("Compile", width/2-38,height/2); kaff = loadImage("kaff.png"); // bgmov = new Movie(this, "bgmov.mp4"); // bgmov.loop(); } int readPhase_i; String inputName = ""; boolean intro_b = true; String[][] loadText_s = { {"1/3 Generate PBR map", "2/3 Generate PBR map", "3/3 Generate PBR map", "1/4 Generate .vtf", "2/4 Generate .vtf", "3/4 Generate .vtf", "4/4 Generate .vtf", "1/5 Generate .qc", "2/5 Generate .qc", "3/5 Generate .qc", "4/5 Generate .qc", "5/5 Generate .qc", "", "Enter Model / Material Name"}, {"Metallic Map", "Roughness Map", "Ambient Occlusion Map", "PBR", "Albedo Map", "Normal Map", "Height Map", "$body *.smd", "$sequence idle *.smd", "$collisionbox *.smd", "$surfaceprop", "$staticprop?", "", ""}, {"Drag and Drop here", "Drag and Drop here", "Drag and Drop here", "Configure", "Drag and Drop here", "Drag and Drop here", "Drag and Drop here", "Drag and Drop here", "Drag and Drop here", "Drag and Drop here", "select", "choose", "", ""}}; //void movieEvent(Movie m) { // m.read(); //} public void draw() { background(29, 30, 30); // image(bgmov,0,0); image(kaff, width-kaff.width, 0); textAlign(CENTER); if (loading_b) { fill(255); text("Hold on", width/2, height/2); } else if (error_b) { errorDraw(); } else if (intro_b) { introDraw(); } else if (!smd_b) { texDraw(); } else { smdDraw(); } if (waitForExport) { exportVMT(); } back(); ad(); textSize(10); text(str(readPhase_i) + "/12", 15, 10); textSize(ts); //println(readPhase_i); } public void back() { if (readPhase_i > 0) { textSize(10); buttons[8].update(); buttons[8].display(); textSize(ts); } } boolean error_b; int error_i; String error_s; boolean loading_b; String filePath, fileName, nameStamm, nameOut, nameExt; boolean loadSMD; boolean isImage; int textureWidth; int textureHeight; public void dropEvent(DropEvent theDropEvent) { //file loading if (!intro_b && theDropEvent.isImage()) { isImage = true; getImage(theDropEvent); if (readPhase_i == 2) { PApplet.runSketch(args, sa); sa.loadMRAO(false, false, false); } else { sa.loadNewTex(); } } if (!intro_b && theDropEvent.isFile() && !isImage) { getSMD(theDropEvent); } isImage = false; } class Button { boolean hover; String title; int x, y, w, h; Button(String title_, int x_, int y_) { title = title_; x = x_; y = y_; w = PApplet.parseInt(textWidth(title)); h = PApplet.parseInt(ts); } public void update() { if (mouseX > x && mouseX < x + w && mouseY > y-h && mouseY < y) { hover = true; } else { hover = false; } w = PApplet.parseInt(textWidth(title)); h = PApplet.parseInt(ts); } public void display() { if (hover) { fill(195, 231, 182, 127); rect(x-(w/5), y+(h/5)+3, w+(2*(w/5)), -h-(2*(h/5)), 5); fill(255); } textAlign(CORNER); text(title, x, y); } } public void mousePressed() { if (buttons[0].hover) { sa.loadMRAO(true, false, false); buttons[0].hover = false; } else if (buttons[1].hover) { sa.loadMRAO(false, true, false); buttons[1].hover = false; } else if (buttons[2].hover) { sa.loadMRAO(false, false, true); buttons[2].hover = false; } else if (buttons[3].hover) { saveImage(); buttons[3].hover = false; } else if (buttons[4].hover) { sa.flipRGB[0] = false; sa.flipRGB[1] = false; sa.flipRGB[2] = false; sa.loadMRAO(false, false, false); buttons[4].hover = false; } else if (buttons[5].hover) { skip(); if (readPhase_i == 3 && imgCount == 0) { skip(); } buttons[5].hover = false; } else if (buttons[6].hover) { isStaticProp = true; nextPhase(); buttons[6].hover = false; } else if (buttons[7].hover) { isStaticProp = false; nextPhase(); buttons[7].hover = false; } else if (buttons[8].hover) { if (imgCount == 0 && readPhase_i == 4) { readPhase_i--; } readPhase_i--; buttons[8].hover = false; } else if (buttons[9].hover) { compile(); buttons[9].hover = false; } else if (adhover) { link("http://www.epistle3.org/"); adhover = false; } } /* todo - add more anim dynamic arraylist */ public void nextPhase() { if (skip && readPhase_i == 2 && imgCount > 0) { PApplet.runSketch(args, sa); sa.loadMRAO(false, false, false); } if (readPhase_i == 3 && appActive) sa.kill(); if (readPhase_i == 6) { if (filePath == null) { //crit_error = true; error_s = "Warning: No texture"; error_b = true; readPhase_i--; } smdInit(); } if (readPhase_i == 7) { if (skip) { //crit_error = true; error_s = "No base model"; error_b = true; readPhase_i--; } bodyFileName = smdFileName; idleFileName = smdFileName; writeQC(); } if (readPhase_i == 8) { if (!skip) { idleNotBody = true; } idleFileName = smdFileName; writeQC(); } if (readPhase_i == 9) { if (!skip) { collisionFileName = smdFileName; hasCollision = true; writeQC(); } } if (readPhase_i == 10) { // if (!surfaceProp.equals("")){ writeQC(); //}; } if (readPhase_i == 11) { writeQC(); } readPhase_i++; skip = false; } boolean smd_b; public void smdInit() { smd_b = true; } public void smdDraw() { if (readPhase_i != 12 && readPhase_i != 7 && readPhase_i != 11) { textSize(14); buttons[5].update(); buttons[5].display(); textSize(ts); } if (readPhase_i == 10) { ts = 20; textAlign(CENTER); textSize(ts); text(surfaceProp, width/2, height/2+(ts+ts/10)); String dash = "_"; if (second() % 2 != 0) { text(dash, width/2 + textWidth(surfaceProp)/2 + 5, height/2+(ts+ts/10)); } } if (readPhase_i == 11) { buttons[6].update(); buttons[6].display(); buttons[7].update(); buttons[7].display(); } if (readPhase_i == 12){ buttons[9].update(); buttons[9].display(); } textAlign(CENTER); ts = 15; textSize(ts); text(loadText_s[0][readPhase_i], width/2, 1*ts); ts = 12; textSize(ts); text(loadText_s[2][readPhase_i], width/2, 3*ts); ts = 20; textSize(ts); text(loadText_s[1][readPhase_i], width/2, 3*ts); } String smdFileName; String smdNameStamm; String smdFilePath; public void getSMD(DropEvent theDropEvent) { smdFileName = theDropEvent.file().getName(); println(smdFileName); nameExt = smdFileName.substring(smdFileName.lastIndexOf('.')); println(nameExt); if (!nameExt.equals(".smd") && !nameExt.equals(".SMD")) { error_s = "Not a .smd file"; error_b = true; } else { //if (theDropEvent.file().getParent() != smdFilePath) exit(); smdFilePath = theDropEvent.file().getParent(); //smdNameStamm = smdFileName.substring(0, fileName.lastIndexOf('.')); copyFile(smdFilePath + "\\" + smdFileName, filePath + "\\models\\pbr\\" + inputName + "\\" + smdFileName); //writeQC(); nextPhase(); } } boolean idleNotBody, hasCollision, hasSurfaceProp, isStaticProp; String surfaceProp = ""; String bodyFileName, idleFileName, collisionFileName; public void writeQC() { String[] qc={ "$modelname \"\\pbr\\" + inputName + "\\" + inputName +".mdl\"", "$body " + inputName + " \"" + bodyFileName + "\"", "", "$cdmaterials \"\\pbr\\" + inputName + "\"", "", "", "", "", "", "" }; if (idleNotBody) qc[2] = "$sequence idle \""+ idleFileName + "\""; else qc[2] = "$sequence idle \"" + bodyFileName + "\""; if (hasCollision) qc[4] = "$collisionmodel \"" + collisionFileName +"\""; if (!surfaceProp.equals("")) qc[5] = "$surfaceprop " + surfaceProp; else qc[5] = ""; if (isStaticProp) qc[6] = "$staticprop"; saveStrings(filePath + "\\models\\pbr\\" + inputName + "\\" + inputName + ".qc", qc); } boolean condition; public void texDraw() { if (readPhase_i == 3) { ts = 12; textSize(ts); for (int i = 0; i < 5; i ++) { if (i == 3) { ts = 20; textSize(ts); } buttons[i].update(); buttons[i].display(); } } ts = 14; textSize(ts); buttons[5].update(); buttons[5].display(); textAlign(CENTER); ts = 15; textSize(ts); text(loadText_s[0][readPhase_i], width/2, 1*ts); ts = 12; textSize(ts); text(loadText_s[2][readPhase_i], width/2, 3*ts); ts = 20; textSize(ts); text(loadText_s[1][readPhase_i], width/2, 3*ts); } public void getImage(DropEvent theDropEvent) { if (readPhase_i != 3 && !loadSMD) { texture_pi[readPhase_i] = theDropEvent.loadImage(); while (texture_pi[readPhase_i].width < 10) { loading_b = true; println("loading.."); } if (filePath == null) filePath = theDropEvent.file().getParent(); fileName = theDropEvent.file().getName(); nameStamm = fileName.substring(0, fileName.lastIndexOf('.')); textureWidth = texture_pi[readPhase_i].width; textureHeight = texture_pi[readPhase_i].height; loading_b = false; //image loaded if (textureWidth != 0) { println("old: " + textureWidth + " new: " + texture_pi[readPhase_i].width); if (texture_pi[readPhase_i].width != textureWidth || texture_pi[readPhase_i].height != textureWidth) { error_s = "Images don't match in size"; error_b = true; } } if (!error_b) { // if (readPhase_i > 3) { if (readPhase_i != 3) { sa.loadNewTex(); saveImage(); imgCount++; } // } else { // readPhase_i++; // } } } } boolean foldersCreated; public void saveImage() { println(filePath); launch("mkdir " + filePath + "\\models"); launch("mkdir " + filePath + "\\models\\pbr"); launch("mkdir " + filePath + "\\models\\pbr\\" + inputName); launch("mkdir " + filePath + "\\materials"); launch("mkdir " + filePath + "\\materials\\pbr"); launch("mkdir " + filePath + "\\materials\\pbr\\" + inputName); foldersCreated = true; nameOut = dataPath("") + "\\mgaoa_map.tga"; if (readPhase_i == 0) { nameOut = dataPath("") + "\\metallic.tga"; } else if (readPhase_i == 1) { nameOut = dataPath("") + "\\roughness.tga"; } else if (readPhase_i == 2) { nameOut = dataPath("") + "\\ambientocclusion.tga"; } else if (readPhase_i == 4) { nameOut = dataPath("") + "\\albedo.tga"; } else if (readPhase_i == 5) { nameOut = dataPath("") + "\\normal.tga"; } else if (readPhase_i == 6) { nameOut = dataPath("") + "\\height.tga"; } render.save(nameOut); exporttimer = 3; waitForExport = true; } public void exportVMT() { loading_b = true; exportinc++; if (exportinc >= exporttimer * frameRate) { println("launching vtfcmd"); exportinc = 0; String vtfcmdpath = dataPath("") + "\\VTFCmd\\VTFCmd.exe"; println(vtfcmdpath + " -file \"" + nameOut + "\" -output \"" + filePath + "\\materials\\pbr\\" + inputName + "\" -format \"dxt5\""); launch(vtfcmdpath + " -file \"" + nameOut + "\" -output \"" + filePath + "\\materials\\pbr\\" + inputName + "\" -format \"dxt5\""); String[] vmt = { "VertexLitPBR", "{", " \"$AlbedoMap\" \"pbr\\" + inputName + "\\albedo\"", "", " \"$NormalMap\" \"pbr\\" + inputName + "\\normal\"", " \"$MetalRoughnessAmbientOccAniMaskMap\" \"pbr\\" + inputName + "\\mgaoa_map\"", " \"$HeightMap\" \"pbr\\" + inputName + "\\height\"", "", " \"$ParallaxHeightRatio\" \"0.1\"", " \"$MinParallaxSteps\" \"9\"", " \"$MaxParallaxSteps\" \"64\"", " \"$ParallaxViewStepBias\" \"1\"", "", " \"$PreintegratedFG\" \"pbr\\PreintegratedFG\"", "", "}" }; println(filePath + "\\" + inputName + ".vmt"); saveStrings(filePath + "\\materials\\pbr\\" + inputName + "\\" + inputName + ".vmt", vmt); loading_b = false; waitForExport = false; nextPhase(); } } SecondApplet sa; String[] args = {"TwoFrameTest"}; int pixelCount; String appTitle; boolean appActive; public class SecondApplet extends PApplet { public void setup() { //int w; //int h; //int w_old; //for(int i = 0; i < texture_pi.length; i++){ // int w_ = texture_pi[i].width; // if (texture_pi[i] // int w_old = //} int w = textureWidth; int h = textureWidth; //println(w); pixelCount = w*h; render = createImage(w, h, ARGB); surface.setResizable(true); surface.setSize(w, h); surface.setTitle(appTitle); appActive = true; if (readPhase_i == 3) loadMRAO(false, false, false); else loadNewTex(); } public void draw() { image(render, 0, 0); } public void kill() { surface.setVisible(false); } public void surfaceTitleSA(String title_) { String title = title_; surface.setTitle(title); } boolean[] flipRGB = {false, false, false}; public void loadNewTex() { render = texture_pi[readPhase_i].get(); } public void loadMRAO(boolean r_b_, boolean b_b_, boolean g_b_) { if (r_b_) { if (!flipRGB[0]) { flipRGB[0] = true; } else { flipRGB[0] = false; } } if (b_b_) { if (!flipRGB[1]) { flipRGB[1] = true; } else { flipRGB[1] = false; } } if (g_b_) { if (!flipRGB[2]) { flipRGB[2] = true; } else { flipRGB[2] = false; } } for (int i = 0; i < texture_pi.length; i++) { if (texture_pi[i] == null) { texture_pi[i] = createImage(textureWidth, textureHeight, ARGB); } } texture_pi[0].loadPixels(); texture_pi[1].loadPixels(); texture_pi[2].loadPixels(); render.loadPixels(); for (int i = 0; i < pixelCount; i++) { float r = red(texture_pi[0].pixels[i]); float g = green(texture_pi[1].pixels[i]); float b = blue(texture_pi[2].pixels[i]); if (flipRGB[0]) r = 255-r; if (flipRGB[1]) g = 255-g; if (flipRGB[2]) b = 255-b; render.pixels[i] = color(r, g, b); } render.updatePixels(); texture_pi[0].updatePixels(); texture_pi[1].updatePixels(); texture_pi[2].updatePixels(); } } public void compile() { print("compiling.."); copyFile(dataPath("") + "\\gameinfo.txt", filePath + "\\gameinfo.txt"); //String[] gameInfo = loadStrings(dataPath("") + "\\gameinfo.txt"); //saveStrings(filePath + "\\gameinfo.txt", gameInfo); //println(gameInfo[1]); String compile_s = dataPath("") + "\\studiomdl\\bin\\studiomdl.exe -game \"" + filePath + "\" \"" + filePath + "\\models\\pbr\\" + inputName + "\\" + inputName + ".qc\""; print(compile_s); launch(compile_s); } public void copyFile(String sourceFile, String destFile) { byte[] source = loadBytes(sourceFile); saveBytes(destFile, source); } public void introDraw() { ts = 12; textSize(ts); text(loadText_s[0][loadText_s[0].length-1], width/2, height/2); ts = 20; textSize(ts); text(inputName, width/2, height/2+(ts+ts/10)); String dash = "_"; if (second() % 2 != 0) { text(dash, width/2 + textWidth(inputName)/2 + 5, height/2+(ts+ts/10)); } } boolean crit_error; public void errorDraw() { fill(255, 0, 0); if (crit_error) text("CRITICAL ERROR", width/2, height/2); else text("ERROR", width/2, height/2); text(error_s, width/2, height/2+(ts+ts/10)); error_i++; if (error_i == 30) { if (crit_error) { exit(); } error_b = false; error_i = 0; fill(255); } } boolean skip; public void skip() { skip = true; nextPhase(); } boolean adhover; public void ad() { if (mouseX > width-kaff.width && mouseX < width && mouseY > 0 && mouseY < kaff.height) { adhover = true; } else { adhover = false; } } public void keyPressed() { if (intro_b) { if (keyCode == BACKSPACE) { if (inputName.length() > 0) { inputName = inputName.substring(0, inputName.length()-1); } } else if (keyCode == DELETE) { inputName = ""; } else if (keyCode != SHIFT && keyCode != RETURN && keyCode != ENTER) { inputName = inputName + key; } if (keyCode == RETURN || keyCode == ENTER) { intro_b = false; } println(inputName); } else if (readPhase_i == 10) { if (keyCode == BACKSPACE) { if (surfaceProp.length() > 0) { surfaceProp = surfaceProp.substring(0, surfaceProp.length()-1); } } else if (keyCode == DELETE) { surfaceProp = ""; } else if (keyCode != SHIFT && keyCode != RETURN && keyCode != ENTER) { surfaceProp = surfaceProp + key; } if (keyCode == RETURN || keyCode == ENTER) { nextPhase(); } } } public void settings() { size(275, 135); } static public void main(String[] passedArgs) { String[] appletArgs = new String[] { "BAconverter4_nomovie" }; if (passedArgs != null) { PApplet.main(concat(appletArgs, passedArgs)); } else { PApplet.main(appletArgs); } } }