Logic and eb and flow

The Partridge Family were neither partridges nor a family. Discuss.
Post Reply
MrGodin
Posts: 721
Joined: November 30th, 2013, 7:40 pm
Location: Merville, British Columbia Canada

Logic and eb and flow

Post by MrGodin » January 16th, 2016, 7:42 pm

So here is what i am working on and trying to speed up.
First thing is i have a terrain partitioned into cells and each cell holds x amount of vertices to make up triangles. I then go through the cells and see which ones are in the view frustum. The ones in view i then place into a std::list to use to render with and do the following. I then sort the list to closest to camera
I convert the mouse screen space to world space resulting with a positional and a directional vector.
I then make a line (pos + dir * scaler). I then check to see if this line intersects with any of the sorted cells axis aligned bounding box.
If i get an intersect, i then go through that cells planes (faces) and see if the line intersects any of them, if so, i return a struct holding the plane and its intersect point on that plane.
(for rotating to plane, and or placing on terrain).
This is all well and good until i came to the instance where the terrain sloped upward and i clicked on it, it would place the object on the other side of the slope. I realized this was because when i was going through the faces, the ones first in the loop where farthest away from the camera, so it would intersect on the other side first, then break the loop.
I corrected this by going through all the faces and with each face intersect i would do a distance compare , hold the current closest one so the end result would have the closest plane intersected. problem solved.
My issue is, this seems to have high overhead because when i move the camera and click the terrain (and because everything is updated with frame rate ie: pos += vel * speed * framerate for example), i get a small delay in movement when selecting a terrain pos. Its worse the farther away i clicked. So before i go changing anything i am just fishing for suggestions on how to speed this process up.
I am thinking that because i have the list of cells in view, that i really don't have a need to sort them ?, since the farther away i click i'd have to go through most all of them anyways. Having said that, is it wise then to even do a line intersect aabb on the cell as well, again since i have cells in view i can just go through them all and do a line through plane intersect test ? ..
If any of this makes sense and something comes to mind about how it could be better, I'd appreciate that.
I'll put up my plane intersect and aabb intersect code to see if that can be streamlined.
Thanks for any input
DXVec3 is a class i inherited from XMFLOAT3 and added dot,cross,length ect to it
(so i can use them in XMStoreFloat3 ect)
anything with DX are my structs or classes

Code: Select all

