简单练习P3D模式下的描绘方式及镜头控制方式.
用六根直线画出原始坐标轴.
用四个立方体画出原始窗口在空间中的位置的及其中心点.
用一个球体表示鼠标位置对应的空间中的位置.
拖动鼠标:改变镜头角度(即镜头函数的视点XY坐标)
按住Ctrl键拖动鼠标:改变镜头位置(即镜头函数的焦点XY坐标)
鼠标滚轮:改变镜头距离(即镜头函数的焦点Z坐标)
[空格]:重置镜头
[Q]:退出程序
问题:镜头距离不应该直接改变坐标, 应该由窗口中心点算出空间中心点位置, 让视点在对空间中心点的直线上移动.
在2.0内制作, 用3.0以上运行可能会报错:
//- --- --- ---
//- public
//- --- --- ---
//-
int pbLeMouseFlag=0;
//-
HcCamera pbTheCamera;
//-
//-
void setup() {size(320, 240,P3D);noStroke();frameRate(16);textAlign(LEFT, TOP);ellipseMode(CENTER);
frame.setTitle("3DTest");
//--
sphereDetail(8,8);
pbTheCamera=new HcCamera();
//--
}//+++
void draw(){background(0);
//--
float lpCoh=map(mouseX, 0,320,0,10);
float lpPaX,lpPbX,lpPcX,lpPdX;
float lpPaY,lpPbY,lpPcY,lpPdY;
float lpPmX,lpPmY,lpPhX,lpPhY;
//--
if(mousePressed){
float lpDiffX=mouseX-pmouseX;
float lpDiffY=mouseY-pmouseY;
if(keyPressed&&(keyCode==17)){//... stands for CTRL pressed
pbTheCamera.ccShiftCenter(-lpDiffX,-lpDiffY, 0);
}else{
pbTheCamera.ccShiftEye(-lpDiffX,-lpDiffY, 0);
}
}
//--
pbTheCamera.ccApply();{
//-- **Axis
stroke(0xEE,0x11,0x11);line(0,0,0, 320,0,0);stroke(0x99,0x11,0x11);line(0,0,0, -320,0,0);
stroke(0x11,0xEE,0x11);line(0,0,0, 0,320,0);stroke(0x11,0x99,0x11);line(0,0,0, 0,-320,0);
stroke(0x11,0x11,0xEE);line(0,0,0, 0,0,320);stroke(0x11,0x11,0x99);line(0,0,0, 0,0,-320);
//-- **Real Screen
noFill();stroke(0x99);rect(0,0,320,240);rect(0,0,160,120);rect(160,120,160,120);
//-- **Real Screen Frame
noFill();stroke(0xFF);
pushMatrix();{
translate(160,0,0);box(320,10,10);
translate(0,240,0);box(320,10,10);
translate(-160,-120,0);box(10,240,10);
translate(320,0,0);box(10,240,10);
}popMatrix();
//-- **Real Mouse Ball
pushMatrix();{
translate(mouseX,mouseY,0);
rotateZ(lpCoh);
sphere(16);
}popMatrix();
//-- **get screen cord
lpPaX=screenX(0, 0, 0);lpPaY=screenY(0, 0, 0);
lpPbX=screenX(320, 0, 0);lpPbY=screenY(320, 0, 0);
lpPcX=screenX(320, 240, 0);lpPcY=screenY(320, 240, 0);
lpPdX=screenX(0, 240, 0);lpPdY=screenY(0, 240, 0);
lpPhX=screenX(160, 120, 0);lpPhY=screenY(160, 120, 0);
lpPmX=screenX(mouseX, mouseY, 0);lpPmY=screenY(mouseX, mouseY, 0);
//--
}pbTheCamera.ccStabilize();
//--
noStroke();fill(0x33,0xEE,0x33);
text("Origin",lpPaX,lpPaY);
text("(width,0)",lpPbX,lpPbY);
text("(width,height)",lpPcX,lpPcY);
text("(0,height)",lpPdX,lpPdY);
text("Center",lpPhX,lpPhY);
text("Mouse\n("+nf(mouseX,3)+","+nf(mouseY,3)+")",lpPmX,lpPmY);
//--
}//+++
void mouseWheel(MouseEvent evt){
float lpAmount=evt.getAmount();
pbTheCamera.cmEyeOffset.z-=-8f*lpAmount;
//--
}//+++
void keyPressed(){switch(key){
case ' ':pbTheCamera.ccReset();break;
//--
case 'q':fsPover();break;
default:break;
}}//+++
//< <<< <<< <<< <<< <<< Overrided
//* *** *** *** *** ***
//*
//* Operate
//*
//* *** *** *** *** ***
//- --- --- ---
void fsPover(){
exit();
}//+++
//< <<< <<< <<< <<< <<< operate
//* *** *** *** *** ***
//*
//* Class
//*
//* *** *** *** *** ***
class HcCamera{
PVector cmEye,cmCenter;
PVector cmEyeOffset, cmCenterOffset;
//--
HcCamera(){
cmEye=new PVector(0,0, (height/2f)/ tan(PI/6f));
cmCenter=new PVector(0,0,0);
cmEyeOffset=new PVector(0,0,120);
cmCenterOffset=new PVector(160,120,0);
}
//--
void ccApply(){
camera(
cmEye.x+cmEyeOffset.x, cmEye.y+cmEyeOffset.y, cmEye.z+cmEyeOffset.z,
cmCenter.x+cmCenterOffset.x, cmCenter.y+cmCenterOffset.y, cmCenter.z+cmCenterOffset.z,
0,1,0
);
}
void ccStabilize(){camera();}
//--
void ccShiftEye(float pxX, float pxY, float pxZ){
cmEyeOffset.x+=pxX;
cmEyeOffset.y+=pxY;
cmEyeOffset.z+=pxZ;
}
void ccShiftCenter(float pxX, float pxY, float pxZ){
cmCenterOffset.x+=pxX;
cmCenterOffset.y+=pxY;
cmCenterOffset.z+=pxZ;
}
//--
void ccReset(){
cmEyeOffset.mult(0);
cmCenterOffset.mult(0);
}
//--
}//+++
//< <<< <<< <<< <<< <<< Class
//EOF
- 本文固定链接: http://iprocessing.cn/2018/01/12/习作ea_立体镜头控制练习/
- 转载请注明: constrain 于 Processing编程艺术 发表