Skip to main content
gamedev.net
🔒 Locked

[Solved] D3DXIntersect... odd behavior

Started by Kalten 3 replies 1k views
Original Post
Kalten
Kalten
I have set up 2 objects using the same meshinstance through a different owning object. As a result of code section 1, a name appears on the mouse when the object is hovered over... I hover my mouse over object 1, nothing. Over object 2, it shows up as object 1. Object 1 appears where it is intended, so does object 2. I move object 1 by any vector, it moves as expected. Transforms are functioning on the individual objects and applying as to be expected. What is odd is that when a tracepoint is put in for the intersect, both object 1 and 2 are returned. Now i can expect this to a degree because its the same meshinstance... but... on vista this behavior is being exhibited, on XP it is not... on XP the selection and hover functions both behave as expected and no issue occurs when clicking, the tracepoint also only returns one value... the code is identical. Code below:

		mouseOverObject = -1;
		float bestDist = 100000.0f;
		RAY ray = mouse.GetRay();
		for (int i=0; i<(int)g_object.size(); i++)
		{
			float dist = -1.0f;
			if(g_object.GetSelectable() == true)
			{
				d3ddev->SetTransform(D3DTS_WORLD, &g_object.GetWM());
				dist = g_object.IntersectMesh(ray.org, ray.dir);
		 
				if(dist >= 0.0f && dist < bestDist)
				{
					mouseOverObject = i;
					bestDist = dist;
				}
			}
		}



Leads to....

float MESHINSTANCE::IntersectMesh(D3DXVECTOR3 rayOrg, D3DXVECTOR3 rayDir)
{

	if(m_pMesh == NULL || m_pMesh->mesh == NULL) return -1.0f;

	BOOL hit;
	float dist;

	D3DXIntersect(m_pMesh->mesh, &rayOrg, &rayDir, &hit, NULL, NULL, NULL, &dist, NULL, NULL);

	if(hit) return dist;
	else return -1.0f;
}



I cant see any reason for it... i'm scratching my head and would appreciate any help! [Edited by - Kalten on April 14, 2009 4:50:12 PM]
Evil Steve
Evil Steve
Is your backbuffer the same size as your client area? I.e. are you using AdjustWindowRectEx when you create your window? If not, your coordinates will be wrong. That would explain why you get different behaviour on different OS's, the window border is a different size.
Kalten
Kalten
I dont think its a co-ords issue...

I've just tried a bit of an isolation test and found that if object 1 or 2 exist without the other then there is no issue... if they concurrently exist then it seems that the second of the created objects is taking ownership of the reference to the meshinstance when its referred to in the object setup...

Could it be more that i have the same pointer being referenced by two parent classes, and if this is the case then how is the movement of the object not leaking into the transform for the second instance of the same pointer but the intersect is?
CukyDoh
CukyDoh
I'm just wondering if you've forgotten to transform your rays into the local mesh space, or does your SetTransform(D3DTS_WORLD, GetWM()) line take care of that already? Or have you already done something like that elsewhere? Transforming the origin point and ray vector by the inverse world matrix for each object should do the trick if not.

As far as my understanding of the function is; The mesh you test against will be in it's default local space, defined directly in it's vertex buffers etc., and will be tested directly against whichever ray data you pass in, and the function will not take into account anything else. And so because of this you'd have to transform your ray to be relative to that local mesh space, rather than in the global world space I'm assuming your ray is in, or else you won't be testing for a collision at the correct location.

I can't imagine you would get any correct results at all if not, but I figured it was worth mentioning anyway as I looked around and couldn't find anything in D3DXIntersect's documentation about auto-transforming the ray by setting a world matrix for it, nor could i find other examples using that method. Nice to know if that is the case though!
Kalten
Kalten
CukyDoh, you appear to be closest to the money :)

the Ray creation process was sitting outside of the loop to create the world matrix for each of the objects, likely referencing the last world matrix to be calculated.

Moving it into the loop makes the mouseover work to a degree (object 2 is labled when object 1 is hovered over) but its getting there...

<edit>

And fixed...

thanks for the help guys...

Looks like it was an order issue for the statements, the ray needs to be created AFTER the worldmatrix transform or work it will not.

heres how it looks.

		for (int i=0; i<(int)g_object.size(); i++)		{						float dist = -1.0f;			if(g_object.GetSelectable() == true)			{				d3ddev->SetTransform(D3DTS_WORLD, &g_object.GetWM());				RAY ray = mouse.GetRay();				dist = g_object.IntersectMesh(ray.org, ray.dir);		 				if(dist >= 0.0f && dist < bestDist)				{					mouseOverObject = i;					bestDist = dist;				}			}		}

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.