Code:
BOOL scrPos(float x, float y, float z, POINT *pt){
// return scrpos relative to leftup corner, x positive to right, y positive to downward
// to be compatible with MouseClick
/* some transformation, by wanyancan.
transed := ({
{1, 0, 0, -camx},
{0, 1, 0, -camy},
{0, 0, 1, -camz},
{0, 0, 0, 1}
})
zroted := ({
{cosY, -sinY, 0, 0},
{sinY, cosY, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}
}).transed
xroted := ({
{1, 0, 0, 0},
{0, cos[alpha], sin[alpha], 0},
{0, -sin[alpha], cos[alpha], 0},
{0, 0, 0, 1}
}).zroted
pos := xroted.({
{myx},
{myy},
{myz},
{1}
}) = {{-camx cosY + cosY myx + camy sinY -
myy sinY}, {cosY myy cos[alpha] +
myx sinY cos[alpha] + (-camy cosY - camx sinY) cos[alpha] -
camz sin[alpha] + myz sin[alpha]}, {-camz cos[alpha] +
myz cos[alpha] - cosY myy sin[alpha] -
myx sinY sin[alpha] - (-camy cosY - camx sinY) sin[alpha]}, {1}}
*/
float camX = ReadFloat(LPCVOID(G_CAMPOS+4)); // camera position
float camY = ReadFloat(LPCVOID(G_CAMPOS));
float camZ = ReadFloat(LPCVOID(G_CAMPOS+8));
float camRotX = ReadFloat(LPCVOID(G_CAMROT)); // camera horizontal direction (0 , 2*pi) north is 0, positive counter-clockwise
float camRotY = ReadFloat(LPCVOID(G_CAMROT+4)); // camera vertical direction (-pi/2, pi/2) look upward is positive
float alpha = asinf(camRotX);
float cosY = cosf(camRotY);
float sinY = sinf(camRotY);
float pos0 = -camX*cosY+cosY*x+camY*sinY-y*sinY;
float pos1 = cosY*y*cosf(alpha)+x*sinY*cosf(alpha)+(-camY*cosY-camX*sinY)*cosf(alpha)-camZ*sinf(alpha) + z*sinf(alpha);
float pos2 = -camZ*cosf(alpha)+z*cosf(alpha)-cosY*y*sinf(alpha)-x*sinY*sin(alpha)-(-camY*cosY-camX*sinY)*sin(alpha);
if (pos1<0.1)
return FALSE;
float fov = 3.1415926/2*0.7; // field of view , view angle is about 0.7
RECT rect;
GetClientRect(wowhwnd, &rect);
float modifier = 1.0f;
if(1.0*rect.right/rect.bottom>1.5)
modifier *=1.15; // widescreen modifier
float scrX = -pos0/pos1/tanf(fov/2*1.08*modifier) * rect.right/2;
float scrY = -pos2/pos1/tanf(fov/2*0.85) * rect.bottom/2;
//printf("cam (%.1f,%.1f,%.1f), camRot (%.1f,%.1f), obj(%.1f,%.1f,%.1f) scr (%.1f, %.1f)\n", camX, camY, camZ, camRotX, camRotY, x,y,z, scrX, scrY);
if (abs(scrX)*3>rect.right || abs(scrY)*3>rect.bottom)
return FALSE; // out of center 1/3 rectangle.
pt->x = scrX+rect.right/2; pt->y = scrY+rect.bottom/2;
return TRUE;
}