Newer
Older
AlgebraicDataflowArchitectureModel / GameEngine / src / main / java / gameEngine / entites / gameComponents / Mesh.java
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();
    }
}