(1) : ヘッダ( head要素内 ) IE では、開発者ツールが開いていないと、console.log がエラーになるので先に実装しておいて、IEWebGL を使う為の基本ツール(webglhelper.js)を『必要な時だけ読みだす』ようにしています。 (2) : Three.js を展開する部分への実装 通常ならば、container_three 内に展開されるのですが、IEWebGL の場合オブジェクトなので、代替えとして埋め込む為に、container_three 内 にスクリプトを書いています。ここでは、renderCanvas と言う名前で代替えエリアを作成して後でその部分を使うように記述します。また、ie 以外でも WebGL が使えないブラウザの為に、描画エリアとしてのこの場所にメッセージを表示するようにしています。 (3) : いろいろチェック ちょっと不自然なコードですが、WebGLRenderingContext.hasOwnProperty('iewebgl') の挙動が一様では無かったので結果的にこうなってしまいました。もっと良い書き方があると思いますが、IE だけの為に努力しても仕方無いのでこれでいいと思います。 ※ init と animate は、Three.js の開始部分です (4) : 一番重要な部分 通常では無い対象エリアである、renderCanvas を Three.js に認識させる部分です。エリアの実装の仕方にもよりますが、本来のエリアが邪魔して renderCanvas が下のほうにズレてしまうので、強引に div を非表示にしている部分がありますが、ここは将来的には調整が必要になるかもしれません( Three.js はやたらと仕様変更があります ) 関連する記事 Three.js(51) でPlane(平面)。IEWebGL をインストールすると IE でも動くサンプル
|
2012年10月25日
IE でも WebGL が動く方法 : Three.js と IEWebGL で ページを書く手順。
2012年10月16日
Three.js(51) でPlane(平面)。IEWebGL をインストールすると IE でも動くサンプル
いまんとこ、Firefox が一番問題が少ないです。Google Chrome はわりと何か起きます。ま、でも、基本的に開発している人(Three.js)が Google Chrome をターゲットにしてるぽいので、殆どは Chrome でテストしています。 Opera Next は結構悲惨な状態で、IE は IEWebGL をインストールすれば動きます。Firefox は、ローカルの file:///C: でも動くので凄いです。 でも、Canvas バージョンなら全てのブラウザで動きますし、Canvas なら Windows8 でビルドできます(動作というか信頼性はまだあまりアテにならないですけれど)。 WebGLバージョンはこちらから
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>Plane / three / WebGL</title> <style type="text/css"> * { font-size: 12px; } body { margin: 0; background-color: #ffffff; } a { color: navy; } #container_three { width: 1000px; height: 600px; border: solid 1px #ccc; margin-left: 50px; background-color: #eee; } #message { position: absolute; left: 0px; top: 0px; color: red; font-size: 20px; } </style> <link rel="stylesheet" href="../jquery/jqcss/black-tie/jquery-ui-1.8.20.custom.css" type="text/css" /> <script type="text/javascript" src="../jquery/jquery-1.7.2.min.js"></script> <script type="text/javascript" src="../jquery/jquery-ui-1.8.20.custom.min.js"></script> <script type="text/javascript"> // ********************************************************* // IE 用 // ********************************************************* if(!window["console"]){window["console"]={};window["console"]["log"]=function(){}} if ((window.navigator.userAgent.toLowerCase()).indexOf("msie") > -1) { (function(){ var str=""; str+="<"+"script type=\"text/javascript\" src=\"../three/webglhelper.js\"></"+"script> "; document.write(str); })(); } </script> </head> <body> <div style='position:absolute;left:60px;top:34px;'> <input id="dragToLook" type="checkbox" onclick='controls.dragToLookStop = !this.checked;'> チェックするとドラッグで FLY </div> <div style='position:absolute;left:280px;top:40px;'>Y軸回転</div> <div id="slider-r-y" style='position:absolute;left:350px;top:40px;width:200px;'></div> <div style='position:absolute;left:16px;top:225px;'>X軸</div> <div id="slider-r-x" style='position:absolute;left:20px;top:250px;height:200px;'></div> <br /><br /> <div id="container_three"> <script id="WebGLCanvasCreationScript" type="text/javascript"> var container = document.getElementById( 'container_three' ); var WebGL_chk; if ((window.navigator.userAgent.toLowerCase()).indexOf("msie") > -1) { WebGLHelper.CreateGLCanvasInline('renderCanvas'); } else { WebGL_chk = ( function () { try { return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); } catch( e ) { return false; } } )(); if ( !WebGL_chk ) { container.innerHTML = "<div id='message' style='postion:absolute;left:100px;top:350px;color:#FF0000;font-size:50px;'>WebGL が使用できません</div>"; } } </script></div> <script type="text/javascript" src="../three/Three_51.js"></script> <script type="text/javascript" src="../three/FlyControls_lightbox.js"></script> <script type="text/javascript"> // ********************************************************* // 共通 // ********************************************************* var camera, scene, renderer; var mesh,mesh2; var w = 1000; var h = 600; var controls; var clock; var data_target = '001.png'; var data_target2 = '002.png'; var parent; // ********************************************************* // キーアクション呼び出し用 // ********************************************************* function control_update() { controls.updateMovementVector(); controls.updateRotationVector(); } // ********************************************************* // Opera 用 // ********************************************************* if( !XMLHttpRequest.DONE ) { console.log("setting"); XMLHttpRequest.prototype.DONE = 4 XMLHttpRequest.prototype.HEADERS_RECEIVED = 2 XMLHttpRequest.prototype.LOADING = 3 XMLHttpRequest.prototype.OPENED = 1 XMLHttpRequest.prototype.UNSENT = 0 } // ********************************************************* // jQuery スライダー // ********************************************************* $(function () { // スピン回転用スライダー $("#slider-r-y").slider({ range: "min", step: 0.01, min: 0, max: Math.PI * 2, value: 0, slide: function (event, ui) { parent.rotation.y = ui.value; // mesh.rotation.y = ui.value; // mesh2.rotation.y = ui.value + 180 * Math.PI / 180; } }); // 縦回転用スライダー $("#slider-r-x").slider({ orientation: "vertical", range: "min", step: 0.01, min: 0, max: Math.PI * 2, value: Math.PI / 32, slide: function (event, ui) { parent.rotation.x = ui.value; // mesh.rotation.x = ui.value; // mesh2.rotation.x = ui.value; } }); }); if ( !WebGL_chk ) { var usePlugin; try { usePlugin = WebGLRenderingContext.hasOwnProperty('iewebgl'); } catch (e) { usePlugin = true; } if ( usePlugin ) { init(); animate(); } else { container.innerHTML = "<div id='message' style='postion:absolute;left:100px;top:350px;color:#FF0000;font-size:50px;'>WebGL が使用できません</div>"; } } else { init(); animate(); } // ********************************************************* // 初期処理 // ********************************************************* function init() { clock = new THREE.Clock(); // ************************************************* // シーン // ************************************************* scene = new THREE.Scene(); scene.position.y = 0; scene.position.x = 0; // ************************************************* // カメラ // ************************************************* camera = new THREE.PerspectiveCamera( 50, w / h, 1, 10000 ); camera.position.set( 0, 0, 650 ); scene.add( camera ); // ************************************************* // キーボードコントロール // ************************************************* controls = new THREE.FlyControls( camera ); controls.movementSpeed = 120; controls.domElement = container; controls.rollSpeed = Math.PI / 48 * 2; controls.dragToLook = true; controls.object.useQuaternion = true; parent = new THREE.Object3D(); // ************************************************* // データの読み込み // ************************************************* var image = new Image() image.onload = function () { var texture = new THREE.Texture( this ); texture.needsUpdate = true; var material = new THREE.MeshBasicMaterial({map: texture, overdraw: true}); // 平面表 mesh = new THREE.Mesh(new THREE.PlaneGeometry(350, 400, 5, 5), material); mesh.rotation.x = 0; mesh.rotation.y = 0; // scene.add(mesh); parent.add( mesh ); }; image.src = data_target; var image2 = new Image() image2.onload = function () { var texture2 = new THREE.Texture( this ); texture2.needsUpdate = true; var material2 = new THREE.MeshBasicMaterial({map: texture2, overdraw: true}); // 平面裏 mesh2 = new THREE.Mesh(new THREE.PlaneGeometry(350, 400, 5, 5), material2); mesh2.rotation.x = 0; mesh2.rotation.y = 180 * Math.PI / 180; // 180°( * Math.PI / 180 が固定 ) // scene.add(mesh2); parent.add( mesh2 ); }; image2.src = data_target2; // ************************************************* // 照明 // ************************************************* var directionalLight1 = new THREE.DirectionalLight( 0xffffff, 1 ); directionalLight1.position.set( 0, 0, 300 ).normalize(); scene.add( directionalLight1 ); var directionalLight2 = new THREE.DirectionalLight( 0xffffff, 1 ); directionalLight2.position.set( 0, 0, -500 ).normalize(); scene.add( directionalLight2 ); scene.add(parent); // ************************************************* // 描画 // ************************************************* if ((window.navigator.userAgent.toLowerCase()).indexOf("msie") > -1) { container.getElementsByTagName("div")[0].style.display = "none"; var externalCanvas = document.getElementById('renderCanvas'); renderer = new THREE.WebGLRenderer({ 'canvas': externalCanvas, antialias: true }); } else { renderer = new THREE.WebGLRenderer( { antialias: true } ); } renderer.setSize( w, h ); // ************************************************* // DIV に適用 // ************************************************* container.appendChild( renderer.domElement ); } // ********************************************************* // アニメーションループ // ********************************************************* function animate() { requestAnimationFrame( animate ); render(); } // ********************************************************* // 表示 // ********************************************************* function render() { var delta = clock.getDelta(); controls.update( delta ); renderer.render( scene, camera ); } </script> <style> .desc { margin-left: 60px; margin-top: -10px; } .cont { cursor: pointer; background-color: orange; } #control_desc td { padding:4px; border: 1px solid;#888; } </style> <div class="desc"> <br /> </div> <pre> <table id="control_desc" class="desc"> <tr> <td class="cont" onmousedown='controls.moveState.forward=1;control_update();' onmouseup='controls.moveState.forward=0;control_update();' onmouseout='controls.moveState.forward=0;control_update();' >W</td><td>前進</td> <td class="cont" onmousedown='controls.moveState.back=1;control_update();' onmouseup='controls.moveState.back=0;control_update();' onmouseout='controls.moveState.back=0;control_update();' >S</td><td>後退</td> <td class="cont" onmousedown='controls.moveState.left=1;control_update();' onmouseup='controls.moveState.left=0;control_update();' onmouseout='controls.moveState.left=0;control_update();' >A</td><td>左移動</td> <td class="cont" onmousedown='controls.moveState.right=1;control_update();' onmouseup='controls.moveState.right=0;control_update();' onmouseout='controls.moveState.right=0;control_update();' >D</td><td>右移動</td> </tr><tr> <td class="cont" onmousedown='controls.moveState.up=1;control_update();' onmouseup='controls.moveState.up=0;control_update();' onmouseout='controls.moveState.up=0;control_update();' >R</td><td>上移動</td> <td class="cont" onmousedown='controls.moveState.down=1;control_update();' onmouseup='controls.moveState.down=0;control_update();' onmouseout='controls.moveState.down=0;control_update();' >F</td><td>下移動</td> <td class="cont" onmousedown='controls.moveState.rollLeft=1;control_update();' onmouseup='controls.moveState.rollLeft=0;control_update();' onmouseout='controls.moveState.rollLeft=0;control_update();' >Q</td><td>左回転</td> <td class="cont" onmousedown='controls.moveState.rollRight=1;control_update();' onmouseup='controls.moveState.rollRight=0;control_update();' onmouseout='controls.moveState.rollRight=0;control_update();' >E</td><td>右回転</td> </tr><tr> <td class="cont" onmousedown='controls.moveState.pitchUp=1;control_update();' onmouseup='controls.moveState.pitchUp=0;control_update();' onmouseout='controls.moveState.pitchUp=0;control_update();' >Y</td><td>同一視点上移動</td> <td class="cont" onmousedown='controls.moveState.pitchDown=1;control_update();' onmouseup='controls.moveState.pitchDown=0;control_update();' onmouseout='controls.moveState.pitchDown=0;control_update();' >H</td><td>同一視点下移動</td> <td class="cont" onmousedown='controls.moveState.yawLeft=1;control_update();' onmouseup='controls.moveState.yawLeft=0;control_update();' onmouseout='controls.moveState.yawLeft=0;control_update();' >G</td><td>同一視点左移動</td> <td class="cont" onmousedown='controls.moveState.yawRight=1;control_update();' onmouseup='controls.moveState.yawRight=0;control_update();' onmouseout='controls.moveState.yawRight=0;control_update();' >J</td><td>同一視点右移動</td> </tr><tr> <td class="cont" onmousedown='controls.moveState.pitchUp=1;controls.moveState.down=1;control_update();' onmouseup='controls.moveState.pitchUp=0;controls.moveState.down=0;control_update();' onmouseout='controls.moveState.pitchUp=0;controls.moveState.down=0;control_update();' >O</td><td>対象物縦回転</td> <td class="cont" onmousedown='controls.moveState.pitchDown=1;controls.moveState.up=1;control_update();' onmouseup='controls.moveState.pitchDown=0;controls.moveState.up=0;control_update();' onmouseout='controls.moveState.pitchDown=0;controls.moveState.up=0;control_update();' >L</td><td>対象物縦回転</td> <td class="cont" onmousedown='controls.moveState.yawLeft=1;controls.moveState.right=1;control_update();' onmouseup='controls.moveState.yawLeft=0;controls.moveState.right=0;control_update();' onmouseout='controls.moveState.yawLeft=0;controls.moveState.right=0;control_update();' >K</td><td>対象物横回転</td> <td class="cont" onmousedown='controls.moveState.yawRight=1;controls.moveState.left=1;control_update();' onmouseup='controls.moveState.yawRight=0;controls.moveState.left=0;control_update();' onmouseout='controls.moveState.yawRight=0;controls.moveState.left=0;control_update();' >;</td><td>対象物横回転</td> </tr> </table> <div class="desc"> <b>▲ カメラの移動キーです</b> <b style='font-size:14px;'>日本語入力状態になっているとキーが効かないので注意して下さい ( 上のオレンジのキーをマウスで長押しても動作します )</b> ※ 移動してからの回転は、回転の中心が変化します ※ キーの同時押しは有効です </div> </pre> </div> </body> </html>
※ WEB上のコードは、一般 WEB 用に多少手を入れてあります
2012年09月19日
Three.js r50(2012/08/15) のわけの解らないバグ?と対処方法
3D データをロードすると、テクスチャがめちゃめちゃになるんですが、テクスチャデータを上下反転させると正しく描画されます。 バグというより、仕様変更のようです。最新の ColladaLoader.js で表示すると正しく描画されます。しかし、古いデータ(JSON) を JSONLoader で表示するとやはり上下反転が必要になります。 かなり新しい機能がたくさん実装されているのでいろいろ試したいところですが、とりあえず IEWebGL に対応したという記述があったので試すと、まあなんとか同じ動きを再現できました。 なんですが、COLLADA(dae)は loader で XPath(evaluate)使ってるのでIEはそもそも動かないです。 JSONデータ(Blender で作成)だと、JSONLoaderなんで( XMLじゃないので使われる予定も無い )動作します。 IEWebGL のサイトでは、Three.js でテクスチャ使ったサンプル動かしてますし・・・。ウチでは、3Dフォントが動きました。今後まだまだいろいろ動きがあるかもしれません。 ※ 追記 : さらに、COLLADA(dae)+Opera NEXT は酷い事になりました ▼ データ( dae ) の phong。emission が 1 なので、ライトは無しでレンダリング。
<phong> <emission> <color sid="emission">1 1 1 1</color> </emission> <ambient> <color sid="ambient">0 0 0 1</color> </ambient> <diffuse> <texture texture="eyes_png-sampler" texcoord="UVMap"/> </diffuse> <specular> <color sid="specular">0 0 0 1</color> </specular> <shininess> <float sid="shininess">50</float> </shininess> <index_of_refraction> <float sid="index_of_refraction">1</float> </index_of_refraction> </phong>
2012年05月21日
オンライン miku さん、好きな角度でどうぞ ( WebGL 限定・・・というか、Google Chrome か Firefoxのみ )
Mac の Safari なら WebGL on にして使えるかもしれません・・・ ※ データが 12メガあるので、最初のロードはしばらく時間がかかります
カメラの移動キー ( マウスドラッグで FLY )
※ 移動してからの回転は、回転の中心が変化します ※ キーの同時押しは有効です
※ 移動してからの回転は、回転の中心が変化します ※ キーの同時押しは有効です
W | 前進 | S | 後退 | A | 左移動 | D | 右移動 |
R | 上移動 | F | 下移動 | Q | 左回転 | E | 右回転 |
Y | 同一視点上移動 | H | 同一視点下移動 | G | 同一視点左移動 | J | 同一視点右移動 |
O | 対象物縦回転 | L | 対象物縦回転 | K | 対象物横回転 | ; | 対象物横回転 |
元データ( .mqo ) 配布サイト : hheaven.net
初音ミクのライセンス
■ 権利者 : クリプトン・フューチャー・メディア株式会社
■ ライセンス名 : ピアプロ・キャラクター・ライセンス
( ※ キャラクター利用のガイドライン )
初音ミクのライセンス
■ 権利者 : クリプトン・フューチャー・メディア株式会社
■ ライセンス名 : ピアプロ・キャラクター・ライセンス
( ※ キャラクター利用のガイドライン )
2012年04月22日
IE9 以降で動作する JavaScript 配列 の indexOf メソッド
indexOf メソッド (配列) (JavaScript) Three.js のソースを読んでいて存在を知りました。上記リンクは正式ドキュメントですが、 以下のように書かれています。Supported in the following document modes: Internet Explorer 9 standards and Internet Explorer 10 standards. Also supported in Metro style apps. IE9 と IE10 の標準モードと Metro( Windows8 VS11 ) Quirks、Internet Explorer 6 標準、Internet Explorer 7 標準、 Internet Explorer 8 標準の各ドキュメント モードでサポートされてい ません。つまり、IE8 では Three.js で シーンからオブジェクトを削除できない 事になるようですが・・・後で試してみます
タグ:javascript
2012年03月10日
自作のデザインフォントを使って、Three.js のテキストオブジェクトテストサンプルです
フリーのフォントを使うとものが大きくなるので、必要なデータのみ抽出するか それなりの入力処理を付加しないと意味無いので、とり急ぎ自分で作ったフォン トで動作確認を行いました。 以下の画像をクリックすると、デモページを開きます。 このページでは、カメラの切り替えやセグメントの数の違いによる表示結果の違い を確認する事ができます。( マウスの位置はカメラ位置です ) こちらのデモでは同じフォントを使って、マウスドラッグによる上下左右の回転処 理を行っています
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。 Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。 また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。 ※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです 対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。 ※ エキスパートモードで表示しています アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります<% if:page_name eq 'archive' -%> アーカイブページでのみ表示される内容 <% /if %> <% if:page_name eq 'category' -%> カテゴリページでのみ表示される内容 <% /if %> <% if:page_name eq 'tag' -%> タグページでのみ表示される内容 <% /if %>この記述は、以下の場所で使用します
|