Mod:Coding Challenge #9: Solar System in Processing - Part 3 (3D textures)
昨日の3Dの続き、テクスチャを球体にマッピングする方法。PShape使うのは知らなかった。応用効きそう。どっちかというとマッピングするテクスチャ画像の用意のほうが大変か。
複数のファイルの名前を意識しないで読み込むやりかたは、以前hysyskがやっていたJavaのインターフェイスのオーバーライドでやるやつを参考にした。便利。
画像自体はチュートリアルにもあるけど、以下のWebサイトで公開されているものをダウンロードした。
import peasy.*; import peasy.org.apache.commons.math.*; import peasy.org.apache.commons.math.geometry.*; File[] imageFiles; JPGFileFilter filter; PImage[] textures; PImage sunTexture; Planet sun; PeasyCam cam; // setup関数 : 初回1度だけ実行される void setup() { size(960, 540, P3D); // ウィンドウサイズを960px,540pxに colorMode(HSB, 360, 100, 100, 100); // HSBでの色指定にする sunTexture = loadImage("sunmap.jpg"); filter = new JPGFileFilter(); imageFiles = new File(dataPath("")).listFiles(filter); textures = new PImage[imageFiles.length]; for (int i = 0; i < imageFiles.length; i++) { textures[i] = loadImage(imageFiles[i].getName()); } cam = new PeasyCam(this, 500); sun = new Planet(100, 0, 0, sunTexture); sun.spawnMoons(10, 1); } // draw関数 : setup関数実行後繰り返し実行される void draw() { background(0, 0, 0); ambientLight(0, 0, 50); pointLight(0, 0, 50, 0, 0, 0); sun.draw(); sun.orbit(); } class Planet { float radius; float distance; Planet[] planets; float angle; float orbitSpeed; PVector v; PShape globe; color c; Planet(float r, float _d, float o, PImage img) { v = PVector.random3D(); radius = r; angle = random(TWO_PI); distance = _d; v.mult(distance); orbitSpeed = o; noStroke(); noFill(); globe = createShape(SPHERE, radius); globe.setTexture(img); } void spawnMoons(int total, int level) { planets = new Planet[total]; for (int i = 0; i < planets.length; i++) { float r = radius/(level*2); float d = random((radius + r), (radius+r)*4); float o = random(-0.01, 0.01); int index = int(random(0, textures.length)); planets[i] = new Planet(r, d, o, textures[index]); if (level < 2) { int num = int(random(0, 3)); planets[i].spawnMoons(num, level+1); } } } void orbit() { angle = angle + orbitSpeed; if (planets != null) { for (int i = 0; i < planets.length; i++) { planets[i].orbit(); } } } void draw() { pushMatrix(); PVector v2 = new PVector(1, 0, 1); PVector p = v.cross(v2); rotate(angle, p.x, p.y, p.z); translate(v.x, v.y, v.z); noStroke(); fill(0, 0, 100); shape(globe); if (planets != null) { for (int i = 0; i < planets.length; i++) { planets[i].draw(); } } popMatrix(); } } import java.io.File; import java.io.FilenameFilter; public class JPGFileFilter implements FilenameFilter { @Override public boolean accept(File directory, String fileName) { if (fileName.endsWith(".jpg")) { return true; } return false; } }