Merged branch 'dev_native' into lm_sla_supports_auto

Added igl library files
This commit is contained in:
Lukas Matena 2018-10-26 15:45:52 +02:00
commit 7681d00ee5
2865 changed files with 142806 additions and 22325 deletions

View file

@ -0,0 +1,691 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_MOUSECONTROLLER_H
#define IGL_OPENGL2_MOUSECONTROLLER_H
// Needs to be included before others
#include <Eigen/StdVector>
#include "RotateWidget.h"
#include "TranslateWidget.h"
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <vector>
// Class for control a skeletal FK rig with the mouse.
namespace igl
{
namespace opengl2
{
class MouseController
{
public:
typedef Eigen::VectorXi VectorXb;
// Propagate selection to descendants so that selected bones and their
// subtrees are all selected.
//
// Input:
// S #S list of whether selected
// P #S list of bone parents
// Output:
// T #S list of whether selected
static inline void propogate_to_descendants_if(
const VectorXb & S,
const Eigen::VectorXi & P,
VectorXb & T);
// Create a matrix of colors for the selection and their descendants.
//
// Inputs:
// selection #S list of whether a bone is selected
// selected_color color for selected bones
// unselected_color color for unselected bones
// Outputs:
// C #P by 4 list of colors
static inline void color_if(
const VectorXb & S,
const Eigen::Vector4f & selected_color,
const Eigen::Vector4f & unselected_color,
Eigen::MatrixXf & C);
enum WidgetMode
{
WIDGET_MODE_ROTATE = 0,
WIDGET_MODE_TRANSLATE = 1,
NUM_WIDGET_MODES = 2,
};
private:
// m_is_selecting whether currently selecting
// m_selection #m_rotations list of whether a bone is selected
// m_down_x x-coordinate of mouse location at down
// m_down_y y-coordinate 〃
// m_drag_x x-coordinate of mouse location at drag
// m_drag_y y-coordinate 〃
// m_widget rotation widget for selected bone
// m_width width of containing window
// m_height height 〃
// m_rotations list of rotations for each bone
// m_rotations_at_selection list of rotations for each bone at time of
// selection
// m_translations list of translations for each bone
// m_fk_rotations_at_selection list of rotations for each bone at time of
// selection
// m_root_enabled Whether root is enabled
bool m_is_selecting;
VectorXb m_selection;
int m_down_x,m_down_y,m_drag_x,m_drag_y;
int m_width,m_height;
igl::opengl2::RotateWidget m_widget;
igl::opengl2::TranslateWidget m_trans_widget;
Eigen::Quaterniond m_widget_rot_at_selection;
//Eigen::Vector3d m_trans_widget_trans_at_selection;
typedef std::vector<
Eigen::Quaterniond,
Eigen::aligned_allocator<Eigen::Quaterniond> > RotationList;
typedef std::vector< Eigen::Vector3d > TranslationList;
RotationList
m_rotations,
m_rotations_at_selection,
m_fk_rotations_at_selection,
m_parent_rotations_at_selection;
TranslationList
m_translations,
m_translations_at_selection,
m_fk_translations_at_selection;
bool m_root_enabled;
WidgetMode m_widget_mode;
public:
MouseController();
// Returns const reference to m_selection
inline const VectorXb & selection() const{return m_selection;};
// 〃 m_is_selecting
inline const bool & is_selecting() const{return m_is_selecting;}
inline bool is_widget_down() const{return m_widget.is_down();}
inline bool is_trans_widget_down() const{return m_trans_widget.is_down();}
// 〃 m_rotations
inline const RotationList & rotations() const{return m_rotations;}
inline const TranslationList & translations() const{return m_translations;}
// Returns non-const reference to m_root_enabled
inline bool & root_enabled(){ return m_root_enabled;}
inline void reshape(const int w, const int h);
// Process down, drag, up mouse events
//
// Inputs:
// x x-coordinate of mouse click with respect to container
// y y-coordinate 〃
// Returns true if accepted (action taken).
inline bool down(const int x, const int y);
inline bool drag(const int x, const int y);
inline bool up(const int x, const int y);
// Draw selection box and widget
inline void draw() const;
// Set `m_selection` based on the last drag selection and initialize
// widget.
//
// Inputs:
// C #C by dim list of joint positions at rest
// BE #BE by 2 list of bone indices at rest
// P #P list of bone parents
inline void set_selection_from_last_drag(
const Eigen::MatrixXd & C,
const Eigen::MatrixXi & BE,
const Eigen::VectorXi & P,
const Eigen::VectorXi & RP);
// Set from explicit selection
inline void set_selection(
const Eigen::VectorXi & S,
const Eigen::MatrixXd & C,
const Eigen::MatrixXi & BE,
const Eigen::VectorXi & P,
const Eigen::VectorXi & RP);
// Set size of skeleton
//
// Inputs:
// n number of bones
inline void set_size(const int n);
// Resets m_rotation elements to identity
inline void reset();
inline void reset_selected();
inline void reset_rotations();
inline void reset_selected_rotations();
inline void reset_translations();
inline void reset_selected_translations();
inline bool set_rotations(const RotationList & vQ);
inline bool set_translations(const TranslationList & vT);
// Sets all entries in m_selection to false
inline void clear_selection();
// Returns true iff some element in m_selection is true
inline bool any_selection() const;
inline void set_widget_mode(const WidgetMode & mode);
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
}
// Implementation
#include "../line_segment_in_rectangle.h"
#include "draw_rectangular_marquee.h"
#include "project.h"
#include "../forward_kinematics.h"
#include <iostream>
#include <algorithm>
#include <functional>
inline void igl::opengl2::MouseController::propogate_to_descendants_if(
const VectorXb & S,
const Eigen::VectorXi & P,
VectorXb & T)
{
using namespace std;
const int n = S.rows();
assert(P.rows() == n);
// dynamic programming
T = S;
vector<bool> seen(n,false);
// Recursively look up chain and see if ancestor is selected
const function<bool(int)> look_up = [&](int e) -> bool
{
if(e==-1)
{
return false;
}
if(!seen[e])
{
seen[e] = true;
T(e) |= look_up(P(e));
}
return T(e);
};
for(int e = 0;e<n;e++)
{
if(!seen[e])
{
T(e) = look_up(e);
}
}
}
inline void igl::opengl2::MouseController::color_if(
const VectorXb & S,
const Eigen::Vector4f & selected_color,
const Eigen::Vector4f & unselected_color,
Eigen::MatrixXf & C)
{
C.resize(S.rows(),4);
for(int e=0;e<S.rows();e++)
{
C.row(e) = S(e)?selected_color:unselected_color;
}
}
inline igl::opengl2::MouseController::MouseController():
m_is_selecting(false),
m_selection(),
m_down_x(-1),m_down_y(-1),m_drag_x(-1),m_drag_y(-1),
m_width(-1),m_height(-1),
m_widget(),
m_widget_rot_at_selection(),
//m_trans_widget_trans_at_selection(),
m_trans_widget(),
m_rotations(),
m_translations(),
m_rotations_at_selection(),
m_root_enabled(true),
m_widget_mode(WIDGET_MODE_ROTATE)
{
}
inline void igl::opengl2::MouseController::reshape(const int w, const int h)
{
m_width = w;
m_height = h;
}
inline bool igl::opengl2::MouseController::down(const int x, const int y)
{
using namespace std;
m_down_x = m_drag_x =x;
m_down_y = m_drag_y =y;
const bool widget_down = any_selection() &&
(
(m_widget_mode == WIDGET_MODE_ROTATE && m_widget.down(x,m_height-y)) ||
(m_widget_mode == WIDGET_MODE_TRANSLATE &&
m_trans_widget.down(x,m_height-y))
);
if(!widget_down)
{
m_is_selecting = true;
}
return m_is_selecting || widget_down;
}
inline bool igl::opengl2::MouseController::drag(const int x, const int y)
{
using namespace std;
using namespace Eigen;
m_drag_x = x;
m_drag_y = y;
if(m_is_selecting)
{
return m_is_selecting;
}else
{
switch(m_widget_mode)
{
default: // fall through
case WIDGET_MODE_ROTATE:
{
if(!m_widget.drag(x,m_height-y))
{
return false;
}
assert(any_selection());
assert(m_selection.size() == (int)m_rotations.size());
assert(m_selection.size() == (int)m_translations.size());
for(int e = 0;e<m_selection.size();e++)
{
if(m_selection(e))
{
// Let:
// w.θr = w.θ ⋅ w.θ₀*
// w.θr takes (absolute) frame of w.θ₀ to w.θ:
// w.θ = w.θr ⋅ w.θ₀
// Define:
// w.θ₀ = θfk ⋅ θx,
// the absolute rotation of the x axis to the deformed bone at
// selection. Likewise,
// w.θ = θfk' ⋅ θx,
// the current absolute rotation of the x axis to the deformed bone.
// Define recursively:
// θfk = θfk(p) ⋅ Θr,
// then because we're only changeing this relative rotation
// θfk' = θfk(p) ⋅ Θr ⋅ θr* ⋅ θr'
// θfk' = θfk ⋅ θr* ⋅ θr'
// w.θ ⋅ θx* = θfk ⋅ θr* ⋅ θr'
// θr ⋅ θfk* ⋅ w.θ ⋅ θx* = θr'
// θr ⋅ θfk* ⋅ w.θr ⋅ w.θ₀ ⋅ θx* = θr'
// θr ⋅ θfk* ⋅ w.θr ⋅ θfk ⋅θx ⋅ θx* = θr'
// θr ⋅ θfk* ⋅ w.θr ⋅ θfk = θr'
// which I guess is the right multiply change after being changed to
// the bases of θfk, the rotation of the bone relative to its rest
// frame.
//
const Quaterniond & frame = m_fk_rotations_at_selection[e];
m_rotations[e] =
m_rotations_at_selection[e] *
frame.conjugate() *
(m_widget.rot*m_widget_rot_at_selection.conjugate()) *
frame;
}
}
}
case WIDGET_MODE_TRANSLATE:
{
if(!m_trans_widget.drag(x,m_height-y))
{
return false;
}
assert(any_selection());
assert(m_selection.size() == (int)m_rotations.size());
assert(m_selection.size() == (int)m_translations.size());
for(int e = 0;e<m_selection.size();e++)
{
if(m_selection(e))
{
m_translations[e] =
m_translations_at_selection[e] +
m_parent_rotations_at_selection[e].conjugate()*
m_trans_widget.m_trans;
}
}
}
}
return true;
}
}
inline bool igl::opengl2::MouseController::up(const int x, const int y)
{
m_is_selecting = false;
m_widget.up(x,m_height-y);
m_trans_widget.up(x,m_height-y);
return false;
}
inline void igl::opengl2::MouseController::draw() const
{
if(any_selection())
{
switch(m_widget_mode)
{
default:
case WIDGET_MODE_ROTATE:
m_widget.draw();
break;
case WIDGET_MODE_TRANSLATE:
m_trans_widget.draw();
break;
}
}
if(m_is_selecting)
{
// Remember settings
GLboolean dt;
glGetBooleanv(GL_DEPTH_TEST,&dt);
int old_vp[4];
glGetIntegerv(GL_VIEWPORT,old_vp);
// True screen space
glViewport(0,0,m_width,m_height);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0,m_width,0,m_height);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glDisable(GL_DEPTH_TEST);
draw_rectangular_marquee(
m_down_x,
m_height-m_down_y,
m_drag_x,
m_height-m_drag_y);
// Restore settings
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glViewport(old_vp[0],old_vp[1],old_vp[2],old_vp[3]);
dt?glEnable(GL_DEPTH_TEST):glDisable(GL_DEPTH_TEST);
}
}
inline void igl::opengl2::MouseController::set_selection_from_last_drag(
const Eigen::MatrixXd & C,
const Eigen::MatrixXi & BE,
const Eigen::VectorXi & P,
const Eigen::VectorXi & RP)
{
using namespace Eigen;
using namespace std;
m_rotations_at_selection = m_rotations;
m_translations_at_selection = m_translations;
assert(BE.rows() == P.rows());
m_selection = VectorXb::Zero(BE.rows());
// m_rotation[e] is the relative rotation stored at bone e (as seen by the
// joint traveling with its parent)
// vQ[e] is the absolute rotation of a bone at rest to its current position:
// vQ[e] = vQ[p(e)] * m_rotation[e]
vector<Quaterniond,aligned_allocator<Quaterniond> > vQ;
vector<Vector3d> vT;
forward_kinematics(C,BE,P,m_rotations,m_translations,vQ,vT);
// Loop over deformed bones
for(int e = 0;e<BE.rows();e++)
{
Affine3d a = Affine3d::Identity();
a.translate(vT[e]);
a.rotate(vQ[e]);
Vector3d s = a * (Vector3d)C.row(BE(e,0));
Vector3d d = a * (Vector3d)C.row(BE(e,1));
Vector3d projs = project(s);
Vector3d projd = project(d);
m_selection(e) = line_segment_in_rectangle(
projs.head(2),projd.head(2),
Vector2d(m_down_x,m_height-m_down_y),
Vector2d(m_drag_x,m_height-m_drag_y));
}
return set_selection(m_selection,C,BE,P,RP);
}
inline void igl::opengl2::MouseController::set_selection(
const Eigen::VectorXi & S,
const Eigen::MatrixXd & C,
const Eigen::MatrixXi & BE,
const Eigen::VectorXi & P,
const Eigen::VectorXi & RP)
{
using namespace Eigen;
using namespace std;
vector<Quaterniond,aligned_allocator<Quaterniond> > & vQ =
m_fk_rotations_at_selection;
vector<Vector3d> & vT = m_fk_translations_at_selection;
forward_kinematics(C,BE,P,m_rotations,m_translations,vQ,vT);
m_parent_rotations_at_selection.resize(
m_rotations.size(),Quaterniond::Identity());
for(size_t r = 0;r<vQ.size();r++)
{
if(P(r)>=0)
{
m_parent_rotations_at_selection[r] = vQ[P(r)];
}
}
if(&m_selection != &S)
{
m_selection = S;
}
assert(m_selection.rows() == BE.rows());
assert(BE.rows() == P.rows());
assert(BE.rows() == RP.rows());
// Zero-out S up a path of ones from e
auto propagate = [&](const int e, const VectorXb & S, VectorXb & N)
{
if(S(e))
{
int f = e;
while(true)
{
int p = P(f);
if(p==-1||!S(p))
{
break;
}
N(f) = false;
f = p;
}
}
};
VectorXb prev_selection = m_selection;
// Combine upward, group rigid parts, repeat
while(true)
{
// Spread selection across rigid pieces
VectorXb SRP(VectorXb::Zero(RP.maxCoeff()+1));
for(int e = 0;e<BE.rows();e++)
{
SRP(RP(e)) |= m_selection(e);
}
for(int e = 0;e<BE.rows();e++)
{
m_selection(e) = SRP(RP(e));
}
// Clear selections below m_selection ancestors
VectorXb new_selection = m_selection;
for(int e = 0;e<P.rows();e++)
{
propagate(e,m_selection,new_selection);
}
m_selection = new_selection;
if(m_selection==prev_selection)
{
break;
}
prev_selection = m_selection;
}
// Now selection should contain just bone roots of m_selection subtrees
if(m_selection.array().any())
{
// Taking average
Vector3d avg_pos(0,0,0);
//m_trans_widget_trans_at_selection.setConstant(0);
m_widget_rot_at_selection.coeffs().setConstant(0);
m_widget.rot.coeffs().array().setConstant(0);
Quaterniond cur_rot(0,0,0,0);
int num_selection = 0;
// Compute average widget for selection
for(int e = 0;e<BE.rows();e++)
{
if(m_selection(e))
{
Vector3d s = C.row(BE(e,0));
Vector3d d = C.row(BE(e,1));
auto b = (d-s).transpose().eval();
{
Affine3d a = Affine3d::Identity();
a.translate(vT[e]);
a.rotate(vQ[e]);
avg_pos += a*s;
}
// Rotation of x axis to this bone
Quaterniond rot_at_bind;
rot_at_bind.setFromTwoVectors(Vector3d(1,0,0),b);
const Quaterniond abs_rot = vQ[e] * rot_at_bind;
m_widget_rot_at_selection.coeffs() += abs_rot.coeffs();
//m_trans_widget_trans_at_selection += vT[e];
num_selection++;
}
}
// Take average
avg_pos.array() /= (double)num_selection;
//m_trans_widget_trans_at_selection.array() /= (double)num_selection;
m_widget_rot_at_selection.coeffs().array() /= (double)num_selection;
m_widget_rot_at_selection.normalize();
m_widget.rot = m_widget_rot_at_selection;
m_widget.pos = avg_pos;
m_trans_widget.m_pos = avg_pos;
//m_trans_widget.m_trans = m_trans_widget_trans_at_selection;
m_trans_widget.m_trans.setConstant(0);
}
m_widget.m_is_enabled = true;
m_trans_widget.m_is_enabled = true;
for(int s = 0;s<m_selection.rows();s++)
{
// a root is selected then disable.
if(!m_root_enabled && m_selection(s) && P(s) == -1)
{
m_widget.m_is_enabled = false;
m_trans_widget.m_is_enabled = false;
break;
}
}
}
inline void igl::opengl2::MouseController::set_size(const int n)
{
using namespace Eigen;
clear_selection();
m_rotations.clear();
m_rotations.resize(n,Quaterniond::Identity());
m_translations.clear();
m_translations.resize(n,Vector3d(0,0,0));
m_selection = VectorXb::Zero(n);
}
inline void igl::opengl2::MouseController::reset()
{
reset_rotations();
reset_translations();
}
inline void igl::opengl2::MouseController::reset_selected()
{
reset_selected_rotations();
reset_selected_translations();
}
inline void igl::opengl2::MouseController::reset_rotations()
{
using namespace Eigen;
using namespace std;
fill(m_rotations.begin(),m_rotations.end(),Quaterniond::Identity());
// cop out. just clear selection
clear_selection();
}
inline void igl::opengl2::MouseController::reset_selected_rotations()
{
using namespace Eigen;
for(int e = 0;e<m_selection.size();e++)
{
if(m_selection(e))
{
m_rotations[e] = Quaterniond::Identity();
}
}
}
inline void igl::opengl2::MouseController::reset_translations()
{
using namespace Eigen;
using namespace std;
fill(m_translations.begin(),m_translations.end(),Vector3d(0,0,0));
// cop out. just clear selection
clear_selection();
}
inline void igl::opengl2::MouseController::reset_selected_translations()
{
using namespace Eigen;
for(int e = 0;e<m_selection.size();e++)
{
if(m_selection(e))
{
m_translations[e] = Vector3d(0,0,0);
}
}
}
inline bool igl::opengl2::MouseController::set_rotations(const RotationList & vQ)
{
if(vQ.size() != m_rotations.size())
{
return false;
}
assert(!any_selection());
m_rotations = vQ;
return true;
}
inline bool igl::opengl2::MouseController::set_translations(const TranslationList & vT)
{
if(vT.size() != m_translations.size())
{
return false;
}
assert(!any_selection());
m_translations = vT;
return true;
}
inline void igl::opengl2::MouseController::clear_selection()
{
m_selection.setConstant(false);
}
inline bool igl::opengl2::MouseController::any_selection() const
{
return m_selection.array().any();
}
inline void igl::opengl2::MouseController::set_widget_mode(const WidgetMode & mode)
{
switch(m_widget_mode)
{
default:
case WIDGET_MODE_TRANSLATE:
m_widget.pos = m_trans_widget.m_pos+m_trans_widget.m_trans;
break;
case WIDGET_MODE_ROTATE:
break;
}
m_widget_mode = mode;
}
#endif

View file

@ -0,0 +1,547 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_ROTATE_WIDGET_H
#define IGL_OPENGL2_ROTATE_WIDGET_H
#include "../material_colors.h"
#include <Eigen/Geometry>
#include <Eigen/Core>
#include <vector>
namespace igl
{
namespace opengl2
{
// 3D Rotate tool widget similar to Maya's. Works best if field of view angle
// is less than ~25.
class RotateWidget
{
// If a is true then use A else use desaturated A
static inline void glColor4fv(const bool a, const Eigen::Vector4f & A);
public:
inline static Eigen::Quaterniond axis_q(const int a);
inline static Eigen::Vector3d view_direction(const int x, const int y);
inline static Eigen::Vector3d view_direction(const Eigen::Vector3d & pos);
Eigen::Vector3d pos;
Eigen::Quaterniond rot,down_rot;
Eigen::Vector2d down_xy,drag_xy,down_dir;
Eigen::Vector3d udown,udrag;
double outer_radius_on_screen;
double outer_over_inner;
bool m_is_enabled;
enum DownType
{
DOWN_TYPE_X = 0,
DOWN_TYPE_Y = 1,
DOWN_TYPE_Z = 2,
DOWN_TYPE_OUTLINE = 3,
DOWN_TYPE_TRACKBALL = 4,
DOWN_TYPE_NONE = 5,
NUM_DOWN_TYPES = 6
} down_type, selected_type;
inline RotateWidget();
// Vector from origin to mouse click "Unprojected" onto plane with depth of
// origin and scale to so that outer radius is 1
//
// Inputs:
// x mouse x position
// y mouse y position
// Returns vector
inline Eigen::Vector3d unproject_onto(const int x, const int y) const;
// Shoot ray from mouse click to sphere
//
// Inputs:
// x mouse x position
// y mouse y position
// Outputs:
// hit position of hit
// Returns true only if there was a hit
inline bool intersect(
const int x,
const int y,
Eigen::Vector3d & hit) const;
inline double unprojected_inner_radius() const;
inline bool down(const int x, const int y);
inline bool drag(const int x, const int y);
inline bool up(const int x, const int y);
inline bool is_down() const;
inline void draw() const;
inline void draw_guide() const;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
}
}
// Implementation
#include "../PI.h"
#include "../EPS.h"
#include "../ray_sphere_intersect.h"
#include "../mat_to_quat.h"
#include "../trackball.h"
#include "gl.h"
#include "project.h"
#include "unproject.h"
#include <iostream>
#include <cassert>
inline void igl::opengl2::RotateWidget::glColor4fv(
const bool a,
const Eigen::Vector4f & A)
{
if(a)
{
::glColor4fv(A.data());
}else
{
Eigen::Vector4f B;
const double f = 0.95; // desaturate by 95%
const double L = 0.3*A(0) + 0.6*A(1) + 0.1*A(2);
B.head(3) = A.head(3).array() + f*(L-A.head(3).array());
B(3) = A(3);
::glColor4fv(B.data());
}
}
inline Eigen::Quaterniond igl::opengl2::RotateWidget::axis_q(const int a)
{
assert(a<3 && a>=0);
const Eigen::Quaterniond axes[3] = {
Eigen::Quaterniond(Eigen::AngleAxisd(igl::PI*0.5,Eigen::Vector3d(0,1,0))),
Eigen::Quaterniond(Eigen::AngleAxisd(igl::PI*0.5,Eigen::Vector3d(1,0,0))),
Eigen::Quaterniond::Identity()};
return axes[a];
}
inline Eigen::Vector3d igl::opengl2::RotateWidget::view_direction(const int x, const int y)
{
using namespace Eigen;
const Vector3d win_s(x,y,0), win_d(x,y,1);
const Vector3d s = unproject(win_s);
const Vector3d d = unproject(win_d);
return d-s;
}
inline Eigen::Vector3d igl::opengl2::RotateWidget::view_direction(const Eigen::Vector3d & pos)
{
using namespace Eigen;
const Vector3d ppos = project(pos);
return view_direction(ppos(0),ppos(1));
}
inline igl::opengl2::RotateWidget::RotateWidget():
pos(0,0,0),
rot(Eigen::Quaterniond::Identity()),
down_rot(rot),
down_xy(-1,-1),drag_xy(-1,-1),
outer_radius_on_screen(91.),
outer_over_inner(1.13684210526),
m_is_enabled(true),
down_type(DOWN_TYPE_NONE),
selected_type(DOWN_TYPE_NONE)
{
}
inline Eigen::Vector3d igl::opengl2::RotateWidget::unproject_onto(
const int x,
const int y) const
{
using namespace Eigen;
// KNOWN BUG: This projects to same depths as pos. I think what we actually
// want is The intersection with the plane perpendicular to the view
// direction at pos. If the field of view angle is small then this difference
// is negligible.
//const Vector3d ppos = project(pos);
//const Vector3d uxy = unproject( Vector3d(x,y,ppos(2)));
// http://en.wikipedia.org/wiki/Line-plane_intersection
//
// Hrrmmm. There's still something wrong here if the ball's in the corner of
// the screen. Am I somehow not accounting for perspective correctly?
//
// Q: What about just projecting the circle's equation and solving for the
// distance?
const Vector3d l0 = unproject(Vector3d(x,y,0));
const Vector3d l = unproject(Vector3d(x,y,1))-l0;
const Vector3d n = view_direction(pos);
const double t = (pos-l0).dot(n)/l.dot(n);
const Vector3d uxy = l0+t*l;
return (uxy-pos)/unprojected_inner_radius()*outer_over_inner*outer_over_inner;
}
inline bool igl::opengl2::RotateWidget::intersect(
const int x,
const int y,
Eigen::Vector3d & hit) const
{
using namespace Eigen;
Vector3d view = view_direction(x,y);
const Vector3d ppos = project(pos);
Vector3d uxy = unproject(Vector3d(x,y,ppos(2)));
double t0,t1;
if(!ray_sphere_intersect(uxy,view,pos,unprojected_inner_radius(),t0,t1))
{
return false;
}
hit = uxy+t0*view;
return true;
}
inline double igl::opengl2::RotateWidget::unprojected_inner_radius() const
{
using namespace Eigen;
Vector3d off,ppos,ppos_off,pos_off;
project(pos,ppos);
ppos_off = ppos;
ppos_off(0) += outer_radius_on_screen/outer_over_inner;
unproject(ppos_off,pos_off);
return (pos-pos_off).norm();
}
inline bool igl::opengl2::RotateWidget::down(const int x, const int y)
{
using namespace Eigen;
using namespace std;
if(!m_is_enabled)
{
return false;
}
down_type = DOWN_TYPE_NONE;
selected_type = DOWN_TYPE_NONE;
down_xy = Vector2d(x,y);
drag_xy = down_xy;
down_rot = rot;
Vector3d ppos = project(pos);
const double r = (ppos.head(2) - down_xy).norm();
const double thresh = 3;
if(fabs(r - outer_radius_on_screen)<thresh)
{
udown = unproject_onto(x,y);
udrag = udown;
down_type = DOWN_TYPE_OUTLINE;
selected_type = DOWN_TYPE_OUTLINE;
// project mouse to same depth as pos
return true;
}else if(r < outer_radius_on_screen/outer_over_inner+thresh*0.5)
{
Vector3d hit;
const bool is_hit = intersect(down_xy(0),down_xy(1),hit);
if(!is_hit)
{
//cout<<"~~~!is_hit"<<endl;
}
auto on_meridian = [&](
const Vector3d & hit,
const Quaterniond & rot,
const Quaterniond & m,
Vector3d & pl_hit) -> bool
{
// project onto rotate plane
pl_hit = hit-pos;
pl_hit = (m.conjugate()*rot.conjugate()*pl_hit).eval();
pl_hit(2) = 0;
pl_hit = (rot*m*pl_hit).eval();
pl_hit.normalize();
pl_hit *= unprojected_inner_radius();
pl_hit += pos;
return (project(pl_hit).head(2)-project(hit).head(2)).norm()<2*thresh;
};
udown = (hit-pos).normalized()/outer_radius_on_screen;
udrag = udown;
for(int a = 0;a<3;a++)
{
Vector3d pl_hit;
if(on_meridian(hit,rot,Quaterniond(axis_q(a)),pl_hit))
{
udown = (pl_hit-pos).normalized()/outer_radius_on_screen;
udrag = udown;
down_type = DownType(DOWN_TYPE_X+a);
selected_type = down_type;
{
Vector3d dir3 = axis_q(a).conjugate()*down_rot.conjugate()*(hit-pos);
dir3 = AngleAxisd(-PI*0.5,Vector3d(0,0,1))*dir3;
dir3 = (rot*axis_q(a)*dir3).eval();
down_dir = (project((hit+dir3).eval())-project(hit)).head(2);
down_dir.normalize();
//// flip y because y coordinate is going to be given backwards in
//// drag()
//down_dir(1) *= -1;
}
return true;
}
}
//assert(is_hit);
down_type = DOWN_TYPE_TRACKBALL;
selected_type = DOWN_TYPE_TRACKBALL;
return true;
}else
{
return false;
}
}
inline bool igl::opengl2::RotateWidget::drag(const int x, const int y)
{
using namespace std;
using namespace Eigen;
if(!m_is_enabled)
{
return false;
}
drag_xy = Vector2d(x,y);
switch(down_type)
{
case DOWN_TYPE_NONE:
return false;
default:
{
const Quaterniond & q = axis_q(down_type-DOWN_TYPE_X);
const double dtheta = -(drag_xy - down_xy).dot(down_dir)/
outer_radius_on_screen/outer_over_inner*PI/2.;
Quaterniond dq(AngleAxisd(dtheta,down_rot*q*Vector3d(0,0,1)));
rot = dq * down_rot;
udrag = dq * udown;
return true;
}
case DOWN_TYPE_OUTLINE:
{
Vector3d ppos = project(pos);
// project mouse to same depth as pos
udrag = unproject_onto(x,y);
const Vector2d A = down_xy - ppos.head(2);
const Vector2d B = drag_xy - ppos.head(2);
const double dtheta = atan2(A(0)*B(1)-A(1)*B(0),A(0)*B(0)+A(1)*B(1));
Vector3d n = view_direction(pos).normalized();
Quaterniond dq(AngleAxisd(dtheta,-n));
//Vector3d n = udrag.cross(udown).normalized();
//Quaterniond dq(AngleAxisd(fabs(dtheta),-n));
rot = dq * down_rot;
}
return true;
case DOWN_TYPE_TRACKBALL:
{
Vector3d ppos = project(pos);
const double r = (double)outer_radius_on_screen/outer_over_inner*2.0;
//const int h = w;
Vector4i vp;
glGetIntegerv(GL_VIEWPORT,vp.data());
const int h = vp(3);
Quaterniond dq;
trackball(
r,r,
1,
Quaterniond::Identity(),
double( down_xy(0)-ppos(0) )+r/2.,
double((h-down_xy(1))-(h-ppos(1)))+r/2.,
double( x-ppos(0) )+r/2.,
double( (h-y)-(h-ppos(1)))+r/2.,
dq);
// We've computed change in rotation according to this view:
// R = mv * r, R' = rot * (mv * r)
// But we only want new value for r:
// R' = mv * r'
// mv * r' = rot * (mv * r)
// r' = mv* * rot * mv * r
Matrix4d mv;
glGetDoublev(GL_MODELVIEW_MATRIX,mv.data());
Quaterniond scene_rot;
// Convert modelview matrix to quaternion
mat4_to_quat(mv.data(),scene_rot.coeffs().data());
scene_rot.normalize();
rot = scene_rot.conjugate() * dq * scene_rot * down_rot;
}
return true;
}
}
inline bool igl::opengl2::RotateWidget::up(const int /*x*/, const int /*y*/)
{
// even if disabled process up
down_type = DOWN_TYPE_NONE;
return false;
}
inline bool igl::opengl2::RotateWidget::is_down() const
{
return down_type != DOWN_TYPE_NONE;
}
inline void igl::opengl2::RotateWidget::draw() const
{
using namespace Eigen;
using namespace std;
glPushAttrib(GL_ENABLE_BIT | GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT | GL_LINE_BIT);
glDisable(GL_CLIP_PLANE0);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glLineWidth(2.0);
double r = unprojected_inner_radius();
Vector3d view = view_direction(pos).normalized();
auto draw_circle = [&](const bool cull)
{
Vector3d view = view_direction(pos).normalized();
glBegin(GL_LINES);
const double th_step = (2.0*igl::PI/100.0);
for(double th = 0;th<2.0*igl::PI+th_step;th+=th_step)
{
Vector3d a(cos(th),sin(th),0.0);
Vector3d b(cos(th+th_step),sin(th+th_step),0.0);
if(!cull || (0.5*(a+b)).dot(view)<FLOAT_EPS)
{
glVertex3dv(a.data());
glVertex3dv(b.data());
}
}
glEnd();
};
glPushMatrix();
glTranslated(pos(0),pos(1),pos(2));
glScaled(r,r,r);
// Draw outlines
{
glPushMatrix();
glColor4fv(m_is_enabled,MAYA_GREY);
Quaterniond q;
q.setFromTwoVectors(Vector3d(0,0,1),view);
glMultMatrixd(Affine3d(q).matrix().data());
draw_circle(false);
glScaled(outer_over_inner,outer_over_inner,outer_over_inner);
if(selected_type == DOWN_TYPE_OUTLINE)
{
glColor4fv(m_is_enabled,MAYA_YELLOW);
}else
{
glColor4fv(m_is_enabled,MAYA_CYAN);
}
draw_circle(false);
glPopMatrix();
}
// Draw quartiles
{
glPushMatrix();
glMultMatrixd(Affine3d(rot).matrix().data());
if(selected_type == DOWN_TYPE_Z)
{
glColor4fv(m_is_enabled,MAYA_YELLOW);
}else
{
glColor4fv(m_is_enabled,MAYA_BLUE);
}
draw_circle(true);
if(selected_type == DOWN_TYPE_Y)
{
glColor4fv(m_is_enabled,MAYA_YELLOW);
}else
{
glColor4fv(m_is_enabled,MAYA_GREEN);
}
glRotated(90.0,1.0,0.0,0.0);
draw_circle(true);
if(selected_type == DOWN_TYPE_X)
{
glColor4fv(m_is_enabled,MAYA_YELLOW);
}else
{
glColor4fv(m_is_enabled,MAYA_RED);
}
glRotated(90.0,0.0,1.0,0.0);
draw_circle(true);
glPopMatrix();
}
glColor4fv(m_is_enabled,MAYA_GREY);
draw_guide();
glPopMatrix();
glPopAttrib();
};
inline void igl::opengl2::RotateWidget::draw_guide() const
{
using namespace Eigen;
using namespace std;
glPushAttrib(
GL_DEPTH_BUFFER_BIT |
GL_ENABLE_BIT |
GL_POLYGON_BIT |
GL_POINT_BIT |
GL_TRANSFORM_BIT |
GL_STENCIL_BUFFER_BIT |
GL_LIGHTING_BIT);
// http://www.codeproject.com/Articles/23444/A-Simple-OpenGL-Stipple-Polygon-Example-EP_OpenGL_
const GLubyte halftone[] = {
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55};
switch(down_type)
{
case DOWN_TYPE_NONE:
case DOWN_TYPE_TRACKBALL:
goto finish;
case DOWN_TYPE_OUTLINE:
glScaled(outer_over_inner,outer_over_inner,outer_over_inner);
break;
default:
break;
}
{
const Vector3d nudown(udown.normalized()),
nudrag(udrag.normalized());
glPushMatrix();
glDisable(GL_CULL_FACE);
glDisable(GL_POINT_SMOOTH);
glPointSize(5.);
glBegin(GL_POINTS);
glVertex3dv(nudown.data());
glVertex3d(0,0,0);
glVertex3dv(nudrag.data());
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3dv(nudown.data());
glVertex3d(0,0,0);
glVertex3dv(nudrag.data());
glEnd();
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(halftone);
glBegin(GL_TRIANGLE_FAN);
glVertex3d(0,0,0);
Quaterniond dq = rot * down_rot.conjugate();
//dq.setFromTwoVectors(nudown,nudrag);
for(double t = 0;t<1;t+=0.1)
{
const Vector3d p = Quaterniond::Identity().slerp(t,dq) * nudown;
glVertex3dv(p.data());
}
glVertex3dv(nudrag.data());
glEnd();
glPopMatrix();
}
finish:
glPopAttrib();
}
#endif

View file

@ -0,0 +1,211 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2016 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_TRANSLATE_WIDGET_H
#define IGL_OPENGL2_TRANSLATE_WIDGET_H
#include "../material_colors.h"
#include <Eigen/Geometry>
#include <Eigen/Core>
#include <vector>
namespace igl
{
namespace opengl2
{
class TranslateWidget
{
public:
// m_pos position of center
// m_trans translation vector
// m_down_xy mouse position on down
// m_drag_xy mouse position on drag
// m_is_enabled whether enabled
Eigen::Vector3d m_pos,m_trans,m_down_trans;
Eigen::Vector2d m_down_xy, m_drag_xy;
bool m_is_enabled;
double m_len;
enum DownType
{
DOWN_TYPE_X = 0,
DOWN_TYPE_Y = 1,
DOWN_TYPE_Z = 2,
DOWN_TYPE_CENTER = 3,
DOWN_TYPE_NONE = 4,
NUM_DOWN_TYPES = 5
} m_down_type, m_selected_type;
inline TranslateWidget(const Eigen::Vector3d & pos = Eigen::Vector3d(0,0,0));
inline bool down(const int x, const int y);
inline bool drag(const int x, const int y);
inline bool up(const int x, const int y);
inline bool is_down() const;
inline void draw() const;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
};
}
}
// Implementation
#include "project.h"
#include "unproject.h"
inline igl::opengl2::TranslateWidget::TranslateWidget(
const Eigen::Vector3d & pos):
m_pos(pos),
m_trans(0,0,0),
m_down_xy(-1,-1),
m_drag_xy(-1,-1),
m_is_enabled(true),
m_len(50),
m_down_type(DOWN_TYPE_NONE),
m_selected_type(DOWN_TYPE_NONE)
{
}
inline bool igl::opengl2::TranslateWidget::down(const int x, const int y)
{
using namespace Eigen;
using namespace std;
if(!m_is_enabled)
{
return false;
}
m_down_trans = m_trans;
m_down_xy = Vector2d(x,y);
m_drag_xy = m_down_xy;
m_down_type = DOWN_TYPE_NONE;
m_selected_type = DOWN_TYPE_NONE;
Vector3d ppos = project((m_pos+m_trans).eval());
const double r = (ppos.head(2) - m_down_xy).norm();
const double center_thresh = 10;
if(r < center_thresh)
{
m_down_type = DOWN_TYPE_CENTER;
m_selected_type = m_down_type;
return true;
}else if(r < m_len)
{
// Might be hit on lines
}
return false;
}
inline bool igl::opengl2::TranslateWidget::drag(const int x, const int y)
{
using namespace std;
using namespace Eigen;
if(!m_is_enabled)
{
return false;
}
m_drag_xy = Vector2d(x,y);
switch(m_down_type)
{
case DOWN_TYPE_NONE:
return false;
default:
{
Vector3d ppos = project((m_pos+m_trans).eval());
Vector3d drag3(m_drag_xy(0),m_drag_xy(1),ppos(2));
Vector3d down3(m_down_xy(0),m_down_xy(1),ppos(2));
m_trans = m_down_trans + unproject(drag3)-unproject(down3);
return true;
}
}
}
inline bool igl::opengl2::TranslateWidget::up(const int /*x*/, const int /*y*/)
{
// even if disabled process up
m_down_type = DOWN_TYPE_NONE;
return false;
}
inline bool igl::opengl2::TranslateWidget::is_down() const
{
return m_down_type != DOWN_TYPE_NONE;
}
inline void igl::opengl2::TranslateWidget::draw() const
{
using namespace Eigen;
using namespace std;
glPushAttrib(GL_ENABLE_BIT | GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT | GL_LINE_BIT);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glLineWidth(2.0);
auto draw_axes = [&]()
{
glBegin(GL_LINES);
glColor3f(1,0,0);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glColor3f(0,1,0);
glVertex3f(0,0,0);
glVertex3f(0,1,0);
glColor3f(0,0,1);
glVertex3f(0,0,0);
glVertex3f(0,0,1);
glEnd();
};
auto draw_cube = []
{
glBegin(GL_LINES);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f);
glEnd();
};
glPushMatrix();
glTranslated( m_pos(0)+m_trans(0), m_pos(1)+m_trans(1), m_pos(2)+m_trans(2));
{
Vector3d off,ppos,ppos_off,pos_off;
project((m_pos+m_trans).eval(),ppos);
ppos_off = ppos;
ppos_off(0) += m_len;
unproject(ppos_off,pos_off);
const double r = (m_pos+m_trans-pos_off).norm();
glScaled(r,r,r);
}
draw_axes();
glScaled(0.05,0.05,0.05);
if(m_selected_type == DOWN_TYPE_CENTER)
{
glColor3fv(MAYA_YELLOW.data());
}else
{
glColor3fv(MAYA_GREY.data());
}
draw_cube();
glPopMatrix();
glPopAttrib();
}
#endif

View file

@ -0,0 +1,283 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "draw_beach_ball.h"
#include "gl.h"
// I'm not sure why windows would need it this way:
// http://lists.cairographics.org/archives/cairo/2008-January/012722.html
#ifdef _MSC_VER
#define SAFE_INLINE __inline
#else
#define SAFE_INLINE inline
#endif
#include <vector>
#include <cmath>
#include <iostream>
// Most of this implementation comes from the AntTweakBar source code:
// TwMgr.cpp, TwMgr.h, TwColor.h, TwColor.cpp, TwOpenGL.h and TwOpenGL.cpp
////////////////////////////////////////////////////////////////////////////
// Begin Copied Straight from AntTweakBar
////////////////////////////////////////////////////////////////////////////
enum EArrowParts { ARROW_CONE, ARROW_CONE_CAP, ARROW_CYL, ARROW_CYL_CAP };
template <typename T> SAFE_INLINE const T& TClamp(const T& X, const T& Limit1, const T& Limit2)
{
if( Limit1<Limit2 )
return (X<=Limit1) ? Limit1 : ( (X>=Limit2) ? Limit2 : X );
else
return (X<=Limit2) ? Limit2 : ( (X>=Limit1) ? Limit1 : X );
}
typedef unsigned int color32;
static SAFE_INLINE color32 Color32FromARGBi(int A, int R, int G, int B)
{
return (((color32)TClamp(A, 0, 255))<<24) | (((color32)TClamp(R, 0, 255))<<16) | (((color32)TClamp(G, 0, 255))<<8) | ((color32)TClamp(B, 0, 255));
}
static SAFE_INLINE color32 Color32FromARGBf(float A, float R, float G, float B)
{
return (((color32)TClamp(A*256.0f, 0.0f, 255.0f))<<24) | (((color32)TClamp(R*256.0f, 0.0f, 255.0f))<<16) | (((color32)TClamp(G*256.0f, 0.0f, 255.0f))<<8) | ((color32)TClamp(B*256.0f, 0.0f, 255.0f));
}
static SAFE_INLINE void Color32ToARGBi(color32 Color, int *A, int *R, int *G, int *B)
{
if(A) *A = (Color>>24)&0xff;
if(R) *R = (Color>>16)&0xff;
if(G) *G = (Color>>8)&0xff;
if(B) *B = Color&0xff;
}
static SAFE_INLINE void Color32ToARGBf(color32 Color, float *A, float *R, float *G, float *B)
{
if(A) *A = (1.0f/255.0f)*float((Color>>24)&0xff);
if(R) *R = (1.0f/255.0f)*float((Color>>16)&0xff);
if(G) *G = (1.0f/255.0f)*float((Color>>8)&0xff);
if(B) *B = (1.0f/255.0f)*float(Color&0xff);
}
static color32 ColorBlend(color32 Color1, color32 Color2, float S)
{
float a1, r1, g1, b1, a2, r2, g2, b2;
Color32ToARGBf(Color1, &a1, &r1, &g1, &b1);
Color32ToARGBf(Color2, &a2, &r2, &g2, &b2);
float t = 1.0f-S;
return Color32FromARGBf(t*a1+S*a2, t*r1+S*r2, t*g1+S*g2, t*b1+S*b2);
}
static std::vector<float> s_SphTri;
static std::vector<color32> s_SphCol;
static void CreateSphere()
{
const int SUBDIV = 7;
s_SphTri.clear();
s_SphCol.clear();
const float A[8*3] = { 1,0,0, 0,0,-1, -1,0,0, 0,0,1, 0,0,1, 1,0,0, 0,0,-1, -1,0,0 };
const float B[8*3] = { 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,-1,0, 0,-1,0, 0,-1,0, 0,-1,0 };
const float C[8*3] = { 0,0,1, 1,0,0, 0,0,-1, -1,0,0, 1,0,0, 0,0,-1, -1,0,0, 0,0,1 };
//const color32 COL_A[8] = { 0xffff8080, 0xff000080, 0xff800000, 0xff8080ff, 0xff8080ff, 0xffff8080, 0xff000080, 0xff800000 };
//const color32 COL_B[8] = { 0xff80ff80, 0xff80ff80, 0xff80ff80, 0xff80ff80, 0xff008000, 0xff008000, 0xff008000, 0xff008000 };
//const color32 COL_C[8] = { 0xff8080ff, 0xffff8080, 0xff000080, 0xff800000, 0xffff8080, 0xff000080, 0xff800000, 0xff8080ff };
const color32 COL_A[8] = { 0xffffffff, 0xffffff40, 0xff40ff40, 0xff40ffff, 0xffff40ff, 0xffff4040, 0xff404040, 0xff4040ff };
const color32 COL_B[8] = { 0xffffffff, 0xffffff40, 0xff40ff40, 0xff40ffff, 0xffff40ff, 0xffff4040, 0xff404040, 0xff4040ff };
const color32 COL_C[8] = { 0xffffffff, 0xffffff40, 0xff40ff40, 0xff40ffff, 0xffff40ff, 0xffff4040, 0xff404040, 0xff4040ff };
int i, j, k, l;
float xa, ya, za, xb, yb, zb, xc, yc, zc, x, y, z, norm, u[3], v[3];
color32 col;
for( i=0; i<8; ++i )
{
xa = A[3*i+0]; ya = A[3*i+1]; za = A[3*i+2];
xb = B[3*i+0]; yb = B[3*i+1]; zb = B[3*i+2];
xc = C[3*i+0]; yc = C[3*i+1]; zc = C[3*i+2];
for( j=0; j<=SUBDIV; ++j )
for( k=0; k<=2*(SUBDIV-j); ++k )
{
if( k%2==0 )
{
u[0] = ((float)j)/(SUBDIV+1);
v[0] = ((float)(k/2))/(SUBDIV+1);
u[1] = ((float)(j+1))/(SUBDIV+1);
v[1] = ((float)(k/2))/(SUBDIV+1);
u[2] = ((float)j)/(SUBDIV+1);
v[2] = ((float)(k/2+1))/(SUBDIV+1);
}
else
{
u[0] = ((float)j)/(SUBDIV+1);
v[0] = ((float)(k/2+1))/(SUBDIV+1);
u[1] = ((float)(j+1))/(SUBDIV+1);
v[1] = ((float)(k/2))/(SUBDIV+1);
u[2] = ((float)(j+1))/(SUBDIV+1);
v[2] = ((float)(k/2+1))/(SUBDIV+1);
}
for( l=0; l<3; ++l )
{
x = (1.0f-u[l]-v[l])*xa + u[l]*xb + v[l]*xc;
y = (1.0f-u[l]-v[l])*ya + u[l]*yb + v[l]*yc;
z = (1.0f-u[l]-v[l])*za + u[l]*zb + v[l]*zc;
norm = sqrtf(x*x+y*y+z*z);
x /= norm; y /= norm; z /= norm;
s_SphTri.push_back(x); s_SphTri.push_back(y); s_SphTri.push_back(z);
static const float FLOAT_EPS = 1.0e-7f;
if( u[l]+v[l]>FLOAT_EPS )
col = ColorBlend(COL_A[i], ColorBlend(COL_B[i], COL_C[i], v[l]/(u[l]+v[l])), u[l]+v[l]);
else
col = COL_A[i];
//if( (j==0 && k==0) || (j==0 && k==2*SUBDIV) || (j==SUBDIV && k==0) )
// col = 0xffff0000;
s_SphCol.push_back(col);
}
}
}
//s_SphTriProj.clear();
//s_SphTriProj.resize(2*s_SphCol.size(), 0);
//s_SphColLight.clear();
//s_SphColLight.resize(s_SphCol.size(), 0);
}
static std::vector<float> s_ArrowTri[4];
static std::vector<float> s_ArrowNorm[4];
static void CreateArrow()
{
const int SUBDIV = 15;
const float CYL_RADIUS = 0.08f;
const float CONE_RADIUS = 0.16f;
const float CONE_LENGTH = 0.25f;
const float ARROW_BGN = -1.1f;
const float ARROW_END = 1.15f;
int i;
for(i=0; i<4; ++i)
{
s_ArrowTri[i].clear();
s_ArrowNorm[i].clear();
}
float x0, x1, y0, y1, z0, z1, a0, a1, nx, nn;
for(i=0; i<SUBDIV; ++i)
{
static const float FLOAT_PI = 3.14159265358979323846f;
a0 = 2.0f*FLOAT_PI*(float(i))/SUBDIV;
a1 = 2.0f*FLOAT_PI*(float(i+1))/SUBDIV;
x0 = ARROW_BGN;
x1 = ARROW_END-CONE_LENGTH;
y0 = cosf(a0);
z0 = sinf(a0);
y1 = cosf(a1);
z1 = sinf(a1);
s_ArrowTri[ARROW_CYL].push_back(x1); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*y0); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*z0);
s_ArrowTri[ARROW_CYL].push_back(x0); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*y0); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*z0);
s_ArrowTri[ARROW_CYL].push_back(x0); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*y1); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*z1);
s_ArrowTri[ARROW_CYL].push_back(x1); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*y0); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*z0);
s_ArrowTri[ARROW_CYL].push_back(x0); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*y1); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*z1);
s_ArrowTri[ARROW_CYL].push_back(x1); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*y1); s_ArrowTri[ARROW_CYL].push_back(CYL_RADIUS*z1);
s_ArrowNorm[ARROW_CYL].push_back(0); s_ArrowNorm[ARROW_CYL].push_back(y0); s_ArrowNorm[ARROW_CYL].push_back(z0);
s_ArrowNorm[ARROW_CYL].push_back(0); s_ArrowNorm[ARROW_CYL].push_back(y0); s_ArrowNorm[ARROW_CYL].push_back(z0);
s_ArrowNorm[ARROW_CYL].push_back(0); s_ArrowNorm[ARROW_CYL].push_back(y1); s_ArrowNorm[ARROW_CYL].push_back(z1);
s_ArrowNorm[ARROW_CYL].push_back(0); s_ArrowNorm[ARROW_CYL].push_back(y0); s_ArrowNorm[ARROW_CYL].push_back(z0);
s_ArrowNorm[ARROW_CYL].push_back(0); s_ArrowNorm[ARROW_CYL].push_back(y1); s_ArrowNorm[ARROW_CYL].push_back(z1);
s_ArrowNorm[ARROW_CYL].push_back(0); s_ArrowNorm[ARROW_CYL].push_back(y1); s_ArrowNorm[ARROW_CYL].push_back(z1);
s_ArrowTri[ARROW_CYL_CAP].push_back(x0); s_ArrowTri[ARROW_CYL_CAP].push_back(0); s_ArrowTri[ARROW_CYL_CAP].push_back(0);
s_ArrowTri[ARROW_CYL_CAP].push_back(x0); s_ArrowTri[ARROW_CYL_CAP].push_back(CYL_RADIUS*y1); s_ArrowTri[ARROW_CYL_CAP].push_back(CYL_RADIUS*z1);
s_ArrowTri[ARROW_CYL_CAP].push_back(x0); s_ArrowTri[ARROW_CYL_CAP].push_back(CYL_RADIUS*y0); s_ArrowTri[ARROW_CYL_CAP].push_back(CYL_RADIUS*z0);
s_ArrowNorm[ARROW_CYL_CAP].push_back(-1); s_ArrowNorm[ARROW_CYL_CAP].push_back(0); s_ArrowNorm[ARROW_CYL_CAP].push_back(0);
s_ArrowNorm[ARROW_CYL_CAP].push_back(-1); s_ArrowNorm[ARROW_CYL_CAP].push_back(0); s_ArrowNorm[ARROW_CYL_CAP].push_back(0);
s_ArrowNorm[ARROW_CYL_CAP].push_back(-1); s_ArrowNorm[ARROW_CYL_CAP].push_back(0); s_ArrowNorm[ARROW_CYL_CAP].push_back(0);
x0 = ARROW_END-CONE_LENGTH;
x1 = ARROW_END;
nx = CONE_RADIUS/(x1-x0);
nn = 1.0f/sqrtf(nx*nx+1);
s_ArrowTri[ARROW_CONE].push_back(x1); s_ArrowTri[ARROW_CONE].push_back(0); s_ArrowTri[ARROW_CONE].push_back(0);
s_ArrowTri[ARROW_CONE].push_back(x0); s_ArrowTri[ARROW_CONE].push_back(CONE_RADIUS*y0); s_ArrowTri[ARROW_CONE].push_back(CONE_RADIUS*z0);
s_ArrowTri[ARROW_CONE].push_back(x0); s_ArrowTri[ARROW_CONE].push_back(CONE_RADIUS*y1); s_ArrowTri[ARROW_CONE].push_back(CONE_RADIUS*z1);
s_ArrowTri[ARROW_CONE].push_back(x1); s_ArrowTri[ARROW_CONE].push_back(0); s_ArrowTri[ARROW_CONE].push_back(0);
s_ArrowTri[ARROW_CONE].push_back(x0); s_ArrowTri[ARROW_CONE].push_back(CONE_RADIUS*y1); s_ArrowTri[ARROW_CONE].push_back(CONE_RADIUS*z1);
s_ArrowTri[ARROW_CONE].push_back(x1); s_ArrowTri[ARROW_CONE].push_back(0); s_ArrowTri[ARROW_CONE].push_back(0);
s_ArrowNorm[ARROW_CONE].push_back(nn*nx); s_ArrowNorm[ARROW_CONE].push_back(nn*y0); s_ArrowNorm[ARROW_CONE].push_back(nn*z0);
s_ArrowNorm[ARROW_CONE].push_back(nn*nx); s_ArrowNorm[ARROW_CONE].push_back(nn*y0); s_ArrowNorm[ARROW_CONE].push_back(nn*z0);
s_ArrowNorm[ARROW_CONE].push_back(nn*nx); s_ArrowNorm[ARROW_CONE].push_back(nn*y1); s_ArrowNorm[ARROW_CONE].push_back(nn*z1);
s_ArrowNorm[ARROW_CONE].push_back(nn*nx); s_ArrowNorm[ARROW_CONE].push_back(nn*y0); s_ArrowNorm[ARROW_CONE].push_back(nn*z0);
s_ArrowNorm[ARROW_CONE].push_back(nn*nx); s_ArrowNorm[ARROW_CONE].push_back(nn*y1); s_ArrowNorm[ARROW_CONE].push_back(nn*z1);
s_ArrowNorm[ARROW_CONE].push_back(nn*nx); s_ArrowNorm[ARROW_CONE].push_back(nn*y1); s_ArrowNorm[ARROW_CONE].push_back(nn*z1);
s_ArrowTri[ARROW_CONE_CAP].push_back(x0); s_ArrowTri[ARROW_CONE_CAP].push_back(0); s_ArrowTri[ARROW_CONE_CAP].push_back(0);
s_ArrowTri[ARROW_CONE_CAP].push_back(x0); s_ArrowTri[ARROW_CONE_CAP].push_back(CONE_RADIUS*y1); s_ArrowTri[ARROW_CONE_CAP].push_back(CONE_RADIUS*z1);
s_ArrowTri[ARROW_CONE_CAP].push_back(x0); s_ArrowTri[ARROW_CONE_CAP].push_back(CONE_RADIUS*y0); s_ArrowTri[ARROW_CONE_CAP].push_back(CONE_RADIUS*z0);
s_ArrowNorm[ARROW_CONE_CAP].push_back(-1); s_ArrowNorm[ARROW_CONE_CAP].push_back(0); s_ArrowNorm[ARROW_CONE_CAP].push_back(0);
s_ArrowNorm[ARROW_CONE_CAP].push_back(-1); s_ArrowNorm[ARROW_CONE_CAP].push_back(0); s_ArrowNorm[ARROW_CONE_CAP].push_back(0);
s_ArrowNorm[ARROW_CONE_CAP].push_back(-1); s_ArrowNorm[ARROW_CONE_CAP].push_back(0); s_ArrowNorm[ARROW_CONE_CAP].push_back(0);
}
//for(i=0; i<4; ++i)
//{
// s_ArrowTriProj[i].clear();
// s_ArrowTriProj[i].resize(2*(s_ArrowTri[i].size()/3), 0);
// s_ArrowColLight[i].clear();
// s_ArrowColLight[i].resize(s_ArrowTri[i].size()/3, 0);
//}
}
////////////////////////////////////////////////////////////////////////////
// End Copied Straight from AntTweakBar
////////////////////////////////////////////////////////////////////////////
IGL_INLINE void igl::opengl2::draw_beach_ball()
{
using namespace std;
CreateSphere();
// Keep track of opengl settings
int cm;
glGetIntegerv(GL_COLOR_MATERIAL,&cm);
// Draw triangles
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
float mat_ambient[4] = {0.1,0.1,0.1,1.0};
float mat_specular[4] = {0.0,0.0,0.0,1.0};
float mat_shininess = 1;
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
glPushMatrix();
glScalef(0.7,0.7,0.7);
glEnable(GL_NORMALIZE);
glBegin(GL_TRIANGLES);
for(int i = 0;i<(int)s_SphCol.size();i++)
{
glNormal3fv(&s_SphTri[i*3]);
glColor4ub(GLubyte(s_SphCol[i]>>16), GLubyte(s_SphCol[i]>>8), GLubyte(s_SphCol[i]), GLubyte(s_SphCol[i]>>24));
glVertex3fv(&s_SphTri[i*3]);
}
glEnd();
glPopMatrix();
CreateArrow();
for(int k = 0;k<3;k++)
{
glPushMatrix();
glColor3f(k==0,k==1,k==2);
glRotatef((k==2?-1.0:1.0)*90,k==0,k==2,k==1);
glBegin(GL_TRIANGLES);
for(int j = 0;j<4;j++)
{
for(int i = 0;i<(int)s_ArrowTri[j].size();i+=3)
{
glNormal3fv(&s_ArrowNorm[j][i]);
glVertex3fv(&s_ArrowTri[j][i]);
}
}
glEnd();
glPopMatrix();
}
(cm ? glEnable(GL_COLOR_MATERIAL):glDisable(GL_COLOR_MATERIAL));
}

