RAMSES Documentation  27.0.130
Information for RAMSES users and developers
ramses-example-local-pick-handling/src/main.cpp

Example of adding touch capability to triangles by creating PickableObjects that cover up the triangles.

// -------------------------------------------------------------------------
// Copyright (C) 2019 BMW AG
// -------------------------------------------------------------------------
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
// -------------------------------------------------------------------------
#include "ramses-client.h"
#include "RamsesObjectTypeUtils.h"
#include <unordered_set>
#include <thread>
#include <iostream>
#include <map>
#include <random>
constexpr uint32_t DisplayWidth = 1280u;
constexpr uint32_t DisplayHeight = 480u;
constexpr int32_t perspViewportOffsetX = 150;
constexpr int32_t perspViewportOffsetY = 130;
constexpr int32_t perspViewportHeight = 240;
constexpr int32_t perspViewportWidth = 640;
{
public:
: m_sceneControlApi(sceneControlApi)
, m_appearanceA(appearanceA)
, m_appearanceB(appearanceB)
, m_colorInput(colorInput)
{
}
void mouseEvent(ramses::displayId_t, ramses::EMouseEvent eventType, int32_t mousePosX, int32_t mousePosY) override
{
{
//Flip PosY
mousePosY = DisplayHeight - mousePosY;
//normalized coordinate calculation
const float mouseXNormalized = ((2.0f * static_cast<float>(mousePosX) / DisplayWidth)) - 1.f;
const float mouseYNormalized = ((2.0f * static_cast<float>(mousePosY) / DisplayHeight)) - 1.f;
m_sceneControlApi.handlePickEvent(ramses::sceneId_t(1u), mouseXNormalized, mouseYNormalized);
std::cout << "Window was clicked at Coordinates: X = " << mousePosX << " Y = " << mousePosY << "\n";
}
}
virtual void objectsPicked(ramses::sceneId_t /*sceneId*/, const ramses::pickableObjectId_t* pickedObjects, uint32_t pickedObjectsCount) override
{
std::uniform_real_distribution<float> dist;
const float r = dist(m_randomGenerator);
const float g = dist(m_randomGenerator);
const float b = dist(m_randomGenerator);
// log all picked objects to the console
for (uint32_t po = 0; po < pickedObjectsCount; ++po)
{
std::cout << "PickableObject with Id: " << pickedObjects[po].getValue() << " has been picked\n";
// change color of clicked triangles to random value
if (pickedObjects[po].getValue() == 1)
{
m_appearanceA.getEffect().findUniformInput("color", m_colorInput);
m_appearanceA.setInputValueVector4f(m_colorInput, r, g, b, 1.0f);
}
else if (pickedObjects[po].getValue() == 2)
{
m_appearanceB.getEffect().findUniformInput("color", m_colorInput);
m_appearanceB.setInputValueVector4f(m_colorInput, r, g, b, 1.0f);
}
}
}
void windowClosed(ramses::displayId_t /*displayId*/) override
{
m_windowClosed = true;
}
bool isWindowClosed() const
{
return m_windowClosed;
}
private:
ramses::RendererSceneControl& m_sceneControlApi;
ramses::Appearance& m_appearanceA;
ramses::Appearance& m_appearanceB;
ramses::UniformInput& m_colorInput;
std::mt19937 m_randomGenerator{std::random_device{}()};
bool m_windowClosed = false;
};
int main(int argc, char* argv[])
{
//Ramses client
ramses::RamsesFrameworkConfig config(argc, argv);
config.setRequestedRamsesShellType(ramses::ERamsesShellType_Console); //needed for automated test of examples
ramses::RamsesFramework framework(config);
ramses::RamsesClient& client(*framework.createClient("ramses-local-client-test"));
ramses::RendererConfig rendererConfig(argc, argv);
ramses::RamsesRenderer& renderer(*framework.createRenderer(rendererConfig));
auto& sceneControlAPI = *renderer.getSceneControlAPI();
renderer.startThread();
ramses::DisplayConfig displayConfig(argc, argv);
displayConfig.setWindowRectangle(150, 150, DisplayWidth, DisplayHeight);
const ramses::displayId_t display = renderer.createDisplay(displayConfig);
renderer.flush();
framework.connect();
//client scene
const ramses::sceneId_t sceneId(1u);
ramses::Scene* clientScene = client.createScene(sceneId, ramses::SceneConfig(), "local client example scene");
// every scene needs a render pass with camera
ramses::OrthographicCamera* orthographicCamera = clientScene->createOrthographicCamera("my orthographicCamera");
orthographicCamera->setFrustum(-1.f, 1.f, -1.f, 1.f, 0.1f, 100.f);
orthographicCamera->setViewport(0, 0, 1280, 480);
orthographicCamera->translate(.2f, 0.f, 5.f);
orthographicCamera->rotate(0.f, 5.f, 0.f);
orthographicCamera->scale(1.f, 2.f, 1.f);
ramses::PerspectiveCamera* perspectiveCamera = clientScene->createPerspectiveCamera("my perspectiveCamera");
perspectiveCamera->setFrustum(19.f, 1280.f / 480.f, 0.1f, 100.f);
perspectiveCamera->translate(0.f, 0.f, 11.f);
perspectiveCamera->rotate(0.f, 12.f, 4.f);
perspectiveCamera->scale(1.f, 2.f, 1.f);
ramses::RenderPass* renderPassA = clientScene->createRenderPass("my render pass A");
ramses::RenderPass* renderPassB = clientScene->createRenderPass("my render pass B");
renderPassA->setCamera(*perspectiveCamera);
renderPassB->setCamera(*orthographicCamera);
ramses::RenderGroup* renderGroupA = clientScene->createRenderGroup();
ramses::RenderGroup* renderGroupB = clientScene->createRenderGroup();
renderPassA->addRenderGroup(*renderGroupA);
renderPassB->addRenderGroup(*renderGroupB);
// prepare triangle geometry: vertex position array and index array
float vertexPositionsArray[] = { -1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 1.f, 0.f };
ramses::ArrayResource* vertexPositions = clientScene->createArrayResource(ramses::EDataType::Vector3F, 3, vertexPositionsArray);
uint16_t indicesArray[] = { 0, 1, 2 };
ramses::ArrayResource* indices = clientScene->createArrayResource(ramses::EDataType::UInt16, 3, indicesArray);
// create an appearance for red triangle
effectDesc.setVertexShaderFromFile("res/ramses-example-local-pick-handling.vert");
effectDesc.setFragmentShaderFromFile("res/ramses-example-local-pick-handling.frag");
ramses::Effect* effect = clientScene->createEffect(effectDesc, ramses::ResourceCacheFlag_DoNotCache, "glsl shader");
ramses::Appearance* appearanceA = clientScene->createAppearance(*effect, "triangle appearance A");
ramses::Appearance* appearanceB = clientScene->createAppearance(*effect, "triangle appearance B");
ramses::GeometryBinding* geometry = clientScene->createGeometryBinding(*effect, "triangle geometry");
geometry->setIndices(*indices);
ramses::AttributeInput positionsInput;
effect->findAttributeInput("a_position", positionsInput);
geometry->setInputBuffer(positionsInput, *vertexPositions);
effect->findUniformInput("color", colorInput);
// create two mesh nodes to define the triangles with chosen appearance
ramses::MeshNode* meshNode = clientScene->createMeshNode("triangle mesh node");
ramses::MeshNode* meshNode2 = clientScene->createMeshNode("triangle mesh node 2");
meshNode->setAppearance(*appearanceA);
meshNode->setTranslation(1.5f, -0.3f, 0.4f);
meshNode->setRotation(12.f, 30.f, 10.f);
meshNode->setScaling(1.2f, 1.5f, 0.7f);
meshNode->setGeometryBinding(*geometry);
// mesh needs to be added to a render group that belongs to a render pass with camera in order to be rendered
renderGroupA->addMeshNode(*meshNode);
meshNode2->setTranslation(1.f, 0.0f, 0.0f);
meshNode2->setRotation(10.f, 34.f, 19.f);
meshNode2->setScaling(0.5f, 0.5f, 0.5f);
meshNode2->setAppearance(*appearanceB);
meshNode2->setGeometryBinding(*geometry);
renderGroupB->addMeshNode(*meshNode2);
appearanceA->setInputValueVector4f(colorInput, 1.0f, 0.0f, 0.3f, 1.0f);
appearanceB->setInputValueVector4f(colorInput, 0.0f, 1.0f, 0.3f, 1.0f);
// use triangle's vertex position array as PickableObject geometry
// the two PickableObjects are exactly covering the two triangles
ramses::ArrayBuffer* pickableGeometryBuffer = clientScene->createArrayBuffer(ramses::EDataType::Vector3F, 3u, "geometryBuffer");
pickableGeometryBuffer->updateData(0u, 3, vertexPositionsArray);
ramses::PickableObject* pickableObject1 = clientScene->createPickableObject(*pickableGeometryBuffer, ramses::pickableObjectId_t(1), "pickableObject");
pickableObject1->setParent(*meshNode);
// use the scenes camera for calculating the right intersection point with the PickableObject
pickableObject1->setCamera(*perspectiveCamera);
ramses::PickableObject* pickableObject2 = clientScene->createPickableObject(*pickableGeometryBuffer, ramses::pickableObjectId_t(2), "pickableObject2");
pickableObject2->setParent(*meshNode2);
pickableObject2->setCamera(*orthographicCamera);
clientScene->publish();
clientScene->flush();
SceneStateEventHandler eventHandler(sceneControlAPI, *appearanceA, *appearanceB, colorInput);
// show the scene on the renderer
sceneControlAPI.setSceneMapping(sceneId, display);
sceneControlAPI.setSceneState(sceneId, ramses::RendererSceneState::Rendered);
sceneControlAPI.flush();
while (!eventHandler.isWindowClosed())
{
std::this_thread::sleep_for(std::chrono::milliseconds(15));
renderer.dispatchEvents(eventHandler);
sceneControlAPI.dispatchEvents(eventHandler);
// signal the scene it is in a state that can be rendered
clientScene->flush();
sceneControlAPI.flush();
}
}
Definition: main.cpp:48
SceneStateEventHandler(ramses::RendererSceneControl &sceneControlApi, ramses::RamsesRenderer &renderer)
Definition: main.cpp:50
The Appearance describes how an object should look like. This includes GLSL uniform values,...
Definition: Appearance.h:34
status_t setInputValueVector4f(const UniformInput &input, float x, float y, float z, float w)
Sets value of the input.
The ArrayBuffer is a data object used to provide vertex or index data to ramses::GeometryBinding::set...
Definition: ArrayBuffer.h:27
status_t updateData(uint32_t firstElement, uint32_t numElements, const void *bufferData)
Update data of the ArrayBuffer object.
The ArrayResource stores a data array of a given type. The data is immutable. The resource can be use...
Definition: ArrayResource.h:26
The AttributeInput is a description of an attribute effect input.
Definition: AttributeInput.h:22
status_t setViewport(int32_t x, int32_t y, uint32_t width, uint32_t height)
Sets the viewport to be used when rendering with this camera.
status_t setFrustum(float leftPlane, float rightPlane, float bottomPlane, float topPlane, float nearPlane, float farPlane)
Sets camera frustum planes of the Camera.
The DisplayConfig holds a set of parameters to be used to initialize a display.
Definition: DisplayConfig.h:22
An effect description holds all necessary information for an effect to be created.
Definition: EffectDescription.h:21
status_t setVertexShaderFromFile(const char *shaderSourceFileName)
Reads and sets vertex shader source from file.
status_t setUniformSemantic(const char *inputName, EEffectUniformSemantic semanticType)
Sets an uniform semantic. Used for uniforms which are not locally available on the client,...
status_t setFragmentShaderFromFile(const char *shaderSourceFileName)
Reads and sets fragment shader source from file.
An effect describes how an object will be rendered to the screen.
Definition: Effect.h:26
status_t findUniformInput(const char *inputName, UniformInput &uniformInput) const
Finds uniform input by input name.
status_t findAttributeInput(const char *inputName, AttributeInput &attributeInput) const
Finds attribute input by input name.
A geometry binding together with an appearance describe how an object will be rendered to the screen.
Definition: GeometryBinding.h:25
status_t setIndices(const ArrayResource &indicesResource)
Assign a data array with data type UInt16 or UInt32 to be used when accessing vertex data.
status_t setInputBuffer(const AttributeInput &attributeInput, const ArrayResource &arrayResource, uint32_t instancingDivisor=0)
Assign a data array resource to a given effect attribute input.
The MeshNode holds all information which is needed to render an object to the screen.
Definition: MeshNode.h:25
status_t setAppearance(Appearance &appearance)
Sets the Appearance of the MeshNode.
status_t setGeometryBinding(GeometryBinding &geometry)
Sets the GeometryBinding of the MeshNode.
status_t setScaling(float x, float y, float z)
Sets the absolute scale in all three dimensions.
status_t setParent(Node &node)
Sets parent Node for this node.
status_t setTranslation(float x, float y, float z)
Sets the absolute translation the absolute values.
status_t rotate(float x, float y, float z)
Rotates in all three directions with the given values without affecting the currently set rotation co...
status_t setRotation(float x, float y, float z)
Sets the absolute rotation in all three directions for left-handed rotation using Euler ZYX rotation ...
status_t scale(float x, float y, float z)
Scales in all three directions with the given values.
status_t translate(float x, float y, float z)
Translates in all three directions with the given values.
The OrthographicCamera is a local camera which defines an orthographic view into the scene.
Definition: OrthographicCamera.h:22
The PerspectiveCamera is a local camera which defines a perspective view into the scene.
Definition: PerspectiveCamera.h:23
status_t setFrustum(float fov, float aspectRatio, float nearPlane, float farPlane)
An alternative method (see ramses::Camera::setFrustum) to set the perspective view frustum of the cam...
PickableObject provides a way to specify a 'pickable' area.
Definition: PickableObject.h:44
status_t setCamera(const Camera &camera)
Set the camera to be used to unproject geometry.
Entry point of RAMSES client API.
Definition: RamsesClient.h:34
The RamsesFrameworkConfig holds a set of parameters to be used to initialize ramses.
Definition: RamsesFrameworkConfig.h:23
Class representing ramses framework components that are needed to initialize an instance of ramses cl...
Definition: RamsesFramework.h:35
RamsesRenderer is the main renderer component which provides API to configure and control the way con...
Definition: RamsesRenderer.h:37
The RenderGroup is a container used to collect renderables which are supposed to be rendered together...
Definition: RenderGroup.h:31
status_t addMeshNode(const MeshNode &mesh, int32_t orderWithinGroup=0)
Add a mesh to this RenderGroup. If a mesh is already contained in this RenderGroup only its render or...
The RenderPass is a container used to collect meshes which are supposed to be rendered together.
Definition: RenderPass.h:31
status_t setCamera(const Camera &camera)
Set the camera to use for rendering the objects of this renderpass.
status_t setClearFlags(uint32_t clearFlags)
Set the clear flags which enable/disable the clearing of the render target assigned to this RenderPas...
status_t addRenderGroup(const RenderGroup &renderGroup, int32_t orderWithinPass=0)
Add a RenderGroup to this RenderPass for rendering.
The RendererConfig holds a set of parameters to be used to initialize a renderer.
Definition: RendererConfig.h:26
Convenience empty implementation of IRendererEventHandler that can be used to derive from when only s...
Definition: IRendererEventHandler.h:194
Convenience empty implementation of IRendererSceneControlEventHandler that can be used to derive from...
Definition: IRendererSceneControlEventHandler.h:214
virtual void objectsPicked(sceneId_t sceneId, const pickableObjectId_t *pickedObjects, uint32_t pickedObjectsCount) override
This method will be called when there were scene objects picked. A ramses::PickableObject can be 'pic...
Definition: IRendererSceneControlEventHandler.h:360
Control states of scenes.
Definition: RendererSceneControl.h:33
status_t handlePickEvent(sceneId_t sceneId, float bufferNormalizedCoordX, float bufferNormalizedCoordY)
Trigger renderer to test if given pick event with coordinates intersects with any instances of ramses...
The SceneConfig holds a set of parameters to be used when creating a scene.
Definition: SceneConfig.h:22
The Scene holds a scene graph. It is the essential class for distributing content to the ramses syste...
Definition: Scene.h:83
OrthographicCamera * createOrthographicCamera(const char *name=nullptr)
Creates a Orthographic Camera in this Scene.
PickableObject * createPickableObject(const ArrayBuffer &geometryBuffer, const pickableObjectId_t id, const char *name=nullptr)
Create a PickableObject.
MeshNode * createMeshNode(const char *name=nullptr)
Creates a scene graph MeshNode. MeshNode is a Node with additional properties and bindings that repre...
Effect * createEffect(const EffectDescription &effectDesc, resourceCacheFlag_t cacheFlag=ResourceCacheFlag_DoNotCache, const char *name=nullptr)
Create a new Effect by parsing a GLSL shader described by an EffectDescription instance....
GeometryBinding * createGeometryBinding(const Effect &effect, const char *name=nullptr)
Creates a new GeometryBinding.
ArrayResource * createArrayResource(EDataType type, uint32_t numElements, const void *arrayData, resourceCacheFlag_t cacheFlag=ResourceCacheFlag_DoNotCache, const char *name=nullptr)
Create a new ArrayResource. It makes a copy of the given data of a certain type as a resource,...
status_t publish(EScenePublicationMode publicationMode=EScenePublicationMode_LocalAndRemote)
Publishes the scene to the ramses system.
RenderPass * createRenderPass(const char *name=nullptr)
Create a render pass in the scene.
Appearance * createAppearance(const Effect &effect, const char *name=nullptr)
Creates a new Appearance.
RenderGroup * createRenderGroup(const char *name=nullptr)
Create a RenderGroup instance in the scene.
PerspectiveCamera * createPerspectiveCamera(const char *name=nullptr)
Creates a Perspective Camera in this Scene.
ArrayBuffer * createArrayBuffer(EDataType dataType, uint32_t maxNumElements, const char *name=nullptr)
Create a new ramses::ArrayBuffer. The created object is a mutable buffer object that can be used as i...
status_t flush(sceneVersionTag_t sceneVersionTag=InvalidSceneVersionTag)
Commits all changes done to the scene since the last flush or since scene creation....
constexpr BaseType getValue() const
Getter for retrieving the underlying value.
Definition: StronglyTypedValue.h:73
The UniformInput is a description of an uniform effect input.
Definition: UniformInput.h:22
@ EClearFlags_None
Definition: RamsesFrameworkTypes.h:257
@ ModelViewProjectionMatrix
Model-view-projection matrix 4x4.
@ UInt16
one component of type uint16_t per data element
@ Vector3F
three components of type float per data element
@ ERamsesShellType_Console
Definition: RamsesFrameworkTypes.h:169
@ Rendered
Scene is being rendered.
constexpr const resourceCacheFlag_t ResourceCacheFlag_DoNotCache
Requests the render to not cache a resource. This is the default value.
Definition: RamsesFrameworkTypes.h:212
EMouseEvent
Specifies events for mouse input.
Definition: Types.h:105
@ EMouseEvent_LeftButtonDown
Definition: Types.h:108
int main(int argc, char *argv[])
Definition: main.cpp:21
constexpr int32_t perspViewportOffsetY
Definition: main.cpp:34
constexpr uint32_t DisplayWidth
Definition: main.cpp:31
constexpr int32_t perspViewportWidth
Definition: main.cpp:36
constexpr int32_t perspViewportHeight
Definition: main.cpp:35
constexpr uint32_t DisplayHeight
Definition: main.cpp:32
constexpr int32_t perspViewportOffsetX
Definition: main.cpp:33