 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
hardhat

Joined: 02 Mar 2006 Posts: 17
|
Posted: Thu Aug 10, 2006 2:02 am Post subject: How to do gluProject in gum |
|
|
Hi,
I've been working on a program where I want to know where something will appear in screen coordinates to decide which camera angle is the best. So, after peeking at the Mesa source code, I've come up with the following:
| Code: |
/** Project a point from object coordinates to screen coordinates.
* \param object point in object coordinates.
* \param view view transformation matrix.
* \param projection projection transformation matrix (for example from gumPerspective).
* \param model model transformation matrix (for example from gumLookAt).
* \param viewport the left, top, width and height of the viewport.
* \param screen on success, the result of the point projected into screen coordinates.
* \returns 1 on success, or 0 if it is a degenerate projection.
*/
s32 gumProject(const ScePspFVector3 *object,const ScePspFMatrix4 *view,const ScePspFMatrix4 *projection,const ScePspFMatrix4 *model,const s32 viewport[4],ScePspFVector3 *screen) {
ScePspFMatrix4 m;
float w;
gumMultMatrix(&m,view,projection);
gumMultMatrix(&m,&m,model);
screen->x=object->x*m.x.x+object->y*m.y.x+object->z*m.z.x+m.w.x;
screen->y=object->x*m.x.y+object->y*m.y.y+object->z*m.z.y+m.w.y;
screen->z=object->x*m.x.z+object->y*m.y.z+object->z*m.z.z+m.w.z;
w=object->x*m.x.w+object->y*m.y.w+object->z*m.z.w+m.w.w;
if(w==0) return FALSE;
screen->x/=w;
screen->y/=w;
screen->z/=w;
// Now map x,y to the range 0-1
screen->x=screen->x*0.5f+0.5f;
screen->y=screen->y*0.5f+0.5f;
// Scale/translate to the viewport size
screen->x=screen->x*viewport[2]+viewport[0]; // *width + left
screen->y=(1.0f-screen->y)*viewport[3]+viewport[1]; // *height+top
return TRUE;
}
|
which can be initialized and called via:
ScePspFMatrix4 view,projection,mode;
ScePspFVector3 from={-20,-10,-20},to={0,0,0},up={0,0,1}; // For example
ScePspFVector3 obj={2,1,0},screen;
s32 viewport[4]={0,0,480,272};
gumLoadIdentity(&view);
gumLoadIdentity(&projection);
gumPerspective(&projection,45.0f,16.0f/9.0f,1.5f,2048.0f);
gumLoadIdentity(&model);
gumLookAt(&model,&from,&to,&up);
// Now project a point obj -> screen
gumProject(&obj,&view,&projection,&model,viewport,&screen);
which should correspond to a point drawn with:
sceGumMatrixMode(GU_VIEW);
sceGumLoadIdentity();
sceGumMatrixMode(GU_PROJECTION);
sceGumLoadIdentity();
sceGumPerspective(45.0f,16.0f/9,0f,1.5f,2048.0f);
sceGumMatrixMode(GU_MODEL);
sceGumLoadIdentity();
sceGumLookAt(&from,&to,&up);
From testing it, I find that all of my projected values seem to be in the range:
x in 238 to 242 for on screen values. I just don't get it. Any ideas?
Edit: updated sample to fix cut and paste errors. Now works perfectly. :-) Enjoy. _________________ HardHat
Try my homebrew: Open Gladiator, Fur Trader, Skater Maze, Jafe's Hike, Jumping Jack
Last edited by hardhat on Fri Feb 22, 2008 5:38 am; edited 1 time in total |
|
| Back to top |
|
 |
hardhat

Joined: 02 Mar 2006 Posts: 17
|
Posted: Fri Feb 22, 2008 5:37 am Post subject: |
|
|
Okay, so I found one last bug. For those of us who like the screen origin at the top left corner, the line:
| Code: | | screen->y=screen->y*viewport[3]+viewport[1]; // *height+top |
should be:
| Code: | | screen->y=(1.0f-screen->y)*viewport[3]+viewport[1]; // *height+top |
_________________ HardHat
Try my homebrew: Open Gladiator, Fur Trader, Skater Maze, Jafe's Hike, Jumping Jack |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|