package gameEngine.entites.gameComponents;
import gameEngine.entites.Entity;
import gameEngine.entites.GameObject;
import gameEngine.views.Color;
import gameEngine.views.Texture;
import gameEngine.views.Window;
import static org.lwjgl.opengl.GL11.*;
public class Mesh extends GameComponent {
public enum MeshType {
SPRITE, CUBE
}
private final MeshType type;
private Texture texture; // スプライトのテクスチャを保持
private final Entity parent; // 親のオブジェクトを持つ
private Color color = new Color(1f, 1f, 1f, 1f);
private int spriteWidth = 64; // スプライト幅(今後指定可能にする)
private int spriteHeight = 64; // スプライト高さ(今後指定可能にする)
public Mesh(Entity parent, MeshType type, String texturePath) {
this.parent = parent;
this.type = type;
if (type == MeshType.SPRITE) {
this.texture = new Texture(texturePath); // Load the image
updateSpriteDimensions();
}
}
public Mesh(Mesh original, Entity newParent) {
this.type = original.type;
this.texture = original.texture; // Textureをそのまま参照
this.parent = newParent; // 新しい親オブジェクトに設定
updateSpriteDimensions();
}
@Override
public GameComponent copy() {
return this;
}
@Override
public void init() {
if (type == MeshType.SPRITE) {
renderSprite(); // スプライトの描画
updateSpriteDimensions();
}
}
@Override
public void update() {
if (type == MeshType.SPRITE) {
Integer id = texture.getId();
if(id == null){
texture.init();
}
renderSprite(); // スプライトの描画
}
}
/**
* メッシュのカラーを変更
*
*/
public void setColor(Color color){
this.color = color;
renderSprite();
}
/**
* スプライトの最終的な表示幅を取得
* @return 表示幅(スケールとZスケールを考慮したサイズ)
*/
public float getDisplayedWidth() {
float zScale = calculateZScale();
return spriteWidth * parent.transform.scale.x * zScale;
}
/**
* スプライトの最終的な表示高さを取得
* @return 表示高さ(スケールとZスケールを考慮したサイズ)
*/
public float getDisplayedHeight() {
float zScale = calculateZScale();
return spriteHeight * parent.transform.scale.y * zScale;
}
/**
* Z軸スケールを計算する
* @return 計算されたZ軸スケール
*/
private float calculateZScale() {
float z = parent.transform.position.z;
if (z >= 0) {
return 1.0f + (z * 0.1f);
} else {
return 1.0f / (1.0f + Math.abs(z) * 0.1f);
}
}
private void updateSpriteDimensions() {
if (texture != null) {
this.spriteWidth = texture.getWidth();
this.spriteHeight = texture.getHeight();
}
}
public void setTexturePath(String texturePath){
this.texture = new Texture(texturePath);
updateSpriteDimensions();
}
private void renderSprite() {
// 2Dの描画モードに切り替え
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
// ピクセル単位の座標系に設定
glOrtho(0, Window.get().width, Window.get().height, 0, -1000, 1000);
// モデルビュー行列に切り替えて描画する位置を決める
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
// テクスチャをバインド
glBindTexture(GL_TEXTURE_2D, texture.getId());
// 親のGameObjectの座標と回転を取得
float x = parent.transform.position.x;
float y = parent.transform.position.y;
float z = parent.transform.position.z;
float rotationZ = parent.transform.rotation.z;
float scaleX = parent.transform.scale.x;
float scaleY = parent.transform.scale.y;
float zScale;
if (z >= 0) {
zScale = 1.0f + (z * 0.1f);
} else {
zScale = 1.0f / (1.0f + Math.abs(z) * 0.1f);
}
// 左上基準でスケーリング
glTranslatef(x, y, z);
glScalef(scaleX * zScale, scaleY * zScale, 1.0f); // スケールを適用
glRotatef(rotationZ, 0, 0, 1); // Z軸周りの回転
// テクスチャの描画設定
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(color.r, color.g, color.b, color.a);
// 四角形を描画
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(0, 0, 0); // 左上の頂点
glTexCoord2f(1, 0); glVertex3f(spriteWidth, 0, 0); // 右上の頂点
glTexCoord2f(1, 1); glVertex3f(spriteWidth, spriteHeight, 0); // 右下の頂点
glTexCoord2f(0, 1); glVertex3f(0, spriteHeight, 0); // 左下の頂点
glEnd();
// テクスチャの使用を終了
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
// 行列を元に戻す
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
}
}