Поделюсь кодом: включить все объекты в камеру.
От: falcoware Россия https://falcoware.com/rus/
Дата: 21.10.20 10:48
Оценка:

void CScene::SmartZoom(float x, float y)
{
// fill Vershiny of piramid...
point3d vtDir;
sub_vectors(&vtDir.x, &IniSet.ptCamPos.x, &IniSet.ptCamTarget.x);

IniSet.ptCamTarget.x = x;
IniSet.ptCamTarget.y = y;
IniSet.ptCamTarget.z = 0.f;

scale_vect(&vtDir.x, 1000.f);
add_vectors(&IniSet.ptCamPos.x, &vtDir.x, &IniSet.ptCamTarget.x);

float fOldDCam = 0.f;
float fSavedDCam = vec_length(&vtDir.x);

for(int ax = 0; ax < 30; ax++){
float fNewDist = (fSavedDCam + fOldDCam) / 2.f;
norm_vect(&vtDir.x);
scale_vect(&vtDir.x, fNewDist);
add_vectors(&IniSet.ptCamPos.x, &vtDir.x, &IniSet.ptCamTarget.x);

point3d versh[4];
point3d eye = { IniSet.ptCamPos.x, IniSet.ptCamPos.y, IniSet.ptCamPos.z };
Screen2World(0, 0, versh[0]);
Screen2World(nScreenSzX, 0, versh[1]);
Screen2World(nScreenSzX, nScreenSzY, versh[2]);
Screen2World(0, nScreenSzY, versh[3]);

int ix, sz = parrObjs.Size();

// Create faces of piramid and search collision with it...
point3d Piramid[4][3];
Piramid[0][0] = eye;
Piramid[1][0] = eye;
Piramid[2][0] = eye;
Piramid[3][0] = eye;
Piramid[0][1] = versh[0];
Piramid[0][2] = versh[1];
Piramid[1][1] = versh[1];
Piramid[1][2] = versh[2];
Piramid[2][1] = versh[2];
Piramid[2][2] = versh[3];
Piramid[3][1] = versh[3];
Piramid[3][2] = versh[0];

// Dyadya WALERA!!!!
BOOL OutFlag = FALSE;
for(ix = nObjOff; ix < sz; ix++){
CObj3d *pObj = parrObjs.e(ix);
pObj->Transform(FALSE);
point3d ptPos = pObj->GetPosition();

plane gran;
for(int jx = 0; jx < 4; jx++){
comp_plane_eqn(&gran.a, &Piramid[jx][0].x, &Piramid[jx][1].x, &Piramid[jx][2].x);
float f1 = gran.a*ptPos.x + gran.b*ptPos.y + gran.c*ptPos.z + gran.d;
float f2 = gran.d;
if(f1*f2 < 0.f){
OutFlag = TRUE;
break;
}
}
if(OutFlag){ break; }
}

sub_vectors(&vtDir.x, &IniSet.ptCamPos.x, &IniSet.ptCamTarget.x);
float fDist = vec_length(&vtDir.x);
if(OutFlag){
fOldDCam = fDist;
}
else{
fSavedDCam = fDist;
}
}

// CString sss;
// sss.Format("%f", IniSet.ptCamPos.z);
// AfxMessageBox(sss);

MoveCameraSomeBack();
GluLookAt();

// sss.Format("%f", IniSet.ptCamPos.z);
// AfxMessageBox(sss);
}

