|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzCore includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tgl.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// TnzExt includes
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/ttexturesstorage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/plasticdeformerstorage.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// tcg includes
|
|
Toshihiro Shimizu |
890ddd |
#include "tcg/tcg_iterator_ops.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "ext/meshutils.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Templated drawing functions
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
struct NoColorFunction {
|
|
Shinya Kitaoka |
120a6e |
void faceColor(int f, int m) {}
|
|
Shinya Kitaoka |
120a6e |
void edgeColor(int e, int m) {}
|
|
Shinya Kitaoka |
120a6e |
void vertexColor(int v, int m) {}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
template
|
|
Shinya Kitaoka |
120a6e |
typename ColorFunction>
|
|
Shinya Kitaoka |
120a6e |
inline void tglDrawEdges(const TTextureMesh &mesh,
|
|
Shinya Kitaoka |
120a6e |
const VerticesContainer &vertices,
|
|
Shinya Kitaoka |
120a6e |
ColorFunction colorFunction) {
|
|
Shinya Kitaoka |
120a6e |
// Draw the mesh wireframe
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINES);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TTextureMesh::edges_container::const_iterator et, eEnd = mesh.edges().end();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (et = mesh.edges().begin(); et != eEnd; ++et) {
|
|
Shinya Kitaoka |
120a6e |
const TTextureMesh::edge_type &ed = *et;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int v0 = ed.vertex(0), v1 = ed.vertex(1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const PointType &p0 = vertices[v0];
|
|
Shinya Kitaoka |
120a6e |
const PointType &p1 = vertices[v1];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
colorFunction.edgeColor(et.index(), -1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
colorFunction.vertexColor(v0, -1);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(tcg::point_traits<pointtype>::x(p0),</pointtype>
|
|
Shinya Kitaoka |
120a6e |
tcg::point_traits<pointtype>::y(p0));</pointtype>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
colorFunction.vertexColor(v1, -1);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(tcg::point_traits<pointtype>::x(p1),</pointtype>
|
|
Shinya Kitaoka |
120a6e |
tcg::point_traits<pointtype>::y(p1));</pointtype>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename colorfunction=""></typename>
|
|
Shinya Kitaoka |
120a6e |
inline void tglDrawFaces(const TMeshImage &meshImage,
|
|
Shinya Kitaoka |
120a6e |
ColorFunction colorFunction) {
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_TRIANGLES);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int m, mCount = meshImage.meshes().size();
|
|
Shinya Kitaoka |
120a6e |
for (m = 0; m != mCount; ++m) {
|
|
Shinya Kitaoka |
120a6e |
const TTextureMesh &mesh = *meshImage.meshes()[m];
|
|
Shinya Kitaoka |
120a6e |
const tcg::list<ttexturevertex> &vertices = mesh.vertices();</ttexturevertex>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Draw the mesh wireframe
|
|
Shinya Kitaoka |
120a6e |
TTextureMesh::faces_container::const_iterator ft, fEnd = mesh.faces().end();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (ft = mesh.faces().begin(); ft != fEnd; ++ft) {
|
|
Shinya Kitaoka |
120a6e |
int v0, v1, v2;
|
|
Shinya Kitaoka |
120a6e |
mesh.faceVertices(ft.index(), v0, v1, v2);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const TTextureVertex &p0 = vertices[v0];
|
|
Shinya Kitaoka |
120a6e |
const TTextureVertex &p1 = vertices[v1];
|
|
Shinya Kitaoka |
120a6e |
const TTextureVertex &p2 = vertices[v2];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
colorFunction.faceColor(ft.index(), m);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
colorFunction.vertexColor(v0, m), glVertex2d(p0.P().x, p0.P().y);
|
|
Shinya Kitaoka |
120a6e |
colorFunction.vertexColor(v1, m), glVertex2d(p1.P().x, p1.P().y);
|
|
Shinya Kitaoka |
120a6e |
colorFunction.vertexColor(v2, m), glVertex2d(p2.P().x, p2.P().y);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <typename colorfunction=""></typename>
|
|
Shinya Kitaoka |
120a6e |
inline void tglDrawFaces(const TMeshImage &meshImage,
|
|
Shinya Kitaoka |
120a6e |
const PlasticDeformerDataGroup *group,
|
|
Shinya Kitaoka |
120a6e |
ColorFunction colorFunction) {
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_TRIANGLES);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Draw faces according to the group's sorted faces list
|
|
Shinya Kitaoka |
120a6e |
typedef std::vector<std::pair<int, int="">> SortedFacesVector;</std::pair<int,>
|
|
Shinya Kitaoka |
6f0974 |
|
|
Shinya Kitaoka |
120a6e |
const SortedFacesVector &sortedFaces = group->m_sortedFaces;
|
|
Shinya Kitaoka |
120a6e |
const std::vector<ttexturemeshp> &meshes = meshImage.meshes();</ttexturemeshp>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int m = -1;
|
|
Shinya Kitaoka |
120a6e |
const TTextureMesh *mesh;
|
|
Shinya Kitaoka |
120a6e |
const double *dstCoords;
|
|
Shinya Kitaoka |
6f0974 |
|
|
Shinya Kitaoka |
120a6e |
int v0, v1, v2;
|
|
Shinya Kitaoka |
6f0974 |
|
|
Shinya Kitaoka |
120a6e |
// Draw each face individually. Change tile and mesh data only if they change
|
|
Shinya Kitaoka |
120a6e |
SortedFacesVector::const_iterator sft, sfEnd(sortedFaces.end());
|
|
Shinya Kitaoka |
120a6e |
for (sft = sortedFaces.begin(); sft != sfEnd; ++sft) {
|
|
Shinya Kitaoka |
120a6e |
int f = sft->first, m_ = sft->second;
|
|
Shinya Kitaoka |
6f0974 |
|
|
Shinya Kitaoka |
120a6e |
if (m != m_) {
|
|
Shinya Kitaoka |
120a6e |
m = m_;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
mesh = meshes[m].getPointer();
|
|
Shinya Kitaoka |
120a6e |
dstCoords = group->m_datas[m].m_output.get();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
mesh->faceVertices(f, v0, v1, v2);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const double *d0 = dstCoords + (v0 << 1), *d1 = dstCoords + (v1 << 1),
|
|
Shinya Kitaoka |
120a6e |
*d2 = dstCoords + (v2 << 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
colorFunction.faceColor(f, m);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
colorFunction.vertexColor(v0, m), glVertex2d(*d0, *(d0 + 1));
|
|
Shinya Kitaoka |
120a6e |
colorFunction.vertexColor(v1, m), glVertex2d(*d1, *(d1 + 1));
|
|
Shinya Kitaoka |
120a6e |
colorFunction.vertexColor(v2, m), glVertex2d(*d2, *(d2 + 1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Mesh Image Utility functions implementation
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void transform(const TMeshImageP &meshImage, const TAffine &aff) {
|
|
Shinya Kitaoka |
120a6e |
const std::vector<ttexturemeshp> &meshes = meshImage->meshes();</ttexturemeshp>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int m, mCount = meshes.size();
|
|
Shinya Kitaoka |
120a6e |
for (m = 0; m != mCount; ++m) {
|
|
Shinya Kitaoka |
120a6e |
TTextureMesh &mesh = *meshes[m];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
tcg::list<ttexturemesh::vertex_type> &vertices = mesh.vertices();</ttexturemesh::vertex_type>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
tcg::list<ttexturemesh::vertex_type>::iterator vt, vEnd(vertices.end());</ttexturemesh::vertex_type>
|
|
Shinya Kitaoka |
120a6e |
for (vt = vertices.begin(); vt != vEnd; ++vt) vt->P() = aff * vt->P();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void tglDrawEdges(const TMeshImage &mi, const PlasticDeformerDataGroup *group) {
|
|
Shinya Kitaoka |
120a6e |
const std::vector<ttexturemeshp> &meshes = mi.meshes();</ttexturemeshp>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int m, mCount = meshes.size();
|
|
Shinya Kitaoka |
120a6e |
if (group) {
|
|
Shinya Kitaoka |
120a6e |
for (m = 0; m != mCount; ++m)
|
|
Shinya Kitaoka |
120a6e |
tglDrawEdges<const *,="" nocolorfunction="" tpointd="" tpointd,="">(</const>
|
|
Shinya Kitaoka |
120a6e |
*meshes[m], (const TPointD *)group->m_datas[m].m_output.get(),
|
|
Shinya Kitaoka |
120a6e |
NoColorFunction());
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
for (m = 0; m != mCount; ++m) {
|
|
Shinya Kitaoka |
120a6e |
const TTextureMesh &mesh = *meshes[m];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
tglDrawEdges<tcg::list<ttexturemesh::vertex_type>, TTextureVertex,</tcg::list<ttexturemesh::vertex_type>
|
|
Shinya Kitaoka |
120a6e |
NoColorFunction>(mesh, mesh.vertices(), NoColorFunction());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void tglDrawFaces(const TMeshImage &image,
|
|
Shinya Kitaoka |
120a6e |
const PlasticDeformerDataGroup *group) {
|
|
Shinya Kitaoka |
120a6e |
if (group)
|
|
Shinya Kitaoka |
120a6e |
tglDrawFaces(image, group, NoColorFunction());
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
tglDrawFaces(image, NoColorFunction());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Colored drawing functions
|
|
Toshihiro Shimizu |
890ddd |
//********************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
struct LinearColorFunction {
|
|
Shinya Kitaoka |
120a6e |
typedef double (*ValueFunc)(const LinearColorFunction *cf, int m,
|
|
Shinya Kitaoka |
120a6e |
int primitive);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
const TMeshImage &m_meshImg;
|
|
Shinya Kitaoka |
120a6e |
const PlasticDeformerDataGroup *m_group;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double m_min, m_max;
|
|
Shinya Kitaoka |
120a6e |
double *m_cMin, *m_cMax;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double m_dt;
|
|
Shinya Kitaoka |
120a6e |
bool m_degenerate;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
ValueFunc m_func;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
LinearColorFunction(const TMeshImage &meshImg,
|
|
Shinya Kitaoka |
120a6e |
const PlasticDeformerDataGroup *group, double min,
|
|
Shinya Kitaoka |
120a6e |
double max, double *cMin, double *cMax, ValueFunc func)
|
|
Shinya Kitaoka |
120a6e |
: m_meshImg(meshImg)
|
|
Shinya Kitaoka |
120a6e |
, m_group(group)
|
|
Shinya Kitaoka |
120a6e |
, m_min(min)
|
|
Shinya Kitaoka |
120a6e |
, m_max(max)
|
|
Shinya Kitaoka |
120a6e |
, m_cMin(cMin)
|
|
Shinya Kitaoka |
120a6e |
, m_cMax(cMax)
|
|
Shinya Kitaoka |
120a6e |
, m_dt(max - min)
|
|
Shinya Kitaoka |
120a6e |
, m_degenerate(m_dt < 1e-4)
|
|
Shinya Kitaoka |
120a6e |
, m_func(func) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void operator()(int primitive, int m) {
|
|
Shinya Kitaoka |
120a6e |
if (m_degenerate) {
|
|
Shinya Kitaoka |
120a6e |
glColor4d(0.5 * (m_cMin[0] + m_cMax[0]), 0.5 * (m_cMin[1] + m_cMax[1]),
|
|
Shinya Kitaoka |
120a6e |
0.5 * (m_cMin[2] + m_cMax[2]), 0.5 * (m_cMin[3] + m_cMax[3]));
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double val = m_func(this, m, primitive);
|
|
Shinya Kitaoka |
120a6e |
double t = (val - m_min) / m_dt, one_t = (m_max - val) / m_dt;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glColor4d(
|
|
Shinya Kitaoka |
120a6e |
one_t * m_cMin[0] + t * m_cMax[0], one_t * m_cMin[1] + t * m_cMax[1],
|
|
Shinya Kitaoka |
120a6e |
one_t * m_cMin[2] + t * m_cMax[2], one_t * m_cMin[3] + t * m_cMax[3]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
struct LinearVertexColorFunction final : public LinearColorFunction,
|
|
Shinya Kitaoka |
d1f6c4 |
public NoColorFunction {
|
|
Shinya Kitaoka |
120a6e |
LinearVertexColorFunction(const TMeshImage &meshImg,
|
|
Shinya Kitaoka |
120a6e |
const PlasticDeformerDataGroup *group, double min,
|
|
Shinya Kitaoka |
120a6e |
double max, double *cMin, double *cMax,
|
|
Shinya Kitaoka |
120a6e |
ValueFunc func)
|
|
Shinya Kitaoka |
120a6e |
: LinearColorFunction(meshImg, group, min, max, cMin, cMax, func) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void vertexColor(int v, int m) { operator()(v, m); }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
struct LinearFaceColorFunction final : public LinearColorFunction,
|
|
Shinya Kitaoka |
d1f6c4 |
public NoColorFunction {
|
|
Shinya Kitaoka |
120a6e |
LinearFaceColorFunction(const TMeshImage &meshImg,
|
|
Shinya Kitaoka |
120a6e |
const PlasticDeformerDataGroup *group, double min,
|
|
Shinya Kitaoka |
120a6e |
double max, double *cMin, double *cMax,
|
|
Shinya Kitaoka |
120a6e |
ValueFunc func)
|
|
Shinya Kitaoka |
120a6e |
: LinearColorFunction(meshImg, group, min, max, cMin, cMax, func) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void faceColor(int v, int m) { operator()(v, m); }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void tglDrawSO(const TMeshImage &image, double minColor[4], double maxColor[4],
|
|
Shinya Kitaoka |
120a6e |
const PlasticDeformerDataGroup *group, bool deformedDomain) {
|
|
Shinya Kitaoka |
120a6e |
struct locals {
|
|
Shinya Kitaoka |
120a6e |
static double returnSO(const LinearColorFunction *cf, int m, int f) {
|
|
Shinya Kitaoka |
120a6e |
return cf->m_group->m_datas[m].m_so[f];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double min = 0.0, max = 0.0;
|
|
Shinya Kitaoka |
120a6e |
if (group) min = group->m_soMin, max = group->m_soMax;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
LinearFaceColorFunction colorFunction(image, group, min, max, minColor,
|
|
Shinya Kitaoka |
120a6e |
maxColor, locals::returnSO);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (group && deformedDomain)
|
|
Shinya Kitaoka |
120a6e |
tglDrawFaces(image, group, colorFunction);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
tglDrawFaces(image, colorFunction);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void tglDrawRigidity(const TMeshImage &image, double minColor[4],
|
|
Shinya Kitaoka |
120a6e |
double maxColor[4], const PlasticDeformerDataGroup *group,
|
|
Shinya Kitaoka |
120a6e |
bool deformedDomain) {
|
|
Shinya Kitaoka |
120a6e |
struct locals {
|
|
Shinya Kitaoka |
120a6e |
static double returnRigidity(const LinearColorFunction *cf, int m, int v) {
|
|
Shinya Kitaoka |
120a6e |
return cf->m_meshImg.meshes()[m]->vertex(v).P().rigidity;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
LinearVertexColorFunction colorFunction(image, group, 1.0, 1e4, minColor,
|
|
Shinya Kitaoka |
120a6e |
maxColor, locals::returnRigidity);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (group && deformedDomain)
|
|
Shinya Kitaoka |
120a6e |
tglDrawFaces(image, group, colorFunction);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
tglDrawFaces(image, colorFunction);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//***********************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
// Texturized drawing implementation
|
|
Toshihiro Shimizu |
890ddd |
//***********************************************************************************************
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void tglDraw(const TMeshImage &meshImage, const DrawableTextureData &texData,
|
|
Shinya Kitaoka |
120a6e |
const TAffine &meshToTexAff,
|
|
Shinya Kitaoka |
120a6e |
const PlasticDeformerDataGroup &group) {
|
|
Shinya Kitaoka |
120a6e |
typedef MeshTexturizer::TextureData::TileData TileData;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Prepare OpenGL
|
|
Shinya Kitaoka |
120a6e |
glPushAttrib(GL_COLOR_BUFFER_BIT | GL_LINE_BIT |
|
|
Shinya Kitaoka |
120a6e |
GL_HINT_BIT); // Preserve original status bits
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_BLEND);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glEnable(GL_LINE_SMOOTH);
|
|
Shinya Kitaoka |
120a6e |
glLineWidth(1.0f);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Prepare variables
|
|
Shinya Kitaoka |
120a6e |
const std::vector<ttexturemeshp> &meshes = meshImage.meshes();</ttexturemeshp>
|
|
Shinya Kitaoka |
120a6e |
const TTextureMesh *mesh;
|
|
Shinya Kitaoka |
6f0974 |
|
|
Shinya Kitaoka |
120a6e |
typedef std::vector<std::pair<int, int="">> SortedFacesVector;</std::pair<int,>
|
|
Shinya Kitaoka |
120a6e |
const SortedFacesVector &sortedFaces = group.m_sortedFaces;
|
|
Shinya Kitaoka |
6f0974 |
|
|
Shinya Kitaoka |
120a6e |
const MeshTexturizer::TextureData *td = texData.m_textureData;
|
|
Shinya Kitaoka |
120a6e |
int t, tCount = td->m_tileDatas.size();
|
|
Shinya Kitaoka |
6f0974 |
|
|
Shinya Kitaoka |
120a6e |
GLuint texId = -1;
|
|
Shinya Kitaoka |
120a6e |
int m = -1;
|
|
Shinya Kitaoka |
120a6e |
const double *dstCoords;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int v0, v1, v2;
|
|
Shinya Kitaoka |
120a6e |
int e1ovi, e2ovi; // Edge X's Other Vertex Index (see below)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Prepare each tile's affine
|
|
Shinya Kitaoka |
120a6e |
std::vector<taffine> tileAff(tCount);</taffine>
|
|
Shinya Kitaoka |
120a6e |
for (t = 0; t != tCount; ++t) {
|
|
Shinya Kitaoka |
120a6e |
const TileData &tileData = td->m_tileDatas[t];
|
|
Shinya Kitaoka |
120a6e |
const TRectD &tileRect = tileData.m_tileGeometry;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
tileAff[t] = TScale(1.0 / (tileRect.x1 - tileRect.x0),
|
|
Shinya Kitaoka |
120a6e |
1.0 / (tileRect.y1 - tileRect.y0)) *
|
|
Shinya Kitaoka |
120a6e |
TTranslation(-tileRect.x0, -tileRect.y0) * meshToTexAff;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Draw each face individually, according to the group's sorted faces list.
|
|
Shinya Kitaoka |
120a6e |
// Change tile and mesh data only if they change - improves performance
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
SortedFacesVector::const_iterator sft, sfEnd(sortedFaces.end());
|
|
Shinya Kitaoka |
120a6e |
for (sft = sortedFaces.begin(); sft != sfEnd; ++sft) {
|
|
Shinya Kitaoka |
120a6e |
int f = sft->first, m_ = sft->second;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m != m_) {
|
|
Shinya Kitaoka |
120a6e |
// Change mesh if different from current
|
|
Shinya Kitaoka |
120a6e |
m = m_;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
mesh = meshes[m].getPointer();
|
|
Shinya Kitaoka |
120a6e |
dstCoords = group.m_datas[m].m_output.get();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Draw each face
|
|
Shinya Kitaoka |
120a6e |
const TTextureMesh::face_type &fc = mesh->face(f);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const TTextureMesh::edge_type &ed0 = mesh->edge(fc.edge(0)),
|
|
Shinya Kitaoka |
120a6e |
&ed1 = mesh->edge(fc.edge(1)),
|
|
Shinya Kitaoka |
120a6e |
&ed2 = mesh->edge(fc.edge(2));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
v0 = ed0.vertex(0);
|
|
Shinya Kitaoka |
120a6e |
v1 = ed0.vertex(1);
|
|
Shinya Kitaoka |
120a6e |
v2 = ed1.vertex((ed1.vertex(0) == v0) | (ed1.vertex(0) == v1));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
e1ovi = (ed1.vertex(0) == v1) |
|
|
Shinya Kitaoka |
120a6e |
(ed1.vertex(1) == v1); // ed1 and ed2 will refer to vertexes
|
|
Shinya Kitaoka |
120a6e |
e2ovi = 1 - e1ovi; // with index 2 and these.
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const TPointD &p0 = mesh->vertex(v0).P(), &p1 = mesh->vertex(v1).P(),
|
|
Shinya Kitaoka |
120a6e |
&p2 = mesh->vertex(v2).P();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (t = 0; t != tCount; ++t) {
|
|
Shinya Kitaoka |
120a6e |
// Draw face against tile
|
|
Shinya Kitaoka |
120a6e |
const TileData &tileData = td->m_tileDatas[t];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Map each face vertex to tile coordinates
|
|
Shinya Kitaoka |
120a6e |
TPointD s[3] = {tileAff[t] * p0, tileAff[t] * p1, tileAff[t] * p2};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Test the face bbox - tile intersection
|
|
Shinya Kitaoka |
120a6e |
if (std::min({s[0].x, s[1].x, s[2].x}) > 1.0 ||
|
|
Shinya Kitaoka |
120a6e |
std::min({s[0].y, s[1].y, s[2].y}) > 1.0 ||
|
|
Shinya Kitaoka |
120a6e |
std::max({s[0].x, s[1].x, s[2].x}) < 0.0 ||
|
|
Shinya Kitaoka |
120a6e |
std::max({s[0].y, s[1].y, s[2].y}) < 0.0)
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// If the tile has changed, interrupt the glBegin/glEnd block and bind the
|
|
Shinya Kitaoka |
120a6e |
// OpenGL texture corresponding to the new tile
|
|
Shinya Kitaoka |
120a6e |
if (tileData.m_textureId != texId) {
|
|
Shinya Kitaoka |
120a6e |
texId = tileData.m_textureId;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glBindTexture(
|
|
Shinya Kitaoka |
120a6e |
GL_TEXTURE_2D,
|
|
Shinya Kitaoka |
120a6e |
tileData
|
|
Shinya Kitaoka |
120a6e |
.m_textureId); // This must be OUTSIDE a glBegin/glEnd block
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const double *d[3] = {dstCoords + (v0 << 1), dstCoords + (v1 << 1),
|
|
Shinya Kitaoka |
120a6e |
dstCoords + (v2 << 1)};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
Now, draw primitives. A note about pixel arithmetic, here.
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Since line antialiasing in OpenGL just manipulates output fragments' alpha
|
|
Shinya Kitaoka |
120a6e |
components,
|
|
Shinya Kitaoka |
120a6e |
we must require that the input texture is NONPREMULTIPLIED.
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Furthermore, this function does not rely on the assumption that the output alpha
|
|
Shinya Kitaoka |
120a6e |
component
|
|
Shinya Kitaoka |
120a6e |
is discarded (as it happens when drawing on screen). This means that just using
|
|
Shinya Kitaoka |
120a6e |
a simple
|
|
Shinya Kitaoka |
120a6e |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) is not an option, since this
|
|
Shinya Kitaoka |
120a6e |
way THE INPUT
|
|
Shinya Kitaoka |
120a6e |
SRC ALPHA GETS MULTIPLIED BY ITSELF - see glBlendFunc's docs - and that shows.
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
The solution is to separate the rendering of RGB and M components - the formers
|
|
Shinya Kitaoka |
120a6e |
use
|
|
Shinya Kitaoka |
120a6e |
GL_SRC_ALPHA, while the latter uses GL_ONE. The result is a PREMULTIPLIED image.
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// First, draw antialiased face edges on the mesh border.
|
|
Shinya Kitaoka |
120a6e |
bool drawEd0 = (ed0.facesCount() < 2), drawEd1 = (ed1.facesCount() < 2),
|
|
Shinya Kitaoka |
120a6e |
drawEd2 = (ed2.facesCount() < 2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
Shinya Kitaoka |
120a6e |
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINES);
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (drawEd0) {
|
|
Shinya Kitaoka |
120a6e |
glTexCoord2d(s[0].x, s[0].y), glVertex2d(*d[0], *(d[0] + 1));
|
|
Shinya Kitaoka |
120a6e |
glTexCoord2d(s[1].x, s[1].y), glVertex2d(*d[1], *(d[1] + 1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (drawEd1) {
|
|
Shinya Kitaoka |
120a6e |
glTexCoord2d(s[e1ovi].x, s[e1ovi].y),
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(*d[e1ovi], *(d[e1ovi] + 1));
|
|
Shinya Kitaoka |
120a6e |
glTexCoord2d(s[2].x, s[2].y), glVertex2d(*d[2], *(d[2] + 1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (drawEd2) {
|
|
Shinya Kitaoka |
120a6e |
glTexCoord2d(s[e2ovi].x, s[e2ovi].y),
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(*d[e2ovi], *(d[e2ovi] + 1));
|
|
Shinya Kitaoka |
120a6e |
glTexCoord2d(s[2].x, s[2].y), glVertex2d(*d[2], *(d[2] + 1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
|
Shinya Kitaoka |
120a6e |
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINES);
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (drawEd0) {
|
|
Shinya Kitaoka |
120a6e |
glTexCoord2d(s[0].x, s[0].y), glVertex2d(*d[0], *(d[0] + 1));
|
|
Shinya Kitaoka |
120a6e |
glTexCoord2d(s[1].x, s[1].y), glVertex2d(*d[1], *(d[1] + 1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (drawEd1) {
|
|
Shinya Kitaoka |
120a6e |
glTexCoord2d(s[e1ovi].x, s[e1ovi].y),
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(*d[e1ovi], *(d[e1ovi] + 1));
|
|
Shinya Kitaoka |
120a6e |
glTexCoord2d(s[2].x, s[2].y), glVertex2d(*d[2], *(d[2] + 1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (drawEd2) {
|
|
Shinya Kitaoka |
120a6e |
glTexCoord2d(s[e2ovi].x, s[e2ovi].y),
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(*d[e2ovi], *(d[e2ovi] + 1));
|
|
Shinya Kitaoka |
120a6e |
glTexCoord2d(s[2].x, s[2].y), glVertex2d(*d[2], *(d[2] + 1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Finally, draw the face
|
|
Shinya Kitaoka |
120a6e |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
Shinya Kitaoka |
120a6e |
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_TRIANGLES);
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
glTexCoord2d(s[0].x, s[0].y), glVertex2d(*d[0], *(d[0] + 1));
|
|
Shinya Kitaoka |
120a6e |
glTexCoord2d(s[1].x, s[1].y), glVertex2d(*d[1], *(d[1] + 1));
|
|
Shinya Kitaoka |
120a6e |
glTexCoord2d(s[2].x, s[2].y), glVertex2d(*d[2], *(d[2] + 1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
|
Shinya Kitaoka |
120a6e |
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_TRIANGLES);
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
glTexCoord2d(s[0].x, s[0].y), glVertex2d(*d[0], *(d[0] + 1));
|
|
Shinya Kitaoka |
120a6e |
glTexCoord2d(s[1].x, s[1].y), glVertex2d(*d[1], *(d[1] + 1));
|
|
Shinya Kitaoka |
120a6e |
glTexCoord2d(s[2].x, s[2].y), glVertex2d(*d[2], *(d[2] + 1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glBindTexture(GL_TEXTURE_2D, 0); // Unbind texture
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
glPopAttrib();
|
|
Toshihiro Shimizu |
890ddd |
}
|