Game
vtk-examples/Cxx/Interaction/Game
Question
If you have a question about this example, please use the VTK Discourse Forum
Code¶
Game.cxx
// Demonstrate moving pieces and "snapping".
#include <vtkActor.h>
#include <vtkCubeSource.h>
#include <vtkInteractorStyleTrackballActor.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPointData.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkRendererCollection.h>
#include <vtkSelectEnclosedPoints.h>
#include <vtkSphereSource.h>
#include <vtkTransform.h>
#include <vtkTransformPolyDataFilter.h>
namespace {
// Define interaction style.
class MouseInteractorStyle6 : public vtkInteractorStyleTrackballActor
{
public:
static MouseInteractorStyle6* New();
vtkTypeMacro(MouseInteractorStyle6, vtkInteractorStyleTrackballActor);
virtual void OnLeftButtonDown() override
{
std::cout << "Pressed left mouse button." << std::endl;
// Forward events.
vtkInteractorStyleTrackballActor::OnLeftButtonDown();
}
virtual void OnMiddleButtonUp() override
{
// std::cout << "Pressed middle mouse button." << std::endl;
int x = this->Interactor->GetEventPosition()[0];
int y = this->Interactor->GetEventPosition()[1];
this->FindPokedRenderer(x, y);
this->FindPickedActor(x, y);
if (this->CurrentRenderer == NULL || this->InteractionProp == NULL)
{
std::cout << "Nothing selected." << std::endl;
return;
}
vtkNew<vtkPropCollection> actors;
this->InteractionProp->GetActors(actors);
actors->InitTraversal();
vtkActor* actor = dynamic_cast<vtkActor*>(actors->GetNextProp());
vtkPolyData* polydata =
dynamic_cast<vtkPolyData*>(actor->GetMapper()->GetInputAsDataSet());
vtkNew<vtkTransform> transform;
transform->SetMatrix(actor->GetMatrix());
vtkNew<vtkTransformPolyDataFilter> transformPolyData;
transformPolyData->SetInputData(polydata);
transformPolyData->SetTransform(transform);
transformPolyData->Update();
vtkNew<vtkSelectEnclosedPoints> selectEnclosedPoints;
selectEnclosedPoints->SetInputConnection(
transformPolyData->GetOutputPort());
selectEnclosedPoints->SetSurfaceData(this->Sphere);
selectEnclosedPoints->Update();
vtkDataArray* insideArray = dynamic_cast<vtkDataArray*>(
selectEnclosedPoints->GetOutput()->GetPointData()->GetArray(
"SelectedPoints"));
bool inside = false;
for (vtkIdType i = 0; i < insideArray->GetNumberOfTuples(); i++)
{
if (insideArray->GetComponent(i, 0) == 1)
{
inside = true;
break;
}
}
if (inside)
{
std::cout << "A point of the cube is inside the sphere!" << std::endl;
// Reset the cube to its original position.
// this->CubeActor->GetMatrix()->Identity();
// this->CubeActor->SetOrigin(0,0,0);
this->CubeActor->SetPosition(0, 0, 0);
this->CubeActor->SetOrientation(0, 0, 0);
this->Interactor->GetRenderWindow()
->GetRenderers()
->GetFirstRenderer()
->Render();
this->Interactor->GetRenderWindow()->Render();
}
// Release interaction
this->StopState();
}
virtual void OnRightButtonDown() override
{
std::cout << "Pressed right mouse button." << std::endl;
// Forward events.
vtkInteractorStyleTrackballActor::OnRightButtonDown();
}
vtkPolyData* Sphere = nullptr;
vtkActor* CubeActor = nullptr;
};
vtkStandardNewMacro(MouseInteractorStyle6);
} // namespace
int main(int, char*[])
{
vtkNew<vtkNamedColors> color;
// Sphere
vtkNew<vtkSphereSource> sphereSource;
sphereSource->SetRadius(2);
sphereSource->Update();
vtkNew<vtkPolyDataMapper> sphereMapper;
sphereMapper->SetInputConnection(sphereSource->GetOutputPort());
vtkNew<vtkActor> sphereActor;
sphereActor->SetMapper(sphereMapper);
sphereActor->GetProperty()->SetColor(color->GetColor3d("Tomato").GetData());
// Cube
vtkNew<vtkCubeSource> cubeSource;
cubeSource->SetCenter(5.0, 0.0, 0.0);
cubeSource->Update();
vtkNew<vtkPolyDataMapper> cubeMapper;
cubeMapper->SetInputConnection(cubeSource->GetOutputPort());
vtkNew<vtkActor> cubeActor;
cubeActor->SetMapper(cubeMapper);
cubeActor->GetProperty()->SetColor(color->GetColor3d("DodgerBlue").GetData());
// Visualize
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer);
renderWindow->SetWindowName("Game");
vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
renderWindowInteractor->SetRenderWindow(renderWindow);
renderer->AddActor(sphereActor);
renderer->AddActor(cubeActor);
renderer->SetBackground(color->GetColor3d("Burlywood").GetData());
renderWindow->Render();
vtkNew<MouseInteractorStyle6> style;
style->Sphere = sphereSource->GetOutput();
style->CubeActor = cubeActor;
renderWindowInteractor->SetInteractorStyle(style);
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
CMakeLists.txt¶
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(Game)
find_package(VTK COMPONENTS
)
if (NOT VTK_FOUND)
message(FATAL_ERROR "Game: Unable to find the VTK build folder.")
endif()
# Prevent a "command line is too long" failure in Windows.
set(CMAKE_NINJA_FORCE_RESPONSE_FILE "ON" CACHE BOOL "Force Ninja to use response files.")
add_executable(Game MACOSX_BUNDLE Game.cxx )
target_link_libraries(Game PRIVATE ${VTK_LIBRARIES}
)
# vtk_module_autoinit is needed
vtk_module_autoinit(
TARGETS Game
MODULES ${VTK_LIBRARIES}
)
Download and Build Game¶
Click here to download Game and its CMakeLists.txt file. Once the tarball Game.tar has been downloaded and extracted,
cd Game/build
If VTK is installed:
cmake ..
If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:
cmake -DVTK_DIR:PATH=/home/me/vtk_build ..
Build the project:
make
and run it:
./Game
WINDOWS USERS
Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.