Skip to content

Commit 6beeac7

Browse files
authored
Can set projection matrix or camera intrinsics in the ADF file (#243)
1 parent 2f08b89 commit 6beeac7

File tree

4 files changed

+188
-25
lines changed

4 files changed

+188
-25
lines changed

adf_loader/version_1_0/adf_loader_1_0.cpp

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,6 +1250,7 @@ bool ADFLoader_1_0::loadCameraAttribs(YAML::Node *a_node, afCameraAttributes *at
12501250
YAML::Node upNode = node["up"];
12511251
YAML::Node clippingPlaneNode = node["clipping plane"];
12521252
YAML::Node fieldViewAngleNode = node["field view angle"];
1253+
YAML::Node windowResolutionNode = node["window resolution"];
12531254
YAML::Node orthoWidthNode = node["orthographic view width"];
12541255
YAML::Node stereoNode = node["stereo"];
12551256
YAML::Node controllingDevicesDataNode = node["controlling devices"];
@@ -1266,6 +1267,8 @@ bool ADFLoader_1_0::loadCameraAttribs(YAML::Node *a_node, afCameraAttributes *at
12661267
YAML::Node depthShaderNode = node["depth compute shaders"];
12671268
YAML::Node multiPassNode = node["multipass"];
12681269
YAML::Node mouseControlMultiplierNode = node["mouse control multipliers"];
1270+
YAML::Node cameraIntrinsicsNode = node["camera intrinsics"];
1271+
YAML::Node projectionMatrixNode = node["projection matrix"];
12691272

12701273
bool valid = true;
12711274

@@ -1329,9 +1332,20 @@ bool ADFLoader_1_0::loadCameraAttribs(YAML::Node *a_node, afCameraAttributes *at
13291332
attribs->m_publishImageInterval = publishImageIntervalNode.as<uint>();
13301333
}
13311334

1335+
if (windowResolutionNode.IsDefined()){
1336+
attribs->m_windowResolution.m_width = windowResolutionNode["width"].as<double>();
1337+
attribs->m_windowResolution.m_height = windowResolutionNode["height"].as<double>();
1338+
attribs->m_windowResolution.m_defined = true;
1339+
}
1340+
13321341
if (publishImageResolutionNode.IsDefined()){
1333-
attribs->m_publishImageResolution.m_width = publishImageResolutionNode["width"].as<double>();
1334-
attribs->m_publishImageResolution.m_height = publishImageResolutionNode["height"].as<double>();
1342+
attribs->m_publishImageResolution.m_width = publishImageResolutionNode["width"].as<unsigned int>();
1343+
attribs->m_publishImageResolution.m_height = publishImageResolutionNode["height"].as<unsigned int>();
1344+
attribs->m_publishImageResolution.m_defined = true;
1345+
}
1346+
else if (attribs->m_windowResolution.m_defined){
1347+
cerr << "INFO! FOR CAMERA " << attribs->m_identificationAttribs.m_name << " PUBLISH IMAGE RESOLUTION NOT SPECIFIED THEREFORE USING DEFINED WINDOW RESOLUTION.";
1348+
attribs->m_publishImageResolution = attribs->m_windowResolution;
13351349
}
13361350

13371351
if (publishDepthNode.IsDefined()){
@@ -1345,6 +1359,7 @@ bool ADFLoader_1_0::loadCameraAttribs(YAML::Node *a_node, afCameraAttributes *at
13451359
if (publishDepthResolutionNode.IsDefined()){
13461360
attribs->m_publishDephtResolution.m_width = publishDepthResolutionNode["width"].as<double>();
13471361
attribs->m_publishDephtResolution.m_height = publishDepthResolutionNode["height"].as<double>();
1362+
attribs->m_publishDephtResolution.m_defined = true;
13481363
}
13491364

13501365
if (publishDepthNoiseNode.IsDefined()){
@@ -1392,6 +1407,49 @@ bool ADFLoader_1_0::loadCameraAttribs(YAML::Node *a_node, afCameraAttributes *at
13921407
}
13931408
}
13941409

1410+
if (cameraIntrinsicsNode.IsDefined()){
1411+
1412+
bool defined = false;
1413+
if (cameraIntrinsicsNode["fx"].IsDefined()){ // Focal Length X
1414+
attribs->m_intrinsics.m_fx = cameraIntrinsicsNode["fx"].as<double>();
1415+
defined |= true;
1416+
}
1417+
if (cameraIntrinsicsNode["fy"].IsDefined()){ // Focal Length Y
1418+
attribs->m_intrinsics.m_fy = cameraIntrinsicsNode["fy"].as<double>();
1419+
defined |= true;
1420+
}
1421+
if (cameraIntrinsicsNode["f"].IsDefined()){ // Focal Length
1422+
attribs->m_intrinsics.m_fx = cameraIntrinsicsNode["f"].as<double>();
1423+
attribs->m_intrinsics.m_fy = cameraIntrinsicsNode["f"].as<double>();
1424+
defined |= true;
1425+
}
1426+
if (cameraIntrinsicsNode["cx"].IsDefined()){ // Principal Offset X
1427+
attribs->m_intrinsics.m_cx = cameraIntrinsicsNode["cx"].as<double>();
1428+
defined |= true;
1429+
}
1430+
if (cameraIntrinsicsNode["cy"].IsDefined()){ // Principal Offset Y
1431+
attribs->m_intrinsics.m_cy = cameraIntrinsicsNode["cy"].as<double>();
1432+
defined |= true;
1433+
}
1434+
if (cameraIntrinsicsNode["s"].IsDefined()){ // Shear
1435+
attribs->m_intrinsics.m_s = cameraIntrinsicsNode["s"].as<double>();
1436+
defined |= true;
1437+
}
1438+
attribs->m_intrinsics.m_defined = defined;
1439+
}
1440+
1441+
if (projectionMatrixNode.IsDefined()){
1442+
try{
1443+
attribs->m_projectionMatrix = projectionMatrixNode.as<vector<vector<double>>>();
1444+
attribs->m_useCustomProjectionMatrix = true;
1445+
cerr << "INFO! CUSTOM PROJECTION MATRIX DEFINED FOR CAMERA " << attribs->m_identificationAttribs.m_name << endl;
1446+
}
1447+
catch(YAML::Exception& e){
1448+
cerr << "ERROR! FAILED TO READ CUSTOM PROJECTION MATRIX FOR CAMERA " << attribs->m_identificationAttribs.m_name << endl;
1449+
cerr << "EXCEPTION! " << e.what() << endl;
1450+
}
1451+
}
1452+
13951453
return valid;
13961454
}
13971455

ambf_framework/afAttributes.h

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,9 +514,11 @@ struct afImageResolutionAttribs{
514514
afImageResolutionAttribs(){
515515
m_width = 640;
516516
m_height = 480;
517+
m_defined = false;
517518
}
518-
double m_width;
519-
double m_height;
519+
unsigned int m_width;
520+
unsigned int m_height;
521+
bool m_defined;
520522
};
521523

522524

@@ -548,6 +550,23 @@ struct afMouseControlScales{
548550
double m_arcball;
549551
};
550552

553+
struct afCameraIntrinsics{
554+
afCameraIntrinsics(){
555+
m_defined = false;
556+
m_fx = 100.;
557+
m_fy = 100.;
558+
m_cx = 0.;
559+
m_cy = 0.;
560+
m_s = 0.;
561+
}
562+
bool m_defined;
563+
double m_fx; // Focal length X
564+
double m_fy; // Focal Length Y
565+
double m_cx; // Principal Offset X
566+
double m_cy; // Principal Offset Y
567+
double m_s; // Shear
568+
};
569+
551570
///
552571
/// \brief The afCameraAttributes struct
553572
///
@@ -570,6 +589,7 @@ struct afCameraAttributes: public afBaseObjectAttributes
570589
m_publishImageInterval = 1;
571590
m_publishDepthInterval = 10;
572591
m_multiPass = false;
592+
m_useCustomProjectionMatrix = false;
573593
}
574594

575595
afVector3d m_lookAt;
@@ -594,13 +614,18 @@ struct afCameraAttributes: public afBaseObjectAttributes
594614
afMouseControlScales m_mouseControlScales;
595615
bool m_multiPass;
596616

617+
afImageResolutionAttribs m_windowResolution;
597618
afImageResolutionAttribs m_publishImageResolution;
598619
afImageResolutionAttribs m_publishDephtResolution;
599620
afNoiseModelAttribs m_depthNoiseAttribs;
600621

601622
afHierarchyAttributes m_hierarchyAttribs;
602623
afKinematicAttributes m_kinematicAttribs;
603624

625+
vector<vector <double>> m_projectionMatrix; // column major
626+
afCameraIntrinsics m_intrinsics;
627+
bool m_useCustomProjectionMatrix;
628+
604629
virtual void resolveRelativePathAttribs(afPath a_parentPath){
605630
if (m_pathsResolved == false){
606631
afBaseObjectAttributes::resolveRelativePathAttribs(a_parentPath);

ambf_framework/afFramework.cpp

Lines changed: 99 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6449,10 +6449,6 @@ bool afCamera::createFromAttribs(afCameraAttributes *a_attribs)
64496449
setName(a_attribs->m_identificationAttribs.m_name);
64506450
setNamespace(a_attribs->m_identificationAttribs.m_namespace);
64516451

6452-
m_camPos << a_attribs->m_kinematicAttribs.m_location.getPosition();
6453-
m_camLookAt << a_attribs->m_lookAt;
6454-
m_camUp << a_attribs->m_up;
6455-
64566452
setOrthographic(a_attribs->m_orthographic);
64576453

64586454
if (a_attribs->m_stereo){
@@ -6481,11 +6477,53 @@ bool afCamera::createFromAttribs(afCameraAttributes *a_attribs)
64816477
}
64826478

64836479
//////////////////////////////////////////////////////////////////////////////////////
6480+
m_camPos << a_attribs->m_kinematicAttribs.m_location.getPosition();
6481+
m_camLookAt << a_attribs->m_lookAt;
6482+
m_camUp << a_attribs->m_up;
64846483
// position and orient the camera
64856484
setView(m_camPos, m_camLookAt, m_camUp);
6485+
m_camera->setClippingPlanes(a_attribs->m_nearPlane, a_attribs->m_farPlane);
6486+
6487+
if (a_attribs->m_intrinsics.m_defined){
6488+
const int rows = 4, cols = 4;
6489+
for (int r = 0 ; r < rows ; r++){
6490+
for (int c = 0 ; c < cols ; c++){
6491+
getInternalCamera()->m_projectionMatrix(r, c) = 0.0;
6492+
}
6493+
}
6494+
computeProjectionFromIntrinsics(&a_attribs->m_intrinsics,
6495+
a_attribs->m_windowResolution.m_width,
6496+
a_attribs->m_windowResolution.m_height,
6497+
a_attribs->m_nearPlane,
6498+
a_attribs->m_farPlane);
6499+
6500+
cerr << "INFO! USING CAMERA INTRINSICS FOR " << getQualifiedName() << endl;
6501+
cerr << "\t Focal Length(x, y): (" << a_attribs->m_intrinsics.m_fx << ", " << a_attribs->m_intrinsics.m_fy << ")" << endl;
6502+
cerr << "\t Principal Offset (x, y): (" << a_attribs->m_intrinsics.m_cx << ", " << a_attribs->m_intrinsics.m_cy << ")" << endl;
6503+
cerr << "\t Shear: " << a_attribs->m_intrinsics.m_s << endl;
6504+
}
6505+
else if (a_attribs->m_useCustomProjectionMatrix){
6506+
getInternalCamera()->m_useCustomProjectionMatrix = true;
6507+
const int rows = 4, cols = 4;
6508+
for (int r = 0 ; r < rows ; r++){
6509+
for (int c = 0 ; c < cols ; c++){
6510+
getInternalCamera()->m_projectionMatrix(r, c) = a_attribs->m_projectionMatrix[r][c];
6511+
}
6512+
}
6513+
6514+
cerr << "INFO! USING CUSTOM PROJECT MATRIX FOR CAMERA: " << getQualifiedName() << endl;
6515+
for (int r = 0 ; r < rows ; r++){
6516+
cerr << "\t[";
6517+
for (int c = 0 ; c < cols ; c++){
6518+
cerr << a_attribs->m_projectionMatrix[r][c] << " ";
6519+
}
6520+
cerr << "\t]" << endl;
6521+
}
6522+
6523+
}
6524+
64866525
m_initialTransform = getLocalTransform();
64876526
// set the near and far clipping planes of the camera
6488-
m_camera->setClippingPlanes(a_attribs->m_nearPlane, a_attribs->m_farPlane);
64896527

64906528
// set stereo mode
64916529
m_camera->setStereoMode(m_stereoMode);
@@ -6593,15 +6631,18 @@ bool afCamera::createWindow()
65936631

65946632
m_monitor = m_monitors[m_monitorNumber];
65956633

6596-
// compute desired size of window
65976634
const GLFWvidmode* mode = glfwGetVideoMode(m_monitor);
6598-
int w = 0.8 * mode->width;
6599-
int h = 0.5 * mode->height;
6600-
int x = 0.5 * (mode->width - w);
6601-
int y = 0.5 * (mode->height - h);
6635+
// compute desired size of window
6636+
afCameraAttributes* camAttribs = (afCameraAttributes*)getAttributes();
6637+
if (camAttribs->m_windowResolution.m_defined){
6638+
m_width = camAttribs->m_windowResolution.m_width;
6639+
m_height = camAttribs->m_windowResolution.m_height;
66026640

6603-
m_width = w;
6604-
m_height = h;
6641+
}
6642+
else{
6643+
m_width = 0.8 * mode->width;
6644+
m_height = 0.5 * mode->height;
6645+
}
66056646

66066647
if (getVisibleFlag() == false){
66076648
cerr << "INFO! CAMERA \"" << m_name << "\" SET TO INVISIBLE. THEREFORE IT IS ONLY VIEWABLE"
@@ -6612,7 +6653,16 @@ bool afCamera::createWindow()
66126653
glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE);
66136654
}
66146655

6615-
m_window = glfwCreateWindow(w, h, window_name.c_str(), nullptr, s_mainWindow);
6656+
int screenOriginX, screenOriginY;
6657+
glfwGetMonitorPos(m_monitor, &screenOriginX, &screenOriginY);
6658+
6659+
int windowOriginX = 0.5 * (mode->width - m_width);
6660+
int windowOriginY = 0.5 * (mode->height - m_height);
6661+
6662+
m_window = glfwCreateWindow(m_width, m_height, window_name.c_str(), nullptr, s_mainWindow);
6663+
// set position of window
6664+
glfwSetWindowPos(m_window, screenOriginX + windowOriginX, screenOriginY + windowOriginY);
6665+
66166666
if (s_windowIdx == 0){
66176667
s_mainWindow = m_window;
66186668
}
@@ -6635,14 +6685,6 @@ bool afCamera::createWindow()
66356685
// get width and height of window
66366686
glfwGetWindowSize(m_window, &m_width, &m_height);
66376687

6638-
6639-
int xpos, ypos;
6640-
glfwGetMonitorPos(m_monitor, &xpos, &ypos);
6641-
x += xpos; y += ypos;
6642-
6643-
// set position of window
6644-
glfwSetWindowPos(m_window, x, y);
6645-
66466688
// glfwSetWindowMonitor(m_window, m_monitor, m_win_x, m_win_y, m_width, m_height, mode->refreshRate);
66476689

66486690
// initialize GLEW library
@@ -6705,6 +6747,32 @@ bool afCamera::assignWindowCallbacks(afCameraWindowCallBacks *a_callbacks)
67056747
return true;
67066748
}
67076749

6750+
bool afCamera::computeProjectionFromIntrinsics(const afCameraIntrinsics *a_attribs, double a_width, double a_height, double a_nearPlane, double a_farPlane){
6751+
double fx = a_attribs->m_fx;
6752+
double fy = a_attribs->m_fy;
6753+
double cx = a_attribs->m_cx;
6754+
double cy = a_attribs->m_cy;
6755+
double s = a_attribs->m_s;
6756+
double W = a_width;
6757+
double H = a_height;
6758+
double image_center_x = W/2.;
6759+
double image_center_y = H/2.;
6760+
double n = a_nearPlane;
6761+
double f = a_farPlane;
6762+
6763+
getInternalCamera()->m_useCustomProjectionMatrix = true;
6764+
getInternalCamera()->m_projectionMatrix(0,0) = (2 * fx) / W;
6765+
getInternalCamera()->m_projectionMatrix(0,1) = (2 * s) / W;
6766+
getInternalCamera()->m_projectionMatrix(0,2) = (W - 2 * cx) / W;
6767+
getInternalCamera()->m_projectionMatrix(1,1) = (2 * fy) / H;
6768+
getInternalCamera()->m_projectionMatrix(1,2) = (-H + 2 * cy) / H;
6769+
getInternalCamera()->m_projectionMatrix(2,2) = (-f - n) / (f - n);
6770+
getInternalCamera()->m_projectionMatrix(2,3) = (-2 * f * n) / (f - n);
6771+
getInternalCamera()->m_projectionMatrix(3,2) = -1.0;
6772+
6773+
return true;
6774+
}
6775+
67086776
///
67096777
/// \brief afCamera::publishDepthCPUBased
67106778
///
@@ -6893,6 +6961,11 @@ void afCamera::render(afRenderOptions &options)
68936961
// get width and height of window
68946962
glfwGetFramebufferSize(m_window, &m_width, &m_height);
68956963

6964+
afCameraIntrinsics intrinsics = (((afCameraAttributes*)getAttributes())->m_intrinsics);
6965+
if (intrinsics.m_defined){
6966+
computeProjectionFromIntrinsics(&intrinsics, m_width, m_height, getInternalCamera()->getNearClippingPlane(), getInternalCamera()->getFarClippingPlane());
6967+
}
6968+
68966969
// Update the Labels in a separate sub-routine
68976970
if (options.m_updateLabels && !m_publishDepth && !m_publishImage){
68986971
updateLabels(options);
@@ -6960,6 +7033,11 @@ void afCamera::renderSkyBox(){
69607033
void afCamera::renderFrameBuffer(){
69617034
if (m_publishImage || m_publishDepth){
69627035

7036+
afCameraIntrinsics intrinsics = (((afCameraAttributes*)getAttributes())->m_intrinsics);
7037+
if (intrinsics.m_defined){
7038+
computeProjectionFromIntrinsics(&intrinsics, m_frameBuffer->getWidth(), m_frameBuffer->getHeight(), getInternalCamera()->getNearClippingPlane(), getInternalCamera()->getFarClippingPlane());
7039+
}
7040+
69637041
activatePreProcessingShaders();
69647042

69657043
m_frameBuffer->renderView();

ambf_framework/afFramework.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,6 +1927,8 @@ class afCamera: public afBaseObject{
19271927

19281928
bool assignWindowCallbacks(afCameraWindowCallBacks* a_callbacks);
19291929

1930+
bool computeProjectionFromIntrinsics(const afCameraIntrinsics* a_attribs, double a_width, double a_height, double a_nearPlane, double a_farPlane);
1931+
19301932
// Since we changed the order of ADF loading such that cameras are loaded before
19311933
// bodies etc. we wouldn't be able to find a body defined as a parent in the
19321934
// camera data-block in the ADF file. Thus after loading the bodies, this method

0 commit comments

Comments
 (0)