void CScene::SmartZoomForSomeObjects(Array<CObj3d *> &pObjsAll)
{
// This procedure places camera in position of visibility of
// all chosen objects. Procedure does not change directions of camera.
matrix MatrCm;
MatrCm.m[0][0] = IniSet.vsCamSystem.axis_x.x;
MatrCm.m[0][1] = IniSet.vsCamSystem.axis_x.y;
MatrCm.m[0][2] = IniSet.vsCamSystem.axis_x.z;
MatrCm.m[0][3] = 0.f;
MatrCm.m[1][0] = IniSet.vsCamSystem.axis_y.x;
MatrCm.m[1][1] = IniSet.vsCamSystem.axis_y.y;
MatrCm.m[1][2] = IniSet.vsCamSystem.axis_y.z;
MatrCm.m[1][3] = 0.f;
MatrCm.m[2][0] = IniSet.vsCamSystem.axis_z.x;
MatrCm.m[2][1] = IniSet.vsCamSystem.axis_z.y;
MatrCm.m[2][2] = IniSet.vsCamSystem.axis_z.z;
MatrCm.m[2][3] = 0.f;
MatrCm.m[3][0] = 0.f;
MatrCm.m[3][1] = 0.f;
MatrCm.m[3][2] = 0.f;
MatrCm.m[3][3] = 1.f;

int ix, jx, sz = pObjsAll.Size();
Array<point3d> arrObjPos;
Array<CObj3d *> pObjs;

for(ix = nObjOff; ix < sz; ix++){
CObj3d *pObj = pObjsAll.e(ix);
if(!IniSet.bSpotCloakedObjects){
if(pObj->IsHidden()){ continue; }
}

pObjs.Append(pObj);

pObj->Transform(FALSE);
point3d ptPos;
transform_point(&ptPos, &pObj->GetPosition(), &MatrCm);
arrObjPos.Append(ptPos);
}// ix definiton of all ObjPos divide about camera

float fxy = 1000.f;
float fxz = 1000.f;
float LB_TAN_45_2_RAD_Y = m_fCameraAngle * pixel_sz;
float LB_TAN_45_2_RAD_Z = m_fCameraAngle;
float fdy, fdz;
int iy,jy,iz,jz;
BOOL noSelect = TRUE;

sz = pObjs.Size();
if(!sz){ return; }
if(sz == 1){
CObj3d *pObj = pObjs.e(0);
pObj->Transform(FALSE);
point3d ptPos = pObj->GetPosition();
SmartZoom(ptPos.x, ptPos.y);
return;
}

for(ix = 0; ix < sz; ix++){
CObj3d *pObj = pObjs.e(ix);
float SizeObi = pObj->fObjSize / 1.75f; // SizeObi = 0.f;
for (jx = ix; jx < sz; jx++) {
pObj = pObjs.e(jx);
float SizeObj = pObj->fObjSize / 1.75f; // SizeObj = 0.f;
if (arrObjPos[ix].y < arrObjPos[jx].y) {
float fbi = (arrObjPos[ix].y — SizeObi) + LB_TAN_45_2_RAD_Y * arrObjPos[ix].x;
float fbj = (arrObjPos[jx].y + SizeObj) — LB_TAN_45_2_RAD_Y * arrObjPos[jx].x;
float ffx = (fbi — fbj) * 0.5f / LB_TAN_45_2_RAD_Y;
if (ffx < fxy) {
iy = ix;
jy = jx;
fxy = ffx;
fdy = (fbi + fbj) * 0.5f;
}//if
}//then
else {
float fbi = (arrObjPos[ix].y + SizeObi) — LB_TAN_45_2_RAD_Y * arrObjPos[ix].x;
float fbj = (arrObjPos[jx].y — SizeObj) + LB_TAN_45_2_RAD_Y * arrObjPos[jx].x;
float ffx = (fbj — fbi) * 0.5f / LB_TAN_45_2_RAD_Y;
if (ffx < fxy) {
iy = jx;
jy = ix;
fxy = ffx;
fdy = (fbi + fbj) * 0.5f;
}//if
}//else
if (arrObjPos[ix].z < arrObjPos[jx].z) {
float fbi = (arrObjPos[ix].z — SizeObi) + LB_TAN_45_2_RAD_Z * arrObjPos[ix].x;
float fbj = (arrObjPos[jx].z + SizeObj) — LB_TAN_45_2_RAD_Z * arrObjPos[jx].x;
float ffx = (fbi — fbj) * 0.5f / LB_TAN_45_2_RAD_Z;
if (ffx < fxz) {
iz = ix;
jz = jx;
fxz = ffx;
fdz = (fbi + fbj) * 0.5f;
}//if
}//then
else {
float fbi = (arrObjPos[ix].z + SizeObi) — LB_TAN_45_2_RAD_Z * arrObjPos[ix].x;
float fbj = (arrObjPos[jx].z — SizeObj) + LB_TAN_45_2_RAD_Z * arrObjPos[jx].x;
float ffx = (fbj — fbi) * 0.5f / LB_TAN_45_2_RAD_Z;
if (ffx < fxz) {
iz = jx;
jz = ix;
fxz = ffx;
fdz = (fbi + fbj) * 0.5f;
}//if
}//else
}// jx
}// ix

// offset of camera
point3d pos;
if(fxz > fxy){
pos.x = fxy;
pos.y = fdy;
pos.z = ( (arrObjPos[iz].x — fxy)
* (arrObjPos[jz].z + pObjs.e(jz)->fObjSize / 1.75f)
+ (arrObjPos[jz].x — fxy)
* (arrObjPos[iz].z — pObjs.e(iz)->fObjSize / 1.75f))
/((arrObjPos[iz].x — fxy) + (arrObjPos[jz].x — fxy));
}
else {
pos.x = fxz;
pos.z = fdz;
pos.y = ( (arrObjPos[iy].x — fxz)
* (arrObjPos[jy].y + pObjs.e(jy)->fObjSize / 1.75f)
+ (arrObjPos[jy].x — fxz)
* (arrObjPos[iy].y — pObjs.e(iy)->fObjSize / 1.75f))
/((arrObjPos[iy].x — fxz) + (arrObjPos[jy].x — fxz));
}

transform_back_point(&pos, &pos, &MatrCm);

IniSet.ptCamPos.x = pos.x;
IniSet.ptCamPos.y = pos.y;
IniSet.ptCamPos.z = pos.z;

pos.z = 0.f;
IniSet.ptCamTarget = pos;

MoveCameraSomeBack();
GluLookAt();
}

https://falcoware.com/rus/ — Бесплатные Игры!!!
Отредактировано 21.10.2020 10:49 falcoware . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.