[3D]processingのカメラで遊ぶためのスケルトン
関連項目
https://note.com/alchan/n/na03ed0df952f
https://note.com/alchan/n/n63464a6f1d3c
https://note.com/alchan/n/nf1096417fdfd
https://note.com/alchan/n/nac6cce7a1ce4
Window
interface IDrawablePG
{
void draw(PGraphics basePG);
}
interface IDrawableApplet
{
void draw(PApplet applet);
}
interface IUpdate
{
void Update();
}
interface IWindow extends IUpdate,IDrawableApplet
{
}
class Window3D implements IWindow
{
//Windowの座標
int x;
int y;
PGraphics pg;
ArrayList<ILayer>Layers = new ArrayList<ILayer>();//使ってない
PApplet Applet;
float SliderMin = -1000;
float SliderMax = 1000;
float GUI_x = 0;
float GUI_y = 150;
int GUI_w = 200;
int GUI_h = 10;
Slider Slider1;//CameraPos.x
float GetCameraPosX(){return Slider1.getValue();}
Slider Slider2;//CameraPos.y
float GetCameraPosY(){return Slider2.getValue();}
Slider Slider3;//CameraPos.z
float GetCameraPosZ(){return Slider3.getValue();}
Slider Slider4;//SceneCenter.x
float GetSceneCenterX(){return Slider4.getValue();}
Slider Slider5;//SceneCenter.y
float GetSceneCenterY(){return Slider5.getValue();}
Slider Slider6;//SceneCenter.z
float GetSceneCenterZ(){return Slider6.getValue();}
ControlP5 Camera1ResetButton;
//デフォルトのカメラパラメータ
//https://processing.org/reference/camera_.html
//camera(width / 2.0、height / 2.0、(height / 2.0)/ tan(PI * 30.0 / 180.0)、width / 2.0、height / 2.0、0、0、1、0)
PVector InitCameraEyePos = new PVector(WindowWidth/2,WindowHeight/2,(WindowHeight/2.0)/tan(PI*30.0/180.0));//視錐体的なものと思われる
PVector InitCameraSceneCenter = new PVector(WindowWidth/2,WindowHeight/2,0);
PVector InitCameraUp = new PVector(0,1,0);
//現在のカメラパラメータ
PVector CameraPos = new PVector(WindowWidth/2,WindowHeight/2,(WindowHeight/2.0)/tan(PI*30.0/180.0));
PVector CameraSceneCenter = new PVector(WindowWidth/2,WindowHeight/2,0);
PVector CameraUp = new PVector(0,1,0);
void InitCamera()
{
this.CameraPos = InitCameraEyePos.copy();
this.CameraSceneCenter = InitCameraSceneCenter.copy();
this.CameraUp = InitCameraUp.copy();
}
void ResetCamera()
{
//カメラパラメータを初期値に
InitCamera();
//初期値に戻したカメラパラメータをスライダーに反映
this.Slider1.setValue(this.CameraPos.x);
this.Slider2.setValue(this.CameraPos.y);
this.Slider3.setValue(this.CameraPos.z);
this.Slider4.setValue(this.CameraSceneCenter.x);
this.Slider5.setValue(this.CameraSceneCenter.y);
this.Slider6.setValue(this.CameraSceneCenter.z);
}
//Graphics毎のカメラの設定
void SetCamera(PVector camera_pos, PVector scene_center, PVector dir)
{
//camera_pos カメラの位置
//scene_center シーンの中心、視線の先と考える
//dir カメラの天地
this.pg.camera(camera_pos.x,camera_pos.y,camera_pos.z,scene_center.x,scene_center.y,scene_center.z,dir.x,dir.y,dir.z);
}
void Update()
{
//Windowに属するレイヤーをWindow.Graphicsに統合
for(ILayer layer : this.Layers)
{
layer.draw(this.pg);
}
//カメラ更新
//スライダーからの入力
this.CameraPos.x = this.Slider1.getValue();
this.CameraPos.y = this.Slider2.getValue();
this.CameraPos.z = this.Slider3.getValue();
this.CameraSceneCenter.x = this.Slider4.getValue();
this.CameraSceneCenter.y = this.Slider5.getValue();
this.CameraSceneCenter.z = this.Slider6.getValue();
//現在のカメラパラメータをカメラに適用
this.SetCamera(CameraPos,CameraSceneCenter,CameraUp);
}
//AppletにWindow.Graphicsを描画
void draw(PApplet applet)
{
applet.image(this.pg,this.x,this.y);
}
//コンストラクタ
Window3D(PApplet applet, int x_, int y_, int w, int h)
{
this.x = x_;
this.y = y_;
this.Applet = applet;
pg = createGraphics(w,h,P3D);
SetupSlider();
}
void SetupSlider()
{
float y_offset = this.GUI_y;
ControlP5 slider1 = new ControlP5(this.Applet);
this.Slider1 = slider1.addSlider("CameraPos.X")
.setRange(SliderMin, SliderMax)
.setValue(CameraPos.x)//初期値
.setPosition(this.x+this.GUI_x, this.y+y_offset)//位置
.setColorLabel(0)
.setSize(GUI_w, GUI_h);//大きさ
y_offset+=GUI_h;
ControlP5 slider2 = new ControlP5(this.Applet);
this.Slider2 = slider2.addSlider("CameraPos.Y")
.setRange(SliderMin, SliderMax)
.setValue(CameraPos.y)//初期値
.setPosition(this.x+this.GUI_x, this.y+y_offset)//位置
.setColorLabel(0)
.setSize(GUI_w, GUI_h);//大きさ
y_offset+=GUI_h;
ControlP5 slider3 = new ControlP5(this.Applet);
this.Slider3 = slider3.addSlider("CameraPos.Z")
.setRange(SliderMin, SliderMax)
.setValue(CameraPos.z)//初期値
.setPosition(this.x+this.GUI_x, this.y+y_offset)//位置
.setColorLabel(0)
.setSize(GUI_w, GUI_h);//大きさ
y_offset+=GUI_h;
ControlP5 slider4 = new ControlP5(this.Applet);
this.Slider4 = slider4.addSlider("SceneCenter.X")
.setRange(SliderMin, SliderMax)
.setValue(CameraSceneCenter.x)//初期値
.setPosition(this.x+this.GUI_x, this.y+y_offset)//位置
.setColorLabel(0)
.setSize(GUI_w, GUI_h);//大きさ
y_offset+=GUI_h;
ControlP5 slider5 = new ControlP5(this.Applet);
this.Slider5 = slider5.addSlider("SceneCenter.Y")
.setRange(SliderMin, SliderMax)
.setValue(CameraSceneCenter.y)//初期値
.setPosition(this.x+this.GUI_x, this.y+y_offset)//位置
.setColorLabel(0)
.setSize(GUI_w, GUI_h);//大きさ
y_offset+=GUI_h;
ControlP5 slider6 = new ControlP5(this.Applet);
this.Slider6 = slider6.addSlider("SceneCenter.Z")
.setRange(SliderMin, SliderMax)
.setValue(CameraSceneCenter.z)//初期値
.setPosition(this.x+this.GUI_x, this.y+y_offset)//位置
.setColorLabel(0)
.setSize(GUI_w, GUI_h);//大きさ
}//setup
}
Layer(未使用)
interface ILayer extends IDrawablePG
{
}
class Layer3D implements ILayer
{
int x;
int y;
PGraphics pg;
void draw(PGraphics basePG)
{
basePG.beginDraw();
basePG.image(this.pg,x,y);
basePG.endDraw();
}
Layer3D(int w, int h)
{
pg = createGraphics(w,h,P3D);
}
}
メイン(遊ぶところ)
import controlP5.*;
ArrayList<IWindow>Windows = new ArrayList<IWindow>();//未使用
int WindowWidth = 250;
int WindowHeight = 250;
void setup()
{
size(800,800,P3D);
frameRate(60);
w1 = new Window3D(this,0,0,WindowWidth,WindowHeight);
w2 = new Window3D(this,WindowWidth,0,WindowWidth,WindowHeight);
w3 = new Window3D(this,0,WindowHeight,WindowWidth,WindowHeight);
w4 = new Window3D(this,WindowWidth,WindowHeight,WindowWidth,WindowHeight);
this.Windows.add(w1);//未使用
this.Windows.add(w2);//未使用
this.Windows.add(w3);//未使用
this.Windows.add(w4);//未使用
}
Window3D w1;
Window3D w2;
Window3D w3;
Window3D w4;
void draw()
{
background(255);
//Window毎にレイヤーを各々統合(未使用)
//及びスライダー値⇒カメラに適用
w1.Update();
w2.Update();
w3.Update();
w4.Update();
//カメラの更新が終わっていればGraphicsに適当に描画しても
//そのイメージは回転される
//この辺をいじって遊ぶ
w1.pg.beginDraw();
w1.pg.background(255);
w1.pg.fill(0,127,255);
w1.pg.box(100);
w1.pg.endDraw();
w2.pg.beginDraw();
w2.pg.background(255);
w2.pg.fill(0,127,255);
w2.pg.translate(WindowWidth/2,WindowHeight/2,0);//y+が下、z+で近づく(物体は手前にくる)
w2.pg.box(100);
w2.pg.endDraw();
w3.pg.beginDraw();
w3.pg.background(255);
w3.pg.fill(0,127,255);
w3.pg.box(100);
w3.pg.endDraw();
w4.pg.beginDraw();
w4.pg.background(255);
w4.pg.endDraw();
//WindowはメインAppletのGraphicsに対して
//Window自身の位置にWindow.Graphicsを描画する
//Applet.image(Window.pg,Window.x,Window.y);
w1.draw(this);
w2.draw(this);
w3.draw(this);
w4.draw(this);
noFill();
//Windowのフレーム(強引
rect(0,0,w1.pg.width,w1.pg.height);
rect(w2.pg.width,0,w2.pg.width,w2.pg.height);
rect(0,w3.pg.height,w3.pg.width,w3.pg.height);
rect(w4.pg.width,w4.pg.height,w4.pg.width,w4.pg.height);
}
こんな塩梅
この記事が気に入ったらサポートをしてみませんか?