PhysX2.8.0 Sampleを改造して人の形を作りたいのですが

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
tmak

PhysX2.8.0 Sampleを改造して人の形を作りたいのですが

#1

投稿記事 by tmak » 9年前

今、私は以前作成した。行列とオイラー角とクオータニオンの回転の違いを確認するプログラムにSampleD6Jointを継ぎたしながら足を作っています
 
オフトピック

コード:

 sceneDesc.gravity = NxVec3(0.0f, 0.0f, 0.0f);
356行目で無重力となっていて標準出力に回転させた時のデータが出力されていただけです[/size] 
単位系がわからないためサイズは実行時に確認しながら作成しています
わかる方がいらっしゃったら教えていただきたい

PhysX2.8.0 Sampleを改造して人の形を作りたいのですが、ジョイントに制限をかける際のパラメータ値をどのようにしたらいいのかわかりません
ジョイントの選定はサンプルをすべて実行し確認しました。
その結果、以下のジョイントが人の形には適しているのかと思いました。
ジョイントの制限は以下のリンクのNxJointLimitDesc クラスを確認したしました
http://maverickproj.web.fc2.com/PhysX_R ... tDesc.html
ラジアン角の場合:( -PI ~ PI )
座標の場合:( -inf ~ inf )
座標の場合とラジアンの場合がさっぱりです
ラジアンで1なのか座標で1なのか判別できないのでは?と少し疑問です

以下のようにコードを書いたのですが、角度の制限も動いている雰囲気もありません
くっついてる状態ですここで何をしたらいいのかわからなくなっています

コード:

#include <stdio.h>
#include <GL\glut.h>
#include <stdlib.h>

#include "NxPhysics.h"
#include "ErrorStream.h"
#include "DebugRenderer.h"
#include "Utilities.h"
#include "DrawObjects.h"
#include "../../v2.8.0/Samples/SampleCommonCode/src/Actors.h"

// 関数のプロトタイプ宣言
void InitGlut(int argc, char **argv);
bool InitNx();

// Physics
NxPhysicsSDK*	gPhysicsSDK = NULL;
NxScene*			gScene = NULL;
static DebugRenderer    gDebugRenderer;
static void CreateCombo(
	const NxVec3& pos, // **初期位置情報
	const NxVec3* initialVelocity=NULL, //**初期速度情報
	const NxVec3* fors=NULL// 
	);
// Rendering
static NxVec3	gEye(10.0f, 10.0f, 10.0f);
static NxVec3	gDir(-0.6f,-0.2f,-0.7f);
static NxVec3	gViewY;
static int		gMouseX = 0;
static int		gMouseY = 0;
bool debug = false;
NxActor *rodPivot;

// ユーザーデータの定義
class myData
{
public:
	double a[3];
	char color;
	int	size;
};

// キーボードの処理
static void KeyboardCallback(unsigned char key, int x, int y)
{ 
	NxQuat quatbuf(rodPivot->getGlobalOrientationQuat());
	NxMat33 nowbuf;
	NxF32 buf[3][3];
	nowbuf = rodPivot->getGlobalOrientation();
	nowbuf.getRowMajor(buf);
	puts("mat");
	for(int i=0;i<3;i++){
		for(int j=0;j<3;j++)
			printf("%5.3f,",buf[i][j]);
		puts("");
	}
	NxReal quat[4];
	quatbuf.getXYZW(quat);
	for(int i=0;i<4;i++)
		printf("%5.3f,",quat[i]);
	switch(key)
	{
	case 27:
		exit(0);
		break;
	case ' ':
		for(int i=0;i<3;i++){
			for(int j=0;j<3;j++)
				scanf("%f,",&buf[i][j]);
			puts("");
		}
		nowbuf.setRowMajor(buf);
		break;
	case '1':
		rodPivot->setAngularVelocity(NxVec3(0.9,0.0,0.0));
		break;
	case '2':
		rodPivot->setAngularVelocity(NxVec3(0.0,0.9,0.0));
		break;
	case '3':
		rodPivot->setAngularVelocity(NxVec3(0.0,0.0,0.9));
		break;
	case 'v':
	case 'V':
		debug = !debug;
		break;
	case 'x':
	case 'X':
		{
			NxActor** actors = gScene->getActors();
			if(gScene->getNbActors() > 1){
				gScene->releaseActor(*actors[gScene->getNbActors()-1]);
			}
		}
		break;		

		
	case 'q':
				CreateCombo(NxVec3(0.0,20.0,0.0));///2000.0cm==20m
		break;		
	case GLUT_KEY_UP:
		gEye += gDir*2.0f;
		break;
	case GLUT_KEY_DOWN:
		gEye -= gDir*2.0f;
		break;
	case GLUT_KEY_LEFT:
		gEye -= gViewY*2.0f;
		break;
	case GLUT_KEY_RIGHT:
		gEye += gViewY*2.0f;
		break;
	}
}

