******************************************************************************************************** * INTRODUCTION - LibGizmo is a small, standalone library that adds a 3D matrix (4x4 floats) manipulation control called 'Gizmo'. It consists of 3 different controls: a Move, a Rotate and a Scale. It works the same way as in 3DStudio Max or Maya. It's written using C++ and the current implementation use OpenGL fixed pipeline. Integration should be easy. ******************************************************************************************************** * LICENSE Copyright (C) 2012 Cedric Guillemet Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************************************** * Contact - email/GTALK : [email protected] - Twitter : @skaven_ - web : http://www.skaven.fr ******************************************************************************************************** * USE - Set include path to inc, library path to lib - Link with LibGizmoDebug.lib for debug build, LibGizmo.lib for release - In your code : #include "iGizmo.h" - create one or more Gizmo with the functions : CreateMoveGizmo(), CreateRotateGizmo(), CreateScaleGizmo() - set a pointer to the 16 floats composing the matrix you want to edit gizmo->SetEditMatrix( objectMatrix ); - Any time the display viewport changes, call SetScreenDimensions gizmo->SetScreenDimension( screenWidth, screenHeight ); - Once a frame, call SetCameraMatrix. The matrices you send float viewMat[16]; float projMat[16]; glGetFloatv (GL_MODELVIEW_MATRIX, viewMat ); glGetFloatv (GL_PROJECTION_MATRIX, projMat ); gizmo->SetCameraMatrix( viewMat, projMat ); - Draw the gizmo gizmo->Draw(); - Change the kind of matrix manipulation (view, local, world). Example for 'WORLD' mode: gizmo->SetLocation( IGizmo::LOCATE_WORLD ); - When you receive a mouse button down, call if (gizmo->OnMouseDown( mousex, mousey )) SetCapture( hWnd ); This methods returns true if you have to capture the mouse. mousex and mousey are display viewport local coordinates. 0,0 is upper left. - for mouse move and mouse button up, call: gizmo->OnMouseMove( mousex, mousey ); gizmo->OnMouseUp( mousex, mousey ); ******************************************************************************************************** * RENDERING - The rendering code is done by OpenGL Fixed pipeline. The implementation is done in GizmoTransformRender.cpp. 6 methodes are called by all the 3 gizmo: void DrawCircle(const tvector3 &orig,float r,float g,float b,const tvector3 &vtx,const tvector3 &vty); void DrawCircleHalf(const tvector3 &orig,float r,float g,float b,const tvector3 &vtx,const tvector3 &vty,tplane &camPlan); void DrawAxis(const tvector3 &orig, const tvector3 &axis, const tvector3 &vtx,const tvector3 &vty, float fct,float fct2,const tvector4 &col); void DrawCamem(const tvector3& orig,const tvector3& vtx,const tvector3& vty,float ng); void DrawQuad(const tvector3& orig, float size, bool bSelected, const tvector3& axisU, const tvector3 &axisV); void DrawTri(const tvector3& orig, float size, bool bSelected, const tvector3& axisU, const tvector3& axisV); You can implement those methods using any API. There aren't any other call to a rendering library anywhere else. There is an old (untested) version using DX9 api. ******************************************************************************************************** * TODO - Linux/MacOSX port - Code cleanup - improve example with local/world/screen space change - DX10/11 rendering
LibGizmo is a small, standalone library that adds a 3D matrix (4x4 floats) manipulation control called 'Gizmo'
Overview
Comments
-
improvement to scaling gizmo
here's a way to not have the scaling gizmo always snap to zero scale when user start scaling non-uniformly
if (m_ScaleType == SCALE_XYZ) { int difx = x - m_LockX; float lng2 = 1.0f + ( float(difx) / 200.0f); SnapScale(lng2); scVect *=lng2; } else { int difx = x - m_LockX; int dify = y - m_LockY; // modification start //////////////////////////////////////////////////// // original code... //float len = sqrtf( (float)(difx*difx) + (float)(dify*dify) ); //float lng2 = len /100.f; // get location of object in screen space tmatrix viewproj = m_Model * m_Proj; tvector3 trans = m_pMatrix->GetTranslation(); tvector4 wpos = vector4(trans.x, trans.y, trans.z, 1.f); wpos.Transform(viewproj); tvector2 spos(wpos.x/wpos.w, -(wpos.y/wpos.w)); if(wpos.z < 0) return; tvector2 screenPos(0,0); tvector2 screenSize((float)mScreenWidth, (float)mScreenHeight); tvector2 pos(screenPos.x + (1.f + spos.x)*(screenSize.x * .5f), (screenPos.y + (1.f + spos.y)*(screenSize.y * .5f))); // compare clicked pos and object pos to choose between x or y axis // and determine which direction is positive or negative float lng2; float distx = abs(m_LockX - pos.x); float disty = abs(m_LockY - pos.y); if(distx >= disty) { if(m_LockX < pos.x) lng2 = 1.0f - ( float(difx) / 100.0f); else lng2 = 1.0f + ( float(difx) / 100.0f); } else { if(m_LockY < pos.y) lng2 = 1.0f - ( float(dify) / 100.0f); else lng2 = 1.0f + ( float(dify) / 100.0f); } // modification end ////////////////////////////////////////////////////// /* float lng2 = ( df.Dot(m_LockVertex)); char tmps[512]; sprintf(tmps, "%5.4f\n", lng2 ); OutputDebugStringA( tmps ); if (lng2 < 1.f) { if ( lng2<= 0.001f ) lng2 = 0.001f; else { //lng2+=4.f; lng2/=5.f; } } else { int a = 1; } */ SnapScale(lng2); scVect *= lng2; scVect += scVect2; }
-
after non-uniform scaling, rotation will be not work correctly
To replicate this bug:
- run the example executable
- press 3 to switch to scale mode 3 scale along the red axis to make the cube into a long box
- press 2 to switch to rotate mode
- try rotate along all axis and observe how the box will be distorted after some rotation
Please let me know if you have question about the bug. I hope it is not a difficult fix :)
-
rotation gizmo usability problem/suggestion
Not a critical bug, but this will allow the LOCATE_VIEW and LOCATE_WORLD mode for rotation gizmo a lot more useful. currently, rotation gizmo doesn't always rotate the object around the gizmo's "visual-axis"... meaning, the X-Y-Z arc rotate the object along the object's X-Y-Z axis, and after a few rotations, user will not be able to tell how the rotation axis is oriented (unless the gizmo is set to LOCAL mode). Ideally, regardless of whether the gizmo is in LOCAL, WORLD, or VIEW mode, the object should always rotate according to the visual arc visualized by the gizmo.
Thanks for a great lib, I found it very useful and I'm sure others will too. Keep up the great work!
-
after rotation, mouse detection will be incorrect in move/scale gizmo
Hi,
First of all, thanks for creating this lib. Love it, extremely useful. I hope you'll keep improving this lib :)
After trying out your lib, I've found a few bugs, but this one is the most important one. You can reproduce this bug easily by:
- run the executable demo included with the lib
- press 2 to switch to rotation gizmo
- rotate the object, (just 90 degree around Y axis should be enough)
- press 1 to switch back to move gizmo
- move the cursor over all the gizmo's arrows
- notice that the gizmo will no longer correctly detect collision between the cursor and the gizmo.
I might be wrong, but it looks like the collision detection is done as if the gizmo is set to LOCATE_LOCAL even when the gizmo is set to LOCATE_VIEW or LOCATE_WORLD
-
Binaries in the repository
Hi,
It is, perhaps, not a great idea to include large binaries and intermediate build files (such as .ipch) in the git repository. It might be worth-while deleting this repository while it doesn't contain any history and re-uploading the source excluding all binaries (use .gitignore rules).
Pre-built versions of the library and example applications can be uploaded to github as a separate downloadable packages.
Thank you, Yuriy
rlottie is a platform independent standalone c++ library for rendering vector based animations and art in realtime
rlottie rlottie is a platform independent standalone c++ library for rendering vector based animations and art in realtime. Lottie loads and renders a
A standalone Dear ImGui node graph implementation.
ImNodes A standalone Dear ImGui node graph implementation. Library provides core features needed to create a node graph, while leaving it to the user
TX Library is a tiny 2D graphics library for Win32 written in C++. This is a small sandbox for the very beginners to help them to learn basic programming principles. The documentation is currently in Russian.
TX Library (TXLib, The Dumb Artist Library) is a tiny 2D graphics library for Win32 written in C++.
A small cross-platform graphics library made in C
minigfx Small graphics library made in C Intended to be: Simple to understand Intuitive Fun to use Features Cross platform: Windows and Linux. To see
CXXGraph is a small library, header only, that manages the Graph and it's algorithms in C++.
CXXGraph is a small library, header only, that manages the Graph and it's algorithms in C++.
Im3d is a small, self-contained library for immediate mode rendering of basic primitives
Im3d is a small, self-contained library for immediate mode rendering of basic primitives (points, lines, triangles), plus an immediate mode UI which provides 3d manipulation 'gizmos' and other tools. It is platform and graphics API agnostic and designed to be compatible with VR.
Horde3D is a small 3D rendering and animation engine. It is written in an effort to create an engine being as lightweight and conceptually clean as possible.
Horde3D Horde3D is a 3D rendering engine written in C++ with an effort being as lightweight and conceptually clean as possible. Horde3D requires a ful
A small dx11 base program I use to test shaders and techniques
Dx11Base A small DirectX 11 program I use to test shaders and techniques (windows only). It is meant to be simple and straightforward. Nothing fancy t
The official Open-Asset-Importer-Library Repository. Loads 40+ 3D-file-formats into one unified and clean data structure.
Open Asset Import Library (assimp) A library to import and export various 3d-model-formats including scene-post-processing to generate missing render
Cross-platform, graphics API agnostic, "Bring Your Own Engine/Framework" style rendering library.
bgfx - Cross-platform rendering library GitHub Discussions Discord Chat What is it? Cross-platform, graphics API agnostic, "Bring Your Own Engine/Fram
Modern C++14 library for the development of real-time graphical applications
CI Community Support bs::framework is a C++ library that aims to provide a unified foundation for the development of real-time graphical applications,
A modern cross-platform low-level graphics library and rendering framework
Diligent Engine A Modern Cross-Platform Low-Level 3D Graphics Library Diligent Engine is a lightweight cross-platform graphics API abstraction library
A multi-platform library for OpenGL, OpenGL ES, Vulkan, window and input
GLFW Introduction GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan application development. It provides a simple, platf
Low Level Graphics Library (LLGL) is a thin abstraction layer for the modern graphics APIs OpenGL, Direct3D, Vulkan, and Metal
Low Level Graphics Library (LLGL) Documentation NOTE: This repository receives bug fixes only, but no major updates. Pull requests may still be accept
Antialiased 2D vector drawing library on top of OpenGL for UI and visualizations.
This project is not actively maintained. NanoVG NanoVG is small antialiased vector graphics rendering library for OpenGL. It has lean API modeled afte
An Open-Source subdivision surface library.
OpenSubdiv OpenSubdiv is a set of open source libraries that implement high performance subdivision surface (subdiv) evaluation on massively parallel
C++ (with python bindings) library for easily reading/writing/manipulating common animation particle formats such as PDB, BGEO, PTC. See the discussion group @ http://groups.google.com/group/partio-discuss
Partio - A library for particle IO and manipulation This is the initial source code release of partio a tool we used for particle reading/writing. It
ANSI C library for NURBS, B-Splines, and Bézier curves with interfaces for C++, C#, D, Go, Java, Lua, Octave, PHP, Python, R, and Ruby.
TinySpline TinySpline is a small, yet powerful library for interpolating, transforming, and querying arbitrary NURBS, B-Splines, and Bézier curves. Th
Epoxy is a library for handling OpenGL function pointer management for you
Epoxy is a library for handling OpenGL function pointer management for you. It hides the complexity of dlopen(), dlsym(), glXGetProcAddress(), eglGetP