ウラデブ

AR、MR、プログラミングとかとか・・・

壁とか天井とか床とかに貼り付けよう 〜 社内が蜘蛛だらけ

ども、ウラさんです。
前回、空間認識をして部屋の壁や床を作れるようになったのでそこへオブジェクトを置いてみます。
壁とか天井に張り付いてて違和感無いのは何かなぁー・・・って考えながらアセットストアを見てたら丁度よいのが無料であったのでそいつにしました。

 

f:id:urasansan:20170405142047j:plain

 はい、蜘蛛ちゃんですねっ!

蜘蛛かヤモリならそこら中に這い回っててもなんら違和感ないですねっ!
キモいですねっ!
蜘蛛が苦手な方には最低な記事になってますねっ!
すみませんっ!っと。



さて、前回のプロジェクトを使って行きます。
SurfaceMeshesToPlanes_MakePlanesCompleteで壁とかが生成された後に

	List<GameObject> walls = new List<GameObject>();
	walls = SurfaceMeshesToPlanes.Instance.GetActivePlanes(PlaneTypes.Wall);

てな感じで、壁や天井を指定してGameObjectのリストが取得出来るみたいです。
オブジェクトが取得できれば、後はUnityの知識ですね。

あるオブジェクトに垂直に張り付くようにオブジェクトを生成出来ればOKですね?
単純に考えればX軸を-90度傾ければ垂直になるでしょう。
ってな事で、

	Quaternion rot = wall.transform.rotation;
	rot.x -= 90;
	Instantiate(prefab,  wall.transform.position, rot);

こんな感じにしたけど、何か変・・・
しゃーない、調べるか・・・
Unityに関しては手探りでやってるだけなんだよなぁ、Unity好きじゃ無いし。

えーと、
「回転はクォータニオン使ってるから知識無い奴が直接値触っちゃダメよーっ!」
って事らしいです。
へーへー、こちとらクォータニオンなんぞ変態数学の知識は無いですよ、すみませんねぇーっ!
知識無い奴は関数使ってねーって事らしいので
Quaternion.Euler
こいつを使えば良いみたい。

	GameObject wall = GameObject.Find("wall");
	Quaternion rot = wall.transform.rotation * Quaternion.Euler (-90, 0, 0);
	Instantiate(prefab,  wall.transform.position, rot);

こんな感じで、Quaternion.Euler使ってX軸を-90度したのと合成すれば良いみたい。

ここまで出来れば、壁や天井は取得出来てるし、垂直に貼り付ける事も出来たので後は簡単ですな。

private void SurfaceMeshesToPlanes_MakePlanesComplete(object source, System.EventArgs args)
{
	RemoveSurfaceVertices.Instance.RemoveSurfaceVerticesWithinBounds(SurfaceMeshesToPlanes.Instance.ActivePlanes);

	SpatialMappingManager.Instance.DrawVisualMeshes = false;

	//	蜘蛛のプレハブ
	GameObject prefab = Resources.Load<GameObject>("spider");

	//	全ての壁に這わせてみる
	List<GameObject> walls = new List<GameObject>();
	walls = SurfaceMeshesToPlanes.Instance.GetActivePlanes(PlaneTypes.Wall);
	foreach( GameObject wall in walls ) {
		Quaternion rot = wall.transform.rotation * Quaternion.Euler(-90, 0, 0);
		Instantiate(prefab,  wall.transform.position, rot);
	}

	//	全ての天井に這わせてみる
	List<GameObject> ceilings = new List<GameObject>();
	ceilings = SurfaceMeshesToPlanes.Instance.GetActivePlanes(PlaneTypes.Ceiling);
	foreach( GameObject ceiling in ceilings ) {
		Quaternion rot = ceiling.transform.rotation * Quaternion.Euler(-90, 0, 0);
		Instantiate(prefab,  ceiling.transform.position, rot);
	}

	//	全ての床に置いてみる
	List<GameObject> floors = new List<GameObject>();
	floors = SurfaceMeshesToPlanes.Instance.GetActivePlanes(PlaneTypes.Floor);
	foreach( GameObject floor in floors ) {
		Quaternion rot = floor.transform.rotation * Quaternion.Euler(-90, 0, 0);
		Instantiate(prefab,  floor.transform.position, rot);
	}
}

こんな感じで、全ての面の中央に蜘蛛ちゃんを配置してみる。

 

f:id:urasansan:20170405144616p:plain

はい、出来た!
キモっ!!!
まぁ、でも、ちゃんと壁等に張り付いてるね、成功だね。

ただ、これだと実際の壁に張り付いてる感が無いので
SurfaceMeshesToPlanes
が作ってるPlanesを消してみます。

f:id:urasansan:20170405150805p:plain

これで良いのかしら・・・?

f:id:urasansan:20170405150938p:plain

透明になった。

って事で、動いてるのはこんな感じ。



キモっ!!!
まぁ、やりたい事は一応出来たね・・・
ただ、裏側が見えちゃってる蜘蛛ちゃんがいるね。
遮蔽されてないね、Hololensなんだからちゃんと遮蔽されて向こう側の壁の蜘蛛ちゃんは見えなくならないとダメだよね。

Occlusionとやらがキーワードだな、よし調べようっ!
では、またっ!

 


蜘蛛じゃなくてヤモリのが良いかなぁ・・・