NxD6Joint* CreateD6Joint(NxActor* a0, NxActor* a1
	,const NxVec3& globalAnchor, const NxVec3& globalAxis
	)
{
	NxReal gLinearLimit = 1.0f;
	NxReal gSwing1Limit = NxPiF32 / 180.0f * 30.0f;
	NxReal gSwing2Limit = NxPiF32 / 180.0f * 70.0f;
	NxReal gTwistLowLimit = NxPiF32 / 180.0f * -90.0f;
	NxReal gTwistHighLimit = NxPiF32 / 180.0f * 45.0f;
	NxD6JointDesc d6Desc;
	d6Desc.actor[0] = a0;
	d6Desc.actor[1] = a1;
	d6Desc.setGlobalAnchor(globalAnchor);
	d6Desc.setGlobalAxis(globalAxis);

	d6Desc.twistMotion = NX_D6JOINT_MOTION_LOCKED;
	d6Desc.swing1Motion = NX_D6JOINT_MOTION_LOCKED;
	d6Desc.swing2Motion = NX_D6JOINT_MOTION_LOCKED;

	d6Desc.xMotion = NX_D6JOINT_MOTION_LOCKED;
	d6Desc.yMotion = NX_D6JOINT_MOTION_LOCKED;
	d6Desc.zMotion = NX_D6JOINT_MOTION_LOCKED;

	d6Desc.linearLimit.value = gLinearLimit;
	d6Desc.swing1Limit.value = gSwing1Limit;
	d6Desc.swing2Limit.value = gSwing2Limit;
	d6Desc.twistLimit.low.value =  gTwistLowLimit;
	d6Desc.twistLimit.high.value = gTwistHighLimit;

	//	d6Desc.projectionMode = NX_JPM_NONE;
	d6Desc.projectionMode = NX_JPM_POINT_MINDIST;

	//	d6Desc.jointFlags |= NX_JF_COLLISION_ENABLED;

	NxJoint* d6Joint = gScene->createJoint(d6Desc);

	return (NxD6Joint*)d6Joint->is(NX_JOINT_D6);
}

// 複合シェープ人の生成
static void CreateComboHuman(
	const NxVec3& pos, // **初期位置情報
	const NxVec3* initialVelocity=NULL, //**初期速度情報
	const NxVec3* fors=NULL// **初期化速度
	){
		if(gScene == NULL) return;

		NxActor *migiasi  = CreateBox(NxVec3(1,0,0), NxVec3(1,0.5,2.7),985);
		NxActor *hidariasi= CreateBox(NxVec3(-1,0,0), NxVec3(1,0.5,2.7),985);
		NxActor *migisune = CreateCapsule(NxVec3(1,0,3),3.7,0.557,985);
		NxD6Joint *j1 = CreateD6Joint(migiasi,migisune,NxVec3(0,0,0),NxVec3(0,0,0));



}

// 複合シェープの生成
static void CreateCombo(
	const NxVec3& pos, // **初期位置情報
	const NxVec3* initialVelocity, //**初期速度情報
	const NxVec3* fors// 
	)
{
	if(gScene == NULL) return;	
	// アクターのパラメータ設定
	NxBodyDesc bodyDesc;

	// 回転運動減衰係数
	bodyDesc.angularDamping	= 0.01f;
	// 線形減衰係数
	bodyDesc.linearDamping  = 0.01f;

	// 初期速度情報
	if(initialVelocity) bodyDesc.linearVelocity = *initialVelocity;

	// Boxシェープの作成
	NxBoxShapeDesc boxDesc1;
	// Dimentions 寸法
	boxDesc1.dimensions = NxVec3(1,4,1);
	NxBoxShapeDesc boxDesc2;
	boxDesc2.dimensions = NxVec3(4,1,1);
	NxBoxShapeDesc boxDesc3;
	boxDesc3.dimensions = NxVec3(1,1,4);


	// シェープを保持してアクターを構成します
	NxActorDesc actorDesc;
	actorDesc.shapes.pushBack(&boxDesc1);
	actorDesc.shapes.pushBack(&boxDesc2);
	actorDesc.shapes.pushBack(&boxDesc3);

	// アクターのパラメータを受け継ぐ
	actorDesc.body			= &bodyDesc;
	// 密度の指定
	actorDesc.density		= 1000.0f;
	// アクターの位置情報
	actorDesc.globalPose.t  = pos;


	rodPivot = gScene->createActor(actorDesc);

}

