ホットスポットに立体(球)を表示してみます(直方体にテクスチャーマッピングする例は↓)。
Google VR Viewライブラリのthree.jsには球を表示するコードはデフォルトで実装されています。他の立体(直方体や三角錐など)は実装されていないので必要なら本家three.jsから借りてきます。
こんな感じ
Google VR Viewではホットスポットは2つのオブジェクトで構成されています。これをそのまま使って、外側のオブジェクトにはボールの画像をテクスチャーマッピングしました。
マッピング用の画像はこんな感じ。adidas TELSTARです。
バンプマッピングにすれば、もっと「もっともらしく」見えるはずです(すいません、手ぇぬいてます)。
マッピング用の画像、いろいろあります。
VR空間の中でボールを動かせますし、拡大・縮小もできます。
拡大・縮小は3軸のパラメータを持っているので、ある軸方向にのみ変形させるとアニメみたいな効果も出せます。
ただし、カードボードでは出来ません。コントローラーが使えるHMDが必要になるでしょう。手に入ったら対応する予定です(^^)。
注 カードボード装着時に立体を表示する場合はこのページを参照
注 Daydreamならいける?音声認識でも動かせるかもしれませんね。
さらに、VRのパノラマ画像の物体同士は相互の位置情報を持っているわけではないので、空間内で重なった物体の「オブジェクトの間」を通過させるようなことはできません。
でも、不可能ではないと思います(3次元のクリッカブルマップのような境界情報とVR空間全体のサイズ情報を持たせて衝突(内外)判定でshow・hideさせるとか…これがあればボールのリフレクトやデフレクトもできるのだけど)が、止めときましょう。AIでもできると思うけど、この程度の判定にそんな重い計算量はいらんでしょう。
ARなら実現されていますね、GIGAZINEの記事(ポケモンGoでおなじみのNianticの技術)。
ただ気になるのはGoogle VR Viewには距離に関してはUnit(単位)という概念が無いような気がする。Distantというパラメーターはmだよとどこかに書いてた覚えはあるけど(間違ってたらごめんなさい)。
【main.js】
hotspots: {
spot1: {
pitch: 20.6,
yaw: 61.9,
radius: 0.5,
distance: 2,
color: ‘#ff0000’,
shape: ‘sphere‘,
comment:”
}
}
【embed.js】
表示したいオブジェクトのsideパラメータはTHREE.FrontSideにします。
HotspotRenderer.prototype.createHotspot_ = function(radius, distance, color, shape)
try{
var loader = new THREE.TextureLoader();
var path = ‘http://wisteriahill.sakura.ne.jp/Panorama/VRVIEW/hotspot_sample/images/ball-telstar.png’;
var texture = loader.load (path);
}catch(e){}
if(shape == “sphere”){
var innerGeometry = new THREE.SphereGeometry(radius,32,32);
var outerGeometry = new THREE.SphereGeometry(radius,32,32);
}
var innerMaterial = new THREE.MeshBasicMaterial({
color: hex_color, side: THREE.DoubleSide, transparent: true,wireframe:false,
opacity: MAX_INNER_OPACITY, depthTest: false
});
var inner = new THREE.Mesh(innerGeometry, innerMaterial);
inner.name = ‘inner’;
inner.rotation.y = 0;
var outerMaterial = new THREE.MeshBasicMaterial({
map:texture,color: 0xffffff, side: THREE.FrontSide, transparent: false,wireframe:false,
opacity: MAX_OUTER_OPACITY, depthTest: false
});
var outer = new THREE.Mesh(outerGeometry, outerMaterial);
outer.name = ‘outer’;
outer.rotation.y = 0;
};
これら関数のもう少し詳しい説明は
Google VR Viewのホットスポットに画像をはりつけてみます
をご参照ください。
立方体・直方体の場合
【three.js】
BoxBufferGeometryは既に実装されているので、この関数の直前にBoxGeometryのコードを貼り付けます(r84のコード)。
function BoxGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) {
Geometry.call( this );
this.type = ‘BoxGeometry’;
this.parameters = {
width: width,
height: height,
depth: depth,
widthSegments: widthSegments,
heightSegments: heightSegments,
depthSegments: depthSegments
};
this.fromBufferGeometry( new BoxBufferGeometry( width, height, depth, widthSegments, heightSegments, depthSegments ) );
this.mergeVertices();
}
BoxGeometry.prototype = Object.create( Geometry.prototype );
BoxGeometry.prototype.constructor = BoxGeometry;
exportします。本家Three.jsではCubeGeometryという関数名もサポートしているようですが実態はBoxGeometryです。
exports.BoxGeometry = BoxGeometry;
exports.CubeGeometry = BoxGeometry;
単純に直方体にテクスチャーマッピングしただけの場合
地べたに立体を置いてみました。なおかつ回転させてみました(回り灯籠とかロータリースタンド看板みたいなやつです)。
注
オリジナルコードのMeshBasicMaterialではsideパラメータがどちらもTHREE.DoubleSideになっていますが、マッピングする場合これだと一部面が抜けるようです。表示したいオブジェクトのsideパラメータはTHREE.FrontSide。
【main.js】
hotspots: {
spot1: {
pitch: 0,
yaw: 111.9,
radius: 0.4,
distance: 3,
color: ‘#0000ff’,
shape: ‘cube‘,
comment:’直方体にテクスチャーマッピングしてます’
}
}
【embed.js】
try{
var loader = new THREE.TextureLoader();
var path = ‘http://wisteriahill.sakura.ne.jp/Panorama/VRVIEW/hotspot_sample/images/gamba-emblem.png’;
var texture = loader.load (path);
}catch(e){}
var outerMaterial = new THREE.MeshBasicMaterial({
map:texture,side: THREE.FrontSide, transparent: false,wireframe:false,
opacity: MAX_INNER_OPACITY, depthTest: false
});
var outer = new THREE.Mesh(outerGeometry, outerMaterial);
Leave a Reply