- OpenGL空間上のオブジェクトをマウスドラッグで移動させる -
前回でオブジェクトの選択をしました。
今回は取得したオブジェクト名を使ってマウスドラッグをさせる時の処理についてです。

オブジェクト名を取得できれば、選択されたオブジェクトが判別できるかと思います
(オブジェクト描画時にglLoadName()等で名前をつけてるのですからね)
ということは、選択されたオブジェクトの色んな情報が引き出せることでしょう。

マウスドラッグをさせるには選択されたオブジェクトの座標が必要ですね。
まず、そのオブジェクト座標を取得します。

座標を取得できたらSetCapture()で引数にウインドウハンドルを指定してマウスキャプチャを開始します。
その後、マウスで指定した場所のウインドウ座標を取得します。LOWORD()/HIWORD()です。

そして前回のマウスピッキング処理をして選択したオブジェクトの一番小さいデプスと一番大きいデプスを取得し、
その2つを加算して2で割ります。このようにすると中間のデプス値が取得できますよね。

あとはウインドウ座標をOpenGLのワールド座標に変換してOpenGL座標を取得します。
この時のデプスを上で計算したデプス値にすると、マウスで選択したときにオブジェクトが置いてあるデプスと
同じデプスで座標を取得できるので、移動させた時に異常に手前になったり奥になったりすることが少なくなるので、
中間デプス値の取得は重要です。

OpenGLのワールド座標が取得できたら、取得した座標をオブジェクトの座標とします。
この処理をマウスが動くたびに繰り返すことで、オブジェクトの移動が可能となります。


[ コーディング例 ]
オブジェクトの名前をマウスで拾う。
(一番手前のオブジェクト名を拾うには前回参照)

取得したオブジェクトの名前からオブジェクト座標を取得。
(この部分はプログラマが定義したオブジェクトのデータ構造によって様々な方法があると思います)

WM_LBUTTONDOWNイベントにて

	SetCapture(hwnd);		//マウスキャプチャの開始


WM_MOUSEMOVEイベントにて
	POINTS mouseMovePoint;

	WinDC = GetDC(hwnd);
	wglMakeCurrent(WinDC, hRC);	//OpenGLとの接続

	//マウスのウインドウ座標取得
	mouseMovePoint.x = LOWORD(lParam);
	mouseMovePoint.y = HIWORD(lParam);

	//ウインドウ座標をOpenGLワールド座標に変換する
	//(関数化したもの。nameDepthは前回で得たオブジェクトの中間デプス値)
	//winToWorldCoodに、ウインドウ座標から変換されたOpenGLワールド座標が格納される。
	GetWorldCoodinates(mouseMovePoint.x, mouseMovePoint.y, &winToWorldCood, modelviewMatrix, projectionMatrix, nameDepth);
			
	int rowNum, colNum;
	
	//オブジェクトの名前からオブジェクト(この場合は頂点)の座標を取得。
	//nameNum==12だったら、オブジェクトの座標はgv[0][2]となるようなデータ構造。
	rowNum = nameNum / 10;
	colNum = nameNum % 10;

	//ピックした頂点の座標を、マウスムーブで取得したワールド座標とする
	gv[rowNum-1][colNum].x = winToWorldCood.x;
	gv[rowNum-1][colNum].y = winToWorldCood.y;
	gv[rowNum-1][colNum].z = winToWorldCood.z;

	wglMakeCurrent(NULL, NULL);
	ReleaseDC(hwnd, WinDC);
	InvalidateRect(hwnd, NULL, FALSE);


WM_LBUTTONUPイベントにて

	ReleaseCapture();	//マウスキャプチャの終了



上記のように、「オブジェクトの座標をマウスのウインドウ座標を変換したワールド座標にする」ことで
オブジェクトの移動が実現できます。


inserted by FC2 system