LibGizmo is a small, standalone library that adds a 3D matrix (4x4 floats) manipulation control called 'Gizmo'

Related tags

Graphics LibGizmo
Overview
********************************************************************************************************
* 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


Issues
  • improvement to scaling gizmo

    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;
                }
    
    opened by mustcode 0
  • after non-uniform scaling, rotation will be not work correctly

    after non-uniform scaling, rotation will be not work correctly

    To replicate this bug:

    1. run the example executable
    2. press 3 to switch to scale mode 3 scale along the red axis to make the cube into a long box
    3. press 2 to switch to rotate mode
    4. 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 :)

    opened by mustcode 0
  • rotation gizmo usability problem/suggestion

    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!

    opened by mustcode 0
  • after rotation, mouse detection will be incorrect in move/scale gizmo

    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:

    1. run the executable demo included with the lib
    2. press 2 to switch to rotation gizmo
    3. rotate the object, (just 90 degree around Y axis should be enough)
    4. press 1 to switch back to move gizmo
    5. move the cursor over all the gizmo's arrows
    6. 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

    opened by mustcode 1
  • Binaries in the repository

    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

    opened by kayru 0
Owner
Cedric Guillemet
Cedric Guillemet
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

Samsung 697 Jun 28, 2022
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

Rokas Kupstys 517 Jun 9, 2022
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

Laurentino Luna 27 Jul 18, 2021
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++.

ZigRazor 143 Jun 28, 2022
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.

John Chapman 772 Jun 24, 2022
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

Volker Vogelhuber 1.2k Jun 22, 2022
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

SebH 84 Apr 5, 2022
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

Open Asset Import Library 7.9k Jun 24, 2022
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

Бранимир Караџић 11.7k Jun 22, 2022
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,

null 1.7k Jun 10, 2022
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

Diligent Graphics 2.4k Jun 29, 2022
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

GLFW 9.2k Jun 24, 2022
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

Lukas Hermanns 1.4k Jun 19, 2022
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

Mikko Mononen 4.4k Jun 19, 2022
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

Pixar Animation Studios 2.6k Jun 25, 2022
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

Walt Disney Animation Studios 400 Jun 20, 2022
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

Marcel Steinbeck 797 Jun 27, 2022
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

Eric Anholt 545 Jun 27, 2022