View file

@ -0,0 +1,27 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_DRAW_BEACH_BALL_H
#define IGL_OPENGL2_DRAW_BEACH_BALL_H
#include "../igl_inline.h"
namespace igl
{
namespace opengl2
{
// Draw a beach ball icon/glyph (from AntTweakBar) at the current origin
// according to the current orientation: ball has radius 0.75 and axis have
// length 1.15
IGL_INLINE void draw_beach_ball();
}
}
#ifndef IGL_STATIC_LIBRARY
# include "draw_beach_ball.cpp"
#endif
#endif

View file

@ -0,0 +1,161 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "draw_floor.h"
#include "gl.h"
IGL_INLINE void igl::opengl2::draw_floor(const float * colorA, const float * colorB,
const int GridSizeX,
const int GridSizeY)
{
const float SizeX = 0.5f*100./(double)GridSizeX;
const float SizeY = 0.5f*100./(double)GridSizeY;
// old settings
int old_lighting=0,old_color_material=0;
glGetIntegerv(GL_LIGHTING,&old_lighting);
glGetIntegerv(GL_COLOR_MATERIAL,&old_color_material);
glDisable(GL_LIGHTING);
glColorMaterial( GL_FRONT, GL_EMISSION);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
// Set material
const float black[] = {0.,0.,0.,1.};
glMaterialfv(GL_FRONT, GL_AMBIENT, black);
glMaterialfv(GL_FRONT, GL_DIFFUSE, black);
glMaterialfv(GL_FRONT, GL_SPECULAR, black);
glMaterialfv(GL_FRONT, GL_EMISSION, black);
glMaterialf(GL_FRONT, GL_SHININESS,0);
const bool use_lighting = false;
if(use_lighting)
{
glEnable(GL_LIGHTING);
}else
{
glDisable(GL_LIGHTING);
}
glBegin(GL_QUADS);
glNormal3f(0,1,0);
for (int x =-GridSizeX/2;x<GridSizeX/2;++x)
{
for (int y =-GridSizeY/2;y<GridSizeY/2;++y)
{
if ((x+y)&0x00000001) //modulo 2
{
glColor4fv(colorA);
}else
{
glColor4fv(colorB);
}
glVertex3f( x*SizeX,0,(y+1)*SizeY);
glVertex3f((x+1)*SizeX,0,(y+1)*SizeY);
glVertex3f((x+1)*SizeX,0, y*SizeY);
glVertex3f( x*SizeX,0, y*SizeY);
}
}
glEnd();
(old_lighting ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING));
(old_color_material? glEnable(GL_COLOR_MATERIAL) : glDisable(GL_COLOR_MATERIAL));
}
IGL_INLINE void igl::opengl2::draw_floor()
{
const float grey[] = {0.80,0.80,0.80,1.};
const float white[] = {0.95,0.95,0.95,1.};
igl::opengl2::draw_floor(grey,white);
}
IGL_INLINE void igl::opengl2::draw_floor_outline(const float * colorA, const float * colorB,
const int GridSizeX,
const int GridSizeY)
{
const float SizeX = 0.5f*100./(double)GridSizeX;
const float SizeY = 0.5f*100./(double)GridSizeY;
float old_line_width =0;
// old settings
int old_lighting=0,old_color_material=0;
glGetIntegerv(GL_LIGHTING,&old_lighting);
glGetIntegerv(GL_COLOR_MATERIAL,&old_color_material);
glDisable(GL_LIGHTING);
// Set material
const float black[] = {0.,0.,0.,1.};
glMaterialfv(GL_FRONT, GL_AMBIENT, black);
glMaterialfv(GL_FRONT, GL_DIFFUSE, black);
glMaterialfv(GL_FRONT, GL_SPECULAR, black);
glMaterialfv(GL_FRONT, GL_EMISSION, black);
glMaterialf(GL_FRONT, GL_SHININESS,0);
const bool use_lighting = false;
if(use_lighting)
{
glEnable(GL_LIGHTING);
}else
{
glDisable(GL_LIGHTING);
}
glLineWidth(2.0f);
glBegin(GL_LINES);
for (int x =-GridSizeX/2;x<=GridSizeX/2;++x)
{
if(x!=(GridSizeX/2))
{
for(int s = -1;s<2;s+=2)
{
int y = s*(GridSizeY/2);
int cy = y==(GridSizeY/2) ? y-1 : y;
if ((x+cy)&0x00000001) //modulo 2
{
glColor4fv(colorA);
//glColor3f(1,0,0);
}else
{
glColor4fv(colorB);
//glColor3f(0,0,1);
}
glVertex3f((x+1)*SizeX,0,y*SizeY);
glVertex3f( x*SizeX,0,y*SizeY);
}
}
if(x==-(GridSizeX/2) || x==(GridSizeX/2))
{
int cx = x==(GridSizeX/2) ? x-1 : x;
for (int y =-GridSizeY/2;y<GridSizeY/2;++y)
{
if ((cx+y)&0x00000001) //modulo 2
{
glColor4fv(colorA);
//glColor3f(1,0,0);
}else
{
glColor4fv(colorB);
//glColor3f(0,0,1);
}
glVertex3f(x*SizeX,0,(y+1)*SizeY);
glVertex3f(x*SizeX,0, y*SizeY);
}
}
}
glEnd();
glGetFloatv(GL_LINE_WIDTH,&old_line_width);
glLineWidth(old_line_width);
(old_lighting ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING));
(old_color_material? glEnable(GL_COLOR_MATERIAL) : glDisable(GL_COLOR_MATERIAL));
}
IGL_INLINE void igl::opengl2::draw_floor_outline()
{
const float grey[] = {0.80,0.80,0.80,1.};
const float white[] = {0.95,0.95,0.95,1.};
igl::opengl2::draw_floor_outline(grey,white);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
#endif

View file

@ -0,0 +1,60 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_DRAW_FLOOR_H
#define IGL_OPENGL2_DRAW_FLOOR_H
#include "../igl_inline.h"
namespace igl
{
namespace opengl2
{
// Draw a checkerboard floor aligned with current (X,Z) plane using ../opengl/OpenGL_
// calls. side=50 centered at (0,0):
// (-25,-25)-->(-25,25)-->(25,25)-->(25,-25)
//
// Use glPushMatrix(), glScaled(), glTranslated() to arrange the floor.
//
// Inputs:
// colorA float4 color
// colorB float4 color
//
// Example:
// // Draw a nice floor
// glPushMatrix();
// glCullFace(GL_BACK);
// glEnable(GL_CULL_FACE);
// glEnable(GL_LIGHTING);
// glTranslated(0,-1,0);
// if(project(Vector3d(0,0,0))(2) - project(Vector3d(0,1,0))(2) > -FLOAT_EPS)
// {
// draw_floor_outline();
// }
// draw_floor();
// glPopMatrix();
// glDisable(GL_CULL_FACE);
//
IGL_INLINE void draw_floor(
const float * colorA,
const float * colorB,
const int GridSizeX=100,
const int GridSizeY=100);
// Wrapper with default colors
IGL_INLINE void draw_floor();
IGL_INLINE void draw_floor_outline(
const float * colorA,
const float * colorB,
const int GridSizeX=100,
const int GridSizeY=100);
// Wrapper with default colors
IGL_INLINE void draw_floor_outline();
}
}
#ifndef IGL_STATIC_LIBRARY
# include "draw_floor.cpp"
#endif
#endif

View file

@ -0,0 +1,278 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "draw_mesh.h"
IGL_INLINE void igl::opengl2::draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N)
{
using namespace Eigen;
MatrixXd _d;
MatrixXi _i;
return draw_mesh(V,F,N,_i,_d,_d,_i,_d,0,_i,0);
}
IGL_INLINE void igl::opengl2::draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N,
const Eigen::MatrixXd & C)
{
using namespace Eigen;
MatrixXd _d;
MatrixXi _i;
return draw_mesh(V,F,N,_i,C,_d,_i,_d,0,_i,0);
}
IGL_INLINE void igl::opengl2::draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N,
const Eigen::MatrixXd & C,
const Eigen::MatrixXd & TC)
{
using namespace Eigen;
MatrixXd _d;
MatrixXi _i;
return draw_mesh(V,F,N,_i,C,TC,_i,_d,0,_i,0);
}
IGL_INLINE void igl::opengl2::draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N,
const Eigen::MatrixXd & C,
const Eigen::MatrixXd & TC,
const Eigen::MatrixXd & W,
const GLuint W_index,
const Eigen::MatrixXi & WI,
const GLuint WI_index)
{
using namespace Eigen;
return draw_mesh(V,F,N,MatrixXi(),C,TC,MatrixXi(),W,W_index,WI,WI_index);
}
IGL_INLINE void igl::opengl2::draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N,
const Eigen::MatrixXi & NF,
const Eigen::MatrixXd & C,
const Eigen::MatrixXd & TC,
const Eigen::MatrixXi & TF,
const Eigen::MatrixXd & W,
const GLuint W_index,
const Eigen::MatrixXi & WI,
const GLuint WI_index)
{
using namespace std;
using namespace Eigen;
const int rF = F.rows();
const int cF = F.cols();
const int cC = C.cols();
const int rC = C.rows();
const int cW = W.cols();
const int rW = W.rows();
const int rV = V.rows();
const int rTC = TC.rows();
const int rTF = TF.rows();
const int rNF = NF.rows();
const int rN = N.rows();
if(F.size() > 0)
{
assert(F.maxCoeff() < V.rows());
assert(V.cols() == 3);
assert(rC == rV || rC == rF || rC == rF*3 || rC==1 || C.size() == 0);
assert(C.cols() >= 3 || C.size() == 0);
assert(N.cols() == 3 || N.size() == 0);
assert(TC.cols() == 2 || TC.size() == 0);
assert(cF == 3 || cF == 4);
assert(TF.size() == 0 || TF.cols() == F.cols());
assert(NF.size() == 0 || NF.cols() == NF.cols());
}
if(W.size()>0)
{
assert(W.rows() == V.rows());
assert(WI.rows() == V.rows());
assert(W.cols() == WI.cols());
}
switch(F.cols())
{
default:
case 3:
glBegin(GL_TRIANGLES);
break;
case 4:
glBegin(GL_QUADS);
break;
}
// loop over faces
for(int i = 0; i<rF;i++)
{
// loop over corners of triangle
for(int j = 0;j<cF;j++)
{
int tc = -1;
if(rTF != 0)
{
tc = TF(i,j);
} else if(rTC == 1)
{
tc = 0;
}else if(rTC == rV)
{
tc = F(i,j);
}else if(rTC == rF*cF)
{
tc = i*cF + j;
}else if(rTC == rF)
{
tc = i;
}else
{
assert(TC.size() == 0);
}
// RGB(A)
Matrix<MatrixXd::Scalar,1,Dynamic> color;
if(rC == 1)
{
color = C.row(0);
}else if(rC == rV)
{
color = C.row(F(i,j));
}else if(rC == rF*cF)
{
color = C.row(i*cF+j);
}else if(rC == rF)
{
color = C.row(i);
}else
{
assert(C.size() == 0);
}
int n = -1;
if(rNF != 0)
{
n = NF(i,j); // indexed normals
} else if(rN == 1)
{
n = 0; // uniform normals
}else if(rN == rF)
{
n = i; // face normals
}else if(rN == rV)
{
n = F(i,j); // vertex normals
}else if(rN == rF*cF)
{
n = i*cF + j; // corner normals
}else
{
assert(N.size() == 0);
}
{
if(rW>0 && W_index !=0 && WI_index != 0)
{
int weights_left = cW;
while(weights_left != 0)
{
int pass_size = std::min(4,weights_left);
int weights_already_passed = cW-weights_left;
// Get attribute location of next 4 weights
int pass_W_index = W_index + weights_already_passed/4;
int pass_WI_index = WI_index + weights_already_passed/4;
switch(pass_size)
{
case 1:
glVertexAttrib1d(
pass_W_index,
W(F(i,j),0+weights_already_passed));
glVertexAttrib1d(
pass_WI_index,
WI(F(i,j),0+weights_already_passed));
break;
case 2:
glVertexAttrib2d(
pass_W_index,
W(F(i,j),0+weights_already_passed),
W(F(i,j),1+weights_already_passed));
glVertexAttrib2d(
pass_WI_index,
WI(F(i,j),0+weights_already_passed),
WI(F(i,j),1+weights_already_passed));
break;
case 3:
glVertexAttrib3d(
pass_W_index,
W(F(i,j),0+weights_already_passed),
W(F(i,j),1+weights_already_passed),
W(F(i,j),2+weights_already_passed));
glVertexAttrib3d(
pass_WI_index,
WI(F(i,j),0+weights_already_passed),
WI(F(i,j),1+weights_already_passed),
WI(F(i,j),2+weights_already_passed));
break;
default:
glVertexAttrib4d(
pass_W_index,
W(F(i,j),0+weights_already_passed),
W(F(i,j),1+weights_already_passed),
W(F(i,j),2+weights_already_passed),
W(F(i,j),3+weights_already_passed));
glVertexAttrib4d(
pass_WI_index,
WI(F(i,j),0+weights_already_passed),
WI(F(i,j),1+weights_already_passed),
WI(F(i,j),2+weights_already_passed),
WI(F(i,j),3+weights_already_passed));
break;
}
weights_left -= pass_size;
}
}
if(tc != -1)
{
glTexCoord2d(TC(tc,0),TC(tc,1));
}
if(rC>0)
{
switch(cC)
{
case 3:
glColor3dv(color.data());
break;
case 4:
glColor4dv(color.data());
break;
default:
break;
}
}
if(n != -1)
{
glNormal3d(N(n,0),N(n,1),N(n,2));
}
glVertex3d(V(F(i,j),0),V(F(i,j),1),V(F(i,j),2));
}
}
}
glEnd();
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
#endif

122
src/igl/opengl2/draw_mesh.h Normal file
View file

@ -0,0 +1,122 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_DRAW_MESH_H
#define IGL_OPENGL2_DRAW_MESH_H
#include "../igl_inline.h"
#include "gl.h"
#include <Eigen/Dense>
namespace igl
{
namespace opengl2
{
// Draw ../opengl/OpenGL_ commands needed to display a mesh with normals
//
// Inputs:
// V #V by 3 eigen Matrix of mesh vertex 3D positions
// F #F by 3|4 eigen Matrix of face (triangle/quad) indices
// N #V|#F by 3 eigen Matrix of 3D normals
IGL_INLINE void draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N);
// Draw ../opengl/OpenGL_ commands needed to display a mesh with normals and per-vertex
// colors
//
// Inputs:
// V #V by 3 eigen Matrix of mesh vertex 3D positions
// F #F by 3|4 eigen Matrix of face (triangle/quad) indices
// N #V|#F by 3 eigen Matrix of 3D normals
// C #V|#F|1 by 3 eigen Matrix of RGB colors
IGL_INLINE void draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N,
const Eigen::MatrixXd & C);
// Inputs:
// V #V by 3 eigen Matrix of mesh vertex 3D positions
// F #F by 3|4 eigen Matrix of face (triangle/quad) indices
// N #V|#F by 3 eigen Matrix of 3D normals
// C #V|#F|1 by 3 eigen Matrix of RGB colors
// TC #V|#F|1 by 3 eigen Matrix of Texture Coordinates
IGL_INLINE void draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N,
const Eigen::MatrixXd & C,
const Eigen::MatrixXd & TC);
// Draw ../opengl/OpenGL_ commands needed to display a mesh with normals, per-vertex
// colors and LBS weights
//
// Inputs:
// V #V by 3 eigen Matrix of mesh vertex 3D positions
// F #F by 3|4 eigen Matrix of face (triangle/quad) indices
// N #V by 3 eigen Matrix of mesh vertex 3D normals
// C #V by 3 eigen Matrix of mesh vertex RGB colors
// TC #V by 3 eigen Matrix of mesh vertex UC coorindates between 0 and 1
// W #V by #H eigen Matrix of per mesh vertex, per handle weights
// W_index Specifies the index of the "weight" vertex attribute: see
// glBindAttribLocation, if W_index is 0 then weights are ignored
// WI #V by #H eigen Matrix of per mesh vertex, per handle weight ids
// WI_index Specifies the index of the "weight" vertex attribute: see
// glBindAttribLocation, if WI_index is 0 then weight indices are ignored
IGL_INLINE void draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N,
const Eigen::MatrixXd & C,
const Eigen::MatrixXd & TC,
const Eigen::MatrixXd & W,
const GLuint W_index,
const Eigen::MatrixXi & WI,
const GLuint WI_index);
// Draw ../opengl/OpenGL_ commands needed to display a mesh with normals, per-vertex
// colors and LBS weights
//
// Inputs:
// V #V by 3 eigen Matrix of mesh vertex 3D positions
// F #F by 3|4 eigen Matrix of face (triangle/quad) indices
// N #V by 3 eigen Matrix of mesh vertex 3D normals
// NF #F by 3 eigen Matrix of face (triangle/quad) normal indices, <0
// means no normal
// C #V by 3 eigen Matrix of mesh vertex RGB colors
// TC #V by 3 eigen Matrix of mesh vertex UC coorindates between 0 and 1
// TF #F by 3 eigen Matrix of face (triangle/quad) texture indices, <0
// means no texture
// W #V by #H eigen Matrix of per mesh vertex, per handle weights
// W_index Specifies the index of the "weight" vertex attribute: see
// glBindAttribLocation, if W_index is 0 then weights are ignored
// WI #V by #H eigen Matrix of per mesh vertex, per handle weight ids
// WI_index Specifies the index of the "weight" vertex attribute: see
// glBindAttribLocation, if WI_index is 0 then weight indices are ignored
IGL_INLINE void draw_mesh(
const Eigen::MatrixXd & V,
const Eigen::MatrixXi & F,
const Eigen::MatrixXd & N,
const Eigen::MatrixXi & NF,
const Eigen::MatrixXd & C,
const Eigen::MatrixXd & TC,
const Eigen::MatrixXi & TF,
const Eigen::MatrixXd & W,
const GLuint W_index,
const Eigen::MatrixXi & WI,
const GLuint WI_index);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "draw_mesh.cpp"
#endif
#endif

