/*========================================================================= Program: ParaView Module: vtkCaveSynchronizedRenderers.cxx Copyright (c) Kitware, Inc. All rights reserved. See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkCaveSynchronizedRenderers.h" #include "vtkCamera.h" #include "vtkMath.h" #include "vtkMultiProcessController.h" #include "vtkObjectFactory.h" #include "vtkPVServerOptions.h" #include "vtkPerspectiveTransform.h" #include "vtkProcessModule.h" #include "vtkRenderer.h" #include "vtkTimerLog.h" #include "vtkTransform.h" #include "vtkUnsignedCharArray.h" #include #include "assert.h" vtkStandardNewMacro(vtkCaveSynchronizedRenderers); //---------------------------------------------------------------------------- vtkCaveSynchronizedRenderers::vtkCaveSynchronizedRenderers() { this->NumberOfDisplays = 0; this->Displays= 0; this->SetNumberOfDisplays(1); this->SetEyeSeparation(0.065); this->DisplayOrigin[0] = -0.5; this->DisplayOrigin[1] = -0.5; this->DisplayOrigin[2] = -0.5; this->DisplayX[0] = 0.5; this->DisplayX[1] = -0.5; this->DisplayX[2] = -0.5; this->DisplayY[0] = 0.5; this->DisplayY[1] = 0.5; this->DisplayY[2] = -0.5; once =1; this->SetParallelController(vtkMultiProcessController::GetGlobalController()); // Initilize using pvx file specified on the command line options. vtkPVServerOptions* options = vtkPVServerOptions::SafeDownCast( vtkProcessModule::GetProcessModule()->GetOptions()); if (!options) { vtkErrorMacro("Are you sure vtkCaveSynchronizedRenderers is crated on " "an appropriate processes?"); } else { this->SetNumberOfDisplays(options->GetNumberOfMachines()); for (int cc=0; cc < this->NumberOfDisplays; cc++) { if (options->GetDisplayName(cc)) { if (this->ParallelController && this->ParallelController->GetLocalProcessId() == cc) { // PutEnv() avoids memory leak. vtksys::SystemTools::PutEnv(options->GetDisplayName(cc)); } } this->DefineDisplay(cc, options->GetLowerLeft(cc), options->GetLowerRight(cc), options->GetUpperRight(cc)); } this->SetEyeSeparation(options->GetEyeSeparation()); } } //---------------------------------------------------------------------------- vtkCaveSynchronizedRenderers::~vtkCaveSynchronizedRenderers() { this->SetNumberOfDisplays(0); } //---------------------------------------------------------------------------- void vtkCaveSynchronizedRenderers::HandleStartRender() { this->ImageReductionFactor = 1; this->Superclass::HandleStartRender(); this->ComputeCamera(this->GetRenderer()->GetActiveCamera()); this->GetRenderer()->ResetCameraClippingRange(); } //----------------------------------------------------------------------------- void vtkCaveSynchronizedRenderers::SetEyeSeparation(double eyeSeparation) { this->EyeSeparation = eyeSeparation; } //----------------------------------------------------------------------------- void vtkCaveSynchronizedRenderers::SetNumberOfDisplays(int numberOfDisplays) { if (numberOfDisplays == this->NumberOfDisplays) { return; } double** newDisplays = 0; if (numberOfDisplays > 0) { newDisplays = new double*[numberOfDisplays]; for (int i = 0; i < numberOfDisplays; ++i) { newDisplays[i] = new double[12]; if (i < this->NumberOfDisplays) { memcpy(newDisplays[i], this->Displays[i], 12 * sizeof(double)); } else { newDisplays[i][0] = -0.5; newDisplays[i][1] = -0.5; newDisplays[i][2] = -0.5; newDisplays[i][3] = 1.0; newDisplays[i][4] = 0.5; newDisplays[i][5] = -0.5; newDisplays[i][6] = -0.5; newDisplays[i][7] = 1.0; newDisplays[i][8] = 0.5; newDisplays[i][9] = 0.5; newDisplays[i][10] = -0.5; newDisplays[i][11] = 1.0; } } } for (int i = 0; i < this->NumberOfDisplays; ++i) { delete [] this->Displays[i]; } delete [] this->Displays; this->Displays = newDisplays; this->NumberOfDisplays = numberOfDisplays; this->Modified(); } //------------------------------------------------------------------------- void vtkCaveSynchronizedRenderers::DefineDisplay( int idx, double origin[3], double x[3], double y[3]) { if (idx >= this->NumberOfDisplays) { vtkErrorMacro("idx is too high !"); return; } memcpy(&this->Displays[idx][0], origin, 3 * sizeof(double)); memcpy(&this->Displays[idx][4], x, 3 * sizeof(double)); memcpy(&this->Displays[idx][8], y, 3 * sizeof(double)); if (idx == this->GetParallelController()->GetLocalProcessId()) { memcpy(this->DisplayOrigin, origin, 3 * sizeof(double)); memcpy(this->DisplayX, x, 3 * sizeof(double)); memcpy(this->DisplayY, y, 3 * sizeof(double)); } this->Modified(); } //------------------------------------------------------------------------- // Room camera is a camera in room coordinates that points at the display. // Client camera is the camera on the client. The out camera is the // combination of the two used for the final cave display. // It is the room camera transformed by the world camera. void vtkCaveSynchronizedRenderers::ComputeCamera(vtkCamera* camera) { if(once) { double eyePosition[3] = {0.0, 0.0, 0.5}; camera->SetScreenBottomLeft(this->DisplayOrigin); camera->SetScreenBottomRight(this->DisplayX); camera->SetScreenTopRight(this->DisplayY); camera->SetUseOffAxisProjection(true); camera->SetEyePosition(eyePosition); camera->SetEyeSeparation(this->EyeSeparation); // cam->SetHeadTracked( true ); // cam->SetScreenConfig( this->DisplayOrigin, // this->DisplayX, // this->DisplayY ,0.065, 1.0); once =0; } } //---------------------------------------------------------------------------- void vtkCaveSynchronizedRenderers::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "NumberOfDisplays: " << this->NumberOfDisplays << endl; vtkIndent rankIndent = indent.GetNextIndent(); for (int i = 0; i < this->NumberOfDisplays; ++i) { os << rankIndent; for (int j = 0; j < 12; ++j) { os << this->Displays[i][j] << " "; } os << endl; } os << indent << "Origin: " << this->DisplayOrigin[0] << " " << this->DisplayOrigin[1] << " " << this->DisplayOrigin[2] << endl; os << indent << "X: " << this->DisplayX[0] << " " << this->DisplayX[1] << " " << this->DisplayX[2] << endl; os << indent << "Y: " << this->DisplayY[0] << " " << this->DisplayY[1] << " " << this->DisplayY[2] << endl; }