Page 1 of 1

Logic and eb and flow

Posted: January 16th, 2016, 7:42 pm
by MrGodin
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;
		
	}

Re: Logic and eb and flow

Posted: January 16th, 2016, 9:14 pm
by MrGodin
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 ? ..

Re: Logic and eb and flow

Posted: January 16th, 2016, 10:07 pm
by albinopapa
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.

Re: Logic and eb and flow

Posted: January 20th, 2016, 6:50 pm
by MrGodin
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