GteMesh.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.3.0 (2016/08/29)
7 
8 #pragma once
9 
10 #include <LowLevel/GteLogger.h>
12 #include <Mathematics/GteVector2.h>
13 #include <Mathematics/GteVector3.h>
14 #include <Mathematics/GteMatrix.h>
17 
18 // The Mesh class is designed to support triangulations of surfaces of a small
19 // number of topologies. See the documents
20 // http://www.geometrictools.com/MeshDifferentialGeometry.pdf
21 // http://www.geometrictools.com/MeshFactory.pdf
22 // for details.
23 //
24 // You must set the vertex attribute sources before calling Update().
25 //
26 // The semantic "position" is required and its source must be an array
27 // of Real with at least 3 channels so that positions are computed as
28 // Vector3<Real>.
29 //
30 // The positions are assumed to be parameterized by texture coordinates
31 // (u,v); the position is thought of as a function P(u,v). If texture
32 // coordinates are provided, the semantic must be "tcoord". If texture
33 // coordinates are not provided, default texture coordinates are computed
34 // internally as described in the mesh factory document.
35 //
36 // The frame for the tangent space is optional. All vectors in the frame
37 // must have sources that are arrays of Real with at least 3 channels per
38 // attribute. If normal vectors are provided, the semantic must be
39 // "normal".
40 //
41 // Two options are supported for tangent vectors. The first option is
42 // that the tangents are surface derivatives dP/du and dP/dv, which are
43 // not necessarily unit length or orthogonal. The semantics must be
44 // "dpdu" and "dpdv". The second option is that the tangents are unit
45 // length and orthogonal, with the infrequent possibility that a vertex
46 // is degenerate in that dP/du and dP/dv are linearly dependent. The
47 // semantics must be "tangent" and "bitangent".
48 //
49 // For each provided vertex attribute, a derived class can initialize
50 // that attribute by overriding one of the Initialize*() functions whose
51 // stubs are defined in this class.
52 
53 namespace gte
54 {
55 
56 enum class MeshTopology
57 {
58  ARBITRARY,
59  RECTANGLE,
60  CYLINDER,
61  TORUS,
62  DISK,
63  SPHERE
64 };
65 
67 {
68 public:
69  // Constructor for MeshTopology::ARBITRARY. The members topology,
70  // numVertices, and numTriangles are set in the obvious manner. The
71  // members numRows and numCols are set to zero. The remaining members
72  // must be set explicitly by the client.
73  inline MeshDescription(uint32_t inNumVertices, uint32_t inNumTriangles);
74 
75  // Constructor for topologies other than MeshTopology::ARBITRARY.
76  // Compute the number of vertices and triangles for the mesh based on the
77  // requested number of rows and columns. If the number of rows or columns
78  // is invalid for the specified topology, they are modified to be valid,
79  // in which case inNumRows/numRows and inNumCols/numCols can differ. If
80  // the input topology is MeshTopology::ARBITRARY, then inNumRows and
81  // inNumCols are assigned to numVertices and numTriangles, respectively,
82  // and numRows and numCols are set to zero. The remaining members must be
83  // set explicitly by the client.
84  inline MeshDescription(MeshTopology inTopology, uint32_t inNumRows, uint32_t inNumCols);
85 
87  uint32_t numVertices;
88  uint32_t numTriangles;
89  std::vector<VertexAttribute> vertexAttributes;
91  bool wantDynamicTangentSpaceUpdate; // default: false
92  bool wantCCW; // default: true
93 
94  // For internal use only.
97  uint32_t numRows, numCols;
98  uint32_t rMax, cMax, rIncrement;
99 
100  // After an attempt to construct a Mesh or Mesh-derived object, examine
101  // this value to determine whether the construction was successful.
103 };
104 
105 template <typename Real>
106 class Mesh
107 {
108 public:
109  // Construction and destruction. This constructor is for ARBITRARY topology.
110  // The vertices and indices must already be assigned by the client. Derived
111  // classes use the protected constructor, but assignment of vertices and
112  // indices occurs in the derived-class constructors.
113  Mesh(MeshDescription const& description, std::vector<MeshTopology> const& validTopologies);
114 
115  virtual ~Mesh();
116 
117  // No copying or assignment is allowed.
118  Mesh(Mesh const&) = delete;
119  Mesh& operator=(Mesh const&) = delete;
120 
121  // Member accessors.
122  inline MeshDescription const& GetDescription() const;
123 
124  // If the underlying geometric data varies dynamically, call this function
125  // to update whatever vertex attributes are specified by the vertex pool.
126  // A derived class
127  void Update();
128 
129 protected:
130  // Access the vertex attributes.
131  inline Vector3<Real>& Position(uint32_t i);
132  inline Vector3<Real>& Normal(uint32_t i);
133  inline Vector3<Real>& Tangent(uint32_t i);
134  inline Vector3<Real>& Bitangent(uint32_t i);
135  inline Vector3<Real>& DPDU(uint32_t i);
136  inline Vector3<Real>& DPDV(uint32_t i);
137  inline Vector2<Real>& TCoord(uint32_t i);
138 
139  // Compute the indices for non-arbitrary topologies. This function is
140  // called by derived classes.
141  void ComputeIndices();
142 
143  // The Update() function allows derived classes to use algorithms
144  // different from least-squares fitting to compute the normals (when
145  // no tangent-space information is requested) or to compute the frame
146  // (normals and tangent space). The UpdatePositions() is a stub; the
147  // base-class has no knowledge about how positions should be modified.
148  // A derived class, however, might choose to use dynamic updating
149  // and override UpdatePositions(). The base-class UpdateNormals()
150  // computes vertex normals as averages of area-weighted triangle
151  // normals (nonparametric approach). The base-class UpdateFrame()
152  // uses a least-squares algorithm for estimating the tangent space
153  // (parametric approach).
154  virtual void UpdatePositions() {}
155  virtual void UpdateNormals();
156  virtual void UpdateFrame();
157 
158  // Constructor inputs.
159  // The client requests this via the constructor; however, if it is
160  // requested and the vertex attributes do not contain entries for
161  // "tangent", "bitangent", "dpdu", or "dpdv", then this member is
162  // set to false.
164 
165  // Copied from mVertexAttributes when available.
177  size_t mDPDUStride;
178  size_t mDPDVStride;
180 
181  // When dynamic tangent-space updates are requested, the update algorithm
182  // requires texture coordinates (user-specified or non-local). It is
183  // possible to create a vertex-adjacent set (with indices into the
184  // vertex array) for each mesh vertex; however, instead we rely on a
185  // triangle iteration and incrementally store the information needed for
186  // the estimation of the tangent space. Each vertex has associated
187  // matrices D and U, but we need to store only U^T*U and D^T*U. See the
188  // PDF for details.
189  std::vector<Matrix<2, 2, Real>> mUTU;
190  std::vector<Matrix<3, 2, Real>> mDTU;
191 };
192 
193 
194 inline MeshDescription::MeshDescription(uint32_t inNumVertices, uint32_t inNumTriangles)
195  :
196  topology(MeshTopology::ARBITRARY),
197  numVertices(inNumVertices),
198  numTriangles(inNumTriangles),
199  wantDynamicTangentSpaceUpdate(false),
200  wantCCW(true),
201  hasTangentSpaceVectors(false),
202  allowUpdateFrame(false),
203  numRows(0),
204  numCols(0),
205  rMax(0),
206  cMax(0),
207  rIncrement(0),
208  constructed(false)
209 {
210  LogAssert(numVertices >= 3, "Invalid number of vertices.");
211  LogAssert(numTriangles >= 1, "Invalid number of triangles.");
212 }
213 
214 inline MeshDescription::MeshDescription(MeshTopology inTopology, uint32_t inNumRows, uint32_t inNumCols)
215  :
216  topology(inTopology),
218  wantCCW(true),
219  hasTangentSpaceVectors(false),
220  allowUpdateFrame(false),
221  constructed(false)
222 {
223  switch (topology)
224  {
226  numVertices = inNumRows;
227  numTriangles = inNumCols;
228  numRows = 0;
229  numCols = 0;
230  rMax = 0;
231  cMax = 0;
232  rIncrement = 0;
233  break;
234 
236  numRows = std::max(inNumRows, 2u);
237  numCols = std::max(inNumCols, 2u);
238  rMax = numRows - 1;
239  cMax = numCols - 1;
241  numVertices = (rMax + 1) * (cMax + 1);
242  numTriangles = 2 * rMax * cMax;
243  break;
244 
246  numRows = std::max(inNumRows, 2u);
247  numCols = std::max(inNumCols, 3u);
248  rMax = numRows - 1;
249  cMax = numCols;
250  rIncrement = numCols + 1;
251  numVertices = (rMax + 1) * (cMax + 1);
252  numTriangles = 2 * rMax * cMax;
253  break;
254 
255  case MeshTopology::TORUS:
256  numRows = std::max(inNumRows, 2u);
257  numCols = std::max(inNumCols, 3u);
258  rMax = numRows;
259  cMax = numCols;
260  rIncrement = numCols + 1;
261  numVertices = (rMax + 1) * (cMax + 1);
262  numTriangles = 2 * rMax * cMax;
263  break;
264 
265  case MeshTopology::DISK:
266  numRows = std::max(inNumRows, 1u);
267  numCols = std::max(inNumCols, 3u);
268  rMax = numRows - 1;
269  cMax = numCols;
270  rIncrement = numCols + 1;
271  numVertices = (rMax + 1) * (cMax + 1) + 1;
272  numTriangles = 2 * rMax * cMax + numCols;
273  break;
274 
276  numRows = std::max(inNumRows, 1u);
277  numCols = std::max(inNumCols, 3u);
278  rMax = numRows - 1;
279  cMax = numCols;
280  rIncrement = numCols + 1;
281  numVertices = (rMax + 1) * (cMax + 1) + 2;
282  numTriangles = 2 * rMax * cMax + 2 * numCols;
283  break;
284  }
285 }
286 
287 template <typename Real>
288 Mesh<Real>::Mesh(MeshDescription const& description, std::vector<MeshTopology> const& validTopologies)
289  :
290  mDescription(description),
291  mPositions(nullptr),
292  mNormals(nullptr),
293  mTangents(nullptr),
294  mBitangents(nullptr),
295  mDPDUs(nullptr),
296  mDPDVs(nullptr),
297  mTCoords(nullptr),
298  mPositionStride(0),
299  mNormalStride(0),
300  mTangentStride(0),
301  mBitangentStride(0),
302  mDPDUStride(0),
303  mDPDVStride(0),
304  mTCoordStride(0)
305 {
306  mDescription.constructed = false;
307  for (auto const& topology : validTopologies)
308  {
309  if (mDescription.topology == topology)
310  {
311  mDescription.constructed = true;
312  break;
313  }
314  }
315 
317  {
318  LogError("The mesh needs triangles/indices.");
319  mDescription.constructed = false;
320  return;
321  }
322 
323  // Set sources for the requested vertex attributes.
326  for (auto const& attribute : mDescription.vertexAttributes)
327  {
328  if (attribute.source != nullptr && attribute.stride > 0)
329  {
330  if (attribute.semantic == "position")
331  {
332  mPositions = reinterpret_cast<Vector3<Real>*>(attribute.source);
333  mPositionStride = attribute.stride;
334  continue;
335  }
336 
337  if (attribute.semantic == "normal")
338  {
339  mNormals = reinterpret_cast<Vector3<Real>*>(attribute.source);
340  mNormalStride = attribute.stride;
341  continue;
342  }
343 
344  if (attribute.semantic == "tangent")
345  {
346  mTangents = reinterpret_cast<Vector3<Real>*>(attribute.source);
347  mTangentStride = attribute.stride;
349  continue;
350  }
351 
352  if (attribute.semantic == "bitangent")
353  {
354  mBitangents = reinterpret_cast<Vector3<Real>*>(attribute.source);
355  mBitangentStride = attribute.stride;
357  continue;
358  }
359 
360  if (attribute.semantic == "dpdu")
361  {
362  mDPDUs = reinterpret_cast<Vector3<Real>*>(attribute.source);
363  mDPDUStride = attribute.stride;
365  continue;
366  }
367 
368  if (attribute.semantic == "dpdv")
369  {
370  mDPDVs = reinterpret_cast<Vector3<Real>*>(attribute.source);
371  mDPDVStride = attribute.stride;
373  continue;
374  }
375 
376  if (attribute.semantic == "tcoord")
377  {
378  mTCoords = reinterpret_cast<Vector2<Real>*>(attribute.source);
379  mTCoordStride = attribute.stride;
380  continue;
381  }
382  }
383  }
384 
385  if (!mPositions)
386  {
387  LogError("The mesh needs positions.");
388  mPositions = nullptr;
389  mNormals = nullptr;
390  mTangents = nullptr;
391  mBitangents = nullptr;
392  mDPDUs = nullptr;
393  mDPDVs = nullptr;
394  mTCoords = nullptr;
395  mPositionStride = 0;
396  mNormalStride = 0;
397  mTangentStride = 0;
398  mBitangentStride = 0;
399  mDPDUStride = 0;
400  mDPDVStride = 0;
401  mTCoordStride = 0;
402  mDescription.constructed = false;
403  return;
404  }
405 
406  // The initial value of allowUpdateFrame is the client request about
407  // wanting dynamic tangent-space updates. If the vertex attributes do
408  // not include tangent-space vectors, then dynamic updates are not
409  // necessary. If tangent-space vectors are present, the update algorithm
410  // requires texture coordinates (mTCoords must be nonnull) or must compute
411  // local coordinates (mNormals must be nonnull).
413  {
415  {
417  }
418 
419  if (!mTCoords && !mNormals)
420  {
422  }
423  }
424 
426  {
427  mUTU.resize(mDescription.numVertices);
428  mDTU.resize(mDescription.numVertices);
429  }
430 }
431 
432 template <typename Real>
434 {
435 }
436 
437 template <typename Real>
439 {
440  return mDescription;
441 }
442 
443 template <typename Real>
445 {
447  {
448  LogError("The Mesh object failed the construction.");
449  return;
450  }
451 
452  UpdatePositions();
453 
455  {
456  UpdateFrame();
457  }
458  else if (mNormals)
459  {
460  UpdateNormals();
461  }
462  // else: The mesh has no frame data, so there is nothing to do.
463 }
464 
465 template <typename Real>
467 {
468  char* positions = reinterpret_cast<char*>(mPositions);
469  return *reinterpret_cast<Vector3<Real>*>(positions + i * mPositionStride);
470 }
471 
472 template <typename Real>
474 {
475  char* normals = reinterpret_cast<char*>(mNormals);
476  return *reinterpret_cast<Vector3<Real>*>(normals + i * mNormalStride);
477 }
478 
479 template <typename Real>
481 {
482  char* tangents = reinterpret_cast<char*>(mTangents);
483  return *reinterpret_cast<Vector3<Real>*>(tangents + i * mTangentStride);
484 }
485 
486 template <typename Real>
488 {
489  char* bitangents = reinterpret_cast<char*>(mBitangents);
490  return *reinterpret_cast<Vector3<Real>*>(bitangents + i * mBitangentStride);
491 }
492 
493 template <typename Real>
494 inline Vector3<Real>& Mesh<Real>::DPDU(uint32_t i)
495 {
496  char* dpdus = reinterpret_cast<char*>(mDPDUs);
497  return *reinterpret_cast<Vector3<Real>*>(dpdus + i * mDPDUStride);
498 }
499 
500 template <typename Real>
501 inline Vector3<Real>& Mesh<Real>::DPDV(uint32_t i)
502 {
503  char* dpdvs = reinterpret_cast<char*>(mDPDVs);
504  return *reinterpret_cast<Vector3<Real>*>(dpdvs + i * mDPDVStride);
505 }
506 
507 template <typename Real>
509 {
510  char* tcoords = reinterpret_cast<char*>(mTCoords);
511  return *reinterpret_cast<Vector2<Real>*>(tcoords + i * mTCoordStride);
512 }
513 
514 template <typename Real>
516 {
517  uint32_t t = 0;
518  for (uint32_t r = 0, i = 0; r < mDescription.rMax; ++r)
519  {
520  uint32_t v0 = i, v1 = v0 + 1;
522  uint32_t v2 = i, v3 = v2 + 1;
523  for (uint32_t c = 0; c < mDescription.cMax; ++c, ++v0, ++v1, ++v2, ++v3)
524  {
525  if (mDescription.wantCCW)
526  {
527  mDescription.indexAttribute.SetTriangle(t++, v0, v1, v2);
528  mDescription.indexAttribute.SetTriangle(t++, v1, v3, v2);
529  }
530  else
531  {
532  mDescription.indexAttribute.SetTriangle(t++, v0, v2, v1);
533  mDescription.indexAttribute.SetTriangle(t++, v1, v2, v3);
534  }
535  }
536  }
537 
539  {
540  uint32_t v0 = 0, v1 = 1, v2 = mDescription.numVertices - 1;
541  for (unsigned int c = 0; c < mDescription.numCols; ++c, ++v0, ++v1)
542  {
543  if (mDescription.wantCCW)
544  {
546  }
547  else
548  {
550  }
551  }
552  }
554  {
555  uint32_t v0 = 0, v1 = 1, v2 = mDescription.numVertices - 2;
556  for (uint32_t c = 0; c < mDescription.numCols; ++c, ++v0, ++v1)
557  {
558  if (mDescription.wantCCW)
559  {
561  }
562  else
563  {
565  }
566  }
567 
569  v1 = v0 + 1;
571  for (uint32_t c = 0; c < mDescription.numCols; ++c, ++v0, ++v1)
572  {
573  if (mDescription.wantCCW)
574  {
576  }
577  else
578  {
580  }
581  }
582  }
583 }
584 
585 template <typename Real>
587 {
588  // Compute normal vector as normalized weighted averages of triangle
589  // normal vectors.
590 
591  // Set the normals to zero to allow accumulation of triangle normals.
592  Vector3<Real> zero{ (Real)0, (Real)0, (Real)0 };
593  for (uint32_t i = 0; i < mDescription.numVertices; ++i)
594  {
595  Normal(i) = zero;
596  }
597 
598  // Accumulate the triangle normals.
599  for (uint32_t t = 0; t < mDescription.numTriangles; ++t)
600  {
601  // Get the positions for the triangle.
602  uint32_t v0, v1, v2;
604  Vector3<Real> P0 = Position(v0);
605  Vector3<Real> P1 = Position(v1);
606  Vector3<Real> P2 = Position(v2);
607 
608  // Get the edge vectors.
609  Vector3<Real> E1 = P1 - P0;
610  Vector3<Real> E2 = P2 - P0;
611 
612  // Compute a triangle normal show length is twice the area of the
613  // triangle.
614  Vector3<Real> triangleNormal = Cross(E1, E2);
615 
616  // Accumulate the triangle normals.
617  Normal(v0) += triangleNormal;
618  Normal(v1) += triangleNormal;
619  Normal(v2) += triangleNormal;
620  }
621 
622  // Normalize the normals.
623  for (uint32_t i = 0; i < mDescription.numVertices; ++i)
624  {
625  Normalize(Normal(i), true);
626  }
627 }
628 
629 template <typename Real>
631 {
632  if (!mTCoords)
633  {
634  // We need to compute vertex normals first in order to compute
635  // local texture coordinates. The vertex normals are recomputed
636  // later based on estimated tangent vectors.
637  UpdateNormals();
638  }
639 
640  // Use the least-squares algorithm to estimate the tangent-space vectors
641  // and, if requested, normal vectors.
642  Matrix<2, 2, Real> zero2x2; // initialized to zero
643  Matrix<3, 2, Real> zero3x2; // initialized to zero
644  std::fill(mUTU.begin(), mUTU.end(), zero2x2);
645  std::fill(mDTU.begin(), mDTU.end(), zero3x2);
646  for (uint32_t t = 0; t < mDescription.numTriangles; ++t)
647  {
648  // Get the positions and differences for the triangle.
649  uint32_t v0, v1, v2;
651  Vector3<Real> P0 = Position(v0);
652  Vector3<Real> P1 = Position(v1);
653  Vector3<Real> P2 = Position(v2);
654  Vector3<Real> D10 = P1 - P0;
655  Vector3<Real> D20 = P2 - P0;
656  Vector3<Real> D21 = P2 - P1;
657 
658  if (mTCoords)
659  {
660  // Get the texture coordinates and differences for the triangle.
661  Vector2<Real> C0 = TCoord(v0);
662  Vector2<Real> C1 = TCoord(v1);
663  Vector2<Real> C2 = TCoord(v2);
664  Vector2<Real> U10 = C1 - C0;
665  Vector2<Real> U20 = C2 - C0;
666  Vector2<Real> U21 = C2 - C1;
667 
668  // Compute the outer products.
669  Matrix<2, 2, Real> outerU10 = OuterProduct(U10, U10);
670  Matrix<2, 2, Real> outerU20 = OuterProduct(U20, U20);
671  Matrix<2, 2, Real> outerU21 = OuterProduct(U21, U21);
672  Matrix<3, 2, Real> outerD10 = OuterProduct(D10, U10);
673  Matrix<3, 2, Real> outerD20 = OuterProduct(D20, U20);
674  Matrix<3, 2, Real> outerD21 = OuterProduct(D21, U21);
675 
676  // Keep a running sum of U^T*U and D^T*U.
677  mUTU[v0] += outerU10 + outerU20;
678  mUTU[v1] += outerU10 + outerU21;
679  mUTU[v2] += outerU20 + outerU21;
680  mDTU[v0] += outerD10 + outerD20;
681  mDTU[v1] += outerD10 + outerD21;
682  mDTU[v2] += outerD20 + outerD21;
683  }
684  else
685  {
686  // Compute local coordinates and differences for the triangle.
687  Vector3<Real> basis[3];
688 
689  basis[0] = Normal(v0);
690  ComputeOrthogonalComplement(1, basis, true);
691  Vector2<Real> U10{ Dot(basis[1], D10), Dot(basis[2], D10) };
692  Vector2<Real> U20{ Dot(basis[1], D20), Dot(basis[2], D20) };
693  mUTU[v0] += OuterProduct(U10, U10) + OuterProduct(U20, U20);
694  mDTU[v0] += OuterProduct(D10, U10) + OuterProduct(D20, U20);
695 
696  basis[0] = Normal(v1);
697  ComputeOrthogonalComplement(1, basis, true);
698  Vector2<Real> U01{ Dot(basis[1], D10), Dot(basis[2], D10) };
699  Vector2<Real> U21{ Dot(basis[1], D21), Dot(basis[2], D21) };
700  mUTU[v1] += OuterProduct(U01, U01) + OuterProduct(U21, U21);
701  mDTU[v1] += OuterProduct(D10, U01) + OuterProduct(D21, U21);
702 
703  basis[0] = Normal(v2);
704  ComputeOrthogonalComplement(1, basis, true);
705  Vector2<Real> U02{ Dot(basis[1], D20), Dot(basis[2], D20) };
706  Vector2<Real> U12{ Dot(basis[1], D21), Dot(basis[2], D21) };
707  mUTU[v2] += OuterProduct(U02, U02) + OuterProduct(U12, U12);
708  mDTU[v2] += OuterProduct(D20, U02) + OuterProduct(D21, U12);
709  }
710 
711  }
712 
713  for (uint32_t i = 0; i < mDescription.numVertices; ++i)
714  {
715  Matrix<3, 2, Real> jacobian = mDTU[i] * Inverse(mUTU[i]);
716 
717  Vector3<Real> basis[3];
718  basis[0] = { jacobian(0, 0), jacobian(1, 0), jacobian(2, 0) };
719  basis[1] = { jacobian(0, 1), jacobian(1, 1), jacobian(2, 1) };
720 
721  if (mDPDUs)
722  {
723  DPDU(i) = basis[0];
724  }
725  if (mDPDVs)
726  {
727  DPDV(i) = basis[1];
728  }
729 
730  ComputeOrthogonalComplement(2, basis, true);
731 
732  if (mNormals)
733  {
734  Normal(i) = basis[2];
735  }
736  if (mTangents)
737  {
738  Tangent(i) = basis[0];
739  }
740  if (mBitangents)
741  {
742  Bitangent(i) = basis[1];
743  }
744  }
745 }
746 
747 }
virtual void UpdatePositions()
Definition: GteMesh.h:154
MeshDescription const & GetDescription() const
Definition: GteMesh.h:438
std::vector< Matrix< 2, 2, Real > > mUTU
Definition: GteMesh.h:189
MeshDescription mDescription
Definition: GteMesh.h:163
void GetTriangle(uint32_t t, uint32_t &v0, uint32_t &v1, uint32_t &v2) const
#define LogAssert(condition, message)
Definition: GteLogger.h:86
uint32_t numRows
Definition: GteMesh.h:97
size_t mNormalStride
Definition: GteMesh.h:174
size_t mTangentStride
Definition: GteMesh.h:175
Vector3< Real > * mPositions
Definition: GteMesh.h:166
Vector3< Real > * mBitangents
Definition: GteMesh.h:169
GLfloat GLfloat v1
Definition: glcorearb.h:812
virtual void UpdateNormals()
Definition: GteMesh.h:586
Vector3< Real > & Bitangent(uint32_t i)
Definition: GteMesh.h:487
size_t mBitangentStride
Definition: GteMesh.h:176
IndexAttribute indexAttribute
Definition: GteMesh.h:90
uint32_t rIncrement
Definition: GteMesh.h:98
Vector3< Real > & DPDU(uint32_t i)
Definition: GteMesh.h:494
void Update()
Definition: GteMesh.h:444
Vector3< Real > * mTangents
Definition: GteMesh.h:168
void SetTriangle(uint32_t t, uint32_t v0, uint32_t v1, uint32_t v2)
virtual ~Mesh()
Definition: GteMesh.h:433
std::vector< VertexAttribute > vertexAttributes
Definition: GteMesh.h:89
const GLubyte * c
Definition: glext.h:11671
MeshTopology
Definition: GteMesh.h:56
bool wantDynamicTangentSpaceUpdate
Definition: GteMesh.h:91
#define LogError(message)
Definition: GteLogger.h:92
Vector3< Real > * mNormals
Definition: GteMesh.h:167
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
GLfloat GLfloat GLfloat GLfloat v3
Definition: glcorearb.h:814
Real Normalize(GVector< Real > &v, bool robust=false)
Definition: GteGVector.h:454
GLfloat v0
Definition: glcorearb.h:811
GLdouble GLdouble t
Definition: glext.h:239
uint32_t numVertices
Definition: GteMesh.h:87
virtual void UpdateFrame()
Definition: GteMesh.h:630
DualQuaternion< Real > Cross(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
Vector3< Real > * mDPDVs
Definition: GteMesh.h:171
std::vector< Matrix< 3, 2, Real > > mDTU
Definition: GteMesh.h:190
Vector2< Real > & TCoord(uint32_t i)
Definition: GteMesh.h:508
GLboolean r
Definition: glcorearb.h:1217
size_t mTCoordStride
Definition: GteMesh.h:179
Vector3< Real > & Tangent(uint32_t i)
Definition: GteMesh.h:480
size_t mPositionStride
Definition: GteMesh.h:173
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:813
Vector2< Real > * mTCoords
Definition: GteMesh.h:172
size_t mDPDUStride
Definition: GteMesh.h:177
void ComputeIndices()
Definition: GteMesh.h:515
Vector3< Real > & Normal(uint32_t i)
Definition: GteMesh.h:473
uint32_t numCols
Definition: GteMesh.h:97
Vector3< Real > & DPDV(uint32_t i)
Definition: GteMesh.h:501
bool hasTangentSpaceVectors
Definition: GteMesh.h:95
Quaternion< Real > Inverse(Quaternion< Real > const &d)
Real ComputeOrthogonalComplement(int numInputs, Vector2< Real > *v, bool robust=false)
Definition: GteVector2.h:123
Mesh(MeshDescription const &description, std::vector< MeshTopology > const &validTopologies)
Definition: GteMesh.h:288
Vector3< Real > & Position(uint32_t i)
Definition: GteMesh.h:466
Vector3< Real > * mDPDUs
Definition: GteMesh.h:170
MeshDescription(uint32_t inNumVertices, uint32_t inNumTriangles)
Definition: GteMesh.h:194
MeshTopology topology
Definition: GteMesh.h:86
uint32_t numTriangles
Definition: GteMesh.h:88
size_t mDPDVStride
Definition: GteMesh.h:178
GMatrix< Real > OuterProduct(GVector< Real > const &U, GVector< Real > const &V)
Definition: GteGMatrix.h:815


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:01