[ プログラム ]
wasdで移動、tfghで立方体を回転できます。
final int Width_Window = 600;
final int Height_Window = 600;
final HashMap<Character, Boolean> InputMap = new HashMap<Character, Boolean>()
{{
put('w', false);
put('s', false);
put('d', false);
put('a', false);
put('t', false);
put('g', false);
put('h', false);
put('f', false);
}};
final int FrameRate = 60;
final int FieldOfView = 60;
final int MoveAmount = 3;
final int RotateAmount = 10;
Cube3D Cube3D_ = new Cube3D(new Vector3(0, 0, 100), new Vector3(0, 0, 0), 15, color(0, 127, 255, 255));
void settings()
{
size(Width_Window, Height_Window);
}
void setup()
{
frameRate(FrameRate);
}
void draw()
{
background(255);
Cube3D_.Draw();
if(InputMap.get('w'))
{
Cube3D_.Add_Pos(new Vector3(0, -MoveAmount, 0));
}
if(InputMap.get('s'))
{
Cube3D_.Add_Pos(new Vector3(0, MoveAmount, 0));
}
if(InputMap.get('d'))
{
Cube3D_.Add_Pos(new Vector3(MoveAmount, 0, 0));
}
if(InputMap.get('a'))
{
Cube3D_.Add_Pos(new Vector3(-MoveAmount, 0, 0));
}
if(InputMap.get('t'))
{
Cube3D_.Add_Rot(new Vector3(-RotateAmount, 0, 0));
}
if(InputMap.get('g'))
{
Cube3D_.Add_Rot(new Vector3(RotateAmount, 0, 0));
}
if(InputMap.get('h'))
{
Cube3D_.Add_Rot(new Vector3(0, -RotateAmount, 0));
}
if(InputMap.get('f'))
{
Cube3D_.Add_Rot(new Vector3(0, RotateAmount, 0));
}
for (Character key : InputMap.keySet())
{
InputMap.replace(key, false);
}
}
Vector2[] Get_Verts2D(Vector3[] _Verts3D)
{
final Vector2[] Verts2D = new Vector2[_Verts3D.length];
for (int i = 0; i < _Verts3D.length; i++)
{
final float Fov = 1 / tan(radians(FieldOfView / 2));
final float Size = (Width_Window > Height_Window ? Width_Window : Height_Window) / 2;
final Vector3 CuurentVert2D = _Verts3D[i].Copy();
Vector2 NewVert2D = new Vector2(0, 0);
NewVert2D.X += (CuurentVert2D.X / CuurentVert2D.Z) * Fov * Size;
NewVert2D.X += Width_Window / 2;
NewVert2D.Y += (CuurentVert2D.Y / CuurentVert2D.Z) * Fov * Size;
NewVert2D.Y += Height_Window / 2;
Verts2D[i] = NewVert2D;
}
return Verts2D;
}
void keyPressed()
{
if(InputMap.containsKey(key))
{
InputMap.replace(key, true);
}
}
class Vector2
{
float X = 0;
float Y = 0;
Vector2(float _X, float _Y)
{
X = _X;
Y = _Y;
}
Vector2 Add(Vector2 _Vector2)
{
return new Vector2(X + _Vector2.X, Y + _Vector2.Y);
}
Vector2 Minus()
{
return new Vector2(-X, -Y);
}
Vector2 Copy()
{
return new Vector2(X, Y);
}
}
class Vector3
{
float X = 0;
float Y = 0;
float Z = 0;
Vector3(float _X, float _Y, float _Z)
{
X = _X;
Y = _Y;
Z = _Z;
}
Vector3 Add(Vector3 _Vector3)
{
return new Vector3(X + _Vector3.X, Y + _Vector3.Y, Z + _Vector3.Z);
}
Vector3 Mult(float _Value)
{
return new Vector3(X * _Value, Y * _Value, Z * _Value);
}
Vector3 Cross(Vector3 _Vector3)
{
return new Vector3(Y * _Vector3.Z - Z * _Vector3.Y, Z * _Vector3.X - X * _Vector3.Z, X * _Vector3.Y - Y * _Vector3.X);
}
Vector3 Minus()
{
return new Vector3(-X, -Y, -Z);
}
Vector3 Copy()
{
return new Vector3(X, Y, Z);
}
float Dot(Vector3 _Vector3)
{
return X * _Vector3.X + Y * _Vector3.Y + Z * _Vector3.Z;
}
}
class Cube3D
{
Vector3 Pos = new Vector3(0, 0, 0);
Vector3 Rot = new Vector3(0, 0, 0);
float Scale = 1;
color Color = color(0);
Vector3[] Verts3D = new Vector3[]
{
new Vector3(-0.5, -0.5, 0.5),
new Vector3(0.5, -0.5, 0.5),
new Vector3(-0.5, 0.5, 0.5),
new Vector3(0.5, 0.5, 0.5),
new Vector3(-0.5, -0.5, -0.5),
new Vector3(0.5, -0.5, -0.5),
new Vector3(-0.5, 0.5, -0.5),
new Vector3(0.5, 0.5, -0.5),
};
int[][] Polygons = new int[][]
{
new int[]{1, 3, 7},
new int[]{1, 7, 5},
new int[]{0, 4, 6},
new int[]{0, 6, 2},
new int[]{0, 1, 4},
new int[]{1, 5, 4},
new int[]{2, 6, 3},
new int[]{3, 6, 7},
new int[]{0, 3, 1},
new int[]{0, 2, 3},
new int[]{4, 5, 7},
new int[]{4, 7, 6},
};
Cube3D(Vector3 _Pos, Vector3 _Rot, float _Scale, color _Color)
{
Color = _Color;
Add_Pos(_Pos);
Add_Rot(_Rot);
Set_Scale(_Scale);
}
void Draw()
{
for (int i = 0; i < Polygons.length; i++)
{
final int[] Polygon = Polygons[i];
final Vector3[] Verts3D_Polygon = new Vector3[]{Verts3D[Polygon[0]], Verts3D[Polygon[1]], Verts3D[Polygon[2]]};
final Vector3 Vec1 = Verts3D_Polygon[1].Add(Verts3D_Polygon[0].Minus());
final Vector3 Vec2 = Verts3D_Polygon[2].Add(Verts3D_Polygon[0].Minus());
final Vector3 Normal_Polygon = Vec1.Cross(Vec2);
final float Dot = Verts3D_Polygon[0].Dot(Normal_Polygon);
if(Dot <= 0)
{
continue;
}
final Vector2[] Verts2D_Polygon = Get_Verts2D(Verts3D_Polygon);
fill(Color);
noStroke();
triangle(Verts2D_Polygon[0].X, Verts2D_Polygon[0].Y, Verts2D_Polygon[1].X, Verts2D_Polygon[1].Y, Verts2D_Polygon[2].X, Verts2D_Polygon[2].Y);
}
}
void Add_Pos(Vector3 _Pos)
{
for (int i = 0; i < Verts3D.length; i++)
{
final Vector3 CurrentVert3D = Verts3D[i].Copy();
final Vector3 NewVert3D = CurrentVert3D.Copy().Add(_Pos);
Verts3D[i] = NewVert3D;
}
Pos = Pos.Add(_Pos);
}
void Add_Rot(Vector3 _Rot)
{
if(_Rot.X != 0)
{
final float Radian = radians(_Rot.X);
final float Sin = sin(Radian);
final float Cos = cos(Radian);
for (int i = 0; i < Verts3D.length; i++)
{
final Vector3 CurrentVert3D = Verts3D[i].Copy();
Vector3 NewVert3D = new Vector3(0, 0, 0);
NewVert3D.X = CurrentVert3D.X;
NewVert3D.Y = Pos.Y + (CurrentVert3D.Y - Pos.Y) * Cos - (CurrentVert3D.Z - Pos.Z) * Sin;
NewVert3D.Z = Pos.Z + (CurrentVert3D.Y - Pos.Y) * Sin + (CurrentVert3D.Z - Pos.Z) * Cos;
Verts3D[i] = NewVert3D;
}
}
if(_Rot.Y != 0)
{
final float Radian = radians(_Rot.Y);
final float Sin = sin(Radian);
final float Cos = cos(Radian);
for (int i = 0; i < Verts3D.length; i++)
{
final Vector3 CurrentVert3D = Verts3D[i].Copy();
Vector3 NewVert3D = new Vector3(0, 0, 0);
NewVert3D.X = Pos.X + (CurrentVert3D.Z - Pos.Z) * Sin + (CurrentVert3D.X - Pos.X) * Cos;
NewVert3D.Y = CurrentVert3D.Y;
NewVert3D.Z = Pos.Z + (CurrentVert3D.Z - Pos.Z) * Cos - (CurrentVert3D.X - Pos.X) * Sin;
Verts3D[i] = NewVert3D;
}
}
if(_Rot.Z != 0)
{
final float Radian = radians(_Rot.Z);
final float Sin = sin(Radian);
final float Cos = cos(Radian);
for (int i = 0; i < Verts3D.length; i++)
{
final Vector3 CurrentVert3D = Verts3D[i].Copy();
Vector3 NewVert3D = new Vector3(0, 0, 0);
NewVert3D.X = Pos.X + (CurrentVert3D.Y - Pos.Y) * Sin + (CurrentVert3D.X - Pos.X) * Cos;
NewVert3D.Y = Pos.Y + (CurrentVert3D.Y - Pos.Y) * Cos - (CurrentVert3D.X - Pos.X) * Sin;
NewVert3D.Z = CurrentVert3D.Z;
Verts3D[i] = NewVert3D;
}
}
Rot = Rot.Add(_Rot);
}
void Set_Scale(float _Scale)
{
for (int i = 0; i < Verts3D.length; i++)
{
final Vector3 CurrentVert3D = Verts3D[i].Copy();
final Vector3 NewVert3D = CurrentVert3D.Copy().Add(Pos.Minus()).Mult(_Scale / Scale).Add(Pos);
Verts3D[i] = NewVert3D;
}
Scale = _Scale;
}
}