void DXMath::MapMouseToWorld(HWND hwnd,DXVec3& inOrigin, DXVec3& inDir, 
		XMMATRIX matProj, XMMATRIX matView, DXVector2 screen)
	{

		DXVec3 vPickRayDir;
		DXVec3 vPickRayOrig;
		XMFLOAT4X4 m_matProj;
		XMStoreFloat4x4(&m_matProj, matProj);
		POINT cursor;
		GetCursorPos(&cursor);
		ScreenToClient(hwnd, &cursor);
		// Compute the vector of the pick ray in screen space
		DXVec3 v;
		v.x = (((2.0f * cursor.x) / screen.x) - 1) / m_matProj._11;
		v.y = -(((2.0f * cursor.y) / screen.y) - 1) / m_matProj._22;
		v.z = 1.0f;
		
		XMFLOAT4X4 m;
		XMStoreFloat4x4(&m, XMMatrixInverse(0, matView));
		vPickRayDir.x = v.x*m._11 + v.y*m._21 + v.z*m._31;
		vPickRayDir.y = v.x*m._12 + v.y*m._22 + v.z*m._32;
		vPickRayDir.z = v.x*m._13 + v.y*m._23 + v.z*m._33;
		vPickRayDir.normalize();

		vPickRayOrig.x = m._41;
		vPickRayOrig.y = m._42;
		vPickRayOrig.z = m._43;
		vPickRayOrig += vPickRayDir*0.01f;
		// set the return values
		inOrigin = vPickRayOrig;
		inDir = vPickRayDir;

	}

	bool DXMath::LineIntersectAABB(DXLineSegment& line, DX_AABB& box)
	{
			DXVec3 d = (line.pt0 - line.pt1) * 0.5f;
			DXVec3 e = (box.MaxPt() - box.MinPt()) * 0.5f;
			DXVec3 c = line.pt1 + d - (box.MinPt() + box.MaxPt()) * 0.5f;
			DXVec3 ad = DXVec3(abs(d.x), abs(d.y), abs(d.z));

			if (fabsf(c[0]) > e[0] + ad[0])
				return false;

			if (fabsf(c[1]) > e[1] + ad[1])
				return false;

			if (fabsf(c[2]) > e[2] + ad[2])
				return false;


			if (fabsf(d[1] * c[2] - d[2] * c[1]) > e[1] * ad[2] + e[2] * ad[1] + FLT_EPSILON)
				return false;

			if (fabsf(d[2] * c[0] - d[0] * c[2]) > e[2] * ad[0] + e[0] * ad[2] + FLT_EPSILON)
				return false;

			if (fabsf(d[0] * c[1] - d[1] * c[0]) > e[0] * ad[1] + e[1] * ad[0] + FLT_EPSILON)
				return false;



			return true;

		

	}
	bool DXMath::LineIntersectPlane(DXLineSegment& line, DXTriIntersection& inter)
	{
		    inter.hit = false;
			DXVec3 IntersectPos;
			DXVec3 linePt1 = line.pt0;
			DXVec3 linePt2 = line.pt1

			// Find distance from linePt1 and linePt2 to the plane defined by the triangle
			DXVec3 D1 = linePt1 - inter.triangle.pt0;
			DXVec3 D2 = linePt2 - inter.triangle.pt0;

			float Dist1 = D1.dot(inter.triangle.Normal());
			float Dist2 = D2.dot(inter.triangle.Normal());
			if ((Dist1 * Dist2) >= 0.0f) return false;  // line doesn't cross the triangle.
			if (Dist1 == Dist2) return false;// line and plane are parallel

											 // Find point on the line that intersects with the plane
			IntersectPos = linePt1 + (linePt2 - linePt1) * (-Dist1 / (Dist2 - Dist1));

			// Find if the interesection point lies inside the triangle by testing it against all edges
			DXVec3 planeNormal = inter.triangle.Normal();
			DXVec3 vTest = planeNormal.cross(inter.triangle.pt1 - inter.triangle.pt0);

			if (vTest.dot(IntersectPos - inter.triangle.pt0) < 0.0f) return false;
			vTest = planeNormal.cross(inter.triangle.pt2 - inter.triangle.pt1);

			if (vTest.dot(IntersectPos - inter.triangle.pt1) < 0.0f) return false;
			vTest = planeNormal.cross(inter.triangle.pt0 - inter.triangle.pt2);

			if (vTest.dot(IntersectPos - inter.triangle.pt0) < 0.0f) return false;

			inter.hit = true;
			inter.intersectPt = IntersectPos;
			return true;
		
	}
Curiosity killed the cat, satisfaction brought him back

MrGodin
Posts: 721
Joined: November 30th, 2013, 7:40 pm
Location: Merville, British Columbia Canada

Re: Logic and eb and flow

Post by MrGodin » January 16th, 2016, 9:14 pm

Hmm, i wonder if checking the normal of the intersected plane, if the dot is wrong then its facing away from origin, hence a culled triangle anyways ? ..
Curiosity killed the cat, satisfaction brought him back

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Logic and eb and flow

Post by albinopapa » January 16th, 2016, 10:07 pm

Wish I could help out, but my math knowledge is pretty limited.

DXVec3 d = (line.pt0 - line.pt1) * 0.5f;
What happens if you reverse the line pts, line.pt1 - line.pt0 instead? Currently, you are making the vector point toward pt0.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

MrGodin
Posts: 721
Joined: November 30th, 2013, 7:40 pm
Location: Merville, British Columbia Canada

Re: Logic and eb and flow

Post by MrGodin » January 20th, 2016, 6:50 pm

Well, to be honest i found that code on the internet as an example, so i modified it to work for me. From what i gather, it doing an inverse ray trace, i believe .. doh !! o.O. I have started over and now am using most XMVECTOR wherever possible, simple to use the DirectXMath functions for cross products and the like
Curiosity killed the cat, satisfaction brought him back

Post Reply