Changeset 147 for trunk/src/formats/obj_loader.cc
- Timestamp:
- 07/05/13 23:44:24 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/formats/obj_loader.cc
r138 r147 119 119 struct mesh_obj_reader : public obj_reader 120 120 { 121 mesh_obj_reader( mesh* m ) : m_mesh( m ), m_position( nullptr ), m_normal( nullptr ), m_tex_coord( nullptr ) {}121 mesh_obj_reader( mesh* m ) : m_mesh( m ), m_position( nullptr ), m_normal( nullptr ), m_tex_coord( nullptr ), m_tangent( nullptr ) {} 122 122 virtual std::size_t add_face( uint32* v, uint32* t, uint32* n, size_t count ); 123 virtual void calculate_tangents(); 123 124 124 125 vertex_attribute< vec3 >* m_position; 125 126 vertex_attribute< vec3 >* m_normal; 126 127 vertex_attribute< vec2 >* m_tex_coord; 128 vertex_attribute< vec4 >* m_tangent; 127 129 mesh* m_mesh; 128 130 }; … … 169 171 } 170 172 171 nv::obj_loader::obj_loader() 172 : m_mesh( nullptr ) 173 // based on http://www.terathon.com/code/tangent.html 174 void mesh_obj_reader::calculate_tangents() 175 { 176 m_tangent = m_mesh->add_attribute< vec4 >( "tangent" ); 177 178 std::vector< vec3 >& vp = m_position->get(); 179 std::vector< vec2 >& vt = m_tex_coord->get(); 180 std::vector< vec3 >& vn = m_normal->get(); 181 std::vector< vec4 >& tg = m_tangent->get(); 182 183 std::size_t count = vp.size(); 184 std::size_t tcount = count / 3; 185 186 std::vector< vec3 > tan1( count ); 187 std::vector< vec3 > tan2( count ); 188 tg.resize( count ); 189 190 for (std::size_t a = 0; a < tcount; ++a ) 191 { 192 uint32 i1 = a * 3; 193 uint32 i2 = a * 3 + 1; 194 uint32 i3 = a * 3 + 2; 195 196 const vec3& v1 = vp[i1]; 197 const vec3& v2 = vp[i2]; 198 const vec3& v3 = vp[i3]; 199 200 const vec2& w1 = vt[i1]; 201 const vec2& w2 = vt[i2]; 202 const vec2& w3 = vt[i3]; 203 204 vec3 xyz1 = v2 - v1; 205 vec3 xyz2 = v3 - v1; 206 vec2 st1 = w2 - w1; 207 vec2 st2 = w3 - w1; 208 209 float x1 = v2.x - v1.x; 210 float y1 = v2.y - v1.y; 211 float z1 = v2.z - v1.z; 212 213 float x2 = v3.x - v1.x; 214 float y2 = v3.y - v1.y; 215 float z2 = v3.z - v1.z; 216 217 float s1 = w2.x - w1.x; 218 float t1 = w2.y - w1.y; 219 float s2 = w3.x - w1.x; 220 float t2 = w3.y - w1.y; 221 222 float r = 1.0f / (s1 * t2 - s2 * t1); 223 224 vec3 sdir = ( t2 * xyz1 - t1 * xyz2 ) * r; 225 vec3 tdir = ( s1 * xyz2 - s2 * xyz1 ) * r; 226 227 // the += below obviously doesn't make sense in this case, but I'll 228 // leave it here for when I move to indices 229 tan1[i1] += sdir; 230 tan1[i2] += sdir; 231 tan1[i3] += sdir; 232 233 tan2[i1] += tdir; 234 tan2[i2] += tdir; 235 tan2[i3] += tdir; 236 } 237 238 for (std::size_t a = 0; a < count; ++a ) 239 { 240 const vec3& n = vn[a]; 241 const vec3& t = tan1[a]; 242 243 tg[a] = vec4( glm::normalize(t - n * glm::dot( n, t )), 244 (glm::dot(glm::cross(n, t), tan2[a]) < 0.0f) ? -1.0f : 1.0f ); 245 } 246 247 } 248 249 nv::obj_loader::obj_loader( bool tangents ) 250 : m_mesh( nullptr ), m_tangents( tangents ) 173 251 { 174 252 … … 191 269 reader.read_stream( sstream ); 192 270 m_size = reader.size; 271 if ( m_tangents ) 272 { 273 reader.calculate_tangents(); 274 } 193 275 return true; 194 276 }
Note: See TracChangeset
for help on using the changeset viewer.