model_data_mesh.h
1 /*
2 ** ClanLib SDK
3 ** Copyright (c) 1997-2013 The ClanLib Team
4 **
5 ** This software is provided 'as-is', without any express or implied
6 ** warranty. In no event will the authors be held liable for any damages
7 ** arising from the use of this software.
8 **
9 ** Permission is granted to anyone to use this software for any purpose,
10 ** including commercial applications, and to alter it and redistribute it
11 ** freely, subject to the following restrictions:
12 **
13 ** 1. The origin of this software must not be misrepresented; you must not
14 ** claim that you wrote the original software. If you use this software
15 ** in a product, an acknowledgment in the product documentation would be
16 ** appreciated but is not required.
17 ** 2. Altered source versions must be plainly marked as such, and must not be
18 ** misrepresented as being the original software.
19 ** 3. This notice may not be removed or altered from any source distribution.
20 **
21 ** Note: Some of the libraries ClanLib may link to may have additional
22 ** requirements or restrictions.
23 **
24 ** File Author(s):
25 **
26 ** Magnus Norddahl
27 */
28 
29 #pragma once
30 
31 #include "model_data_draw_range.h"
32 
33 namespace clan
34 {
35 
38 {
39 public:
40  std::vector<Vec3f> vertices;
41  std::vector<Vec3f> normals;
42  std::vector<Vec3f> tangents;
43  std::vector<Vec3f> bitangents;
44  std::vector<Vec4ub> bone_weights;
45  std::vector<Vec4ub> bone_selectors;
46  std::vector<Vec4ub> colors;
47  std::vector< std::vector<Vec2f> > channels;
48  std::vector<unsigned int> elements;
49  std::vector<ModelDataDrawRange> draw_ranges;
50 
51  void calculate_tangents();
52 };
53 
55 {
56  if (!channels.empty())
57  {
58  tangents.resize(vertices.size());
59  bitangents.resize(vertices.size());
60 
61  std::vector<Vec3f> tan1, tan2;
62  tan1.resize(vertices.size());
63  tan2.resize(vertices.size());
64  for (size_t i = 0; i + 2 < elements.size(); i += 3)
65  {
66  unsigned int i1 = elements[i + 0];
67  unsigned int i2 = elements[i + 1];
68  unsigned int i3 = elements[i + 2];
69 
70  const Vec3f& v1 = vertices[i1];
71  const Vec3f& v2 = vertices[i2];
72  const Vec3f& v3 = vertices[i3];
73 
74  const Vec2f& w1 = channels[0][i1];
75  const Vec2f& w2 = channels[0][i2];
76  const Vec2f& w3 = channels[0][i3];
77 
78  float x1 = v2.x - v1.x;
79  float x2 = v3.x - v1.x;
80  float y1 = v2.y - v1.y;
81  float y2 = v3.y - v1.y;
82  float z1 = v2.z - v1.z;
83  float z2 = v3.z - v1.z;
84 
85  float s1 = w2.x - w1.x;
86  float s2 = w3.x - w1.x;
87  float t1 = w2.y - w1.y;
88  float t2 = w3.y - w1.y;
89 
90  float r = 1.0f / (s1 * t2 - s2 * t1);
91  Vec3f sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
92  Vec3f tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
93 
94  tan1[i1] += sdir;
95  tan1[i2] += sdir;
96  tan1[i3] += sdir;
97 
98  tan2[i1] += tdir;
99  tan2[i2] += tdir;
100  tan2[i3] += tdir;
101  }
102 
103  for (size_t i = 0; i < vertices.size(); i++)
104  {
105  const Vec3f &n = normals[i];
106  const Vec3f &t = tan1[i];
107 
108  // Gram-Schmidt orthogonalize
109  tangents[i] = (t - n * Vec3f::dot(n, t)).normalize();
110 
111  // Calculate handedness
112  float handedness = (Vec3f::dot(Vec3f::cross(n, t), tan2[i]) < 0.0f) ? -1.0f : 1.0f;
113 
114  bitangents[i] = handedness * Vec3f::cross(n, t);
115  }
116  }
117 }
118 
119 }
120 
std::vector< unsigned int > elements
Definition: model_data_mesh.h:48
static Vec3< float > cross(const Vec3< float > &vector1, const Vec3< float > &vector2)
Calculate the cross product between two vectors.
Type x
Definition: vec3.h:81
Type y
Definition: vec3.h:82
std::vector< Vec3f > tangents
Definition: model_data_mesh.h:42
void calculate_tangents()
Definition: model_data_mesh.h:54
std::vector< Vec4ub > bone_selectors
Definition: model_data_mesh.h:45
std::vector< Vec4ub > bone_weights
Definition: model_data_mesh.h:44
std::vector< Vec3f > normals
Definition: model_data_mesh.h:41
Type x
Definition: vec2.h:82
std::vector< Vec3f > bitangents
Definition: model_data_mesh.h:43
std::vector< ModelDataDrawRange > draw_ranges
Definition: model_data_mesh.h:49
static float dot(const Vec3< float > &vector1, const Vec3< float > &vector2)
Dot products between two vectors.
Definition: vec3.h:107
std::vector< Vec3f > vertices
Definition: model_data_mesh.h:40
std::vector< Vec4ub > colors
Definition: model_data_mesh.h:46
std::vector< std::vector< Vec2f > > channels
Definition: model_data_mesh.h:47
Vertex attributes and draw ranges required to draw a mesh.
Definition: model_data_mesh.h:37
Type z
Definition: vec3.h:83
Type y
Definition: vec2.h:83