Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

262 lines
6.1 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkFollower.cxx,v $
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm 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 "vtkFollower.h"
#include "vtkCamera.h"
#include "vtkMath.h"
#include "vtkMatrix4x4.h"
#include "vtkObjectFactory.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkTexture.h"
#include "vtkTransform.h"
#include <math.h>
vtkCxxRevisionMacro(vtkFollower, "$Revision: 1.45 $");
vtkStandardNewMacro(vtkFollower);
vtkCxxSetObjectMacro(vtkFollower,Camera,vtkCamera);
// Creates a follower with no camera set
vtkFollower::vtkFollower()
{
this->Camera = NULL;
this->Device = vtkActor::New();
}
vtkFollower::~vtkFollower()
{
if (this->Camera)
{
this->Camera->UnRegister(this);
}
this->Device->Delete();
}
// Copy the follower's composite 4x4 matrix into the matrix provided.
void vtkFollower::GetMatrix(vtkMatrix4x4 *result)
{
double *pos, *vup;
double Rx[3], Ry[3], Rz[3], p1[3];
vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
int i;
double distance;
this->GetOrientation();
this->Transform->Push();
this->Transform->PostMultiply();
this->Transform->Identity();
// apply user defined matrix last if there is one
if (this->UserMatrix)
{
this->Transform->Concatenate(this->UserMatrix);
}
this->Transform->Translate(-this->Origin[0],
-this->Origin[1],
-this->Origin[2]);
// scale
this->Transform->Scale(this->Scale[0],
this->Scale[1],
this->Scale[2]);
// rotate
this->Transform->RotateY(this->Orientation[1]);
this->Transform->RotateX(this->Orientation[0]);
this->Transform->RotateZ(this->Orientation[2]);
if (this->Camera)
{
// do the rotation
// first rotate y
pos = this->Camera->GetPosition();
vup = this->Camera->GetViewUp();
if (this->Camera->GetParallelProjection())
{
this->Camera->GetDirectionOfProjection(Rz);
Rz[0] = -Rz[0];
Rz[1] = -Rz[1];
Rz[2] = -Rz[2];
}
else
{
distance = sqrt(
(pos[0] - this->Position[0])*(pos[0] - this->Position[0]) +
(pos[1] - this->Position[1])*(pos[1] - this->Position[1]) +
(pos[2] - this->Position[2])*(pos[2] - this->Position[2]));
for (i = 0; i < 3; i++)
{
Rz[i] = (pos[i] - this->Position[i])/distance;
}
}
// We cannot directly use the vup angle since it can be aligned with Rz:
//vtkMath::Cross(vup,Rz,Rx);
//vtkMath::Normalize(Rx);
//vtkMath::Cross(Rz,Rx,Ry);
//instead use the view right angle:
double dop[3], vur[3];
this->Camera->GetDirectionOfProjection(dop);
vtkMath::Cross(dop,vup,vur);
vtkMath::Normalize(vur);
vtkMath::Cross(Rz, vur, Ry);
vtkMath::Normalize(Ry);
vtkMath::Cross(Ry,Rz,Rx);
matrix->Element[0][0] = Rx[0];
matrix->Element[1][0] = Rx[1];
matrix->Element[2][0] = Rx[2];
matrix->Element[0][1] = Ry[0];
matrix->Element[1][1] = Ry[1];
matrix->Element[2][1] = Ry[2];
matrix->Element[0][2] = Rz[0];
matrix->Element[1][2] = Rz[1];
matrix->Element[2][2] = Rz[2];
this->Transform->Concatenate(matrix);
}
// translate to projection reference point PRP
// this is the camera's position blasted through
// the current matrix
p1[0] = this->Origin[0] + this->Position[0];
p1[1] = this->Origin[1] + this->Position[1];
p1[2] = this->Origin[2] + this->Position[2];
this->Transform->Translate(p1[0],p1[1],p1[2]);
this->Transform->GetMatrix(result);
matrix->Delete();
this->Transform->Pop();
}
void vtkFollower::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
if ( this->Camera )
{
os << indent << "Camera:\n";
this->Camera->PrintSelf(os,indent.GetNextIndent());
}
else
{
os << indent << "Camera: (none)\n";
}
}
int vtkFollower::RenderOpaqueGeometry(vtkViewport *vp)
{
if ( ! this->Mapper )
{
return 0;
}
if (!this->Property)
{
// force creation of a property
this->GetProperty();
}
if (this->GetIsOpaque())
{
vtkRenderer *ren = static_cast<vtkRenderer *>(vp);
this->Render(ren);
return 1;
}
return 0;
}
int vtkFollower::RenderTranslucentGeometry(vtkViewport *vp)
{
if ( ! this->Mapper )
{
return 0;
}
if (!this->Property)
{
// force creation of a property
this->GetProperty();
}
if (!this->GetIsOpaque())
{
vtkRenderer *ren = static_cast<vtkRenderer *>(vp);
this->Render(ren);
return 1;
}
return 0;
}
// This causes the actor to be rendered. It, in turn, will render the actor's
// property and then mapper.
void vtkFollower::Render(vtkRenderer *ren)
{
this->Property->Render(this, ren);
vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
this->Device->SetProperty (this->Property);
this->Property->Render(this, ren);
if (this->BackfaceProperty)
{
this->BackfaceProperty->BackfaceRender(this, ren);
this->Device->SetBackfaceProperty(this->BackfaceProperty);
}
/* render the texture */
if (this->Texture)
{
this->Texture->Render(ren);
}
// make sure the device has the same matrix
this->GetMatrix(matrix);
this->Device->SetUserMatrix(matrix);
this->Device->Render(ren,this->Mapper);
matrix->Delete();
}
void vtkFollower::GetMatrix(double m[16])
{
this->GetMatrix(this->Matrix);
vtkMatrix4x4::DeepCopy(m,this->Matrix);
}
void vtkFollower::ShallowCopy(vtkProp *prop)
{
vtkFollower *f = vtkFollower::SafeDownCast(prop);
if ( f != NULL )
{
this->SetCamera(f->GetCamera());
}
// Now do superclass
this->vtkActor::ShallowCopy(prop);
}