// 囲いシェープ
static void RoundedBox(
	const double takasa=3,
	const double x_kyori=50,
	const double z_kyori=50,
	const double atusa=1
	)
{
	if(gScene == NULL) return;	

	NxBodyDesc bodyDesc;
	bodyDesc.angularDamping	= 0.5f;

	NxBoxShapeDesc boxDesc1;
	boxDesc1.dimensions = NxVec3(atusa,takasa,z_kyori);
	boxDesc1.localPose.t= NxVec3(-x_kyori+atusa,takasa,0);
	NxBoxShapeDesc boxDesc2;
	boxDesc2.dimensions = NxVec3(atusa,takasa,z_kyori);
	boxDesc2.localPose.t= NxVec3(x_kyori-atusa,takasa,0);
	NxBoxShapeDesc boxDesc3;
	boxDesc3.dimensions = NxVec3(x_kyori,takasa,atusa);
	boxDesc3.localPose.t= NxVec3(0,takasa,-z_kyori+atusa);
	NxBoxShapeDesc boxDesc4;
	boxDesc4.dimensions = NxVec3(x_kyori,takasa,atusa);
	boxDesc4.localPose.t= NxVec3(0,takasa,z_kyori-atusa);

	NxActorDesc actorDesc;
	actorDesc.shapes.pushBack(&boxDesc1);
	actorDesc.shapes.pushBack(&boxDesc2);
	actorDesc.shapes.pushBack(&boxDesc3);
	actorDesc.shapes.pushBack(&boxDesc4);

	actorDesc.body			= &bodyDesc;
	actorDesc.density		= 1000000.0f;
	actorDesc.globalPose.t  = NxVec3(0.0,1,0.0);
	gScene->createActor(actorDesc);
}


////
///
////
///
////
///
////
///
////
// メイン関数
int main(int argc, char** argv)
{
	printf("スペースキーはキューブを生成します\n");
	printf("1は複合シェープを生成します\n");
	printf("2は机を生成します\n");
	printf("Bはボックスを生成します\n");
	printf("Cはカプセルを生成します\n");
	printf("Sは球を生成します\n");
	printf("Vキーはデバッグ画面を切り替えます\n");
	printf("Xキーはアクターを削除します\n");
	// glutの初期化
	InitGlut(argc, argv);
	// PhysXの初期化
	if (InitNx()){
		CreateCombo(NxVec3(0.0,2000.0,0.0));///2000.0cm==20m
		CreateComboHuman(NxVec3(0.0,100.0,0.0));
		RoundedBox();
		glutMainLoop();
	}
	return 0;
}

// 画面の描画
static void RenderCallback()
{
	if(gScene == NULL) return;

	gScene->simulate(1.0f/60.0f);
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

	// 射影マトリックス
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60.0f, (float)glutGet(GLUT_WINDOW_WIDTH)/(float)glutGet(GLUT_WINDOW_HEIGHT), 1.0f, 10000.0f);
	gluLookAt(gEye.x, gEye.y, gEye.z, gEye.x + gDir.x, gEye.y + gDir.y, gEye.z + gDir.z, 0.0f, 1.0f, 0.0f);

	// ビューマトリックス
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	int nbActors = gScene->getNbActors();
	gScene->fetchResults(NX_RIGID_BODY_FINISHED, true);
	if (debug)
	{
		gDebugRenderer.renderData(*gScene->getDebugRenderable());
	}
	else
	{
		NxActor** actors = gScene->getActors();
		while(nbActors--)
		{

			NxActor* actor= *actors;
			if(actor->userData){
				myData *mydata =(myData*)(actor)->userData;
				//				NxVec3 set(mydata->a[0],mydata->a[1],mydata->a[2]);
				//				NxVec3 set(0.0,rand()%1000,0.0);
				//				actor->addForce(set);

			}

			DrawActor(*actors++);
		}
		gScene->flushStream();
	}	

	glutSwapBuffers();
}
// PhysXの初期化
static bool InitNx()
{
	// PhysX SDKの生成
	NxPhysicsSDKDesc desc;
	NxSDKCreateError errorCode = NXCE_NO_ERROR;
	gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, NULL, new ErrorStream(), desc, &errorCode);
	if(gPhysicsSDK == NULL) 
	{
		printf("\nSDKの生成に失敗\n");
		return false;
	}

	gPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.05f);

	gPhysicsSDK->setParameter(NX_VISUALIZE_COLLISION_SHAPES, 1);
	gPhysicsSDK->setParameter(NX_VISUALIZATION_SCALE, 10.0f);

	// シーンの生成
	NxSceneDesc sceneDesc;
	sceneDesc.gravity				= NxVec3(0.0f, -1.0f, 0.0f);
	gScene = gPhysicsSDK->createScene(sceneDesc);
	if(gScene == NULL) 
	{
		printf("\nシーンの生成に失敗\n");
		return false;
	}

	// デフォルトのマテリアル
	NxMaterial* defaultMaterial = gScene->getMaterialFromIndex(0);
	defaultMaterial->setRestitution(0.0f);
	defaultMaterial->setStaticFriction(0.5f);
	defaultMaterial->setDynamicFriction(0.5f);

	// 地面の生成
	NxPlaneShapeDesc planeDesc;
	NxActorDesc actorDesc;
	actorDesc.shapes.pushBack(&planeDesc);
	gScene->createActor(actorDesc);

	return true;
}

