質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.13%

Three.jsでのMMDHelperでTHREE.MMDHelper is not a constructorのエラーが出る。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,740

misogil

score 13

前提・実現したいこと

three.jsとartoolkit5を利用して,マーカーに反応してMMDモデルを出したいのだが,
MMDモデルを出すコードでTHREE.MMDHelper is not a constructorのエラーが発生する。

発生している問題・エラーメッセージ

THREE.MMDHelper is not a constructor
黒い画面が右上に小さく出てくるだけ。

該当のソースコード

<html>
<head>
<title>Pattern marker example with Three.js</title>
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">
<style>
html,body {
    margin: 0;
    padding: 0;
    width: 100%;
    text-align: center;
    overflow-x: hidden;
}
.portrait canvas {
    transform-origin: 0 0;
    transform: rotate(-90deg) translateX(-100%);
}
.desktop canvas {
     transform: scale(-1, 1);
}
</style>
</head>
<body>

<h1>Pattern marker example with Three.js</h1>
<p>On Chrome on Android, tap the screen to start playing video stream.</p>
<p>Show  <a href="https://github.com/artoolkit/artoolkit5/blob/master/doc/patterns/Hiro%20pattern.pdf">Hiro pattern</a> and <a href="https://github.com/artoolkit/artoolkit5/blob/master/doc/patterns/Kanji%20pattern.pdf">Kanji pattern</a> to camera to display a colorful objects on top of them. Tap the screen to rotate the objects.

<p>&larr; <a href="index.html">Back to examples</a></p>

<script async src="./jsartoolkit5/build/artoolkit.min.js"></script>
<script async src="./jsartoolkit5/examples/js/third_party/three.js/three.min.js"></script>
<script async src="./jsartoolkit5/js/artoolkit.three.js"></script>


<script src="js/libs/mmdparser.min.js"></script>
<script src="js/libs/ammo.js"></script>

<script src="js/loaders/TGALoader.js"></script>
<script src="js/loaders/MMDLoader.js"></script>
<script src="js/effects/OutlineEffect.js"></script>
<script src="js/animation/CCDIKSolver.js"></script>
<script src="js/animation/MMDPhysics.js"></script>

<script src="js/controls/OrbitControls.js"></script>

<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="js/libs/dat.gui.min.js"></script>
<script>

window.ARThreeOnLoad = function() {


    ARController.getUserMediaThreeScene({maxARVideoSize: 320, cameraParam: './jsartoolkit5/examples/Data/camera_para-iPhone 5 rear 640x480 1.0m.dat',
    onSuccess: function(arScene, arController, arCamera) {

        document.body.className = arController.orientation;

        var renderer = new THREE.WebGLRenderer({antialias: true});
        if (arController.orientation === 'portrait') {
            var w = (window.innerWidth / arController.videoHeight) * arController.videoWidth;
            var h = window.innerWidth;
            renderer.setSize(w, h);
            renderer.domElement.style.paddingBottom = (w-h) + 'px';
        } else {
            if (/Android|mobile|iPad|iPhone/i.test(navigator.userAgent)) {
                renderer.setSize(window.innerWidth, (window.innerWidth / arController.videoWidth) * arController.videoHeight);
            } else {
                renderer.setSize(arController.videoWidth, arController.videoHeight);
                document.body.className += ' desktop';
            }
        }

        document.body.insertBefore(renderer.domElement, document.body.firstChild);

        var rotationV = 0;
        var rotationTarget = 0;

        // ここから

        renderer.domElement.addEventListener('click', function(ev) {
            ev.preventDefault();
            rotationTarget += 1;
        }, false);

        var helper = new THREE.MMDHelper();
        var fmodel = './models/pmd/miku_v2.pmd';
        var fvmd = ['./models/vmd/wavefile_v2.vmd'];

        var onProgress = function (xhr) {
        };
        var onError = function (xhr) {
            alert('読み込みに失敗しました。');
        };

        var loader = new THREE.MMDLoader();
        loader.load(fmodel, fvmd, function (object) {

            mesh = object;
            mesh.position.y = -10;
            mesh.position.z = 0.5;
            helper.add(mesh);
            helper.setAnimation(mesh);

            /*
             * Note: create CCDIKHelper after calling helper.setAnimation()
             */
            ikHelper = new THREE.CCDIKHelper( mesh );
            ikHelper.visible = false;
            scene.add( ikHelper );

            /*
             * Note: You're recommended to call helper.setPhysics()
             *       after calling helper.setAnimation().
             */
            //helper.setPhysics( mesh );
            physicsHelper = new THREE.MMDPhysicsHelper( mesh );
            physicsHelper.visible = false;
            scene.add( physicsHelper );

            //helper.unifyAnimationDuration( { afterglow: 2.0 } );
        }, onProgress, onError);

        // ここまで

        var sphere = new THREE.Mesh(
            new THREE.SphereGeometry(0.5, 8, 8),
            new THREE.MeshNormalMaterial()
        );
        sphere.material.shading = THREE.FlatShading;
        sphere.position.z = 0.5;

        var torus = new THREE.Mesh(
            new THREE.TorusGeometry(0.3, 0.2, 8, 8),
            new THREE.MeshNormalMaterial()
        );
        torus.material.shading = THREE.FlatShading;
        torus.position.z = 0.5;
        torus.rotation.x = Math.PI/2;

        arController.loadMarker('./jsartoolkit5/examples/Data/patt.hiro', function(markerId) {
            var markerRoot = arController.createThreeMarker(markerId);
            markerRoot.add(loader);
            arScene.scene.add(markerRoot);
        });

        arController.loadMarker('./jsartoolkit5/examples/Data/patt.kanji', function(markerId) {
            var markerRoot = arController.createThreeMarker(markerId);
            markerRoot.add(torus);
            arScene.scene.add(markerRoot);
        });

        var tick = function() {
            arScene.process();

            rotationV += (rotationTarget - sphere.rotation.z) * 0.05;
            sphere.rotation.z += rotationV;
            torus.rotation.y += rotationV;
            rotationV *= 0.8;

            arScene.renderOn(renderer);
            requestAnimationFrame(tick);
        };

        tick();

    }});

    delete window.ARThreeOnLoad;

};

if (window.ARController && ARController.getUserMediaThreeScene) {
    ARThreeOnLoad();
}
</script>

</body>
</html>

試したこと

Three.jsのソースコードのexampleが正常に動くことを確認した。
なお, この自前の部分のコードがなければARとして正常に動くことも確認している
ライブラリなどは, three.jsのexampleと同じものを入れた。
しかし, 右上に黒い画面が出てくるだけで正常にカメラも立ち上がらない。

補足情報(言語/FW/ツール等のバージョンなど)

より詳細な情報

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

artoolkit5 のサンプルに同梱されている three.js は、2年前のr71と、だいぶ古いもののようです。
現在、Three.jsはr85で、特にr83からMMDLoaderは変更が大きく、最新バージョンをThree.js.orgから取得したとしても、うまくいかないでしょう。

また、さらに残念なことに、Three.js の r71では、MMDloaderはまだ作られていませんでした。

そのため、 jsartoolkit5/examples/js/third_party/three.js/ のフォルダの中の three.min.js を、最新のr85(または手元にあるMMDLoaderの中のバージョン)として、MMDLoaderが動くかどうか(そしてartoolkitが動くか)を試してみるとよいかもしれません。

または、three.js でMMDLoaderが作られた、一番古いバージョンである r74を試してみるのもアリでしょう。

three.js r74

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.13%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る