View file

@ -0,0 +1,100 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "draw_point.h"
// Implementation
#include "gl.h"
#include <cassert>
#include <cmath>
IGL_INLINE void igl::opengl2::draw_point(
const double x,
const double y,
const double z,
const double requested_r,
const bool selected)
{
// Push GL settings
glPushAttrib(GL_ENABLE_BIT | GL_LIGHTING_BIT);
float f;
glGetFloatv(GL_POINT_SIZE_MAX,&f);
// THIS IS OVERZEALOUS on Mac OS X: OpenGL reports a smaller point size than
// possible.
//assert(requested_r<=0.5*f);
double r = (requested_r<0.5*f?requested_r:0.5*f);
//glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
// get current color
float color[4];
glGetFloatv(GL_CURRENT_COLOR,color);
double outline_size = (r>7 ? sqrt(r/7.0) : 1.0);
// White outline
glColor4f(1,1,1,color[3]);
glPointSize(2*r);
glBegin(GL_POINTS);
glVertex3d(x,y,z);
glEnd();
// Black outline
glColor4f(0,0,0,color[3]);
glPointSize(2*r-2*outline_size);
glBegin(GL_POINTS);
glVertex3d(x,y,z);
glEnd();
// Foreground
glColor4fv(color);
glPointSize(2*r-4*outline_size);
glBegin(GL_POINTS);
glVertex3d(x,y,z);
glEnd();
// Selection inner circle
if(selected)
{
glColor4f(0,0,0,color[3]);
double selected_size = 2*r-7*outline_size;
selected_size = (selected_size>3?selected_size:3);
glPointSize(selected_size);
glBegin(GL_POINTS);
glVertex3d(x,y,z);
glEnd();
}
// reset color
glColor4fv(color);
// Pop GL settings
glPopAttrib();
}
template <typename DerivedP>
IGL_INLINE void igl::opengl2::draw_point(
const Eigen::PlainObjectBase<DerivedP> & P,
const double requested_r,
const bool selected)
{
switch(P.size())
{
case 2:
return draw_point(P(0),P(1),0,requested_r,selected);
default:
return draw_point(P(0),P(1),P(2),requested_r,selected);
}
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template void igl::opengl2::draw_point<Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, double, bool);
template void igl::opengl2::draw_point<Eigen::Matrix<double, 2, 1, 0, 2, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> > const&, double, bool);
#endif

