Hey all,

I'm trying to do some ray intersection detection but I'm having some problems.

My app starts by loading a cube object into a .x file.

I have a player class and a target class that both use the same model, but each has it's own world matrix.

D3DXMATRIX shotOrigin = m_vecShots[i]->World;
D3DXVECTOR3 rayOrigin(shotOrigin._41, 0, shotOrigin._43);
CMatrixModifier::TranslateZ(shotOrigin, 1.0f, false);
D3DXVECTOR3 rayDirection(shotOrigin._41, 0, shotOrigin._43);

D3DXMATRIX Inv;
D3DXMatrixIdentity(&Inv);
			
D3DXMatrixInverse(&Inv, NULL, CApplication::GetInstance()->m_pTest->GetMatrix()); // Inverse of the world matrix of the target (object I want to detect collision with)
D3DXVec3TransformCoord(&rayOrigin, &rayOrigin, &Inv);
D3DXVec3TransformNormal(&rayDirection, &rayDirection, &Inv);
			
D3DXIntersect(m_pXManager->GetModel(0)->GetMesh(), &rayOrigin, &rayDirection, &bHit, NULL, NULL, NULL, NULL, NULL, NULL);

It's odd because it'll detect the collision when the two cubes are sitting on top of each other but as soon as the center of the PLAYER cube leaves the TARGET cube mesh, it no longer detects the collisions.

I think I'm doing something wrong when I convert the ray into model space, but I'm not sure.

Any ideas?

Recommended Answers

All 4 Replies

Ok, I have an update.

I have moved the TARGET cube around the screen (it floats around) and the D3DXIntersect functuion is working properly until I move the Player cube away from 0, 0, 0.

Is it something to do with the origin/direction of the ray that I'm making?

What is the desired direction of the ray? If it is +Z, just specify (0,0,1) for rayDirection.

Currently you're generating something rather strange - a direction parallel to the line, defined by the points (0,0,0) and (shotOrigin._41, 0, shotOrigin._43) from line 4 of your code.

Otherwise, the conversion from world to model space is correct. And btw, the call to D3DXMatrixIdentity() is redundant.

Cool, thanks for the reply.

I'm at work at the moment, but I'll give that a try and update when I get home later.

What is the desired direction of the ray? If it is +Z, just specify (0,0,1) for rayDirection.

Currently you're generating something rather strange - a direction parallel to the line, defined by the points (0,0,0) and (shotOrigin._41, 0, shotOrigin._43) from line 4 of your code.

Otherwise, the conversion from world to model space is correct. And btw, the call to D3DXMatrixIdentity() is redundant.

Huzzah! I got it!

It wasn't entirely your suggestion that did it, but you pointed me in the correct direction! For that, I thank you sir.

Here is the whole function that activates a shot, orients it towards the mouse and detects if it's collided with a cube

for(unsigned int i = 0; i < m_vecShots.size(); ++i)
{
	if(!m_vecShots[i]->Active)
	{
		m_vecShots[i]->Active = true;
			
		ChangeShotType(_krePlayerMode, m_vecShots[i]);

		// Fucntion
		D3DXVECTOR3 vecCurPos;
			
		// Get Cursor Pos (maybe change this to get enemy pos in cycle of objects?)
		vecCurPos = (*m_pCursorManager->GetCursorLoc());

		float x = vecCurPos.x - _krmatWorld._41;
		float z = vecCurPos.z - _krmatWorld._43;

		float r = 10;//sqrt((x * x) + (z * z));

		// Stretch the shot to be appropriate length
		//D3DXMatrixScaling(&m_vecShots[i]->World, 0.1f, 1.0f, r); // INI (Make the bullet a 1 * 1 square and scale the X to a percent of 1.0!! User defined area of effect.)
		D3DXMatrixScaling(&m_vecShots[i]->World, 0.3f, 0, 0.3f); // Setting the size of the tracer.

		// Get Cursor Angle
		float g = (*m_pCursorManager->GetCursorAngle(vecCurPos, _krmatWorld));

		// g += (rand() % 30) - 15; // INI. Making shot inaccurate.

		CMatrixModifier::RotateY(m_vecShots[i]->World, g);

		CMatrixModifier::SetXAbsolute(m_vecShots[i]->World, _krmatWorld._41);
		CMatrixModifier::SetZAbsolute(m_vecShots[i]->World, _krmatWorld._43);

			
			
			
		D3DXMATRIX shotWorld = m_vecShots[i]->World;
		D3DXVECTOR3 tempa(shotWorld._41, shotWorld._42, shotWorld._43);
		CMatrixModifier::TranslateZ(shotWorld, 1.0f, false);			
		D3DXVECTOR3 tempb(shotWorld._41 - _krmatWorld._41, 0, shotWorld._43 - _krmatWorld._43);

		D3DXMATRIX Inv;
			
		D3DXMatrixInverse(&Inv, NULL, CApplication::GetInstance()->m_pTest->GetMatrix());
		D3DXVec3TransformCoord(&tempa, &tempa, &Inv);
		D3DXVec3TransformNormal(&tempb, &tempb, &Inv);
			
		D3DXIntersect(m_pXManager->GetModel(0)->GetMesh(), &tempa, &tempb, &bHit, NULL, NULL, NULL, NULL, NULL, NULL);

		break;
	}
}

There's some tidying up to do, I know, but I'm just happy it works.

What I was forgetting to do was D3DXVECTOR3 tempb(shotOrigin._41 [b]- _krmatWorld._41[/b], 0, shotOrigin._43 [b]- _krmatWorld._43[/b]); .

Edit: Great, now that I'm looking at it, I'm not evern sure why that was the fix.

It seems like it SHOULD have been working without the fix and the fix SHOULD have broken it. I'll keep mulling over it. I have having code I don't understand.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.