diff --git a/bin/bc5.ini b/bin/bc5.ini index 6b84835e..317f0614 100644 --- a/bin/bc5.ini +++ b/bin/bc5.ini @@ -36,6 +36,10 @@ disable_shaders_DESC=Default of 0 to simulate a more realistic water surface, or anti_alias=4 view_angle=90 view_angle_DESC=The angle of view in degrees +split_views=1 +split_views_DESC=How many sections to split the view into (useful for panoramic view on a very wide screen) +centre_view=1 +centre_view_DESC=If split views is used, which screen should be the one looking ahead. Can be fractional. look_angle=0 look_angle_DESC=The initial view angle (from the ships head) minimum_distance=0.05 diff --git a/src/SimulationModel.cpp b/src/SimulationModel.cpp index 96393f9f..7aa605fb 100644 --- a/src/SimulationModel.cpp +++ b/src/SimulationModel.cpp @@ -1437,6 +1437,11 @@ SimulationModel::~SimulationModel() setZoom(zoomOn); } + irr::f32 SimulationModel::getZoom() const + { + return currentZoom; + } + void SimulationModel::setViewAngle(irr::f32 viewAngle) { modelParameters.viewAngle = viewAngle; @@ -1838,6 +1843,11 @@ SimulationModel::~SimulationModel() camera.update(0, quat, pos, lensShift, true); } + void SimulationModel::updateCamera(irr::core::quaternion quat) + { + camera.update(0, quat); + } + void SimulationModel::update() { diff --git a/src/SimulationModel.hpp b/src/SimulationModel.hpp index 31c2fe9d..ab410752 100644 --- a/src/SimulationModel.hpp +++ b/src/SimulationModel.hpp @@ -303,6 +303,7 @@ class SimulationModel //Start of the 'Model' part of MVC void setMouseDown(bool isMouseDown); void setZoom(bool zoomOn); void setZoom(bool zoomOn, irr::f32 zoomLevel); + irr::f32 getZoom() const; void setViewAngle(irr::f32 viewAngle); irr::u32 getLoopNumber() const; std::string getSerialisedScenario() const; @@ -373,6 +374,8 @@ class SimulationModel //Start of the 'Model' part of MVC Lines* getLines(); // Get pointer to lines object void updateCameraVRPos(irr::core::quaternion quat, irr::core::vector3df pos, irr::core::vector2df lensShift); + + void updateCamera(irr::core::quaternion quat); // Update camera view without updating anything else void update(); diff --git a/src/main.cpp b/src/main.cpp index 646872c0..be0458cf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -540,6 +540,16 @@ int main(int argc, char ** argv) viewAngle = 90; } + irr::u32 splitViews = IniFile::iniFileTou32(iniFilename, "split_views"); //How many cameras to split the view across + if (splitViews < 1) { + splitViews = 1; + } + + irr::f32 centreView = IniFile::iniFileTof32(iniFilename, "centre_view", 1.0); //Which screen should be centred, can be fractional + centreView = centreView - 1; // Indexing from 1 for users, from 0 internally + + viewAngle = viewAngle / (irr::f32)splitViews; + bool viewOwnShip = (IniFile::iniFileTou32(iniFilename, "own_ship_hidden") != 1); irr::f32 cameraMinDistance = IniFile::iniFileTof32(iniFilename, "minimum_distance"); @@ -809,8 +819,8 @@ int main(int argc, char ** argv) graphicsHeight = sh; irr::u32 graphicsWidth3d = su; irr::u32 graphicsHeight3d = sh * VIEW_PROPORTION_3D; - irr::f32 aspect = (irr::f32)su / (irr::f32)sh; - irr::f32 aspect3d = (irr::f32)graphicsWidth3d / (irr::f32)graphicsHeight3d; + irr::f32 aspect = (irr::f32)su / (irr::f32)sh / (irr::f32)splitViews; + irr::f32 aspect3d = (irr::f32)graphicsWidth3d / (irr::f32)graphicsHeight3d / (irr::f32)splitViews; std::cout << "graphicsWidth: "<< graphicsWidth << " graphicsHeight: " << graphicsHeight << std::endl; @@ -1222,18 +1232,48 @@ int main(int argc, char ** argv) // Normal rendering if (!fullScreenRadar) { + + int renderWindowWidthPx; + int renderWindowHeightPx; + irr::f32 renderWindowAspectRatio; + + irr::core::quaternion quat; + irr::f32 viewAngleWithZoom = viewAngle / model.getZoom(); + if (guiMain.getShowInterface()) { - driver->setViewPort(irr::core::rect(0, 0, graphicsWidth3d, graphicsHeight3d)); - model.updateViewport(aspect3d); + // 2d view shown + renderWindowWidthPx = graphicsWidth3d; + renderWindowHeightPx = graphicsHeight3d; + renderWindowAspectRatio = aspect3d; // Already includes split effect if needed } else { - driver->setViewPort(irr::core::rect(0, 0, graphicsWidth, graphicsHeight)); - model.updateViewport(aspect); + // Just 3d view, use the whole screen + renderWindowWidthPx = graphicsWidth; + renderWindowHeightPx = graphicsHeight; + renderWindowAspectRatio = aspect; // Already includes split effect if needed } - - if (guiMain.getShow3d()) { - smgr->drawAll(); + + if (splitViews > 1) { + renderWindowWidthPx = renderWindowWidthPx / splitViews; } + + // Set the right aspect ratio (may be changed by radar/VR render) + model.updateViewport(renderWindowAspectRatio); + + for (int cameraSplitStep = 0; cameraSplitStep < splitViews; cameraSplitStep++) + { + driver->setViewPort(irr::core::rect(cameraSplitStep * renderWindowWidthPx, 0, (cameraSplitStep + 1) * renderWindowWidthPx, renderWindowHeightPx)); + + if (guiMain.getShow3d()) { + quat.fromAngleAxis((cameraSplitStep - centreView)* viewAngleWithZoom* irr::core::DEGTORAD, irr::core::vector3df(0, 1, 0)); + model.updateCamera(quat); + smgr->drawAll(); + } + } + + // Reset camera if needed + quat.fromAngleAxis(0, irr::core::vector3df(0, 1, 0)); + model.updateCamera(quat); } if (vr3dMode && vrSuccess == 0) {