View file

@ -0,0 +1,47 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_DRAW_POINT_H
#define IGL_OPENGL2_DRAW_POINT_H
#include "../igl_inline.h"
#include <Eigen/Core>
namespace igl
{
namespace opengl2
{
//double POINT_COLOR[3] = {239./255.,213./255.,46./255.};
// Draw a nice looking, colored dot at a given point in 3d.
//
// Note: expects that GL_CURRENT_COLOR is set with the desired foreground color
//
// Inputs:
// x x-coordinate of point, modelview coordinates
// y y-coordinate of point, modelview coordinates
// z z-coordinate of point, modelview coordinates
// requested_r outer-most radius of dot {7}, measured in screen space pixels
// selected fills inner circle with black {false}
// Asserts that requested_r does not exceed 0.5*GL_POINT_SIZE_MAX
IGL_INLINE void draw_point(
const double x,
const double y,
const double z,
const double requested_r = 7,
const bool selected = false);
template <typename DerivedP>
IGL_INLINE void draw_point(
const Eigen::PlainObjectBase<DerivedP> & P,
const double requested_r = 7,
const bool selected = false);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "draw_point.cpp"
#endif
#endif

View file

@ -0,0 +1,62 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "draw_rectangular_marquee.h"
#include "gl.h"
#include "glu.h"
#include "../material_colors.h"
IGL_INLINE void igl::opengl2::draw_rectangular_marquee(
const int from_x,
const int from_y,
const int to_x,
const int to_y)
{
using namespace std;
int l;
glGetIntegerv(GL_LIGHTING,&l);
int s;
glGetIntegerv(GL_LINE_STIPPLE,&s);
double lw;
glGetDoublev(GL_LINE_WIDTH,&lw);
glDisable(GL_LIGHTING);
// Screen space for this viewport
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT,viewport);
const int width = viewport[2];
const int height = viewport[3];
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0,width,0,height);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glEnable(GL_LINE_STIPPLE);
glLineStipple(3,0xAAAA);
glLineWidth(1);
glColor4f(0.2,0.2,0.2,1);
glBegin(GL_LINE_STRIP);
glVertex2d(from_x,from_y);
glVertex2d(to_x,from_y);
glVertex2d(to_x,to_y);
glVertex2d(from_x,to_y);
glVertex2d(from_x,from_y);
glEnd();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glLineWidth(lw);
(s ? glEnable(GL_LINE_STIPPLE):glDisable(GL_LINE_STIPPLE));
(l ? glEnable(GL_LIGHTING):glDisable(GL_LIGHTING));
}

