🔬 AI発明ギャラリー syunsuke アンギラス
🔒 サンドボックス内で実行中 ⛶ 全画面で遊ぶ
HTML / CSS / JS
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Anguirus 1955 - Classic Movie Diorama</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <style>
        body { margin: 0; overflow: hidden; background-color: #222; font-family: 'Hiragino Mincho ProN', 'serif'; }
        canvas { display: block; }
        #info {
            position: absolute;
            top: 20px;
            left: 20px;
            color: #ddd;
            background: rgba(0,0,0,0.8);
            padding: 15px;
            border-radius: 4px;
            pointer-events: none;
            border-left: 2px solid #666;
        }
        #info h1 { margin: 0 0 5px 0; font-size: 18px; color: #fff; letter-spacing: 2px; }
        #controls {
            position: absolute;
            bottom: 20px;
            left: 20px;
            color: #888;
            font-size: 12px;
            background: rgba(0,0,0,0.4);
            padding: 5px 10px;
        }
    </style>
</head>
<body>

<div id="info">
    <h1>暴竜アンギラス (1955 映画再現)</h1>
    <p>映画『ゴジラの逆襲』スチール写真に基づく造形</p>
    <p style="font-size: 11px; color: #999;">• 四足歩行ポーズの再現<br>• モノクローム・特撮ライティング<br>• 劇中背景(大阪・コンクリート建築)</p>
</div>

<div id="controls">
    ドラッグ: 視点回転 | ホイール: ズーム
</div>

