之前進度是把天空包跟紙飛機的部分各自做完,之後再做結合,然後就開始寫上LeapMotion的專有寫法,我利用hand.isRight()把手寫死,變成只能用右手來來操作紙飛機,然後再用PVector設定一些方向,利用大拇指hand.getThumb()、中指getPinkyFinger()和小拇指hand.getMiddleFinger()偵測來控制方向,完整程式碼如下:
import de.voidplus.leapmotion.*;
PImage air;
int ptsW, ptsH;
int numPointsW;
int numPointsH_2pi;
int numPointsH;
float[] coorX;
float[] coorY;
float[] coorZ;
float[] multXZ;
float dirX=0, dirY=0, rotX=0, rotY=0;
PVector pos=null, dir=null, dir2=null, dir3=null, dir4=null;
LeapMotion leap;
import ddf.minim.*;
AudioPlayer player;
Minim minim;
void setup() {
size(1280, 720, P3D);
minim=new Minim(this);
player=minim.loadFile("v.mp3",1024);
leap = new LeapMotion(this);
pos = new PVector(300, 50, 0);
player.play(); //bgm播放
air=loadImage("a3.jpg");
ptsW=30;
ptsH=30;
initializeSphere(ptsW, ptsH);
}
void mouseDragged(){
rotX += mouseX-pmouseX;
rotY -= mouseY-pmouseY;
}
void draw() {
background(0);
float handAngle=0, handAngle2=0, handAngle3=0;
for(Hand hand : leap.getHands()){
pos = hand.getPosition();
PVector p0=hand.getThumb().getPosition(); //p0是大拇指
PVector p1=hand.getPinkyFinger().getPosition(); //p1 是小拇指
PVector p2=hand.getMiddleFinger().getPosition(); //p2是中指
PVector dir = PVector.sub(p1,p0); //PVector.sub();向量相減
PVector dir2 = PVector.sub(dir, p2);
PVector dir3 = PVector.div(dir2, 2);//plane center vector //PVector.div(); 向量相除
if(dir!=null||dir3!= null){
if(hand.isRight()||hand.hasArm()){
handAngle = atan2(dir.y, dir.x); //atan2(); 算tan角度 dir.y/dir.x
handAngle2 = atan2(dir3.x, dir3.x);
}
}
}
translate(pos.x, pos.y, pos.z);
pushMatrix();
rotateZ(handAngle);
rotateX(handAngle2*10);
airplane_v1(); //呼叫紙飛機函示
popMatrix();
camera(pos.x, height/2, (height/2) / tan(PI/6), pos.x, height/2, 0, 0, 1, 0); //紙飛機攝影機的位置
pushMatrix();
rotateZ(handAngle*0.5);
rotateX(radians(pos.y*0.15)); //rot up and down
rotateY(radians(pos.x*0.5)); //=w=
rotateX(radians(rotY));
rotateY(radians(rotX));
noStroke();
noFill();
translate(width/2, height/2, 0);
textureSphere(4000, 4000, 4000, air); //球型天空包
popMatrix();
}
void initializeSphere(int numPtsW, int numPtsH_2pi) { //球形整數參數
// The number of points around the width and height
numPointsW=numPtsW+1;
numPointsH_2pi=numPtsH_2pi; // How many actual pts around the sphere (not just from top to bottom)
numPointsH=ceil((float)numPointsH_2pi/2)+1; // How many pts from top to bottom (abs(....) b/c of the possibility of an odd numPointsH_2pi)
coorX=new float[numPointsW]; // All the x-coor in a horizontal circle radius 1
coorY=new float[numPointsH]; // All the y-coor in a vertical circle radius 1
coorZ=new float[numPointsW]; // All the z-coor in a horizontal circle radius 1
multXZ=new float[numPointsH]; // The radius of each horizontal circle (that you will multiply with coorX and coorZ)
for (int i=0; i<numPointsW ;i++) { // For all the points around the width
float thetaW=i*2*PI/(numPointsW-1);
coorX[i]=sin(thetaW);
coorZ[i]=cos(thetaW);
}
for (int i=0; i<numPointsH; i++) { // For all points from top to bottom
if (int(numPointsH_2pi/2) != (float)numPointsH_2pi/2 && i==numPointsH-1) { // If the numPointsH_2pi is odd and it is at the last pt
float thetaH=(i-1)*2*PI/(numPointsH_2pi);
coorY[i]=cos(PI+thetaH);
multXZ[i]=0;
}
else {
//The numPointsH_2pi and 2 below allows there to be a flat bottom if the numPointsH is odd
float thetaH=i*2*PI/(numPointsH_2pi);
//PI+ below makes the top always the point instead of the bottom.
coorY[i]=cos(PI+thetaH);
multXZ[i]=sin(thetaH);
}
}
}
void textureSphere(float rx, float ry, float rz, PImage t) { //球形貼圖參數
//These are so we can map certain parts of the image on to the shape
float changeU=t.width/(float)(numPointsW-1);
float changeV=t.height/(float)(numPointsH-1);
float u=0; // Width variable for the texture
float v=0; // Height variable for the texture
beginShape(TRIANGLE_STRIP);
texture(t);
for (int i=0; i<(numPointsH-1); i++) { // For all the rings but top and bottom
// Goes into the array here instead of loop to save time
float coory=coorY[i];
float cooryPlus=coorY[i+1];
float multxz=multXZ[i];
float multxzPlus=multXZ[i+1];
for(int j=0; j<numPointsW; j++) { // For all the pts in the ring
normal(-coorX[j]*multxz, -coory, -coorZ[j]*multxz);
vertex(coorX[j]*multxz*rx, coory*ry, coorZ[j]*multxz*rz, u, v);
normal(-coorX[j]*multxzPlus, -cooryPlus, -coorZ[j]*multxzPlus);
vertex(coorX[j]*multxzPlus*rx, cooryPlus*ry, coorZ[j]*multxzPlus*rz, u, v+changeV);
u+=changeU;
}
v+=changeV;
u=0;
}
endShape();
}
void airplane_v1(){
pushMatrix();
//lights();
stroke(0);
scale(5);
color c = color(255, 255, 0);
fill(c);
beginShape(TRIANGLES); //paper airplane
vertex(0, -40, 0);//01
vertex(-20, -10, 0);
vertex(-5, -10, 0);
vertex(-5, -10, 0);//02
vertex(0, 0, -10);
vertex(0, -40, 0);
vertex(0, 0, -10);//03
vertex(5, -10, 0);
vertex(0, -40, 0);
vertex(5, -10, 0);//04
vertex(20, -10, 0);
vertex(0, -40, 0);
endShape();
popMatrix();
}
展示到此結束。
*********************************************************************************作品心得:
網路上的紙飛機影片被我們寫出來了!還蠻開心的XD 雖然我們的作品看起來有點單調,但是我們還是很開心,因為是自己寫出來的 =w=
寫的過程中有遇到Processing的函示庫不懂? 自己去官網查,然後再加以應用! 雖然有部分英文不太懂,但是整題還是可以看個大概,不過,看過別組的展示後,我們也要再加以反省,因為畢竟是展示性質的作品,如果功能太單調,就吸引不到觀眾,雖然很殘酷,但這是事實。 (我們分數不高= = 幹!)
所以我們下次的目標就是想辦法在加一些很炫的特效來玩迎合觀眾的口味並完善我們的紙飛機(笑)。
沒有留言:
張貼留言