View file

@ -0,0 +1,35 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_DRAW_RECTANGULAR_MARQUEE_H
#define IGL_OPENGL2_DRAW_RECTANGULAR_MARQUEE_H
#include "../igl_inline.h"
namespace igl
{
namespace opengl2
{
// Draw a rectangular marquee (selection box) in screen space. This sets up
// screen space using current viewport.
//
// Inputs:
// from_x x coordinate of from point
// from_y y coordinate of from point
// to_x x coordinate of to point
// to_y y coordinate of to point
IGL_INLINE void draw_rectangular_marquee(
const int from_x,
const int from_y,
const int to_x,
const int to_y);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "draw_rectangular_marquee.cpp"
#endif
#endif

View file

@ -0,0 +1,166 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "draw_skeleton_3d.h"
#include "../PI.h"
#include "../material_colors.h"
#include "gl.h"
#include <Eigen/Geometry>
#include <iostream>
template <
typename DerivedC,
typename DerivedBE,
typename DerivedT,
typename Derivedcolor>
IGL_INLINE void igl::opengl2::draw_skeleton_3d(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE,
const Eigen::PlainObjectBase<DerivedT> & T,
const Eigen::PlainObjectBase<Derivedcolor> & color,
const double half_bbd)
{
// Note: Maya's skeleton *does* scale with the mesh suggesting a scale
// parameter. Further, its joint balls are not rotated with the bones.
using namespace Eigen;
using namespace std;
if(color.size() == 0)
{
return draw_skeleton_3d(C,BE,T,MAYA_SEA_GREEN,half_bbd);
}
assert(color.cols() == 4 || color.size() == 4);
if(T.size() == 0)
{
typedef Eigen::Matrix<typename DerivedT::Scalar,Dynamic,Dynamic> Mat;
Mat I = Mat::Identity(C.cols()+1,C.cols());
Mat T = I.replicate(BE.rows(),1);
// insane base case
if(T.size() == 0)
{
return;
}
return draw_skeleton_3d(C,BE,T,color,half_bbd);
}
assert(T.rows() == BE.rows()*(C.cols()+1));
assert(T.cols() == C.cols());
// push old settings
glPushAttrib(GL_LIGHTING_BIT);
glPushAttrib(GL_LINE_BIT);
glDisable(GL_LIGHTING);
glLineWidth(1.0);
auto draw_sphere = [](const double r)
{
auto draw_circle = []()
{
glBegin(GL_LINE_STRIP);
for(double th = 0;th<2.0*igl::PI;th+=(2.0*igl::PI/30.0))
{
glVertex3d(cos(th),sin(th),0.0);
}
glVertex3d(cos(0),sin(0),0.0);
glEnd();
};
glPushMatrix();
glScaled(r,r,r);
draw_circle();
glRotated(90.0,1.0,0.0,0.0);
draw_circle();
glRotated(90.0,0.0,1.0,0.0);
draw_circle();
glPopMatrix();
};
auto draw_pyramid = []()
{
glBegin(GL_LINE_STRIP);
glVertex3d(0, 1,-1);
glVertex3d(0,-1,-1);
glVertex3d(0,-1, 1);
glVertex3d(0, 1, 1);
glVertex3d(0, 1,-1);
glEnd();
glBegin(GL_LINES);
glVertex3d(0, 1,-1);
glVertex3d(1,0,0);
glVertex3d(0,-1,-1);
glVertex3d(1,0,0);
glVertex3d(0,-1, 1);
glVertex3d(1,0,0);
glVertex3d(0, 1, 1);
glVertex3d(1,0,0);
glEnd();
};
// Loop over bones
for(int e = 0;e < BE.rows();e++)
{
// Draw a sphere
auto s = C.row(BE(e,0));
auto d = C.row(BE(e,1));
auto b = (d-s).transpose().eval();
double r = 0.02*half_bbd;
Matrix4d Te = Matrix4d::Identity();
Te.block(0,0,3,4) = T.block(e*4,0,4,3).transpose();
Quaterniond q;
q.setFromTwoVectors(Vector3d(1,0,0),b);
glPushMatrix();
glMultMatrixd(Te.data());
glTranslated(s(0),s(1),s(2));
if(color.size() == 4)
{
glColor4d( color(0), color(1), color(2), color(3));
}else
{
glColor4d( color(e,0), color(e,1), color(e,2), color(e,3));
}
draw_sphere(r);
const double len = b.norm()-2.*r;
if(len>=0)
{
auto u = b.normalized()*r;
glPushMatrix();
glTranslated(u(0),u(1),u(2));
glMultMatrixd(Affine3d(q).matrix().data());
glScaled(b.norm()-2.*r,r,r);
draw_pyramid();
glPopMatrix();
}
glTranslated(b(0),b(1),b(2));
draw_sphere(r);
glPopMatrix();
}
// Reset settings
glPopAttrib();
glPopAttrib();
}
template <typename DerivedC, typename DerivedBE, typename DerivedT>
IGL_INLINE void igl::opengl2::draw_skeleton_3d(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE,
const Eigen::PlainObjectBase<DerivedT> & T)
{
return draw_skeleton_3d(C,BE,T,MAYA_SEA_GREEN);
}
template <typename DerivedC, typename DerivedBE>
IGL_INLINE void igl::opengl2::draw_skeleton_3d(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE)
{
return draw_skeleton_3d(C,BE,Eigen::MatrixXd(),MAYA_SEA_GREEN);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template void igl::opengl2::draw_skeleton_3d<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&);
template void igl::opengl2::draw_skeleton_3d<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&);
template void igl::opengl2::draw_skeleton_3d<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<float, 4, 1, 0, 4, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 4, 1, 0, 4, 1> > const&, double);
template void igl::opengl2::draw_skeleton_3d<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<float, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -1, 0, -1, -1> > const&, double);
#endif