<script>
    let scene, camera, renderer;
    let lon = 150; 
    let lat = 10; 
    let distance = 28; 
    let isDragging = false;
    let previousMousePosition = { x: 0, y: 0 };

    window.onload = function() {
        init();
        animate();
    };

    function init() {
        scene = new THREE.Scene();
        // 写真のような曇天のモノクロ背景
        scene.background = new THREE.Color(0x444444);
        scene.fog = new THREE.Fog(0x444444, 20, 70);

        camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 1000);
        
        renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.shadowMap.enabled = true;
        renderer.shadowMap.type = THREE.PCFSoftShadowMap;
        document.body.appendChild(renderer.domElement);

        // --- ライティング (特撮スタジオ風のモノクロライティング) ---
        const ambientLight = new THREE.AmbientLight(0xffffff, 0.3);
        scene.add(ambientLight);

        // 主光源
        const sunLight = new THREE.DirectionalLight(0xffffff, 0.8);
        sunLight.position.set(20, 20, 10);
        sunLight.castShadow = true;
        sunLight.shadow.mapSize.width = 2048;
        sunLight.shadow.mapSize.height = 2048;
        scene.add(sunLight);

        // 逆光(トゲの輪郭を強調)
        const rimLight = new THREE.SpotLight(0xffffff, 1.2);
        rimLight.position.set(-20, 15, -15);
        scene.add(rimLight);

        // --- 地面 ---
        const groundMat = new THREE.MeshPhongMaterial({ color: 0x333333, flatShading: true });
        const ground = new THREE.Mesh(new THREE.PlaneGeometry(100, 100), groundMat);
        ground.rotation.x = -Math.PI / 2;
        ground.position.y = -1.5;
        ground.receiveShadow = true;
        scene.add(ground);

        createEnvironment();
        createAnguirus1955();

        // 操作イベント
        document.addEventListener('mousedown', (e) => { isDragging = true; previousMousePosition = { x: e.clientX, y: e.clientY }; });
        document.addEventListener('mouseup', () => isDragging = false);
        document.addEventListener('mousemove', (e) => {
            if (isDragging) {
                const deltaX = e.clientX - previousMousePosition.x;
                const deltaY = e.clientY - previousMousePosition.y;
                lon -= deltaX * 0.3;
                lat += deltaY * 0.2;
                lat = Math.max(0, Math.min(60, lat));
            }
            previousMousePosition = { x: e.clientX, y: e.clientY };
        });
        window.addEventListener('wheel', (e) => {
            distance += e.deltaY * 0.03;
            distance = Math.max(10, Math.min(distance, 60));
        });
        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });
    }

    function createEnvironment() {
        const env = new THREE.Group();
        const buildingMat = new THREE.MeshPhongMaterial({ color: 0x555555, flatShading: true });

        // --- 写真の建物の再現 (窓の並んだ長い建物) ---
        const createBuilding = (w, h, d, x, z) => {
            const bGroup = new THREE.Group();
            const box = new THREE.Mesh(new THREE.BoxGeometry(w, h, d), buildingMat);
            bGroup.add(box);

            // 窓の表現
            const windowGeo = new THREE.BoxGeometry(0.2, 0.4, 0.1);
            const windowMat = new THREE.MeshBasicMaterial({ color: 0x222222 });
            for(let iy=0; iy<3; iy++) {
                for(let ix=0; ix<w*1.5; ix++) {
                    const win = new THREE.Mesh(windowGeo, windowMat);
                    win.position.set(-w/2 + 0.5 + ix*0.6, h/2 - 0.5 - iy*0.8, d/2 + 0.01);
                    bGroup.add(win);
                }
            }
            bGroup.position.set(x, h/2 - 1.5, z);
            return bGroup;
        };

        env.add(createBuilding(10, 5, 4, -8, -5));
        env.add(createBuilding(12, 4, 3, 5, -8));

        // 瓦礫と樹木
        const debrisMat = new THREE.MeshPhongMaterial({ color: 0x333333 });
        for(let i=0; i<20; i++) {
            const rock = new THREE.Mesh(new THREE.DodecahedronGeometry(Math.random()*0.5 + 0.2), debrisMat);
            rock.position.set((Math.random()-0.5)*20, -1.3, (Math.random()-0.5)*15);
            env.add(rock);
        }
        
        // 前景の木
        const treeMat = new THREE.MeshPhongMaterial({ color: 0x222222 });
        const tree = new THREE.Mesh(new THREE.ConeGeometry(1, 3, 8), treeMat);
        tree.position.set(-5, 0, 8);
        env.add(tree);

        env.traverse(n => { n.castShadow = true; n.receiveShadow = true; });
        scene.add(env);
    }

    function createAnguirus1955() {
        const anguirus = new THREE.Group();
        const mat = new THREE.MeshPhongMaterial({ color: 0x333333, flatShading: true });
        const shellMat = new THREE.MeshPhongMaterial({ color: 0x222222, flatShading: true });
        const spikeMat = new THREE.MeshPhongMaterial({ color: 0x999999, flatShading: true });

        // --- 胴体 (四足歩行用の水平ポーズ) ---
        const torso = new THREE.Mesh(new THREE.CylinderGeometry(1.2, 1.4, 4.5, 16), mat);
        torso.rotation.z = Math.PI / 2;
        torso.position.y = 0.5;
        anguirus.add(torso);

        // --- 甲羅 (低く、平たく) ---
        const shell = new THREE.Mesh(new THREE.SphereGeometry(1.6, 24, 12, 0, Math.PI * 2, 0, Math.PI / 2), shellMat);
        shell.scale.set(1.1, 0.6, 1.8);
        shell.position.y = 0.8;
        anguirus.add(shell);

        // --- トゲ (写真通り、非常に密で鋭い) ---
        const spikeBase = new THREE.ConeGeometry(0.08, 0.8, 4);
        for(let i=0; i<220; i++) {
            const spike = new THREE.Mesh(spikeBase, spikeMat);
            const phi = Math.random() * Math.PI * 2;
            const theta = Math.random() * (Math.PI / 2.2);
            const x = Math.sin(theta) * Math.cos(phi) * 1.7;
            const y = Math.cos(theta) * 1.0 + 0.8;
            const z = Math.sin(theta) * Math.sin(phi) * 2.8;
            spike.position.set(x, y, z);
            // トゲを少し後ろ向きに傾ける
            const target = new THREE.Vector3(x, y*2, z*2 + 1);
            spike.lookAt(target);
            spike.rotateX(Math.PI / 2);
            anguirus.add(spike);
        }

        // --- 頭 (低く構えて咆哮) ---
        const headGroup = new THREE.Group();
        const head = new THREE.Mesh(new THREE.BoxGeometry(1.1, 1, 1.8), mat);
        headGroup.add(head);

        // 下顎 (咆哮中)
        const jaw = new THREE.Mesh(new THREE.BoxGeometry(0.9, 0.4, 1.3), mat);
        jaw.position.set(0, -0.4, 1.0);
        jaw.rotation.x = 0.6;
        headGroup.add(jaw);

        // 角 (鼻先と後頭部)
        const hornGeo = new THREE.ConeGeometry(0.12, 0.6, 6);
        const noseHorn = new THREE.Mesh(hornGeo, spikeMat);
        noseHorn.position.set(0, 0.4, 1.6);
        noseHorn.rotation.x = -0.3;
        headGroup.add(noseHorn);

        for(let i=0; i<2; i++) {
            const h = new THREE.Mesh(hornGeo, spikeMat);
            h.position.set(i === 0 ? 0.3 : -0.3, 0.5, 0);
            h.rotation.x = -0.6;
            headGroup.add(h);
        }

        headGroup.position.set(0, 0.8, 2.5);
        headGroup.rotation.x = -0.4; // 斜め上を向く
        anguirus.add(headGroup);

        // --- 脚 (四足歩行、短め) ---
        const legGeo = new THREE.CylinderGeometry(0.4, 0.5, 1.5, 12);
        const lp = [[1.0, -0.7, 1.8], [-1.0, -0.7, 1.8], [1.0, -0.7, -1.8], [-1.0, -0.7, -1.8]];
        lp.forEach(p => {
            const leg = new THREE.Mesh(legGeo, mat);
            leg.position.set(p[0], p[1], p[2]);
            anguirus.add(leg);
        });

        // --- 長い尻尾 ---
        const tail = new THREE.Group();
        const segmentCount = 18;
        for(let i=0; i<segmentCount; i++) {
            const s = 0.8 * (1 - i/segmentCount);
            const seg = new THREE.Mesh(new THREE.SphereGeometry(s, 12, 8), mat);
            // 大きくうねる尻尾
            seg.position.z = -i * 0.8;
            seg.position.x = Math.sin(i * 0.4) * 2;
            seg.position.y = -0.2 - i * 0.05;
            
            // 尻尾のトゲ
            if(i < 12) {
                const ts = new THREE.Mesh(new THREE.ConeGeometry(0.1, 0.5, 4), spikeMat);
                ts.position.y = s;
                seg.add(ts);
            }
            tail.add(seg);
        }
        tail.position.set(0, 0.2, -2.2);
        anguirus.add(tail);

        anguirus.position.set(3, -0.1, 0);
        anguirus.rotation.y = -0.5;
        anguirus.traverse(n => { n.castShadow = true; n.receiveShadow = true; });
        scene.add(anguirus);
    }

    function animate() {
        requestAnimationFrame(animate);
        
        const phi = THREE.MathUtils.degToRad(90 - lat);
        const theta = THREE.MathUtils.degToRad(lon);
        camera.position.x = distance * Math.sin(phi) * Math.cos(theta);
        camera.position.y = distance * Math.cos(phi);
        camera.position.z = distance * Math.sin(phi) * Math.sin(theta);
        
        camera.lookAt(0, 1, 0);

        renderer.render(scene, camera);
    }
</script>
</body>
</html>

アンギラス

1995のアンギラスをモデルにしました

🤖 使用したAI
Gemini
👁 20 回閲覧
📅 投稿:2026年4月14日 🔄 更新:2026年8月13日
応援スタンプを押してみよう!