버그 해결을 위한 모든 질문을 던져
0 votes
73 views

지금 환경은 C++, 다렉12, 불릿 물리엔진으로 작업중인데요.

한국어 자료는 아예 없을 뿐더러 외국계 사이트에도 자료가 거의 전무한 수준이네요...ㅠ

불릿 피직스의 예제중 하나인 Hinge2Vehicle을 보고 작업중인데, 해당 예제에는 차량을 조종할 수 있는 조작계 자체가

코딩이 안되어있더라구요.

다만 각각의 바퀴들에 모터를 설정해주고 최대 모터 포스를 넣어놓은 걸 보니까 바퀴를 포함하는 힌지 자체에 setTargetVelocity라는 목표 모터 포스까지 점점 가속하는 함수가 제공되는걸 확인했습니다.

해서 각각의 힌지들 (차량 섀시와 바퀴를 연결해놓은 힌지)을 바퀴 클래스에 저장하고, 프레임 돌아갈때마다 입력을 확인해서 입력받았다면 setTargetVelocity를 실행하도록 만들었는데

문제는 여기서 바퀴가 돌아갈 때 자동차처럼 자전하는게 아니라 바퀴와 연결되어있는 섀시를 중심으로 공전합니다ㅠ

모터 관련된 함수는 힌지만 가지고 있으니 리지드 바디 자체를 밀거나 하는건 전혀 의미 없는 짓이고...

게다가 공식 문서들도 설명이 미비해서 hinge->enableMotor(3, true)같은 것들의 첫번째 파라미터는 뭔지도 모르겠어요... 3이면 힌지 자체의 회전이고 5면 스티어링과 같은 형태로 움직이긴 하는데 어째서 그런건지는 전혀 알 수가 없네요....

제발 부탁드립니다 힌지 만드는 거랑 조작받는 부분은 코드로 첨부할게요...


//플레이어 초기화
CVehiclePlayer::CVehiclePlayer(ID3D12Device* pd3dDevice, ID3D12GraphicsCommandList* pd3dCommandList, ID3D12RootSignature* pd3dGraphicsRootSignature, btAlignedObjectArray<btCollisionShape*>& btCollisionShapes, btDiscreteDynamicsWorld* pbtDynamicsWorld, int nMeshes) : CPlayer(nMeshes)
{
	CMeshFileRead* pVehicleMesh = new CMeshFileRead(pd3dDevice, pd3dCommandList, "Models/FlyerPlayership.bin", false);
	CMeshFileRead* pWheelMesh = new CMeshFileRead(pd3dDevice, pd3dCommandList, "Models/Sphere.bin", false);
	SetMesh(0, pVehicleMesh);

	SetMaterial(XMFLOAT4{ 0.0f, 0.25f, 0.875f, 1.0f }, XMFLOAT4{ 1.0f, 1.0f, 1.0f, 1.0f }, XMFLOAT4{ 1.0f, 1.0f, 1.0f, 1.0f }, XMFLOAT4{ 0.0f, 0.0f, 0.0f, 0.0f }, 100, XMFLOAT3(0.0f, 0.25f, 0.875f));

	m_pCamera = ChangeCamera(THIRD_PERSON_CAMERA, 0.0f);
	CreateShaderVariables(pd3dDevice, pd3dCommandList);
	SetPosition(XMFLOAT3(100.0f, 50.0f, 100.0f));

	auto extents = pVehicleMesh[0].GetBoundingBox().Extents;

	btCollisionShape* chassisShape = new btBoxShape(btVector3(extents.x, extents.y, extents.z));
	btCollisionShapes.push_back(chassisShape);

	btTransform btCarTransform;
	btCarTransform.setIdentity();
	btCarTransform.setOrigin(btVector3(m_xmf3Position.x, m_xmf3Position.y, m_xmf3Position.z));

	m_pbtRigidBody = BulletHelper::CreateRigidBody(2.0f, btCarTransform, chassisShape, pbtDynamicsWorld);

	btTransform FH_tr;
	const btScalar FALLHEIGHT = -3;
	FH_tr.setOrigin(btVector3(0, 0, 0));
	btCollisionShape* wheelShape = new btCylinderShapeX(btVector3(0.4f, 0.5f, 0.5f));

	btVector3 wheelPos[4] = {
		btVector3(btScalar(m_xmf3Position.x - (extents.x / 2)), btScalar(m_xmf3Position.y), btScalar(m_xmf3Position.z + (extents.z / 2))),
		btVector3(btScalar(m_xmf3Position.x + (extents.x / 2)), btScalar(m_xmf3Position.y), btScalar(m_xmf3Position.z + (extents.z / 2))),
		btVector3(btScalar(m_xmf3Position.x + (extents.x / 2)), btScalar(m_xmf3Position.y), btScalar(m_xmf3Position.z - (extents.z / 2))),
		btVector3(btScalar(m_xmf3Position.x - (extents.x / 2)), btScalar(m_xmf3Position.y), btScalar(m_xmf3Position.z - (extents.z / 2))) };

	for (int i = 0; i < 4; i++)
	{
		btRigidBody* pBodyA = m_pbtRigidBody;
		pBodyA->setActivationState(DISABLE_DEACTIVATION);

		btTransform tr;
		tr.setIdentity();
		tr.setOrigin(wheelPos[i]);

		btRigidBody* pBodyB = BulletHelper::CreateRigidBody(1.0f, tr, wheelShape, pbtDynamicsWorld);
		pBodyB->setFriction(1110);
		pBodyB->setActivationState(DISABLE_DEACTIVATION);

		btVector3 parentAxis(0.f, 1.f, 0.f);
		btVector3 childAxis(1.f, 0.f, 0.f);
		btVector3 anchor = tr.getOrigin();
		btHinge2Constraint* pHinge2 = new btHinge2Constraint(*pBodyA, *pBodyB, anchor, parentAxis, childAxis);

		// add constraint to world
		pbtDynamicsWorld->addConstraint(pHinge2, true);

		// Drive engine.
		pHinge2->enableMotor(3, true);
		pHinge2->setMaxMotorForce(3, 1000);
		pHinge2->setTargetVelocity(3, 0);

		// Steering engine.
		pHinge2->enableMotor(5, true);
		pHinge2->setMaxMotorForce(5, 1000);
		pHinge2->setTargetVelocity(5, 0);

		pHinge2->setParam(BT_CONSTRAINT_CFM, 0.15f, 2);
		pHinge2->setParam(BT_CONSTRAINT_ERP, 0.35f, 2);

		pHinge2->setDamping(2, 2.0);
		pHinge2->setStiffness(2, 40.0);

		btScalar m[16];
		pBodyB->getWorldTransform().getOpenGLMatrix(m);

		m_pWheel[i] = new CWheel(Matrix4x4::glMatrixToD3DMatrix(m), pWheelMesh);
		m_pWheel[i]->SetRigidBody(pBodyB);
		m_pWheel[i]->setHinge(pHinge2);
	}

	CPlayerShader* pShader = new CPlayerShader();
	pShader->CreateShader(pd3dDevice, pd3dGraphicsRootSignature);
	SetShader(pShader);

	for (int i = 0; i < 4; ++i)
	{
		m_pWheel[i]->SetShader(pShader);
	}
}