View file

@ -0,0 +1,53 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_DRAW_SKELETON_3D_H
#define IGL_OPENGL2_DRAW_SKELETON_3D_H
#include "../igl_inline.h"
#include "../material_colors.h"
#include <Eigen/Core>
namespace igl
{
namespace opengl2
{
// Draw a skeleton
//
// Inputs:
// C #C by dim List of joint rest positions
// BE #BE by 2 list of bone edge indices into C
// T #BE*(dim+1) by dim matrix of stacked transposed bone transformations
// color #BE|1 by 4 list of color
// half_bbd half bounding box diagonal to determine scaling {1.0}
template <
typename DerivedC,
typename DerivedBE,
typename DerivedT,
typename Derivedcolor>
IGL_INLINE void draw_skeleton_3d(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE,
const Eigen::PlainObjectBase<DerivedT> & T,
const Eigen::PlainObjectBase<Derivedcolor> & color,
const double half_bbd=0.5);
// Default color
template <typename DerivedC, typename DerivedBE, typename DerivedT>
IGL_INLINE void draw_skeleton_3d(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE,
const Eigen::PlainObjectBase<DerivedT> & T);
template <typename DerivedC, typename DerivedBE>
IGL_INLINE void draw_skeleton_3d(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "draw_skeleton_3d.cpp"
#endif
#endif

View file

@ -0,0 +1,122 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "draw_skeleton_vector_graphics.h"
#include "draw_point.h"
#include "gl.h"
#include "../material_colors.h"
IGL_INLINE void igl::opengl2::draw_skeleton_vector_graphics(
const Eigen::MatrixXd & C,
const Eigen::MatrixXi & BE)
{
return draw_skeleton_vector_graphics(C,BE,BBW_POINT_COLOR,BBW_LINE_COLOR);
}
IGL_INLINE void igl::opengl2::draw_skeleton_vector_graphics(
const Eigen::MatrixXd & C,
const Eigen::MatrixXi & BE,
const float * point_color,
const float * line_color)
{
using namespace Eigen;
int old_lighting=0;
double old_line_width=1;
glGetIntegerv(GL_LIGHTING,&old_lighting);
glGetDoublev(GL_LINE_WIDTH,&old_line_width);
int cm;
glGetIntegerv(GL_COLOR_MATERIAL,&cm);
glDisable(GL_LIGHTING);
glDisable(GL_LINE_STIPPLE);
//glEnable(GL_POLYGON_OFFSET_FILL);
glEnable(GL_COLOR_MATERIAL);
glLineWidth(10.0);
glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
float mat_ambient[4] = {0.1,0.1,0.1,1.0};
float mat_specular[4] = {0.0,0.0,0.0,1.0};
float mat_shininess = 1;
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
for(int i = 0;i<3;i++)
{
switch(i)
{
case 0: glColor3fv(WHITE); glLineWidth(10); break;
case 1: glColor3fv(BLACK); glLineWidth( 6); break;
case 2: glColor3fv(line_color); glLineWidth( 4); break;
}
// Loop over bone edges
glBegin(GL_LINES);
for(int e = 0;e<BE.rows();e++)
{
RowVector3d tip = C.row(BE(e,0));
RowVector3d tail = C.row(BE(e,1));
glVertex3dv(tip.data());
glVertex3dv(tail.data());
}
glEnd();
}
glColor3fv(point_color);
for(int i = 0;i<C.rows();i++)
{
RowVector3d p = C.row(i);
draw_point(p(0),p(1),p(2));
}
(cm ? glEnable(GL_COLOR_MATERIAL):glDisable(GL_COLOR_MATERIAL));
//glDisable(GL_POLYGON_OFFSET_FILL);
glEnable(GL_LIGHTING);
(old_lighting ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING));
glLineWidth(old_line_width);
}
template <typename DerivedC, typename DerivedBE, typename DerivedT>
IGL_INLINE void igl::opengl2::draw_skeleton_vector_graphics(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE,
const Eigen::PlainObjectBase<DerivedT> & T)
{
return draw_skeleton_vector_graphics(C,BE,T,BBW_POINT_COLOR,BBW_LINE_COLOR);
}
template <typename DerivedC, typename DerivedBE, typename DerivedT>
IGL_INLINE void igl::opengl2::draw_skeleton_vector_graphics(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE,
const Eigen::PlainObjectBase<DerivedT> & T,
const float * point_color,
const float * line_color)
{
DerivedC CT;
DerivedBE BET;
const int dim = T.cols();
assert(dim == C.cols());
CT.resize(2*BE.rows(),C.cols());
BET.resize(BE.rows(),2);
for(int e = 0;e<BE.rows();e++)
{
BET(e,0) = 2*e;
BET(e,1) = 2*e+1;
const auto & c0 = C.row(BE(e,0));
const auto & c1 = C.row(BE(e,1));
const auto & L = T.block(e*(dim+1),0,dim,dim);
const auto & t = T.block(e*(dim+1)+dim,0,1,dim);
CT.row(2*e) = c0 * L + t;
CT.row(2*e+1) = c1 * L + t;
}
draw_skeleton_vector_graphics(CT,BET,point_color,line_color);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template void igl::opengl2::draw_skeleton_vector_graphics<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&);
#endif

View file

@ -0,0 +1,52 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_DRAW_SKELETON_VECTOR_GRAPHICS_H
#define IGL_OPENGL2_DRAW_SKELETON_VECTOR_GRAPHICS_H
#include "../igl_inline.h"
#include <Eigen/Core>
namespace igl
{
namespace opengl2
{
// Draw a skeleton with a 2D vector graphcis style à la BBW, STBS, Monotonic,
// FAST papers.
//
// Inputs:
// C #C by dim list of joint positions
// BE #BE by 2 list of bone edge indices into C
// point_color color of points
// line_color color of lines
IGL_INLINE void draw_skeleton_vector_graphics(
const Eigen::MatrixXd & C,
const Eigen::MatrixXi & BE,
const float * point_color,
const float * line_color);
// Use default colors (originally from BBW paper)
IGL_INLINE void draw_skeleton_vector_graphics(
const Eigen::MatrixXd & C,
const Eigen::MatrixXi & BE);
// T #BE*(dim+1) by dim matrix of stacked transposed bone transformations
template <typename DerivedC, typename DerivedBE, typename DerivedT>
IGL_INLINE void draw_skeleton_vector_graphics(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE,
const Eigen::PlainObjectBase<DerivedT> & T,
const float * point_color,
const float * line_color);
template <typename DerivedC, typename DerivedBE, typename DerivedT>
IGL_INLINE void draw_skeleton_vector_graphics(
const Eigen::PlainObjectBase<DerivedC> & C,
const Eigen::PlainObjectBase<DerivedBE> & BE,
const Eigen::PlainObjectBase<DerivedT> & T);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "draw_skeleton_vector_graphics.cpp"
#endif
#endif

File diff suppressed because one or more lines are too long

44
src/igl/opengl2/gl.h Normal file
View file

@ -0,0 +1,44 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_GL_H
#define IGL_OPENGL2_GL_H
#ifdef IGL_OPENGL_GL_H
# error "igl/opengl/gl.h already included"
#endif
// Always use this:
// #include "gl.h"
// Instead of:
// #include <OpenGL/gl.h>
// or
// #include <GL/gl.h>
//
// For now this includes glu, glew and glext (perhaps these should be
// separated)
#ifdef _WIN32
# define NOMINMAX
# include <Windows.h>
# undef DrawText
# undef NOMINMAX
#endif
#ifndef __APPLE__
# define GLEW_STATIC
# include <GL/glew.h>
#endif
#ifdef __APPLE__
# include <OpenGL/gl.h>
# define __gl_h_ /* Prevent inclusion of the old gl.h */
#else
# include <GL/gl.h>
#endif
#endif

32
src/igl/opengl2/glext.h Normal file
View file

@ -0,0 +1,32 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2017 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL_GLEXT_H
#define IGL_OPENGL_GLEXT_H
#ifdef IGL_OPENGL2_GLEXT_H
# error "igl/opengl2/glext.h already included"
#endif
// Always use this:
// #include "gl.h"
// Instead of:
// #include <OpenGL/glext.h>
// or
// #include <GL/glext.h>
//
#ifdef __APPLE__
# include <OpenGL/glext.h>
#elif _WIN32
// do nothing(?)
#else
# include <GL/glext.h>
#endif
#endif

30
src/igl/opengl2/glu.h Normal file
View file

@ -0,0 +1,30 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2017 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_GLU_H
#define IGL_OPENGL2_GLU_H
#ifdef IGL_OPENGL_GLU_H
# error "igl/opengl/glu.h already included"
#endif
// Always use this:
// #include "glu.h"
// Instead of:
// #include <OpenGL/glu.h>
// or
// #include <GL/glu.h>
//
#ifdef __APPLE__
# include <OpenGL/glu.h>
#else
# include <GL/glu.h>
#endif
#endif

View file

@ -0,0 +1,195 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "lens_flare.h"
#include "../C_STR.h"
#include "unproject.h"
#include "project.h"
#include "shine_textures.h"
#include "flare_textures.h"
#include <iostream>
#include <stdint.h>
// http://www.opengl.org/archives/resources/features/KilgardTechniques/LensFlare/glflare.c
IGL_INLINE void igl::opengl2::lens_flare_load_textures(
std::vector<GLuint> & shine_id,
std::vector<GLuint> & flare_id)
{
const auto setup_texture =[](
const uint8_t * texture,
const int width,
const int height,
GLuint texobj,
GLenum minFilter, GLenum maxFilter)
{
glBindTexture(GL_TEXTURE_2D, texobj);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, maxFilter);
glTexImage2D(GL_TEXTURE_2D, 0, 1, width, height, 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE, texture);
};
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
shine_id.resize(10);
glGenTextures(10,&shine_id[0]);
for (int i = 0; i < (int)shine_id.size(); i++) {
setup_texture(
SHINE_TEXTURES[i],
SHINE_TEXTURE_WIDTHS[i],
SHINE_TEXTURE_HEIGHTS[i],
shine_id[i], GL_LINEAR, GL_LINEAR);
}
flare_id.resize(6);
glGenTextures(6,&flare_id[0]);
for (int i = 0; i < (int)flare_id.size(); i++) {
setup_texture(
FLARE_TEXTURES[i],
FLARE_TEXTURE_WIDTHS[i],
FLARE_TEXTURE_HEIGHTS[i],
flare_id[i], GL_LINEAR, GL_LINEAR);
}
}
IGL_INLINE void igl::opengl2::lens_flare_create(
const float * A,
const float * B,
const float * C,
std::vector<igl::opengl2::Flare> & flares)
{
using namespace std;
flares.resize(12);
/* Shines */
flares[0] = Flare(-1, 1.0f, 0.1f, C, 1.0);
flares[1] = Flare(-1, 1.0f, 0.15f, B, 1.0);
flares[2] = Flare(-1, 1.0f, 0.35f, A, 1.0);
/* Flares */
flares[3] = Flare(2, 1.3f, 0.04f, A, 0.6);
flares[4] = Flare(3, 1.0f, 0.1f, A, 0.4);
flares[5] = Flare(1, 0.5f, 0.2f, A, 0.3);
flares[6] = Flare(3, 0.2f, 0.05f, A, 0.3);
flares[7] = Flare(0, 0.0f, 0.04f, A, 0.3);
flares[8] = Flare(5, -0.25f, 0.07f, A, 0.5);
flares[9] = Flare(5, -0.4f, 0.02f, A, 0.6);
flares[10] = Flare(5, -0.6f, 0.04f, A, 0.4);
flares[11] = Flare(5, -1.0f, 0.03f, A, 0.2);
}
IGL_INLINE void igl::opengl2::lens_flare_draw(
const std::vector<igl::opengl2::Flare> & flares,
const std::vector<GLuint> & shine_ids,
const std::vector<GLuint> & flare_ids,
const Eigen::Vector3f & light,
const float near_clip,
int & shine_tic)
{
bool ot2 = glIsEnabled(GL_TEXTURE_2D);
bool ob = glIsEnabled(GL_BLEND);
bool odt = glIsEnabled(GL_DEPTH_TEST);
bool ocm = glIsEnabled(GL_COLOR_MATERIAL);
bool ol = glIsEnabled(GL_LIGHTING);
int obsa,obda,odf,odwm;
glGetIntegerv(GL_BLEND_SRC_ALPHA,&obsa);
glGetIntegerv(GL_BLEND_DST_ALPHA,&obda);
glGetIntegerv(GL_DEPTH_FUNC,&odf);
glGetIntegerv(GL_DEPTH_WRITEMASK,&odwm);
glDisable(GL_COLOR_MATERIAL);
glEnable(GL_DEPTH_TEST);
//glDepthFunc(GL_LEQUAL);
glDepthMask(GL_FALSE);
glEnable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
using namespace Eigen;
using namespace std;
//// view_dir direction from eye to position it is looking at
//const Vector3f view_dir = (at - from).normalized();
//// near_clip distance from eye to near clipping plane along view_dir
//// center position on near clipping plane along viewdir from eye
//const Vector3f center = from + near_clip*view_dir;
Vector3f plight = project(light);
// Orthogonal vectors to view direction at light
Vector3f psx = plight;
psx(0) += 1;
Vector3f psy = plight;
psy(1) += 1;
// axis toward center
int vp[4];
glGetIntegerv(GL_VIEWPORT,vp);
Vector3f center = unproject(Vector3f(0.5*vp[2],0.5*vp[3],plight[2]-1e-3));
//Vector3f center(0,0,1);
Vector3f axis = light-center;
//glLineWidth(4.);
//glColor3f(1,0,0);
//glBegin(GL_LINES);
//glVertex3fv(center.data());
//glVertex3fv(light.data());
//glEnd();
const Vector3f SX = unproject(psx).normalized();
const Vector3f SY = unproject(psy).normalized();
for(int i = 0; i < (int)flares.size(); i++)
{
const Vector3f sx = flares[i].scale * SX;
const Vector3f sy = flares[i].scale * SY;
glColor3fv(flares[i].color);
if (flares[i].type < 0) {
glBindTexture(GL_TEXTURE_2D, shine_ids[shine_tic]);
shine_tic = (shine_tic + 1) % shine_ids.size();
} else
{
glBindTexture(GL_TEXTURE_2D, flare_ids[flares[i].type]);
}
/* position = center + flare[i].loc * axis */
const Vector3f position = center + flares[i].loc * axis;
Vector3f tmp;
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
tmp = position + sx;
tmp = tmp + sy;
glVertex3fv(tmp.data());
glTexCoord2f(1.0, 0.0);
tmp = position - sx;
tmp = tmp + sy;
glVertex3fv(tmp.data());
glTexCoord2f(1.0, 1.0);
tmp = position - sx;
tmp = tmp - sy;
glVertex3fv(tmp.data());
glTexCoord2f(0.0, 1.0);
tmp = position + sx;
tmp = tmp - sy;
glVertex3fv(tmp.data());
glEnd();
}
ot2?glEnable(GL_TEXTURE_2D):glDisable(GL_TEXTURE_2D);
ob?glEnable(GL_BLEND):glDisable(GL_BLEND);
odt?glEnable(GL_DEPTH_TEST):glDisable(GL_DEPTH_TEST);
ocm?glEnable(GL_COLOR_MATERIAL):glDisable(GL_COLOR_MATERIAL);
ol?glEnable(GL_LIGHTING):glDisable(GL_LIGHTING);
glBlendFunc(obsa,obda);
glDepthFunc(odf);
glDepthMask(odwm);
}

View file

@ -0,0 +1,93 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_LENS_FLARE_H
#define IGL_OPENGL2_LENS_FLARE_H
#include "../igl_inline.h"
#include "gl.h"
#include <Eigen/Core>
#include <vector>
namespace igl
{
namespace opengl2
{
struct Flare{
int type; /* flare texture index, 0..5 */
float scale;
float loc; /* position on axis */
float color[3];
Flare():
type(-1),
scale(0),
loc(0)
{}
Flare(int type, float location, float scale, const float color[3], float colorScale) :
type(type),
scale(scale),
loc(location)
{
this->color[0] = color[0] * colorScale;
this->color[1] = color[1] * colorScale;
this->color[2] = color[2] * colorScale;
}
};
// Initialize shared data for lens flates
//
// Inputs:
// start_id starting texture id location (should have at least id:id+16 free)
// Outputs:
// shine list of texture ids for shines
// flare list of texture ids for flares
IGL_INLINE void lens_flare_load_textures(
std::vector<GLuint> & shine_ids,
std::vector<GLuint> & flare_ids);
// Create a set of lens flares
//
// Inputs:
// A primary color
// B secondary color
// C secondary color
// Outputs:
// flares list of flare objects
IGL_INLINE void lens_flare_create(
const float * A,
const float * B,
const float * C,
std::vector<Flare> & flares);
// Draw lens flares
//
// Inputs:
// flares list of Flare objects
// shine_ids list of shine textures
// flare_ids list of flare texture ids
// light position of light
// near_clip near clipping plane
// shine_tic current "tic" in shine textures
// Outputs:
// shine_tic current "tic" in shine textures
IGL_INLINE void lens_flare_draw(
const std::vector<Flare> & flares,
const std::vector<GLuint> & shine_ids,
const std::vector<GLuint> & flare_ids,
const Eigen::Vector3f & light,
const float near_clip,
int & shine_tic);
}
};
#ifndef IGL_STATIC_LIBRARY
# include "lens_flare.cpp"
#endif
#endif

View file

@ -0,0 +1,31 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "model_proj_viewport.h"
#include "gl.h"
template <typename Derivedmodel, typename Derivedproj, typename Derivedviewport>
IGL_INLINE void igl::opengl2::model_proj_viewport(
Eigen::PlainObjectBase<Derivedmodel> & model,
Eigen::PlainObjectBase<Derivedproj> & proj,
Eigen::PlainObjectBase<Derivedviewport> & viewport)
{
Eigen::Matrix4d MV,P;
Eigen::Vector4i VPi;
glGetDoublev(GL_MODELVIEW_MATRIX,MV.data());
glGetDoublev(GL_PROJECTION_MATRIX,P.data());
glGetIntegerv(GL_VIEWPORT,VPi.data());
viewport = VPi.cast<typename Derivedviewport::Scalar>();
model = MV.cast<typename Derivedmodel::Scalar>();
proj = P.cast<typename Derivedproj::Scalar>();
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template void igl::opengl2::model_proj_viewport<Eigen::Matrix<double, 4, 4, 0, 4, 4>, Eigen::Matrix<double, 4, 4, 0, 4, 4>, Eigen::Matrix<double, 4, 1, 0, 4, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 4, 4, 0, 4, 4> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 4, 4, 0, 4, 4> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, 4, 1, 0, 4, 1> >&);
template void igl::opengl2::model_proj_viewport<Eigen::Matrix<float, 4, 4, 0, 4, 4>, Eigen::Matrix<float, 4, 4, 0, 4, 4>, Eigen::Matrix<float, 4, 1, 0, 4, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, 4, 4, 0, 4, 4> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, 4, 4, 0, 4, 4> >&, Eigen::PlainObjectBase<Eigen::Matrix<float, 4, 1, 0, 4, 1> >&);
#endif

View file

@ -0,0 +1,33 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_MODEL_PROJ_VIEW_H
#define IGL_OPENGL2_MODEL_PROJ_VIEW_H
#include "../igl_inline.h"
#include <Eigen/Core>
namespace igl
{
namespace opengl2
{
// Collect the model-view, projection and viewport matrices
//
// Outputs:
// model 4x4 modelview matrix
// proj 4x4 projection matrix
// viewport 4x1 viewport vector
//
template <typename Derivedmodel, typename Derivedproj, typename Derivedviewport>
IGL_INLINE void model_proj_viewport(
Eigen::PlainObjectBase<Derivedmodel> & model,
Eigen::PlainObjectBase<Derivedproj> & proj,
Eigen::PlainObjectBase<Derivedviewport> & viewport);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "model_proj_viewport.cpp"
#endif
#endif

View file

@ -0,0 +1,38 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "print_gl_get.h"
#include <cstdio>
IGL_INLINE void igl::opengl2::print_gl_get(GLenum pname)
{
double dM[16];
int rows = 4;
int cols = 4;
switch(pname)
{
case GL_MODELVIEW_MATRIX:
case GL_PROJECTION_MATRIX:
{
rows = 4;
cols = 4;
glGetDoublev(pname,dM);
for(int i = 0;i<rows;i++)
{
for(int j = 0;j<cols;j++)
{
printf("%lg ",dM[j*rows+i]);
}
printf("\n");
}
break;
}
default:
fprintf(stderr,"ERROR in print_gl_get(), gl enum not recognized.\n");
}
}

View file

@ -0,0 +1,28 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_PRINT_GL_GET_H
#define IGL_OPENGL2_PRINT_GL_GET_H
#include "gl.h"
#include "../igl_inline.h"
namespace igl
{
namespace opengl2
{
// Prints the value of pname found by issuing glGet*(pname,*)
// Inputs:
// pname enum key to gl parameter
IGL_INLINE void print_gl_get(GLenum pname);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "print_gl_get.cpp"
#endif
#endif

View file

@ -0,0 +1,73 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "project.h"
#include "../project.h"
#include "gl.h"
#include "glu.h"
#include <iostream>
IGL_INLINE int igl::opengl2::project(
const double objX,
const double objY,
const double objZ,
double* winX,
double* winY,
double* winZ)
{
using namespace std;
// Put model, projection, and viewport matrices into double arrays
double MV[16];
double P[16];
int VP[4];
glGetDoublev(GL_MODELVIEW_MATRIX, MV);
glGetDoublev(GL_PROJECTION_MATRIX, P);
glGetIntegerv(GL_VIEWPORT, VP);
int ret = gluProject(objX,objY,objZ,MV,P,VP,winX,winY,winZ);
return ret;
}
template <typename Derivedobj, typename Derivedwin>
IGL_INLINE int igl::opengl2::project(
const Eigen::PlainObjectBase<Derivedobj> & obj,
Eigen::PlainObjectBase<Derivedwin> & win)
{
assert(obj.size() >= 3);
Eigen::Vector3d dobj(obj(0),obj(1),obj(2));
Eigen::Vector3d dwin;
int ret = igl::opengl2::project(dobj(0),dobj(1),dobj(2),
&dwin.data()[0],
&dwin.data()[1],
&dwin.data()[2]);
win(0) = dwin(0);
win(1) = dwin(1);
win(2) = dwin(2);
return ret;
}
template <typename Derivedobj>
IGL_INLINE Derivedobj igl::opengl2::project(
const Eigen::PlainObjectBase<Derivedobj> & obj)
{
Derivedobj win;
igl::opengl2::project(obj,win);
return win;
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template int igl::opengl2::project<Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
template int igl::opengl2::project<Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<float, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> >&);
template int igl::opengl2::project<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
template Eigen::Matrix<double, 3, 1, 0, 3, 1> igl::opengl2::project<Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&);
template Eigen::Matrix<float, 3, 1, 0, 3, 1> igl::opengl2::project<Eigen::Matrix<float, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&);
template Eigen::Matrix<double, 1, -1, 1, 1, -1> igl::opengl2::project<Eigen::Matrix<double, 1, -1, 1, 1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 1, -1, 1, 1, -1> > const&);
template Eigen::Matrix<double, 1, 3, 1, 1, 3> igl::opengl2::project<Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&);
template Eigen::Matrix<double, 1, 2, 1, 1, 2> igl::opengl2::project<Eigen::Matrix<double, 1, 2, 1, 1, 2> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 2, 1, 1, 2> > const&);
template Eigen::Matrix<double, 2, 1, 0, 2, 1> igl::opengl2::project<Eigen::Matrix<double, 2, 1, 0, 2, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> > const&);
#endif