// PhysXの終了処理
static void ExitNx()
{
	if(gPhysicsSDK != NULL)
	{
		if(gScene != NULL) gPhysicsSDK->releaseScene(*gScene);
		gScene = NULL;
		NxReleasePhysicsSDK(gPhysicsSDK);
		gPhysicsSDK = NULL;
	}
}

// 矢印キーの処理
static void ArrowKeyCallback(int key, int x, int y)
{
	KeyboardCallback(key,x,y);
}

// マウスの処理
static void MouseCallback(int button, int state, int x, int y)
{
	gMouseX = x;
	gMouseY = y;
}

// マウスのドラッグの処理
static void MotionCallback(int x, int y)
{
	int dx = gMouseX - x;
	int dy = gMouseY - y;

	gDir.normalize();
	gViewY.cross(gDir, NxVec3(0,1,0));

	NxQuat qx(NxPiF32 * dx * 20/ 180.0f, NxVec3(0,1,0));
	qx.rotate(gDir);
	NxQuat qy(NxPiF32 * dy * 20/ 180.0f, gViewY);
	qy.rotate(gDir);

	gMouseX = x;
	gMouseY = y;
}

// ウインドウのサイズの変更
static void ReshapeCallback(int width, int height)
{
	glViewport(0, 0, width, height);
}

// アイドリングの処理
static void IdleCallback()
{
	glutPostRedisplay();
}

// glutの初期化
void InitGlut(int argc, char **argv)
{
	glutInit(&argc, argv);
	glutInitWindowSize(512, 512);
	glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
	int mainHandle = glutCreateWindow("Sample");
	glutSetWindow(mainHandle);
	glutDisplayFunc(RenderCallback);
	glutReshapeFunc(ReshapeCallback);
	glutIdleFunc(IdleCallback);
	glutKeyboardFunc(KeyboardCallback);
	glutSpecialFunc(ArrowKeyCallback);
	glutMouseFunc(MouseCallback);
	glutMotionFunc(MotionCallback);
	MotionCallback(0,0);
	atexit(ExitNx);

	// デフォルトの描画パラメータ
	glClearColor(0.3f, 0.4f, 0.5f, 1.0);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_COLOR_MATERIAL);

	// 光源の設定
	glEnable(GL_LIGHTING);
	float ambientColor[]	= { 0.0f, 0.1f, 0.2f, 0.0f };
	float diffuseColor[]	= { 1.0f, 1.0f, 1.0f, 0.0f };		
	float specularColor[]	= { 0.0f, 0.0f, 0.0f, 0.0f };		
	float position[]		= { 100.0f, 100.0f, 400.0f, 1.0f };		
	glLightfv(GL_LIGHT0, GL_AMBIENT, ambientColor);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseColor);
	glLightfv(GL_LIGHT0, GL_SPECULAR, specularColor);
	glLightfv(GL_LIGHT0, GL_POSITION, position);
	glEnable(GL_LIGHT0);
}

まとめると質問は3つです
  1. ラジアンの範囲内の座標はどうなってしまうのか?
  2. 単位系はどうなっているのか?
  3. どうして、完全にくっついているのか?

“C言語何でも質問掲示板” へ戻る