Getting a 2D Polygon from 3D face
-
- Posts: 81
- Joined: Thu Oct 16, 2008 6:50 am
Getting a 2D Polygon from 3D face
Hello
I am completely stuck. I need to obtain a 2D polygon from a face displayed in a 3D mesh.
Here is a picture of what I need. The red 'polygon' is what I need in 2D e.g. looking from the camera from position, I need the coordinates of the red 3D face, but as 2D points.
I hope this makes sense - I am completely stuck. I have tried using viewing, projection and world matrices with no luck to transform the 3D points.
Thanks
Asp
I am completely stuck. I need to obtain a 2D polygon from a face displayed in a 3D mesh.
Here is a picture of what I need. The red 'polygon' is what I need in 2D e.g. looking from the camera from position, I need the coordinates of the red 3D face, but as 2D points.
I hope this makes sense - I am completely stuck. I have tried using viewing, projection and world matrices with no luck to transform the 3D points.
Thanks
Asp
-
- Competition winner
- Posts: 1123
- Joined: Sun Jun 10, 2007 11:14 pm
http://irrlicht.sourceforge.net/docu/cl ... 70c0b2393d
This is a function to convert from a 3d point to a 2d. An example would be:
This is a function to convert from a 3d point to a 2d. An example would be:
Code: Select all
smgr->getSceneCollisionManager->getScreenCoordinatesFrom3DPosition(pos)
-
- Posts: 81
- Joined: Thu Oct 16, 2008 6:50 am
-
- Posts: 81
- Joined: Thu Oct 16, 2008 6:50 am
-
- Posts: 81
- Joined: Thu Oct 16, 2008 6:50 am
Vitek
Here is a picture of what I am now getting. The blue mesh on the right is the 3d model, with a face highlighted in red. On the lefthand side is a 2D view with the same face highlighted. You can see that it is 'squashed'. What I need is the view on the right, but converted to 2d. I have slightly modified my own version of getScreenCoordinatesFrom3DPosition, as I am trying to maintain the aspect ratios etc.
Here is what I have at the moment :
(I2DPnt is equavalent to vector2df)
The input to this routine is a position vector, directly retrieved from a SMeshBuffer.
Thanks
Asp
Here is a picture of what I am now getting. The blue mesh on the right is the 3d model, with a face highlighted in red. On the lefthand side is a 2D view with the same face highlighted. You can see that it is 'squashed'. What I need is the view on the right, but converted to 2d. I have slightly modified my own version of getScreenCoordinatesFrom3DPosition, as I am trying to maintain the aspect ratios etc.
Here is what I have at the moment :
(I2DPnt is equavalent to vector2df)
Code: Select all
I2DPnt IHLR::GetCoords(core::vector3df pos3d, ICameraSceneNode* camera)
{
ISceneManager *smgr = pCD->DwgSmgr;
if (!smgr || !Device->driver)
return I2DPnt(-1000,-1000);//core::position2d<s32>(-1000,-1000);
if (!camera)
camera = smgr->getActiveCamera();
if (!camera)
return I2DPnt(-1000,-1000);
//return core::position2d<s32>(-1000,-1000);
const core::rect<s32>& viewPort = Device->driver->getViewPort();
core::dimension2d<s32> dim(viewPort.getWidth(), viewPort.getHeight());
dim.Width /= 2;
dim.Height /= 2;
core::matrix4 trans = camera->getProjectionMatrix();
trans *= camera->getViewMatrix();
f32 transformedPos[4] = { pos3d.X, pos3d.Y, pos3d.Z, 1.0f };
trans.multiplyWith1x4Matrix(transformedPos);
if (transformedPos[3] < 0)
//return core::position2d<s32>(-10000,-10000);
return I2DPnt(-10000,-10000);
I2DPnt p(transformedPos[0],transformedPos[1]);
//return p;
const f32 zDiv = transformedPos[3] == 0.0f ? 1.0f :
core::reciprocal(transformedPos[3]);
I2DPnt Screen(viewPort.getWidth(),viewPort.getHeight());
p.set(Screen.x * (transformedPos[0] * zDiv),Screen.y * (transformedPos[1] * zDiv));
//return core::position2d<s32>(
// core::round32(dim.Width * transformedPos[0] * zDiv) + dim.Width,
// dim.Height - core::round32(dim.Height * (transformedPos[1] * zDiv)));
return p;
}
Thanks
Asp
Try using this (untested):
Code: Select all
I2DPnt IHLR::GetCoords(core::vector3df pos3d, ICameraSceneNode* camera)
{
ISceneManager *smgr = pCD->DwgSmgr;
if (!smgr || !Device->driver)
return I2DPnt(-1000,-1000);//core::position2d<s32>(-1000,-1000);
if (!camera)
camera = smgr->getActiveCamera();
if (!camera)
return I2DPnt(-1000,-1000);
//return core::position2d<s32>(-1000,-1000);
const core::rect<s32>& viewPort = Device->driver->getViewPort();
core::dimension2d<s32> dim(viewPort.getWidth(), viewPort.getHeight());
dim.Width /= 2;
dim.Height /= 2;
core::matrix4 trans = camera->getProjectionMatrix();
trans *= camera->getViewMatrix();
trans *= driver->getTransofrm(ETS_WORLD); // <- added
f32 transformedPos[4] = { pos3d.X, pos3d.Y, pos3d.Z, 1.0f };
trans.multiplyWith1x4Matrix(transformedPos);
if (transformedPos[3] < 0)
//return core::position2d<s32>(-10000,-10000);
return I2DPnt(-10000,-10000);
I2DPnt p(transformedPos[0],transformedPos[1]);
//return p;
const f32 zDiv = transformedPos[3] == 0.0f ? 1.0f :
core::reciprocal(transformedPos[3]);
I2DPnt Screen(viewPort.getWidth(),viewPort.getHeight());
p.set(Screen.x * (transformedPos[0] * zDiv),Screen.y * (transformedPos[1] * zDiv));
//return core::position2d<s32>(
// core::round32(dim.Width * transformedPos[0] * zDiv) + dim.Width,
// dim.Height - core::round32(dim.Height * (transformedPos[1] * zDiv)));
return p;
}
-
- Posts: 81
- Joined: Thu Oct 16, 2008 6:50 am
-
- Posts: 81
- Joined: Thu Oct 16, 2008 6:50 am
I am still having some issues with this. My current solution (which produces the correct results), calculates the intersections of an arbitrary view plane with the 3D geometry. I am sure that some kind of matrix operation will do the same, but I have been unable to calculate this. My algorithm for projecting a 3D point to a 2D point within an arbitrary plane is as follows :
pnt is the coordinate in 3D
From is the viewpoint (eye position)
Plane is the arbitrary view plane
intp is the returned 3D point of intersection
Plane.paramOf returns a 2D coordinate within the plane.
I am sure there must be a better (and faster) way of doing this.
Thanks
Anton
Code: Select all
I2DPnt DCELFace::ProjectedPnt(const I3DPnt &pnt,const I3DPnt &From,const I3DPlane &Plane,I3DPnt &intp) const
{
I3DLine line(pnt,From - pnt);
bool Intersect = line.IntersectWith(Plane,intp,false);
if (!Intersect)
Trace(false,"ProjectedPnt problem");
return Plane.paramOf(intp);
}
From is the viewpoint (eye position)
Plane is the arbitrary view plane
intp is the returned 3D point of intersection
Plane.paramOf returns a 2D coordinate within the plane.
I am sure there must be a better (and faster) way of doing this.
Thanks
Anton
I really don't understand what you're trying to do. Perhaps if you described what you are trying to do we can help you. I understand that you have 3d geometry, and you want to extract several polygons and transform them into 2d coordinates. What I don't understand is why you want this, and what you intend on doing with them. Why do you not want to continue working in 3d?
If you know the position of each of the verticies of the face(s) you need to select (in world space), you can transform those coordinates into 2d screen coordinates using the function mentioned previously.
Travis
If you know the position of each of the verticies of the face(s) you need to select (in world space), you can transform those coordinates into 2d screen coordinates using the function mentioned previously.
Travis
-
- Posts: 81
- Joined: Thu Oct 16, 2008 6:50 am
Travis
I am doing a Hidden Line Removal routine as per the Weiler-Atherton algorithm. This requires 3D polygons to be converted to 2D to enable a polygon clipping routine to then determine visible surfaces. Once the visible lines have been identified, I need to convert it back to 3D (this is an optional step, as HLR 2D output is often the only output required). The 2d polygons are then sorted along the viewing direction and clipping performed on them. I have the routine working really well, but I do believe that there must be a more efficient routine for converting from 3D to 2d, without using the intersection of the plane. The 1st picture in the original post does show my requirement. This is all being used in a CAD system.
For reference. here is a screenie of a 2D drawing, which was generated from 3D and the all Hidden Lines/Surfaces removed. A user will then typically adorn the 2D drawing derived from 3D with more traditional drawing tools.
Asp
Thanks for your interest and response.
I am doing a Hidden Line Removal routine as per the Weiler-Atherton algorithm. This requires 3D polygons to be converted to 2D to enable a polygon clipping routine to then determine visible surfaces. Once the visible lines have been identified, I need to convert it back to 3D (this is an optional step, as HLR 2D output is often the only output required). The 2d polygons are then sorted along the viewing direction and clipping performed on them. I have the routine working really well, but I do believe that there must be a more efficient routine for converting from 3D to 2d, without using the intersection of the plane. The 1st picture in the original post does show my requirement. This is all being used in a CAD system.
For reference. here is a screenie of a 2D drawing, which was generated from 3D and the all Hidden Lines/Surfaces removed. A user will then typically adorn the 2D drawing derived from 3D with more traditional drawing tools.
Asp
Thanks for your interest and response.