47
src/igl/opengl2/project.h Normal file
View file

@ -0,0 +1,47 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_PROJECT_H
#define IGL_OPENGL2_PROJECT_H
#include "../igl_inline.h"
#include <Eigen/Dense>
namespace igl
{
namespace opengl2
{
// Wrapper for gluProject that uses the current GL_MODELVIEW_MATRIX,
// GL_PROJECTION_MATRIX, and GL_VIEWPORT
// Inputs:
// obj* 3D objects' x, y, and z coordinates respectively
// Outputs:
// win* pointers to screen space x, y, and z coordinates respectively
// Returns return value of gluProject call
IGL_INLINE int project(
const double objX,
const double objY,
const double objZ,
double* winX,
double* winY,
double* winZ);
// Eigen wrapper
template <typename Derivedobj, typename Derivedwin>
IGL_INLINE int project(
const Eigen::PlainObjectBase<Derivedobj> & obj,
Eigen::PlainObjectBase<Derivedwin> & win);
// Eigen wrapper with return
template <typename Derivedobj>
IGL_INLINE Derivedobj project(
const Eigen::PlainObjectBase<Derivedobj> & obj);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "project.cpp"
#endif
#endif

View file

@ -0,0 +1,28 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "right_axis.h"
#include "gl.h"
IGL_INLINE void igl::opengl2::right_axis(double * x, double * y, double * z)
{
double mv[16];
glGetDoublev(GL_MODELVIEW_MATRIX, mv);
igl::opengl2::right_axis(mv,x,y,z);
}
IGL_INLINE void igl::opengl2::right_axis(const double * mv,double * x, double * y, double * z)
{
*x = -mv[0*4+0];
*y = -mv[1*4+0];
*z = -mv[2*4+0];
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
#endif

View file

@ -0,0 +1,34 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_RIGHT_AXIS_H
#define IGL_OPENGL2_RIGHT_AXIS_H
#include "../igl_inline.h"
namespace igl
{
namespace opengl2
{
// Determines the right axis or depth axis of the current gl matrix
// Outputs:
// x pointer to x-coordinate in scene coordinates of the un-normalized
// right axis
// y pointer to y-coordinate in scene coordinates of the un-normalized
// right axis
// z pointer to z-coordinate in scene coordinates of the un-normalized
// right axis
// mv pointer to modelview matrix
//
// Note: Right axis is returned *UN-normalized*
IGL_INLINE void right_axis(double * x, double * y, double * z);
IGL_INLINE void right_axis(const double * mv, double * x, double * y, double * z);
}
};
#ifndef IGL_STATIC_LIBRARY
# include "right_axis.cpp"
#endif
#endif

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,80 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "sort_triangles.h"
#include "project.h"
#include "../sort_triangles.h"
#include "gl.h"
#include "../sort.h"
#include "../slice.h"
#include "../barycenter.h"
#include <iostream>
template <
typename DerivedV,
typename DerivedF,
typename DerivedFF,
typename DerivedI>
void igl::opengl2::sort_triangles(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
Eigen::PlainObjectBase<DerivedFF> & FF,
Eigen::PlainObjectBase<DerivedI> & I)
{
using namespace Eigen;
using namespace std;
// Put model, projection, and viewport matrices into double arrays
Matrix4d MV;
Matrix4d P;
glGetDoublev(GL_MODELVIEW_MATRIX, MV.data());
glGetDoublev(GL_PROJECTION_MATRIX, P.data());
if(V.cols() == 3)
{
Matrix<typename DerivedV::Scalar, DerivedV::RowsAtCompileTime,4> hV;
hV.resize(V.rows(),4);
hV.block(0,0,V.rows(),V.cols()) = V;
hV.col(3).setConstant(1);
return igl::sort_triangles(hV,F,MV,P,FF,I);
}else
{
return igl::sort_triangles(V,F,MV,P,FF,I);
}
}
template <
typename DerivedV,
typename DerivedF,
typename DerivedFF,
typename DerivedI>
void igl::opengl2::sort_triangles_slow(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
Eigen::PlainObjectBase<DerivedFF> & FF,
Eigen::PlainObjectBase<DerivedI> & I)
{
using namespace Eigen;
using namespace std;
// Barycenter, centroid
Eigen::Matrix<typename DerivedV::Scalar, DerivedF::RowsAtCompileTime,1> D,sD;
Eigen::Matrix<typename DerivedV::Scalar, DerivedF::RowsAtCompileTime,3> BC;
D.resize(F.rows(),3);
barycenter(V,F,BC);
for(int f = 0;f<F.rows();f++)
{
Eigen::Matrix<typename DerivedV::Scalar, 3,1> bc,pbc;
bc = BC.row(f);
project(bc,pbc);
D(f) = pbc(2);
}
sort(D,1,false,sD,I);
slice(F,I,1,FF);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
template void igl::opengl2::sort_triangles<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
template void igl::opengl2::sort_triangles_slow<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
#endif

View file

@ -0,0 +1,70 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_SORT_TRIANGLES_H
#define IGL_OPENGL2_SORT_TRIANGLES_H
#include "../igl_inline.h"
#include <Eigen/Core>
namespace igl
{
namespace opengl2
{
template <
typename DerivedV,
typename DerivedF,
typename DerivedFF,
typename DerivedI>
IGL_INLINE void sort_triangles(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
Eigen::PlainObjectBase<DerivedFF> & FF,
Eigen::PlainObjectBase<DerivedI> & I);
template <
typename DerivedV,
typename DerivedF,
typename DerivedFF,
typename DerivedI>
IGL_INLINE void sort_triangles_slow(
const Eigen::PlainObjectBase<DerivedV> & V,
const Eigen::PlainObjectBase<DerivedF> & F,
Eigen::PlainObjectBase<DerivedFF> & FF,
Eigen::PlainObjectBase<DerivedI> & I);
//template <
// typename DerivedV,
// typename DerivedF,
// typename DerivedMV,
// typename DerivedP,
// typename DerivedFF,
// typename DerivedI>
//IGL_INLINE void sort_triangles_robust(
// const Eigen::PlainObjectBase<DerivedV> & V,
// const Eigen::PlainObjectBase<DerivedF> & F,
// const Eigen::PlainObjectBase<DerivedMV> & MV,
// const Eigen::PlainObjectBase<DerivedP> & P,
// Eigen::PlainObjectBase<DerivedFF> & FF,
// Eigen::PlainObjectBase<DerivedI> & I);
//template <
// typename DerivedV,
// typename DerivedF,
// typename DerivedFF,
// typename DerivedI>
//IGL_INLINE void sort_triangles_robust(
// const Eigen::PlainObjectBase<DerivedV> & V,
// const Eigen::PlainObjectBase<DerivedF> & F,
// Eigen::PlainObjectBase<DerivedFF> & FF,
// Eigen::PlainObjectBase<DerivedI> & I);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "sort_triangles.cpp"
#endif
#endif

View file

@ -0,0 +1,63 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "unproject.h"
#include "model_proj_viewport.h"
#include "../unproject.h"
#include "gl.h"
#include <Eigen/Dense>
#include <Eigen/LU>
IGL_INLINE void igl::opengl2::unproject(
const double winX,
const double winY,
const double winZ,
double* objX,
double* objY,
double* objZ)
{
Eigen::Vector3d obj;
igl::opengl2::unproject(Eigen::Vector3d(winX,winY,winZ),obj);
*objX = obj(0);
*objY = obj(1);
*objZ = obj(2);
}
template <typename Derivedwin, typename Derivedobj>
IGL_INLINE void igl::opengl2::unproject(
const Eigen::PlainObjectBase<Derivedwin> & win,
Eigen::PlainObjectBase<Derivedobj> & obj)
{
const auto ret = igl::opengl2::unproject(win);
obj = ret.template cast<typename Derivedobj::Scalar>();
}
template <typename Derivedwin>
IGL_INLINE Derivedwin igl::opengl2::unproject(
const Eigen::PlainObjectBase<Derivedwin> & win)
{
using namespace Eigen;
typedef typename Derivedwin::Scalar Scalar;
Matrix4d MV,P;
Vector4d VPd;
model_proj_viewport(MV,P,VPd);
Vector3d wind = win.template cast<double>();
Vector3d objd = igl::unproject(wind,MV,P,VPd);
return objd.template cast<Scalar>();
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::opengl2::unproject<Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<float, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> >&);
template void igl::opengl2::unproject<Eigen::Matrix<float, 3, 1, 0, 3, 1>, Eigen::Matrix<float, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> >&);
template Eigen::Matrix<float, 3, 1, 0, 3, 1> igl::opengl2::unproject<Eigen::Matrix<float, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<float, 3, 1, 0, 3, 1> > const&);
template Eigen::Matrix<double, 3, 1, 0, 3, 1> igl::opengl2::unproject<Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&);
template void igl::opengl2::unproject<Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
#endif

View file

@ -0,0 +1,46 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_UNPROJECT_H
#define IGL_OPENGL2_UNPROJECT_H
#include "../igl_inline.h"
#include <Eigen/Core>
namespace igl
{
namespace opengl2
{
// Wrapper for gluUnproject that uses the current GL_MODELVIEW_MATRIX,
// GL_PROJECTION_MATRIX, and GL_VIEWPORT
// Inputs:
// win* screen space x, y, and z coordinates respectively
// Outputs:
// obj* pointers to 3D objects' x, y, and z coordinates respectively
// Returns return value of gluUnProject call
IGL_INLINE void unproject(
const double winX,
const double winY,
const double winZ,
double* objX,
double* objY,
double* objZ);
template <typename Derivedwin, typename Derivedobj>
IGL_INLINE void unproject(
const Eigen::PlainObjectBase<Derivedwin> & win,
Eigen::PlainObjectBase<Derivedobj> & obj);
template <typename Derivedwin>
IGL_INLINE Derivedwin unproject(
const Eigen::PlainObjectBase<Derivedwin> & win);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "unproject.cpp"
#endif
#endif

View file

@ -0,0 +1,45 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "unproject_to_zero_plane.h"
#include "gl.h"
#include "project.h"
#include "unproject.h"
IGL_INLINE void igl::opengl2::unproject_to_zero_plane(
const double winX,
const double winY,
double* objX,
double* objY,
double* objZ)
{
double winOrigin[3];
igl::opengl2::project(0,0,0,&winOrigin[0],&winOrigin[1],&winOrigin[2]);
return igl::opengl2::unproject(winX, winY, winOrigin[2], objX, objY, objZ);
}
template <typename Derivedwin, typename Derivedobj>
IGL_INLINE void igl::opengl2::unproject_to_zero_plane(
const Eigen::PlainObjectBase<Derivedwin> & win,
Eigen::PlainObjectBase<Derivedobj> & obj)
{
return unproject_to_zero_plane(win(0),win(1),
&obj.data()[0],
&obj.data()[1],
&obj.data()[2]);
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::opengl2::unproject_to_zero_plane<Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
template void igl::opengl2::unproject_to_zero_plane<Eigen::Matrix<double, 2, 1, 0, 2, 1>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
template void igl::opengl2::unproject_to_zero_plane<Eigen::Matrix<double, 2, 1, 0, 2, 1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
#endif

View file

@ -0,0 +1,42 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_UNPROJECT_TO_ZERO_PLANE_H
#define IGL_OPENGL2_UNPROJECT_TO_ZERO_PLANE_H
#include "../igl_inline.h"
#include <Eigen/Core>
namespace igl
{
namespace opengl2
{
// Wrapper for gluUnproject that uses the current GL_MODELVIEW_MATRIX,
// GL_PROJECTION_MATRIX, and GL_VIEWPORT to unproject a screen position
// (winX,winY) to a 3d location at same depth as the current origin.
// Inputs:
// win* screen space x, y, and z coordinates respectively
// Outputs:
// obj* pointers to 3D objects' x, y, and z coordinates respectively
// Returns return value of gluUnProject call
IGL_INLINE void unproject_to_zero_plane(
const double winX,
const double winY,
double* objX,
double* objY,
double* objZ);
template <typename Derivedwin, typename Derivedobj>
IGL_INLINE void unproject_to_zero_plane(
const Eigen::PlainObjectBase<Derivedwin> & win,
Eigen::PlainObjectBase<Derivedobj> & obj);
}
}
#ifndef IGL_STATIC_LIBRARY
# include "unproject_to_zero_plane.cpp"
#endif
#endif

View file

@ -0,0 +1,28 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "up_axis.h"
#include "gl.h"
IGL_INLINE void igl::opengl2::up_axis(double * x, double * y, double * z)
{
double mv[16];
glGetDoublev(GL_MODELVIEW_MATRIX, mv);
igl::opengl2::up_axis(mv,x,y,z);
}
IGL_INLINE void igl::opengl2::up_axis(const double *mv, double * x, double * y, double * z)
{
*x = -mv[0*4+1];
*y = -mv[1*4+1];
*z = -mv[2*4+1];
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
#endif

36
src/igl/opengl2/up_axis.h Normal file
View file

@ -0,0 +1,36 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_UP_AXIS_H
#define IGL_OPENGL2_UP_AXIS_H
#include "../igl_inline.h"
namespace igl
{
namespace opengl2
{
// Determines the up axis or depth axis of the current gl matrix
// Outputs:
// x pointer to x-coordinate in scene coordinates of the un-normalized
// up axis
// y pointer to y-coordinate in scene coordinates of the un-normalized
// up axis
// z pointer to z-coordinate in scene coordinates of the un-normalized
// up axis
// mv pointer to modelview matrix
//
// Note: Up axis is returned *UN-normalized*
IGL_INLINE void up_axis(double * x, double * y, double * z);
IGL_INLINE void up_axis(const double * mv, double * x, double * y, double * z);
}
};
#ifndef IGL_STATIC_LIBRARY
# include "up_axis.cpp"
#endif
#endif

View file

@ -0,0 +1,40 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#include "view_axis.h"
#include "gl.h"
IGL_INLINE void igl::opengl2::view_axis(double * x, double * y, double * z)
{
double mv[16];
glGetDoublev(GL_MODELVIEW_MATRIX, mv);
igl::opengl2::view_axis(mv,x,y,z);
}
IGL_INLINE void igl::opengl2::view_axis(const double * mv, double * x, double * y, double * z)
{
*x = -mv[0*4+2];
*y = -mv[1*4+2];
*z = -mv[2*4+2];
}
template <typename DerivedV>
IGL_INLINE void igl::opengl2::view_axis(Eigen::PlainObjectBase<DerivedV> & V)
{
double x,y,z;
view_axis(&x,&y,&z);
V(0) = x;
V(1) = y;
V(2) = z;
}
#ifdef IGL_STATIC_LIBRARY
// Explicit template instantiation
// generated by autoexplicit.sh
template void igl::opengl2::view_axis<Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
template void igl::opengl2::view_axis<Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&);
#endif

View file

@ -0,0 +1,43 @@
// This file is part of libigl, a simple c++ geometry processing library.
//
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
//
// 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 http://mozilla.org/MPL/2.0/.
#ifndef IGL_OPENGL2_VIEW_AXIS_H
#define IGL_OPENGL2_VIEW_AXIS_H
#include "../igl_inline.h"
#include <Eigen/Core>
namespace igl
{
namespace opengl2
{
// Determines the view axis or depth axis of the current gl matrix
// Inputs:
// mv pointer to modelview matrix
// Outputs:
// x pointer to x-coordinate in scene coordinates of the un-normalized
// viewing axis
// y pointer to y-coordinate in scene coordinates of the un-normalized
// viewing axis
// z pointer to z-coordinate in scene coordinates of the un-normalized
// viewing axis
//
// Note: View axis is returned *UN-normalized*
IGL_INLINE void view_axis(const double * mv, double * x, double * y, double * z);
// Extract mv from current GL state.
IGL_INLINE void view_axis(double * x, double * y, double * z);
template <typename DerivedV>
IGL_INLINE void view_axis(Eigen::PlainObjectBase<DerivedV> & V);
}
};
#ifndef IGL_STATIC_LIBRARY
# include "view_axis.cpp"
#endif
#endif