#ifndef NAVLIB_H_INCLUDED_
#define NAVLIB_H_INCLUDED_
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (c) 2014-2021 3Dconnexion.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*/
/**
* @file navlib.h
* @brief describes the interface for navigating in a 2D or 3D view.
*/
#include
///
/// Contains the navigation library API types and functions
///
///
/// The functions and types describe an interface for navigating in a 2D or 3D view.
///
/// In this scheme, a 3dconnexion library is responsible for calculating the position of the camera
/// viewing the scene or object as well as displaying the settings and for supporting user
/// customization.
///
///
/// The application is responsible for passing the description of an interface of the 2D/3D view to
/// the 3dconnexion library, and for reacting to the changes to the properties identified by the
/// 3dconnexion library.
///
///
_NAVLIB_BEGIN
// ************************************************************************************************
// Properties
///
/// Property set by the client to indicate that the connection is currently active.
///
///
/// The type is and is
/// .
/// Clients that have multiple navigation instances open need to inform the navlib which of
/// them is the target for 3D Mouse input. They do this by setting the active_k property of a
/// navigation instance to true.
///
static const property_t active_k = "active";
///
/// Property that a client sets to indicate it has keyboard focus.
///
///
/// The type is and is
/// .
/// Clients that run in container applications via the NLServer proxy set this property to
/// indicate keyboard focus. This will set 3DMouse focus to the navlib connection.
///
static const property_t focus_k = "focus";
///
/// Client property that the navlib sets when a motion model is active.
///
///
/// The type is and is
/// .
/// The motion_k property is set to true by the navlib to notify
/// the client that it is executing a motion model and will update the camera matrix regularly. This
/// is useful for clients that need to run an animation loop. When the navlib has finished
/// navigating the camera position it will set the property to false. By setting motion_k to false,
/// a client may temporarily interrupt a navigation communication and force the Navlib to
/// reinitialize the navigation.
///
static const property_t motion_k = "motion";
///
/// Specifies the transform from the client's coordinate system to the navlib coordinate system.
///
///
/// The type is and is
/// .
/// The Navigation Library coordinate system is Y up, X to the right and Z out of the screen.
/// This property is queried directly after new navigation instance is created. This allows the
/// client to specify the other properties using the coordinate system used in the client. For the
/// keep Y up ('Lock Horizon') algorithm to work correctly a non-identity matrix needs to be
/// specified whenever the ground plane is not the X-Z plane.
///
static const property_t coordinate_system_k = "coordinateSystem";
/* Frame properties*/
///
/// Specifies the begin and end of a navigation transaction.
///
///
/// The type is and is
/// .
/// The Navigation Library can set more than one client property for a single navigation
/// frame. For example when navigating in an orthographic projection possibly both the view affine
/// and extents will be modified depending on the 3DMouse input. The Navigation Library sets the
/// transaction_k property to a value >0 at the beginning of a navigation frame and to 0 at the end.
/// Clients that need to actively refresh the view can trigger the refresh when the value is set to
/// 0.
///
static const property_t transaction_k = "transaction";
///
/// Specifies the time stamp of an animation frame in milliseconds.
///
///
/// The type is and is
/// .
/// When the frame_timing_source_k property is set to 1, the client initiates a frame
/// transaction by informing the Navigation Library of the frame time. When the value is 0, the
/// Navigation Library attempts to synchronize the frames to the monitor vertical blanking
/// rate.
///
static const property_t frame_time_k = "frame.time";
///
/// Specifies the source of the frame timing.
///
///
/// The type is and is
/// .
/// By setting the frame_timing_source_k property to 1, the client application informs the
/// Navigation Library that the client has an animation loop and will be the source of the frame
/// timing.
///
static const property_t frame_timing_source_k = "frame.timingSource";
///
/// Specifies whether a device is present
///
///
/// The type is and is
/// .
/// Currently this always returns true.
///
static const property_t device_present_k = "device.present";
///
/// Defines a set of commands.
///
///
/// The type is * and is
/// .
/// Command sets can be considered to be button banks. The set can be either the complete list
/// of commands that are available in the application or a single set of commands for a specific
/// application context. The navlib will not query the application for this property. It is the
/// responsibility of the application to update this property when commands are to be made available
/// to the user.
///
static const property_t commands_tree_k = "commands.tree";
///
/// The active command.
///
///
/// The type is and is
/// .
/// When the user presses a 3DMouse button that has been assign an application command
/// exposed by the commands_tree_k property, the navlib will write this property. The string value
/// will be the corresponding id passed in the commands_tree_k property. Generally the navlib will
/// set this property to an empty string when the corresponding button has been released.
///
static const property_t commands_activeCommand_k = "commands.activeCommand";
///
/// Specifies the active set of commands.
///
///
/// The type is and is
/// .
/// In applications that have exposed multiple command sets this property needs to be set to
/// define the command set that is active. The navlib will not query the application for this
/// property. It is the responsibility of the application to update this property when the set of
/// commands need to be changed. Normally this will be due to change in application state and may
/// correspond to a menu/toolbar change. If only a single set of commands has been defined, this
/// property defaults to that set.
///
static const property_t commands_activeSet_k = "commands.activeSet";
///
/// Specifies an array of images for the 3Dconnexion UI.
///
///
/// The type is and is
/// .
/// An image with the same as a command
/// will be associated with that command in the 3Dconnexion
/// UI.
///
static const property_t images_k = "images";
/* view properties */
///
/// Specifies the transformation matrix of the view camera.
///
///
/// The type is and is
/// .
/// This matrix specifies the camera to world transformation of the view. That is,
/// transforming the position (0, 0, 0) by this matrix yields the position of the camera in world
/// coordinates. The navlib will, generally, query this matrix at the beginning of a navigation
/// action and then set the property once per frame.
///
static const property_t view_affine_k = "view.affine";
///
/// Specifies the plane equation of the construction plane.
///
///
/// The type is and is
/// .
/// The plane equation is used by the Navigation Library to distinguish views used for
/// construction in orthographic projections: typically the top, right left etc. views. The
/// Navigation Library assumes that when the camera's look-at axis is parallel to the plane normal,
/// the view should not be rotated.
///
static const property_t view_constructionPlane_k = "view.constructionPlane";
///
/// Specifies the orthographic extents of the view in camera coordinates.
///
///
/// The type is and is
/// .
/// The orthographic extents of the view are returned as a bounding box in world units
/// relative to the camera/view frame. The view frame is a right-handed coordinate system centered
/// on the view with x to the right and y up. The Navigation Library will only access this property
/// if the view is orthographic.
///
static const property_t view_extents_k = "view.extents";
///
/// Specifies the vertical field-of-view of a perspective camera/view in radians.
///
///
/// The type is and is
/// .
///
static const property_t view_fov_k = "view.fov";
///
/// Specifies the frustum of a perspective camera/view in camera coordinates.
///
///
/// The type is and is
/// .
/// The navlib uses this property to calculate the field-of-view of the perspective camera.
/// The frustum is also used in algorithms that need to determine if the model is currently visible.
/// The navlib will not write to this property. Instead, if necessary, the navlib will write to the
/// property and leave the client to change the frustum as it
/// wishes.
///
static const property_t view_frustum_k = "view.frustum";
///
/// Specifies whether the projection type of the view/camera is perspective.
///
///
/// The type is and is
/// .
/// This property defaults to true. If the client does not supply a function for the navlib to
/// query the view's projection (which it will generally do at the onset of motion), then it must
/// set the property in the navlib if the projection is orthographic or when it changes.
///
static const property_t view_perspective_k = "view.perspective";
///
/// Specifies the position of the target of the view/camera.
///
///
/// The type is and is
/// .
/// The view interest.
///
static const property_t view_target_k = "view.target";
///
/// Specifies whether the view can be rotated.
///
///
/// The type is and is
/// .
/// This property is generally used to differentiate between orthographic 3D views and views
/// that can only be panned and zoomed such as plan views.
///
static const property_t view_rotatable_k = "view.rotatable";
///
/// Specifies the orientation of the view designated as the front view.
///
///
/// The type is and is
/// .
/// The Navigation Library will only query the value of this property when the connection is
/// created. It is used to orientate the model to one of the 'Front', 'Back', 'Right', 'Left' etc.
/// views in response to the respective pre-defined view commands. If the orientation of the front
/// view is redefined after the connection is opened by the user, the client application is required
/// to update the property to the new value.
///
static const property_t views_front_k = "views.front";
///
/// Specifies the position of the rotation pivot.
///
///
/// The type is and is
/// .
/// The Navigation Library will generally set property when
/// navigation ends. The position will depend on which pivot model is being used. The application
/// can set the pivot to a fix position by setting this property. A side effect of the application
/// setting the property is that the property is set to true.
///
static const property_t pivot_position_k = "pivot.position";
///
/// Specifies whether the position of the rotation pivot is set by the user.
///
///
/// The type is and is
/// .
/// With the property set to true, the Navigation Library will disable the internal pivot
/// position algorithms.
///
static const property_t pivot_user_k = "pivot.user";
///
/// Specifies whether the rotation pivot widget is visible.
///
///
/// The type is and is
/// .
/// Set by the Navigation Library when it wants to set the visibility of the pivot used for
/// the 3D navigation. This will be dependent on the user setting for the pivot visibility in the
/// 3Dconnexion Properties configuration and whether the Navigation Library is actively navigating
/// the scene.
///
static const property_t pivot_visible_k = "pivot.visible";
///
/// Specifies the origin of the ray used for hit-testing.
///
///
/// The type is and is
/// .
/// Set by the Navigation Library. The location is relative to the world coordinate
/// system.
///
static const property_t hit_lookfrom_k = "hit.lookfrom";
///
/// Specifies the direction of the ray used for hit-testing.
///
///
/// The type is and is
/// .
/// Set by the Navigation Library. The direction is relative to the world coordinate
/// system frame.
///
static const property_t hit_direction_k = "hit.direction";
///
/// Specifies the diameter of the ray used for hit-testing.
///
///
/// The type is and is
/// .
/// Set by the Navigation Library. This is the diameter of the aperture on the frustum near
/// plane. In a perspective project the ray is a cone.
///
static const property_t hit_aperture_k = "hit.aperture";
///
/// Specifies the point of the model that is hit by the ray originating from
/// .
///
///
/// The type is and is
/// .
/// This property is queried by the navlib. The navlib will generally calculate if it is
/// possible to hit a part of the model from the and
/// properties before setting up the hit-test properties and
/// querying the property. The position is relative to the world coordinate system frame.
///
static const property_t hit_lookat_k = "hit.lookat";
///
/// Specifies whether the hit-testing is limited solely to the current selection set.
///
///
/// The type is and is
/// .
///
static const property_t hit_selectionOnly_k = "hit.selectionOnly";
///
/// Specifies the transformation matrix of the selection set.
///
///
/// The type is and is
/// .
/// This matrix specifies the object to world transformation of the selection set. That is,
/// transforming the position (0, 0, 0) by this matrix yields the position of the set in world
/// coordinates. The navlib will, generally, query this matrix at the beginning of a navigation
/// action that involves moving the selection and then set the property once per frame.
///
static const property_t selection_affine_k = "selection.affine";
///
/// Specifies whether the selection set is empty.
///
///
/// The type is and is
/// .
/// When true, nothing is selected.
///
static const property_t selection_empty_k = "selection.empty";
///
/// Specifies the bounding box of the selection set.
///
///
/// The type is and is
/// .
/// The extents of the selection are returned as a bounding box in world coordinates. The
/// Navigation Library will only access this property if the
/// property is false.
///
static const property_t selection_extents_k = "selection.extents";
///
/// Specifies the bounding box of the model.
///
///
/// The type is and is
/// .
///
static const property_t model_extents_k = "model.extents";
///
/// Specifies the position of the mouse cursor. on the projection plane in world coordinates.
///
///
/// The type is and is
/// .
/// The position of the mouse cursor is in world coordinates on the projection plane. For a
/// perspective projection the Navigation Library uses the near clipping as the projection plane.
/// In OpenGL the position would typically be retrieved using gluUnProject with winZ set to
/// 0.0.
///
static const property_t pointer_position_k = "pointer.position";
///
/// V3DK press event.
///
static const property_t events_keyPress_k = "events.keyPress";
///
/// V3DK release event.
///
static const property_t events_keyRelease_k = "events.keyRelease";
///
/// Used to query and apply settings in the 3Dconnexion Properties UI.
///
///
/// The type is and is
/// .
/// The property settings_k does not actually exist in the Navigation Library. To read or
/// write a property to the application profile, the settings_k needs to be appended with "." and
/// the name of the profile property."settings.MoveObjects" is used to read or write the
/// value of the "MoveObjects" property in the profile settings.
///
static const property_t settings_k = "settings";
///
/// Specifies the change revision of the profile settings.
///
///
/// The type is and is
/// .
/// This property is incremented when the settings changed. The value is only valid for the
/// current connection to the Navigation Library and is not persistent over multiple sessions. If
/// the client needs to know the value of a 3Dconnexion profile setting it should re-read the value
/// when settings_changed_k is changed.
///
static const property_t settings_changed_k = "settings.changed";
// Workaround for error C2099: initializer is not a constant when compiling .c
#if __cplusplus
///
/// Defines the type of a property and the access required of the client application.
///
static const propertyDescription_t propertyDescription[] = {
/* property, type, required client access */
{active_k, bool_type, eno_access},
{focus_k, bool_type, eno_access},
{motion_k, bool_type, ewrite_access},
{coordinate_system_k, matrix_type, eread_access},
{device_present_k, bool_type, eno_access},
{events_keyPress_k, long_type, ewrite_access},
{events_keyRelease_k, long_type, ewrite_access},
/* frame properties*/
{transaction_k, long_type, ewrite_access},
{frame_time_k, double_type, eread_access},
{frame_timing_source_k, long_type, eread_access},
/* view properties */
{view_affine_k, matrix_type, eread_write_access},
{view_constructionPlane_k, plane_type, eread_access},
{view_extents_k, box_type, eread_write_access},
{view_fov_k, float_type, eread_write_access},
{view_frustum_k, frustum_type, eread_access},
{view_perspective_k, bool_type, eread_access},
{view_rotatable_k, bool_type, eread_access},
{view_target_k, point_type, eread_access},
/* views properties*/
{views_front_k, matrix_type, eread_access},
/* pivot properties */
{pivot_position_k, point_type, eread_write_access},
{pivot_user_k, bool_type, eno_access},
{pivot_visible_k, bool_type, ewrite_access},
/* hit-test properties */
{hit_lookfrom_k, point_type, ewrite_access},
{hit_direction_k, vector_type, ewrite_access},
{hit_aperture_k, float_type, ewrite_access},
{hit_lookat_k, point_type, eread_access},
{hit_selectionOnly_k, bool_type, ewrite_access},
/* selection properties */
{selection_affine_k, matrix_type, eread_write_access},
{selection_empty_k, bool_type, eread_access},
{selection_extents_k, box_type, eread_access},
/* model properties */
{model_extents_k, box_type, eread_access},
/* pointer (cursor) properties */
{pointer_position_k, point_type, eread_access},
/* commands properties */
{commands_tree_k, actionnodeexptr_type, eno_access},
{commands_activeSet_k, string_type, eno_access},
{commands_activeCommand_k, string_type, ewrite_access},
/* images properties*/
{images_k, imagearray_type, eno_access},
/* settings property*/
{settings_k, string_type, eno_access},
{settings_changed_k, long_type, ewrite_access}};
#endif
/**********************************************************************************************
Functions exported from the library
**********************************************************************************************/
///
/// Creates a new navigation instance.
///
/// The client specifies the name of the instance and the properties that are available
/// for querying and updating by the navigation framework.
/// A pointer to a for the new navigation
/// instance.
/// The name of the application.
/// An array of structures containing the
/// property name, accessor and mutator functions that the client exposes to the navigation
/// instance.
/// The number of entries passed in the
/// property_accessors parameter.
/// Pointer to a . This parameter is optional
/// and may be null.
/// 0 on success or a navlib error, see and
/// .
_NAVLIB_DLLAPI long __cdecl NlCreate(nlHandle_t *pnh, const char *appname,
const accessor_t property_accessors[], size_t accessor_count,
const nlCreateOptions_t *options);
///
/// Closes an open navigation instance handle and destroys the navigation instance.
///
/// A valid of an open navigation instance.
/// 0 if the function succeeds, otherwise a navlib error, see
/// and .
_NAVLIB_DLLAPI long __cdecl NlClose(nlHandle_t nh);
///
/// Read the value of a property cached in the navlib.
///
/// The of the open navigation instance.
/// The name of the property whose value is being queried.
/// A pointer to a that contains the property value when
/// the function returns.
/// 0 if the function succeeds, otherwise a navlib error, see
/// and .
_NAVLIB_DLLAPI long __cdecl NlReadValue(nlHandle_t nh, property_t name, value_t *value);
///
/// Write the value for a property to the navlib.
///
/// The of the open navigation instance.
/// The name of the property whose value is to be written.
/// A pointer to a that contains the new property
/// value.
/// 0 if the function succeeds, otherwise a navlib error, see
/// and .
_NAVLIB_DLLAPI long __cdecl NlWriteValue(nlHandle_t nh, property_t name, const value_t *value);
///
/// Query the type of a navlib property.
///
/// The name of the property whose type is to be queried.
/// One of the values.
_NAVLIB_DLLAPI propertyType_t __cdecl NlGetType(property_t name);
_NAVLIB_END
#endif // NAVLIB_H_INCLUDED_