| Revision | db6acbc7ea320b7172b449a55caa719808733b52 (tree) |
|---|---|
| Time | 2018-09-29 17:51:30 |
| Author | qw_fuku <fkhideaki@gmai...> |
| Commiter | qw_fuku |
Merge branch 'develop'
| @@ -28,7 +28,6 @@ void BaseMesh::Clear(void) | ||
| 28 | 28 | m_Materials.clear(); |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | - | |
| 32 | 31 | //! 1頂点1法線となるように法線バッファを生成する |
| 33 | 32 | void BaseMesh::CreateNormalsEachVerts(bool resetSmooth) |
| 34 | 33 | { |
| @@ -75,11 +74,11 @@ void BaseMesh::UpdateNormal(void) | ||
| 75 | 74 | |
| 76 | 75 | for (size_t j = 0; j < f.NumTriangles(); ++j) |
| 77 | 76 | { |
| 78 | - lm::vec3f n = CalcFaceNormal(f, 0, j+1, j+2); | |
| 77 | + lm::vec3f n = CalcFaceNormal(f, 0, j + 1, j + 2); | |
| 79 | 78 | |
| 80 | - m_Normals[f.m_NormIds[0 ]] += n; | |
| 81 | - m_Normals[f.m_NormIds[j+1]] += n; | |
| 82 | - m_Normals[f.m_NormIds[j+2]] += n; | |
| 79 | + m_Normals[f.m_NormIds[0]] += n; | |
| 80 | + m_Normals[f.m_NormIds[j + 1]] += n; | |
| 81 | + m_Normals[f.m_NormIds[j + 2]] += n; | |
| 83 | 82 | } |
| 84 | 83 | } |
| 85 | 84 |
| @@ -98,56 +97,60 @@ void BaseMesh::NormalizeNormal(void) | ||
| 98 | 97 | m_Normals[i].normalize(); |
| 99 | 98 | } |
| 100 | 99 | |
| 101 | - | |
| 102 | 100 | //! ポリゴンの構造からエッジバッファを生成する |
| 103 | 101 | void BaseMesh::CreateEdgeFromFace(void) |
| 104 | 102 | { |
| 105 | 103 | m_Edges.clear(); |
| 106 | 104 | |
| 107 | - std::vector< std::set<int> > VertLinks(m_Verts.size()); | |
| 105 | + std::vector<std::set<int>> VertLinks(m_Verts.size()); | |
| 108 | 106 | for (const BaseFace& f : m_Faces) |
| 109 | 107 | { |
| 110 | - for( size_t j = 0 ; j < f.NumVertices() ; ++j ) | |
| 108 | + for (size_t j = 0; j < f.NumVertices(); ++j) | |
| 111 | 109 | { |
| 112 | - int edge_vid0 = f.m_VertIds[ j ]; | |
| 113 | - int edge_vid1 = f.m_VertIds[ (j+1) % f.NumVertices() ]; | |
| 114 | - if( edge_vid0 > edge_vid1 ) | |
| 115 | - std::swap( edge_vid0 , edge_vid1 ); | |
| 110 | + int edge_vid0 = f.m_VertIds[j]; | |
| 111 | + int edge_vid1 = f.m_VertIds[(j + 1) % f.NumVertices()]; | |
| 112 | + if (edge_vid0 > edge_vid1) | |
| 113 | + std::swap(edge_vid0, edge_vid1); | |
| 116 | 114 | |
| 117 | - VertLinks[edge_vid0].insert( edge_vid1 ); | |
| 115 | + VertLinks[edge_vid0].insert(edge_vid1); | |
| 118 | 116 | } |
| 119 | 117 | } |
| 120 | 118 | |
| 121 | 119 | for (size_t i = 0; i < VertLinks.size(); ++i) |
| 122 | 120 | { |
| 123 | - for( std::set<int>::iterator iter = VertLinks[i].begin() ; iter != VertLinks[i].end() ; ++iter ) | |
| 121 | + for (std::set<int>::iterator iter = VertLinks[i].begin(); iter != VertLinks[i].end(); ++iter) | |
| 124 | 122 | { |
| 125 | 123 | BaseEdge e; |
| 126 | 124 | e.m_EdgeVids[0] = (int)i; |
| 127 | 125 | e.m_EdgeVids[1] = *iter; |
| 128 | - m_Edges.push_back( e ); | |
| 126 | + m_Edges.push_back(e); | |
| 129 | 127 | } |
| 130 | 128 | } |
| 131 | 129 | } |
| 132 | 130 | |
| 133 | 131 | void BaseMesh::CreateTangentsByUV(void) |
| 134 | 132 | { |
| 133 | + if (true) | |
| 134 | + CreateTangentsByUV_E(); | |
| 135 | + else | |
| 136 | + CreateTangentsByUV_F(); | |
| 137 | +} | |
| 138 | + | |
| 139 | +void BaseMesh::CreateTangentsByUV_E(void) | |
| 140 | +{ | |
| 135 | 141 | m_Tangents.clear(); |
| 136 | 142 | m_Tangents.resize(m_UVs.size(), lm::vec3f::get_zero()); |
| 137 | 143 | |
| 138 | - for (size_t i = 0; i < m_Faces.size(); ++i) | |
| 144 | + for (const lib_geo::BaseFace& f : m_Faces) | |
| 139 | 145 | { |
| 140 | - const lib_geo::BaseFace& f = m_Faces[i]; | |
| 141 | - | |
| 142 | - if( !f.HasUV() ) | |
| 146 | + if (!f.HasUV()) | |
| 143 | 147 | continue; |
| 144 | 148 | |
| 145 | - size_t polygon_size = f.m_UVIds.size(); | |
| 146 | - | |
| 147 | - for(size_t j = 0; j < polygon_size; ++j) | |
| 149 | + size_t numE = f.m_UVIds.size(); | |
| 150 | + for (size_t j = 0; j < numE; ++j) | |
| 148 | 151 | { |
| 149 | 152 | size_t idx0 = j; |
| 150 | - size_t idx1 = (j+1) % polygon_size; | |
| 153 | + size_t idx1 = (j + 1) % numE; | |
| 151 | 154 | |
| 152 | 155 | int uvid0 = f.m_UVIds[idx0]; |
| 153 | 156 | int uvid1 = f.m_UVIds[idx1]; |
| @@ -173,9 +176,68 @@ void BaseMesh::CreateTangentsByUV(void) | ||
| 173 | 176 | } |
| 174 | 177 | } |
| 175 | 178 | |
| 176 | - for (size_t i = 0; i < m_UVs.size(); ++i) | |
| 179 | + for (lm::vec3f& t : m_Tangents) | |
| 177 | 180 | { |
| 178 | - m_Tangents[i].normalize(); | |
| 181 | + t.normalize(); | |
| 182 | + } | |
| 183 | +} | |
| 184 | + | |
| 185 | +void BaseMesh::CreateTangentsByUV_F(void) | |
| 186 | +{ | |
| 187 | + m_Tangents.clear(); | |
| 188 | + m_Tangents.resize(m_UVs.size(), lm::vec3f::get_zero()); | |
| 189 | + | |
| 190 | + for (const lib_geo::BaseFace& f : m_Faces) | |
| 191 | + { | |
| 192 | + if (!f.HasUV()) | |
| 193 | + continue; | |
| 194 | + | |
| 195 | + size_t numT = f.m_UVIds.size() - 2; | |
| 196 | + for (size_t j = 0; j < numT; ++j) | |
| 197 | + { | |
| 198 | + size_t idx1 = 0; | |
| 199 | + size_t idx2 = j + 1; | |
| 200 | + size_t idx3 = j + 2; | |
| 201 | + | |
| 202 | + int uvid1 = f.m_UVIds[idx1]; | |
| 203 | + int uvid2 = f.m_UVIds[idx2]; | |
| 204 | + int uvid3 = f.m_UVIds[idx3]; | |
| 205 | + int vid1 = f.m_VertIds[idx1]; | |
| 206 | + int vid2 = f.m_VertIds[idx2]; | |
| 207 | + int vid3 = f.m_VertIds[idx3]; | |
| 208 | + int nid1 = f.m_NormIds[idx1]; | |
| 209 | + int nid2 = f.m_NormIds[idx2]; | |
| 210 | + int nid3 = f.m_NormIds[idx3]; | |
| 211 | + | |
| 212 | + lm::vec3f& P1 = m_Verts[vid1]; | |
| 213 | + lm::vec3f& P2 = m_Verts[vid2]; | |
| 214 | + lm::vec3f& P3 = m_Verts[vid3]; | |
| 215 | + lm::vec3f& N1 = m_Normals[nid1]; | |
| 216 | + lm::vec3f& N2 = m_Normals[nid2]; | |
| 217 | + lm::vec3f& N3 = m_Normals[nid3]; | |
| 218 | + lm::vec2f& uv1 = m_UVs[uvid1]; | |
| 219 | + lm::vec2f& uv2 = m_UVs[uvid2]; | |
| 220 | + lm::vec2f& uv3 = m_UVs[uvid3]; | |
| 221 | + | |
| 222 | + lm::vec3f dv21 = P2 - P1; | |
| 223 | + lm::vec3f dv31 = P3 - P1; | |
| 224 | + lm::vec2f dt21 = uv2 - uv1; | |
| 225 | + lm::vec2f dt31 = uv3 - uv1; | |
| 226 | + | |
| 227 | + float fn2 = dt21.x * dt31.y - dt21.y * dt31.x; | |
| 228 | + if (fn2 != 0) | |
| 229 | + { | |
| 230 | + lm::vec3f tt = -(dv31 * dt21.y - dv21 * dt31.y) / fn2; | |
| 231 | + m_Tangents[uvid1] = (N1 ^ tt) ^ N1; | |
| 232 | + m_Tangents[uvid2] = (N2 ^ tt) ^ N2; | |
| 233 | + m_Tangents[uvid3] = (N3 ^ tt) ^ N3; | |
| 234 | + } | |
| 235 | + } | |
| 236 | + } | |
| 237 | + | |
| 238 | + for (lm::vec3f& t : m_Tangents) | |
| 239 | + { | |
| 240 | + t.normalize(); | |
| 179 | 241 | } |
| 180 | 242 | } |
| 181 | 243 |
| @@ -243,7 +305,7 @@ void BaseMesh::SetAdj_VtoE(void) | ||
| 243 | 305 | |
| 244 | 306 | void BaseMesh::SetAdj_EtoF(void) |
| 245 | 307 | { |
| 246 | - std::vector< std::vector<BaseEdge*> > EidMap(m_Verts.size()); | |
| 308 | + std::vector<std::vector<BaseEdge*>> EidMap(m_Verts.size()); | |
| 247 | 309 | for (size_t i = 0; i < m_Edges.size(); ++i) |
| 248 | 310 | { |
| 249 | 311 | BaseEdge& e = m_Edges[i]; |
| @@ -267,7 +329,7 @@ void BaseMesh::SetAdj_EtoF(void) | ||
| 267 | 329 | { |
| 268 | 330 | int vid0 = f.m_VertIds[j]; |
| 269 | 331 | int vid1 = f.m_VertIds[(j + 1) % NumFVerts]; |
| 270 | - if(vid0 > vid1) | |
| 332 | + if (vid0 > vid1) | |
| 271 | 333 | std::swap(vid0, vid1); |
| 272 | 334 | |
| 273 | 335 | std::vector<BaseEdge*>& va_edges = EidMap[vid0]; |
| @@ -311,11 +373,11 @@ void BaseMesh::UpdateAdjVertNormal(void) | ||
| 311 | 373 | { |
| 312 | 374 | for (size_t j = 0; j < f.NumTriangles(); ++j) |
| 313 | 375 | { |
| 314 | - lm::vec3f n = CalcFaceNormal(f, 0, j+1, j+2); | |
| 376 | + lm::vec3f n = CalcFaceNormal(f, 0, j + 1, j + 2); | |
| 315 | 377 | |
| 316 | - m_VertAdj[f.m_VertIds[0 ]].m_NormalAvg += n; | |
| 317 | - m_VertAdj[f.m_VertIds[j+1]].m_NormalAvg += n; | |
| 318 | - m_VertAdj[f.m_VertIds[j+2]].m_NormalAvg += n; | |
| 378 | + m_VertAdj[f.m_VertIds[0]].m_NormalAvg += n; | |
| 379 | + m_VertAdj[f.m_VertIds[j + 1]].m_NormalAvg += n; | |
| 380 | + m_VertAdj[f.m_VertIds[j + 2]].m_NormalAvg += n; | |
| 319 | 381 | } |
| 320 | 382 | } |
| 321 | 383 |
| @@ -341,7 +403,6 @@ lm::range3f BaseMesh::CalcAABB(void) const | ||
| 341 | 403 | return aabb; |
| 342 | 404 | } |
| 343 | 405 | |
| 344 | - | |
| 345 | 406 | //! 全ポリゴンを三角化する. |
| 346 | 407 | void BaseMesh::Triangulate(void) |
| 347 | 408 | { |
| @@ -360,7 +421,7 @@ void BaseMesh::Triangulate(void) | ||
| 360 | 421 | continue; |
| 361 | 422 | } |
| 362 | 423 | |
| 363 | - for (size_t j = 0 ; j < f.NumTriangles(); ++j) | |
| 424 | + for (size_t j = 0; j < f.NumTriangles(); ++j) | |
| 364 | 425 | { |
| 365 | 426 | int sub_vid0 = 0; |
| 366 | 427 | int sub_vid1 = (int)j + 1; |
| @@ -382,7 +443,6 @@ void BaseMesh::Triangulate(void) | ||
| 382 | 443 | CreateAdjBuffers(); |
| 383 | 444 | } |
| 384 | 445 | |
| 385 | - | |
| 386 | 446 | //! 未使用頂点バッファを切り詰める. |
| 387 | 447 | void BaseMesh::RemoveNotReferencedVertex(void) |
| 388 | 448 | { |
| @@ -395,7 +455,7 @@ void BaseMesh::RemoveNotReferencedVertex(void) | ||
| 395 | 455 | std::vector<int> NewVertIdx(m_Verts.size(), -1); |
| 396 | 456 | for (size_t i = 0; i < VertRef.size(); ++i) |
| 397 | 457 | { |
| 398 | - if( VertRef[i] ) | |
| 458 | + if (VertRef[i]) | |
| 399 | 459 | NewVertIdx[i] = (int)VidCount++; |
| 400 | 460 | } |
| 401 | 461 |
| @@ -408,7 +468,7 @@ void BaseMesh::RemoveNotReferencedVertex(void) | ||
| 408 | 468 | } |
| 409 | 469 | |
| 410 | 470 | size_t UidCount = 0; |
| 411 | - std::vector<int> NewUVIdx( m_UVs.size() , -1 ); | |
| 471 | + std::vector<int> NewUVIdx(m_UVs.size(), -1); | |
| 412 | 472 | for (size_t i = 0; i < UVRef.size(); ++i) |
| 413 | 473 | { |
| 414 | 474 | if (UVRef[i]) |
| @@ -491,45 +551,43 @@ void BaseMesh::RemoveNotReferencedVertex(void) | ||
| 491 | 551 | // 修正前のメッシュで使用されていた頂点を求める |
| 492 | 552 | void BaseMesh::GetReferencedVertMap(std::vector<bool>& VertRef, std::vector<bool>& NormalRef, std::vector<bool>& UVRef) const |
| 493 | 553 | { |
| 494 | - VertRef.resize( m_Verts.size() , false ); | |
| 495 | - NormalRef.resize( m_Normals.size() , false ); | |
| 496 | - UVRef.resize( m_UVs.size() , false ); | |
| 554 | + VertRef.resize(m_Verts.size(), false); | |
| 555 | + NormalRef.resize(m_Normals.size(), false); | |
| 556 | + UVRef.resize(m_UVs.size(), false); | |
| 497 | 557 | |
| 498 | 558 | for (const BaseFace& face : m_Faces) |
| 499 | 559 | { |
| 500 | - for( size_t j = 0 ; j < face.m_VertIds.size() ; ++j ) | |
| 560 | + for (size_t j = 0; j < face.m_VertIds.size(); ++j) | |
| 501 | 561 | { |
| 502 | - VertRef[ face.m_VertIds[j] ] = true; | |
| 562 | + VertRef[face.m_VertIds[j]] = true; | |
| 503 | 563 | } |
| 504 | 564 | |
| 505 | - for( size_t j = 0 ; j < face.m_NormIds.size() ; ++j ) | |
| 565 | + for (size_t j = 0; j < face.m_NormIds.size(); ++j) | |
| 506 | 566 | { |
| 507 | - NormalRef[ face.m_NormIds[j] ] = true; | |
| 567 | + NormalRef[face.m_NormIds[j]] = true; | |
| 508 | 568 | } |
| 509 | 569 | |
| 510 | - for( size_t j = 0 ; j < face.m_UVIds.size() ; ++j ) | |
| 570 | + for (size_t j = 0; j < face.m_UVIds.size(); ++j) | |
| 511 | 571 | { |
| 512 | - UVRef[ face.m_UVIds[j] ] = true; | |
| 572 | + UVRef[face.m_UVIds[j]] = true; | |
| 513 | 573 | } |
| 514 | 574 | } |
| 515 | 575 | |
| 516 | 576 | for (const BasePolyline& pl : m_Polylines) |
| 517 | 577 | { |
| 518 | - for( size_t j = 0; j < pl.m_PLVids.size(); ++j ) | |
| 578 | + for (size_t j = 0; j < pl.m_PLVids.size(); ++j) | |
| 519 | 579 | { |
| 520 | - VertRef[ pl.m_PLVids[j] ] = true; | |
| 580 | + VertRef[pl.m_PLVids[j]] = true; | |
| 521 | 581 | } |
| 522 | 582 | } |
| 523 | 583 | } |
| 524 | 584 | |
| 525 | - | |
| 526 | 585 | //! 隣接頂点の結合 |
| 527 | 586 | void BaseMesh::RemDoubleVertex(void) |
| 528 | 587 | { |
| 529 | - // 実装中 | |
| 588 | + // 実装中 | |
| 530 | 589 | } |
| 531 | 590 | |
| 532 | - | |
| 533 | 591 | void BaseMesh::Translate(const lm::vec3f& v) |
| 534 | 592 | { |
| 535 | 593 | for (lm::vec3f& v : m_Verts) |
| @@ -538,7 +596,7 @@ void BaseMesh::Translate(const lm::vec3f& v) | ||
| 538 | 596 | } |
| 539 | 597 | } |
| 540 | 598 | |
| 541 | -void BaseMesh::Translate(float x , float y , float z) | |
| 599 | +void BaseMesh::Translate(float x, float y, float z) | |
| 542 | 600 | { |
| 543 | 601 | for (lm::vec3f& v : m_Verts) |
| 544 | 602 | { |
| @@ -554,7 +612,7 @@ void BaseMesh::Scale(float s) | ||
| 554 | 612 | } |
| 555 | 613 | } |
| 556 | 614 | |
| 557 | -void BaseMesh::Scale(float sx , float sy , float sz) | |
| 615 | +void BaseMesh::Scale(float sx, float sy, float sz) | |
| 558 | 616 | { |
| 559 | 617 | for (lm::vec3f& v : m_Verts) |
| 560 | 618 | { |
| @@ -586,7 +644,6 @@ void BaseMesh::Rotate(const lm::vec3f& axis, float angle) | ||
| 586 | 644 | v.rotate(angle, axis); |
| 587 | 645 | } |
| 588 | 646 | |
| 589 | - | |
| 590 | 647 | size_t BaseMesh::NumTriangles(void) const |
| 591 | 648 | { |
| 592 | 649 | size_t n = 0; |
| @@ -598,19 +655,18 @@ size_t BaseMesh::NumTriangles(void) const | ||
| 598 | 655 | return n; |
| 599 | 656 | } |
| 600 | 657 | |
| 601 | - | |
| 602 | 658 | void BaseMesh::CalcNormalEachVerts(std::vector<lm::vec3f>& normals) const |
| 603 | 659 | { |
| 604 | 660 | normals.clear(); |
| 605 | - normals.resize( m_Verts.size() , lm::vec3f(0.0f, 0.0f, 0.0f) ); | |
| 661 | + normals.resize(m_Verts.size(), lm::vec3f(0.0f, 0.0f, 0.0f)); | |
| 606 | 662 | |
| 607 | 663 | for (const BaseFace& f : m_Faces) |
| 608 | 664 | { |
| 609 | 665 | for (size_t j = 0; j < f.NumTriangles(); ++j) |
| 610 | 666 | { |
| 611 | - int vid0 = f.m_VertIds[0 ]; | |
| 612 | - int vid1 = f.m_VertIds[j+1]; | |
| 613 | - int vid2 = f.m_VertIds[j+2]; | |
| 667 | + int vid0 = f.m_VertIds[0]; | |
| 668 | + int vid1 = f.m_VertIds[j + 1]; | |
| 669 | + int vid2 = f.m_VertIds[j + 2]; | |
| 614 | 670 | const lm::vec3f& v0 = m_Verts[vid0]; |
| 615 | 671 | const lm::vec3f& v1 = m_Verts[vid1]; |
| 616 | 672 | const lm::vec3f& v2 = m_Verts[vid2]; |
| @@ -622,11 +678,10 @@ void BaseMesh::CalcNormalEachVerts(std::vector<lm::vec3f>& normals) const | ||
| 622 | 678 | } |
| 623 | 679 | } |
| 624 | 680 | |
| 625 | - for( size_t i = 0 ; i < normals.size() ; ++i ) | |
| 681 | + for (size_t i = 0; i < normals.size(); ++i) | |
| 626 | 682 | normals[i].normalize(); |
| 627 | 683 | } |
| 628 | 684 | |
| 629 | - | |
| 630 | 685 | lm::vec3f BaseMesh::GetFaceCenter(const size_t face_idx) const |
| 631 | 686 | { |
| 632 | 687 | return GetFaceCenter(m_Faces[face_idx]); |
| @@ -665,32 +720,31 @@ lm::vec3f BaseMesh::CalcFaceNormal(const BaseFace& f, int lvid0, int lvid1, int | ||
| 665 | 720 | return cross(v1 - v0, v2 - v0); |
| 666 | 721 | } |
| 667 | 722 | |
| 668 | - | |
| 669 | 723 | void BaseMesh::MergeLinkedPolylines(void) |
| 670 | 724 | { |
| 671 | - for(;;) | |
| 725 | + for (;;) | |
| 672 | 726 | { |
| 673 | 727 | bool updated = false; |
| 674 | 728 | |
| 675 | - for(size_t i = 0; i < m_Polylines.size(); ++i) | |
| 729 | + for (size_t i = 0; i < m_Polylines.size(); ++i) | |
| 676 | 730 | { |
| 677 | - for(size_t j = i + 1; j < m_Polylines.size(); ++j) | |
| 731 | + for (size_t j = i + 1; j < m_Polylines.size(); ++j) | |
| 678 | 732 | { |
| 679 | 733 | BasePolyline& p0 = m_Polylines[i]; |
| 680 | 734 | BasePolyline& p1 = m_Polylines[j]; |
| 681 | 735 | |
| 682 | - if(p0.m_PLVids.back() == p1.m_PLVids.front()) | |
| 736 | + if (p0.m_PLVids.back() == p1.m_PLVids.front()) | |
| 683 | 737 | { |
| 684 | 738 | } |
| 685 | - else if(p0.m_PLVids.back() == p1.m_PLVids.back()) | |
| 739 | + else if (p0.m_PLVids.back() == p1.m_PLVids.back()) | |
| 686 | 740 | { |
| 687 | 741 | std::reverse(p1.m_PLVids.begin(), p1.m_PLVids.end()); |
| 688 | 742 | } |
| 689 | - else if(p0.m_PLVids.front() == p1.m_PLVids.front()) | |
| 743 | + else if (p0.m_PLVids.front() == p1.m_PLVids.front()) | |
| 690 | 744 | { |
| 691 | 745 | std::reverse(p0.m_PLVids.begin(), p0.m_PLVids.end()); |
| 692 | 746 | } |
| 693 | - else if(p0.m_PLVids.front() == p1.m_PLVids.back()) | |
| 747 | + else if (p0.m_PLVids.front() == p1.m_PLVids.back()) | |
| 694 | 748 | { |
| 695 | 749 | std::reverse(p0.m_PLVids.begin(), p0.m_PLVids.end()); |
| 696 | 750 | std::reverse(p1.m_PLVids.begin(), p1.m_PLVids.end()); |
| @@ -700,7 +754,7 @@ void BaseMesh::MergeLinkedPolylines(void) | ||
| 700 | 754 | continue; |
| 701 | 755 | } |
| 702 | 756 | |
| 703 | - for(size_t k = 1; k < p1.m_PLVids.size(); ++k) | |
| 757 | + for (size_t k = 1; k < p1.m_PLVids.size(); ++k) | |
| 704 | 758 | { |
| 705 | 759 | p0.m_PLVids.push_back(p1.m_PLVids[k]); |
| 706 | 760 | } |
| @@ -713,12 +767,11 @@ void BaseMesh::MergeLinkedPolylines(void) | ||
| 713 | 767 | } |
| 714 | 768 | } |
| 715 | 769 | |
| 716 | - if(!updated) | |
| 770 | + if (!updated) | |
| 717 | 771 | break; |
| 718 | 772 | } |
| 719 | 773 | } |
| 720 | 774 | |
| 721 | - | |
| 722 | 775 | bool BaseMesh::GetClosestSubfacePos(const lm::vec3f& pos, SubfaceIdx& sf, lm::vec3f& close_pos) const |
| 723 | 776 | { |
| 724 | 777 | sf.Reset(); |
| @@ -32,6 +32,8 @@ public: | ||
| 32 | 32 | virtual void CreateEdgeFromFace(void); |
| 33 | 33 | |
| 34 | 34 | virtual void CreateTangentsByUV(void); |
| 35 | + virtual void CreateTangentsByUV_E(void); | |
| 36 | + virtual void CreateTangentsByUV_F(void); | |
| 35 | 37 | |
| 36 | 38 | virtual void ClearAllAdjBuffer(void); |
| 37 | 39 | virtual void CreateAdjBuffers(void); |
| @@ -15,10 +15,7 @@ namespace lib_geo | ||
| 15 | 15 | |
| 16 | 16 | StlMesh::StlMesh(void) |
| 17 | 17 | { |
| 18 | - for( int i = 0 ; i < MSG_LENGTH ; ++i ) | |
| 19 | - { | |
| 20 | - m_Message[i] = 0; | |
| 21 | - } | |
| 18 | + ClearMessage(); | |
| 22 | 19 | } |
| 23 | 20 | |
| 24 | 21 | void StlMesh::Clear(void) |
| @@ -29,7 +26,7 @@ void StlMesh::Clear(void) | ||
| 29 | 26 | |
| 30 | 27 | void StlMesh::ClearMessage(void) |
| 31 | 28 | { |
| 32 | - for( int i = 0 ; i < MSG_LENGTH ; ++i ) | |
| 29 | + for (int i = 0; i < MSG_LENGTH; ++i) | |
| 33 | 30 | { |
| 34 | 31 | m_Message[i] = 0; |
| 35 | 32 | } |
| @@ -44,44 +41,44 @@ bool StlMesh::LoadBinary(std::istream& in) | ||
| 44 | 41 | in.read(m_Message, MSG_LENGTH); |
| 45 | 42 | |
| 46 | 43 | unsigned int NumFaces; |
| 47 | - in.read((char*)&NumFaces , sizeof(unsigned int)); | |
| 44 | + in.read((char*)&NumFaces, sizeof(unsigned int)); | |
| 48 | 45 | |
| 49 | 46 | const size_t expectedBinaryFileSize = NumFaces * 50 + 84; |
| 50 | 47 | |
| 51 | 48 | if (expectedBinaryFileSize != fileSize) |
| 52 | 49 | return false; |
| 53 | 50 | |
| 54 | - m_Faces.resize( NumFaces ); | |
| 51 | + m_Faces.resize(NumFaces); | |
| 55 | 52 | for (size_t i = 0; i < NumFaces; ++i) |
| 56 | 53 | { |
| 57 | - char padding[2] = { 0 , 0 }; | |
| 54 | + char padding[2] = {0, 0}; | |
| 58 | 55 | |
| 59 | 56 | StlFace& f = m_Faces[i]; |
| 60 | - in.read( (char*)f.m_Normal.v() , sizeof(float)*3 ); | |
| 61 | - in.read( (char*)f.m_Verts[0].v() , sizeof(float)*3 ); | |
| 62 | - in.read( (char*)f.m_Verts[1].v() , sizeof(float)*3 ); | |
| 63 | - in.read( (char*)f.m_Verts[2].v() , sizeof(float)*3 ); | |
| 64 | - in.read( padding , 2 ); | |
| 57 | + in.read((char*)f.m_Normal.v(), sizeof(float) * 3); | |
| 58 | + in.read((char*)f.m_Verts[0].v(), sizeof(float) * 3); | |
| 59 | + in.read((char*)f.m_Verts[1].v(), sizeof(float) * 3); | |
| 60 | + in.read((char*)f.m_Verts[2].v(), sizeof(float) * 3); | |
| 61 | + in.read(padding, 2); | |
| 65 | 62 | } |
| 66 | 63 | |
| 67 | 64 | return true; |
| 68 | 65 | } |
| 69 | 66 | |
| 70 | -bool StlMesh::LoadText(std::istream& in) | |
| 67 | +bool StlMesh::LoadAscii(std::istream& in) | |
| 71 | 68 | { |
| 72 | 69 | if (!IsExistValidAsciiHeader(in)) |
| 73 | 70 | return false; |
| 74 | 71 | |
| 75 | 72 | Clear(); |
| 76 | 73 | |
| 77 | - in.seekg( 0 , std::ios::beg ); | |
| 74 | + in.seekg(0, std::ios::beg); | |
| 78 | 75 | |
| 79 | 76 | StlFace f; |
| 80 | 77 | int vcount = 0; |
| 81 | 78 | |
| 82 | 79 | std::string ws; |
| 83 | 80 | std::getline(in, ws); |
| 84 | - while(!in.eof()) | |
| 81 | + while (!in.eof()) | |
| 85 | 82 | { |
| 86 | 83 | std::getline(in, ws); |
| 87 | 84 | if (ws.empty()) |
| @@ -94,7 +91,7 @@ bool StlMesh::LoadText(std::istream& in) | ||
| 94 | 91 | if (s == "facet") |
| 95 | 92 | { |
| 96 | 93 | lm::vec3f o(0.0f, 0.0f, 0.0f); |
| 97 | - f.m_Normal = o; | |
| 94 | + f.m_Normal = o; | |
| 98 | 95 | f.m_Verts[0] = o; |
| 99 | 96 | f.m_Verts[1] = o; |
| 100 | 97 | f.m_Verts[2] = o; |
| @@ -132,7 +129,7 @@ bool StlMesh::LoadText(std::istream& in) | ||
| 132 | 129 | |
| 133 | 130 | bool StlMesh::IsExistValidAsciiHeader(std::istream& in) |
| 134 | 131 | { |
| 135 | - in.read( m_Message , MSG_LENGTH ); | |
| 132 | + in.read(m_Message, MSG_LENGTH); | |
| 136 | 133 | |
| 137 | 134 | m_Message[5] = '\0'; |
| 138 | 135 | std::string top = m_Message; |
| @@ -148,91 +145,128 @@ bool StlMesh::Load(std::istream& ist) | ||
| 148 | 145 | |
| 149 | 146 | ist.seekg(0, std::ios::beg); |
| 150 | 147 | |
| 151 | - if (LoadText(ist)) | |
| 148 | + if (LoadAscii(ist)) | |
| 152 | 149 | return true; |
| 153 | 150 | |
| 154 | 151 | return false; |
| 155 | - | |
| 156 | 152 | } |
| 157 | 153 | |
| 158 | -bool StlMesh::Load( const std::string& i_Filename ) | |
| 154 | +bool StlMesh::Load(const std::string& filename) | |
| 159 | 155 | { |
| 160 | - std::ifstream ifs( i_Filename.c_str() , std::ios::binary ); | |
| 161 | - if( !ifs.is_open() ) | |
| 156 | + std::ifstream ifs(filename.c_str(), std::ios::binary); | |
| 157 | + if (!ifs.is_open()) | |
| 162 | 158 | return false; |
| 163 | 159 | |
| 164 | 160 | return Load(ifs); |
| 165 | 161 | } |
| 166 | 162 | |
| 167 | -bool StlMesh::Save( std::ostream& ost ) const | |
| 163 | +bool StlMesh::SaveBinary(std::ostream& ost) const | |
| 168 | 164 | { |
| 169 | 165 | unsigned int NumFaces = (unsigned int)m_Faces.size(); |
| 170 | - ost.write( m_Message , MSG_LENGTH ); | |
| 171 | - ost.write( (char*)&NumFaces , sizeof(unsigned int) ); | |
| 166 | + ost.write(m_Message, MSG_LENGTH); | |
| 167 | + ost.write((char*)&NumFaces, sizeof(unsigned int)); | |
| 172 | 168 | |
| 173 | - for( size_t i = 0 ; i < NumFaces ; ++i ) | |
| 169 | + char padding[2] = {0, 0}; | |
| 170 | + | |
| 171 | + for (const StlFace& f : m_Faces) | |
| 174 | 172 | { |
| 175 | - char padding[2] = { 0 , 0 }; | |
| 173 | + ost.write((char*)f.m_Normal.v(), sizeof(float) * 3); | |
| 174 | + ost.write((char*)f.m_Verts[0].v(), sizeof(float) * 3); | |
| 175 | + ost.write((char*)f.m_Verts[1].v(), sizeof(float) * 3); | |
| 176 | + ost.write((char*)f.m_Verts[2].v(), sizeof(float) * 3); | |
| 177 | + ost.write(padding, 2); | |
| 178 | + } | |
| 179 | + | |
| 180 | + return true; | |
| 181 | +} | |
| 182 | + | |
| 183 | +bool StlMesh::SaveBinary(const std::string& filename) const | |
| 184 | +{ | |
| 185 | + std::ofstream ofs(filename.c_str(), std::ios::binary); | |
| 186 | + if (!ofs.is_open()) | |
| 187 | + return false; | |
| 188 | + | |
| 189 | + return SaveBinary(ofs); | |
| 190 | +} | |
| 191 | + | |
| 192 | +bool StlMesh::SaveAscii(std::ostream& ost) const | |
| 193 | +{ | |
| 194 | + ost << "solid " << m_Message << std::endl; | |
| 176 | 195 | |
| 177 | - ost.write( (char*)m_Faces[i].m_Normal.v() , sizeof(float)*3 ); | |
| 178 | - ost.write( (char*)m_Faces[i].m_Verts[0].v() , sizeof(float)*3 ); | |
| 179 | - ost.write( (char*)m_Faces[i].m_Verts[1].v() , sizeof(float)*3 ); | |
| 180 | - ost.write( (char*)m_Faces[i].m_Verts[2].v() , sizeof(float)*3 ); | |
| 181 | - ost.write( padding , 2 ); | |
| 196 | + for (const StlFace& f : m_Faces) | |
| 197 | + { | |
| 198 | + WriteAscciiVert(ost, "facet normal", f.m_Normal); | |
| 199 | + ost << "outer loop" << std::endl; | |
| 200 | + WriteAscciiVert(ost, "vertex", f.m_Verts[0]); | |
| 201 | + WriteAscciiVert(ost, "vertex", f.m_Verts[1]); | |
| 202 | + WriteAscciiVert(ost, "vertex", f.m_Verts[2]); | |
| 203 | + ost << "endloop" << std::endl; | |
| 204 | + ost << "endfacet" << std::endl; | |
| 182 | 205 | } |
| 183 | 206 | |
| 207 | + ost << "endsolid" << std::endl; | |
| 208 | + | |
| 184 | 209 | return true; |
| 185 | 210 | } |
| 186 | 211 | |
| 187 | -bool StlMesh::Save( const std::string& i_Filename ) const | |
| 212 | +bool StlMesh::SaveAscii(const std::string& filename) const | |
| 188 | 213 | { |
| 189 | - std::ofstream ofs( i_Filename.c_str() , std::ios::binary ); | |
| 190 | - if( !ofs.is_open() ) | |
| 214 | + std::ofstream ofs(filename.c_str()); | |
| 215 | + if (!ofs.is_open()) | |
| 191 | 216 | return false; |
| 192 | 217 | |
| 193 | - return Save( ofs ); | |
| 218 | + return SaveAscii(ofs); | |
| 219 | +} | |
| 220 | + | |
| 221 | +void StlMesh::WriteAscciiVert(std::ostream& out, const char* head, const lm::vec3f& v) const | |
| 222 | +{ | |
| 223 | + out << head | |
| 224 | + << " " << v.x | |
| 225 | + << " " << v.y | |
| 226 | + << " " << v.z | |
| 227 | + << std::endl; | |
| 194 | 228 | } |
| 195 | 229 | |
| 196 | -bool StlMesh::ConvertToBaseMesh( BaseMesh& o_mesh ) const | |
| 230 | +bool StlMesh::ConvertToBaseMesh(BaseMesh& bm) const | |
| 197 | 231 | { |
| 198 | - o_mesh.Clear(); | |
| 232 | + bm.Clear(); | |
| 199 | 233 | |
| 200 | - o_mesh.m_Verts.resize( m_Faces.size() * 3 ); | |
| 201 | - o_mesh.m_Normals.resize( m_Faces.size() ); | |
| 202 | - o_mesh.m_Faces.resize( m_Faces.size() ); | |
| 234 | + bm.m_Verts.resize(m_Faces.size() * 3); | |
| 235 | + bm.m_Normals.resize(m_Faces.size()); | |
| 236 | + bm.m_Faces.resize(m_Faces.size()); | |
| 203 | 237 | |
| 204 | - for( size_t i = 0 ; i < m_Faces.size() ; ++i ) | |
| 238 | + for (size_t i = 0; i < m_Faces.size(); ++i) | |
| 205 | 239 | { |
| 206 | 240 | const StlFace& f = m_Faces[i]; |
| 207 | 241 | |
| 208 | - o_mesh.m_Verts[ i * 3 + 0 ] = f.m_Verts[0]; | |
| 209 | - o_mesh.m_Verts[ i * 3 + 1 ] = f.m_Verts[1]; | |
| 210 | - o_mesh.m_Verts[ i * 3 + 2 ] = f.m_Verts[2]; | |
| 242 | + bm.m_Verts[i * 3 + 0] = f.m_Verts[0]; | |
| 243 | + bm.m_Verts[i * 3 + 1] = f.m_Verts[1]; | |
| 244 | + bm.m_Verts[i * 3 + 2] = f.m_Verts[2]; | |
| 211 | 245 | |
| 212 | - o_mesh.m_Normals[ i ] = f.m_Normal; | |
| 246 | + bm.m_Normals[i] = f.m_Normal; | |
| 213 | 247 | |
| 214 | - o_mesh.m_Faces[i].m_VertIds.resize(3); | |
| 215 | - o_mesh.m_Faces[i].m_NormIds.resize(3); | |
| 248 | + BaseFace& bf = bm.m_Faces[i]; | |
| 249 | + bf.m_VertIds.resize(3); | |
| 250 | + bf.m_NormIds.resize(3); | |
| 216 | 251 | |
| 217 | - o_mesh.m_Faces[i].m_VertIds[0] = (int)(i * 3 + 0); | |
| 218 | - o_mesh.m_Faces[i].m_VertIds[1] = (int)(i * 3 + 1); | |
| 219 | - o_mesh.m_Faces[i].m_VertIds[2] = (int)(i * 3 + 2); | |
| 252 | + bf.m_VertIds[0] = (int)(i * 3 + 0); | |
| 253 | + bf.m_VertIds[1] = (int)(i * 3 + 1); | |
| 254 | + bf.m_VertIds[2] = (int)(i * 3 + 2); | |
| 220 | 255 | |
| 221 | - o_mesh.m_Faces[i].m_NormIds[0] = (int)i; | |
| 222 | - o_mesh.m_Faces[i].m_NormIds[1] = (int)i; | |
| 223 | - o_mesh.m_Faces[i].m_NormIds[2] = (int)i; | |
| 256 | + bf.m_NormIds[0] = (int)i; | |
| 257 | + bf.m_NormIds[1] = (int)i; | |
| 258 | + bf.m_NormIds[2] = (int)i; | |
| 224 | 259 | } |
| 225 | 260 | |
| 226 | 261 | return true; |
| 227 | 262 | } |
| 228 | 263 | |
| 229 | - | |
| 230 | 264 | //! サイズ0の法線を含む場合にtrueを返す |
| 231 | 265 | bool StlMesh::ExistZeroLengthNormal(void) const |
| 232 | 266 | { |
| 233 | - for( size_t i = 0 ; i < m_Faces.size() ; ++i ) | |
| 267 | + for (const StlFace& f : m_Faces) | |
| 234 | 268 | { |
| 235 | - if( m_Faces[i].m_Normal.is_zero() ) | |
| 269 | + if (f.m_Normal.is_zero()) | |
| 236 | 270 | return true; |
| 237 | 271 | } |
| 238 | 272 |
| @@ -17,8 +17,8 @@ class BaseMesh; | ||
| 17 | 17 | class StlFace |
| 18 | 18 | { |
| 19 | 19 | public: |
| 20 | - lm::vec3f m_Normal; | |
| 21 | - lm::vec3f m_Verts[3]; | |
| 20 | + lm::vec3f m_Normal; | |
| 21 | + lm::vec3f m_Verts[3]; | |
| 22 | 22 | }; |
| 23 | 23 | |
| 24 | 24 |
| @@ -31,12 +31,16 @@ public: | ||
| 31 | 31 | StlMesh(void); |
| 32 | 32 | void Clear(void); |
| 33 | 33 | |
| 34 | - bool Load( std::istream& ist ); | |
| 35 | - bool Load( const std::string& i_Filename ); | |
| 36 | - bool Save( std::ostream& ost ) const; | |
| 37 | - bool Save( const std::string& i_Filename ) const; | |
| 34 | + bool Load(std::istream& ist); | |
| 35 | + bool Load(const std::string& filename); | |
| 38 | 36 | |
| 39 | - bool ConvertToBaseMesh( BaseMesh& o_mesh ) const; | |
| 37 | + bool SaveBinary(std::ostream& ost) const; | |
| 38 | + bool SaveBinary(const std::string& filename) const; | |
| 39 | + | |
| 40 | + bool SaveAscii(std::ostream& ost) const; | |
| 41 | + bool SaveAscii(const std::string& filename) const; | |
| 42 | + | |
| 43 | + bool ConvertToBaseMesh(BaseMesh& bm) const; | |
| 40 | 44 | |
| 41 | 45 | bool ExistZeroLengthNormal(void) const; |
| 42 | 46 |
| @@ -44,12 +48,14 @@ private: | ||
| 44 | 48 | void ClearMessage(void); |
| 45 | 49 | |
| 46 | 50 | bool LoadBinary(std::istream& in); |
| 47 | - bool LoadText(std::istream& in); | |
| 51 | + bool LoadAscii(std::istream& in); | |
| 48 | 52 | |
| 49 | 53 | bool IsExistValidAsciiHeader(std::istream& in); |
| 50 | 54 | |
| 51 | 55 | bool IsBinarySTL(size_t fileSize); |
| 52 | 56 | |
| 57 | + void WriteAscciiVert(std::ostream& out, const char* head, const lm::vec3f& v) const; | |
| 58 | + | |
| 53 | 59 | public: |
| 54 | 60 | char m_Message[MSG_LENGTH]; |
| 55 | 61 | std::vector<StlFace> m_Faces; |
| @@ -235,6 +235,7 @@ void FormMain::InitializeVisiblStateMenu(void) | ||
| 235 | 235 | dbmap.AddBinder(new MenuBinder(ui.actionEnableCulling , &cfg_3d.m_EnableCullFace )); |
| 236 | 236 | dbmap.AddBinder(new MenuBinder(ui.actionDrawVid , &cfg_3d.m_DrawVid )); |
| 237 | 237 | dbmap.AddBinder(new MenuBinder(ui.actionDrawVertNormal , &cfg_3d.m_DrawVertNormal )); |
| 238 | + dbmap.AddBinder(new MenuBinder(ui.actionDrawVertTan , &cfg_3d.m_DrawVertTan )); | |
| 238 | 239 | dbmap.AddBinder(new MenuBinder(ui.actionDrawVert , &cfg_3d.m_DrawVert )); |
| 239 | 240 | dbmap.AddBinder(new MenuBinder(ui.actionWireVBO , &cfg_3d.m_EnableWireVBO )); |
| 240 | 241 | dbmap.AddBinder(new MenuBinder(ui.actionIndexColorMode , &cfg_3d.m_IndexMaterial )); |
| @@ -49,5 +49,6 @@ | ||
| 49 | 49 | <file>Resources/RecordStroke.png</file> |
| 50 | 50 | <file>Resources/HilightSelectWire.png</file> |
| 51 | 51 | <file>Resources/VCol.png</file> |
| 52 | + <file>Resources/VertTan.png</file> | |
| 52 | 53 | </qresource> |
| 53 | 54 | </RCC> |
| @@ -256,6 +256,7 @@ | ||
| 256 | 256 | <addaction name="actionDrawVert"/> |
| 257 | 257 | <addaction name="actionDrawVid"/> |
| 258 | 258 | <addaction name="actionDrawVertNormal"/> |
| 259 | + <addaction name="actionDrawVertTan"/> | |
| 259 | 260 | <addaction name="actionDrawFid"/> |
| 260 | 261 | <addaction name="actionHighlightSelected"/> |
| 261 | 262 | <addaction name="actionHighlightSelectedWire"/> |
| @@ -997,6 +998,7 @@ border: 1px solid black; | ||
| 997 | 998 | <addaction name="actionDrawWire"/> |
| 998 | 999 | <addaction name="actionDrawVert"/> |
| 999 | 1000 | <addaction name="actionDrawVertNormal"/> |
| 1001 | + <addaction name="actionDrawVertTan"/> | |
| 1000 | 1002 | <addaction name="actionDrawVid"/> |
| 1001 | 1003 | <addaction name="actionDrawFid"/> |
| 1002 | 1004 | <addaction name="actionDrawPolyline"/> |
| @@ -3792,6 +3794,19 @@ border: 1px solid black; | ||
| 3792 | 3794 | <string>VertexColor(0-1)</string> |
| 3793 | 3795 | </property> |
| 3794 | 3796 | </action> |
| 3797 | + <action name="actionDrawVertTan"> | |
| 3798 | + <property name="checkable"> | |
| 3799 | + <bool>true</bool> | |
| 3800 | + </property> | |
| 3801 | + <property name="icon"> | |
| 3802 | + <iconset> | |
| 3803 | + <normalon>:/FormMain/Resources/VertTan.png</normalon> | |
| 3804 | + </iconset> | |
| 3805 | + </property> | |
| 3806 | + <property name="text"> | |
| 3807 | + <string>Tangent(Vert)</string> | |
| 3808 | + </property> | |
| 3809 | + </action> | |
| 3795 | 3810 | </widget> |
| 3796 | 3811 | <layoutdefault spacing="6" margin="11"/> |
| 3797 | 3812 | <customwidgets> |
| @@ -679,9 +679,11 @@ void GeometryRender::DrawMeshExtAll(void) | ||
| 679 | 679 | |
| 680 | 680 | if (m_Mesh->GetParent()->m_VertexOnlyMode || m_Config->m_DrawVert) |
| 681 | 681 | DrawVert(mesh); |
| 682 | - | |
| 682 | + | |
| 683 | 683 | if (m_Config->m_DrawVertNormal) |
| 684 | 684 | DrawVertNormal(mesh); |
| 685 | + if (m_Config->m_DrawVertTan) | |
| 686 | + DrawVertTangent(mesh); | |
| 685 | 687 | |
| 686 | 688 | if (m_Config->m_DrawFid) |
| 687 | 689 | DrawMeshFid(mesh); |
| @@ -855,10 +857,15 @@ void GeometryRender::DrawVertNormal(const lib_geo::BaseMesh& mesh) | ||
| 855 | 857 | glColor3d(0, 0.5, 1); |
| 856 | 858 | for (const lib_geo::BaseFace& f : mesh.m_Faces) |
| 857 | 859 | { |
| 860 | + if (mesh.m_Normals.empty()) | |
| 861 | + continue; | |
| 862 | + | |
| 858 | 863 | for (size_t j = 0; j < f.m_NormIds.size(); ++j) |
| 859 | 864 | { |
| 860 | 865 | int vi = f.m_VertIds[j]; |
| 861 | 866 | int ni = f.m_NormIds[j]; |
| 867 | + if (ni == -1) | |
| 868 | + continue; | |
| 862 | 869 | |
| 863 | 870 | const lm::vec3f& v = mesh.m_Verts[vi]; |
| 864 | 871 | const lm::vec3f& n = mesh.m_Normals[ni]; |
| @@ -866,3 +873,28 @@ void GeometryRender::DrawVertNormal(const lib_geo::BaseMesh& mesh) | ||
| 866 | 873 | } |
| 867 | 874 | } |
| 868 | 875 | } |
| 876 | + | |
| 877 | +void GeometryRender::DrawVertTangent(const lib_geo::BaseMesh& mesh) | |
| 878 | +{ | |
| 879 | + float LineLen = m_Config->m_NormalLength * m_Mesh->GetBBox().max_length(); | |
| 880 | + | |
| 881 | + glLineWidth(1.0f); | |
| 882 | + glColor3d(1, 0, 0.5); | |
| 883 | + for (const lib_geo::BaseFace& f : mesh.m_Faces) | |
| 884 | + { | |
| 885 | + if (mesh.m_Tangents.empty()) | |
| 886 | + continue; | |
| 887 | + | |
| 888 | + for (size_t j = 0; j < f.m_UVIds.size(); ++j) | |
| 889 | + { | |
| 890 | + int vi = f.m_VertIds[j]; | |
| 891 | + int ni = f.m_UVIds[j]; | |
| 892 | + if (ni == -1) | |
| 893 | + continue; | |
| 894 | + | |
| 895 | + const lm::vec3f& v = mesh.m_Verts[vi]; | |
| 896 | + const lm::vec3f& t = mesh.m_Tangents[ni]; | |
| 897 | + glDrawSegment(v, v + t * LineLen); | |
| 898 | + } | |
| 899 | + } | |
| 900 | +} |
| @@ -59,6 +59,7 @@ private: | ||
| 59 | 59 | void DrawVertPoint(const lib_geo::BaseMesh& mesh); |
| 60 | 60 | void DrawVertVid(MeshBuf& mbuf); |
| 61 | 61 | void DrawVertNormal(const lib_geo::BaseMesh& mesh); |
| 62 | + void DrawVertTangent(const lib_geo::BaseMesh& mesh); | |
| 62 | 63 | |
| 63 | 64 | void SetGLNormalColor(const lm::vec3f& n) const; |
| 64 | 65 |
| @@ -118,6 +118,7 @@ void Serialize_Config_ViewOption(SerializeBase& s, View3DConfig& config_3d) | ||
| 118 | 118 | s.Serialize( config_3d.m_DrawBBox ); |
| 119 | 119 | s.Serialize( config_3d.m_DrawBBoxRange ); |
| 120 | 120 | s.Serialize( config_3d.m_DrawVertNormal ); |
| 121 | + s.Serialize( config_3d.m_DrawVertTan ); | |
| 121 | 122 | s.Serialize( config_3d.m_ShowVidTopMost ); |
| 122 | 123 | s.Serialize( config_3d.m_DrawBone ); |
| 123 | 124 |
| @@ -35,6 +35,7 @@ uniform sampler2D tex_normal; | ||
| 35 | 35 | |
| 36 | 36 | varying vec3 v_ref_view; |
| 37 | 37 | varying vec3 v_ref_normal; |
| 38 | +varying vec3 v_ref_tan; | |
| 38 | 39 | |
| 39 | 40 | uniform float env_reflection = 0.5; |
| 40 | 41 | uniform float fresnel_refact = 1.6; |
| @@ -86,10 +87,10 @@ vec4 GetPhongSpecular(vec3 N, vec3 L, vec3 V, int light_idx) | ||
| 86 | 87 | return gl_FrontLightProduct[light_idx].specular * NHP; |
| 87 | 88 | } |
| 88 | 89 | |
| 89 | -float GetFresnelReflection() | |
| 90 | +float GetFresnelReflection(vec3 N) | |
| 90 | 91 | { |
| 91 | 92 | float fr = fresnel_refact; |
| 92 | - float c = dot(v_ref_normal, v_ref_view); | |
| 93 | + float c = dot(N, v_ref_view); | |
| 93 | 94 | if (RequireFlipNormal()) |
| 94 | 95 | c = -c; |
| 95 | 96 |
| @@ -103,9 +104,9 @@ float GetFresnelReflection() | ||
| 103 | 104 | return 0.5 * gc * gc * (1.0 + gc1 * gc1); |
| 104 | 105 | } |
| 105 | 106 | |
| 106 | -float GetFresnelReflectionLimit() | |
| 107 | +float GetFresnelReflectionLimit(vec3 N) | |
| 107 | 108 | { |
| 108 | - return clamp(GetFresnelReflection(), 0.0, 1.0); | |
| 109 | + return clamp(GetFresnelReflection(N), 0.0, 1.0); | |
| 109 | 110 | } |
| 110 | 111 | |
| 111 | 112 |
| @@ -211,31 +212,32 @@ vec3 GetFlatNormal(void) | ||
| 211 | 212 | return normalize(cross(dx, dy)); |
| 212 | 213 | } |
| 213 | 214 | |
| 214 | -vec3 GetFlagNormal(void) | |
| 215 | +vec3 GetNormalmap(vec3 vn, vec3 vt) | |
| 216 | +{ | |
| 217 | + vec3 t_normal = texture2DProj(tex_normal, gl_TexCoord[0]).xyz; | |
| 218 | + t_normal *= 2.0; | |
| 219 | + t_normal -= 1.0; | |
| 220 | + t_normal = normalize(t_normal); | |
| 221 | + | |
| 222 | + vec3 VT = normalize(vt); | |
| 223 | + vec3 VN = normalize(vn); | |
| 224 | + vec3 VB = normalize(cross(VN, VT)); | |
| 225 | + | |
| 226 | + return normalize( | |
| 227 | + VT * t_normal.x + | |
| 228 | + VB * t_normal.y + | |
| 229 | + VN * t_normal.z); | |
| 230 | +} | |
| 231 | + | |
| 232 | +vec3 GetFlagNormal(vec3 vn, vec3 vt) | |
| 215 | 233 | { |
| 216 | 234 | if (enable_flatshade) |
| 217 | 235 | return GetFlatNormal(); |
| 218 | 236 | |
| 219 | - vec3 N; | |
| 220 | 237 | if (enable_normalmap) |
| 221 | - { | |
| 222 | - vec3 t_normal = texture2DProj(tex_normal, gl_TexCoord[0]).xyz; | |
| 223 | - t_normal *= 2.0; | |
| 224 | - t_normal -= 1.0; | |
| 225 | - t_normal = normalize(t_normal); | |
| 226 | - | |
| 227 | - vec3 VT = normalize(v_tangent); | |
| 228 | - vec3 VN = normalize(v_normal); | |
| 229 | - vec3 VB = normalize(cross(VN, VT)); | |
| 230 | - | |
| 231 | - N = normalize(VT * t_normal.x + VB * t_normal.y + VN * t_normal.z); | |
| 232 | - } | |
| 238 | + return GetNormalmap(vn, vt); | |
| 233 | 239 | else |
| 234 | - { | |
| 235 | - N = normalize(v_normal); | |
| 236 | - } | |
| 237 | - | |
| 238 | - return N; | |
| 240 | + return normalize(vn); | |
| 239 | 241 | } |
| 240 | 242 | |
| 241 | 243 | vec3 GetDSNormal(vec3 N) |
| @@ -296,8 +298,8 @@ vec4 GetPhongReflectionSumWithShadow(vec3 N) | ||
| 296 | 298 | |
| 297 | 299 | vec4 GetEnvironmentReflection() |
| 298 | 300 | { |
| 299 | - vec3 R = normalize(v_ref_normal * 2.0 * dot(v_ref_normal, v_ref_view) - v_ref_view); | |
| 300 | - //vec3 R = normalize(v_ref_normal); | |
| 301 | + vec3 N = GetFlagNormal(v_ref_normal, v_ref_tan); | |
| 302 | + vec3 R = normalize(N * 2.0 * dot(N, v_ref_view) - v_ref_view); | |
| 301 | 303 | |
| 302 | 304 | float ty = acos(R.y) / PI; |
| 303 | 305 |
| @@ -305,7 +307,7 @@ vec4 GetEnvironmentReflection() | ||
| 305 | 307 | |
| 306 | 308 | vec4 env_texcoord = vec4(tx, ty, 0.0, 1.0); |
| 307 | 309 | vec4 ret = texture2DProj(tex_envmap, env_texcoord); |
| 308 | - ret *= env_reflection * GetFresnelReflectionLimit(); | |
| 310 | + ret *= env_reflection * GetFresnelReflectionLimit(N); | |
| 309 | 311 | |
| 310 | 312 | ret.w = 0.0; |
| 311 | 313 | return ret; |
| @@ -385,7 +387,7 @@ void main(void) | ||
| 385 | 387 | |
| 386 | 388 | gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); |
| 387 | 389 | |
| 388 | - vec3 N = GetFlagNormal(); | |
| 390 | + vec3 N = GetFlagNormal(v_normal, v_tangent); | |
| 389 | 391 | |
| 390 | 392 | if (enable_lighting) |
| 391 | 393 | gl_FragColor += GetPhongReflectionSumWithShadow(GetDSNormal(N)); |
| @@ -11,6 +11,7 @@ varying vec4 v_shadow_pos; | ||
| 11 | 11 | |
| 12 | 12 | varying vec3 v_ref_view; |
| 13 | 13 | varying vec3 v_ref_normal; |
| 14 | +varying vec3 v_ref_tan; | |
| 14 | 15 | |
| 15 | 16 | uniform mat4 scene_mat; |
| 16 | 17 |
| @@ -32,11 +33,9 @@ void main(void) | ||
| 32 | 33 | v_ref_view = vec3(t.x, t.y, t.z); |
| 33 | 34 | |
| 34 | 35 | vec4 nt = scene_mat * vec4(gl_Normal.x, gl_Normal.y, gl_Normal.z, 1.0); |
| 35 | - vec3 ntt = vec3(nt.x, nt.y, nt.z) / nt.w; | |
| 36 | - | |
| 37 | - v_ref_normal = ntt; | |
| 38 | - | |
| 39 | - //v_ref_normal = gl_Normal; | |
| 36 | + v_ref_normal = nt.xyz/ nt.w; | |
| 37 | + vec4 tt = scene_mat * vec4(Tangent.x, Tangent.y, Tangent.z, 1.0); | |
| 38 | + v_ref_tan = tt.xyz/ tt.w; | |
| 40 | 39 | |
| 41 | 40 | v_shadow_pos = shadow_mat * gl_Vertex; |
| 42 | 41 |
| @@ -33,6 +33,7 @@ public: | ||
| 33 | 33 | m_DrawBBox .Reset( false , "DrawBBox" ); |
| 34 | 34 | m_DrawBBoxRange .Reset( false , "DrawBBoxRange" ); |
| 35 | 35 | m_DrawVertNormal .Reset( false , "DrawVertNormal" ); |
| 36 | + m_DrawVertTan .Reset( false , "DrawVertTan" ); | |
| 36 | 37 | m_ShowVidTopMost .Reset( false , "IndexTopMost" ); |
| 37 | 38 | m_DrawBone .Reset( false , "DrawBone" ); |
| 38 | 39 |
| @@ -107,6 +108,7 @@ public: | ||
| 107 | 108 | NamedValue<bool> m_DrawBBox; |
| 108 | 109 | NamedValue<bool> m_DrawBBoxRange; |
| 109 | 110 | NamedValue<bool> m_DrawVertNormal; |
| 111 | + NamedValue<bool> m_DrawVertTan; | |
| 110 | 112 | NamedValue<bool> m_ShowVidTopMost; |
| 111 | 113 | NamedValue<bool> m_DrawBone; |
| 112 | 114 |