// 업데이트 및 조작
void CVehiclePlayer::Update(float fTimeElapsed, btDiscreteDynamicsWorld* pbtDynamicsWorld, DWORD dwBehave)
{
	switch (dwBehave)
	{
		case DIR_LEFT:
		{
			m_gVehicleSteering += m_steeringIncrement;
			if (m_gVehicleSteering > m_steeringClamp)
				m_gVehicleSteering = m_steeringClamp;
			for (int i = 0; i < 2; ++i)
			{
				m_pWheel[i]->getHinge()->setTargetVelocity(5, m_gVehicleSteering);
			}

			break;
		}
		case DIR_RIGHT:
		{
			m_gVehicleSteering -= m_steeringIncrement;
			if (m_gVehicleSteering < -m_steeringClamp)
				m_gVehicleSteering = -m_steeringClamp;
			for (int i = 0; i < 2; ++i)
			{
				m_pWheel[i]->getHinge()->setTargetVelocity(5, m_gVehicleSteering);
			}
			break;
		}
		case DIR_FORWARD:
		{
			m_gEngineForce = m_maxEngineForce;
			m_gBreakingForce = 0.f;

			for (int i = 0; i < 2; ++i)
			{
				m_pWheel[i]->getHinge()->setTargetVelocity(3, m_gEngineForce);
			}

			break;
		}
		case DIR_BACKWARD:
		{
			m_gEngineForce = -m_maxEngineForce;
			m_gBreakingForce = 0.f;

			for (int i = 0; i < 2; ++i)
			{
				m_pWheel[i]->getHinge()->setTargetVelocity(3, m_gEngineForce);
			}

			break;
		}
	}

	

	auto CollisionObjectArray = pbtDynamicsWorld->getCollisionObjectArray();
	btScalar* m = new btScalar[16];
	CollisionObjectArray[CollisionObjectArray.findLinearSearch(m_pbtRigidBody)]->getWorldTransform().getOpenGLMatrix(m);
	m_xmf4x4World = Matrix4x4::glMatrixToD3DMatrix(m);
	
	m_xmf3Position = XMFLOAT3(m_xmf4x4World._41, m_xmf4x4World._42, m_xmf4x4World._43);
	m_xmf3Look = XMFLOAT3(m_xmf4x4World._31, m_xmf4x4World._32, m_xmf4x4World._33);
	m_xmf3Up = XMFLOAT3(m_xmf4x4World._21, m_xmf4x4World._22, m_xmf4x4World._23);
	m_xmf3Right = XMFLOAT3(m_xmf4x4World._11, m_xmf4x4World._12, m_xmf4x4World._13);

	m_pCamera->Update(m_xmf3Position, fTimeElapsed);

	for (int i = 0; i < 4; ++i)
	{
		m_pWheel[i]->Update(fTimeElapsed, pbtDynamicsWorld);
	}

	//카메라의 카메라 변환 행렬을 다시 생성한다.
	m_pCamera->RegenerateViewMatrix();
}

 

asked (4 point) , 73 views

질문에 대한 답변을 하려면 로그인 또는 가입해야합니다.

버그 해결을 위해 도움을 구하고, 도움을 주세요. 우리는 그렇게 발전합니다.

throw bug 는 프로그래밍에 대한 전분야를 다룹니다. 질문,논의거리,팁,정보공유 모든 것이 가능합니다. 프로그래밍과 관련이 없는 내용은 환영받지 못합니다.

507 질문
655 answers
643 댓글
118,131 users