Mercurial > mm7
comparison Vis.cpp @ 323:d720a13e2273
Very basic picking & entering houses
author | Nomad |
---|---|
date | Wed, 20 Feb 2013 08:23:12 +0200 |
parents | 640a176c030f |
children | 5cfb5dadf330 |
comparison
equal
deleted
inserted
replaced
322:ce39b96acf5c | 323:d720a13e2273 |
---|---|
384 v5 = v17 + 1; | 384 v5 = v17 + 1; |
385 } | 385 } |
386 } | 386 } |
387 | 387 |
388 //----- (004C17CF) -------------------------------------------------------- | 388 //----- (004C17CF) -------------------------------------------------------- |
389 void Vis::PickOutdoorFaces_Mouse(float fDepth, RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter, bool one_sided) | 389 void Vis::PickOutdoorFaces_Mouse(float fDepth, RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter, bool only_reachable) |
390 { | 390 { |
391 if (!pOutdoor) | 391 if (!pOutdoor) |
392 return; | 392 return; |
393 | 393 |
394 for (uint i = 0; i < pOutdoor->uNumBModels; ++i) | 394 for (uint i = 0; i < pOutdoor->uNumBModels; ++i) |
395 { | 395 { |
396 int v24; | 396 int reachable; |
397 if (!IsBModelVisible(i, &v24)) | 397 if (!IsBModelVisible(i, &reachable)) |
398 continue; | 398 continue; |
399 if (one_sided && !v24) | 399 if (!reachable && only_reachable) |
400 continue; | 400 continue; |
401 | 401 |
402 auto bmodel = &pOutdoor->pBModels[i]; | 402 auto bmodel = &pOutdoor->pBModels[i]; |
403 | |
404 for (uint j = 0; j < bmodel->uNumFaces; ++j) | 403 for (uint j = 0; j < bmodel->uNumFaces; ++j) |
405 { | 404 { |
406 auto face = bmodel->pFaces + j; | 405 auto face = bmodel->pFaces + j; |
407 if (is_part_of_selection(face, filter)) | 406 if (is_part_of_selection(face, filter)) |
408 { | 407 { |
412 RenderVertexSoft intersection; | 411 RenderVertexSoft intersection; |
413 if (Intersect_Ray_Face(pRay, pRay + 1, &fDepth, &intersection, &blv_face, i)) | 412 if (Intersect_Ray_Face(pRay, pRay + 1, &fDepth, &intersection, &blv_face, i)) |
414 { | 413 { |
415 pGame->pIndoorCameraD3D->ViewTransform(&intersection, 1u); | 414 pGame->pIndoorCameraD3D->ViewTransform(&intersection, 1u); |
416 int v13 = _48B561_mess_with_scaling_along_z(/*v12, */intersection.vWorldViewPosition.x); | 415 int v13 = _48B561_mess_with_scaling_along_z(/*v12, */intersection.vWorldViewPosition.x); |
417 LOWORD(v13) = (8 * (j | (i << 6)) | OBJECT_BModel) + v13; | 416 v13 += (8 * (j | (i << 6)) | OBJECT_BModel); |
418 | 417 |
419 list->AddObject(face, VisObjectType_Face, v13); | 418 list->AddObject(face, VisObjectType_Face, v13); |
420 } | 419 } |
420 | |
421 if (blv_face.uAttributes & 0x80000000) | |
422 face->uAttributes |= FACE_OUTLINED; | |
423 else | |
424 face->uAttributes &= ~FACE_OUTLINED; | |
421 } | 425 } |
422 } | 426 } |
423 } | 427 } |
424 } | 428 } |
425 | 429 |
573 } | 577 } |
574 | 578 |
575 //----- (004C1C0C) -------------------------------------------------------- | 579 //----- (004C1C0C) -------------------------------------------------------- |
576 bool Vis::Intersect_Ray_Face(RenderVertexSoft *pRayStart, RenderVertexSoft *pRayEnd, float *pDepth, RenderVertexSoft *a4, BLVFace *a5, unsigned int a6) | 580 bool Vis::Intersect_Ray_Face(RenderVertexSoft *pRayStart, RenderVertexSoft *pRayEnd, float *pDepth, RenderVertexSoft *a4, BLVFace *a5, unsigned int a6) |
577 { | 581 { |
578 BLVFace *v7; // ebx@1 | 582 //BLVFace *v7; // ebx@1 |
579 bool result; // eax@1 | 583 //bool result; // eax@1 |
580 double v9; // st7@3 | 584 double v9; // st7@3 |
581 __int16 v10; // fps@3 | 585 //__int16 v10; // fps@3 |
582 char v11; // c0@3 | 586 //char v11; // c0@3 |
583 char v12; // c2@3 | 587 //char v12; // c2@3 |
584 char v13; // c3@3 | 588 //char v13; // c3@3 |
585 __int16 v14; // fps@5 | 589 //__int16 v14; // fps@5 |
586 char v15; // c0@5 | 590 //char v15; // c0@5 |
587 char v16; // c2@5 | 591 //char v16; // c2@5 |
588 char v17; // c3@5 | 592 //char v17; // c3@5 |
589 double v18; // st5@6 | 593 double v18; // st5@6 |
590 __int16 v19; // fps@6 | 594 //__int16 v19; // fps@6 |
591 char v20; // c0@6 | 595 //char v20; // c0@6 |
592 char v21; // c2@6 | 596 //char v21; // c2@6 |
593 char v22; // c3@6 | 597 //char v22; // c3@6 |
594 unsigned __int8 v23; // c0@6 | 598 //unsigned __int8 v23; // c0@6 |
595 char v24; // c2@6 | 599 //char v24; // c2@6 |
596 unsigned __int8 v25; // c3@6 | 600 //unsigned __int8 v25; // c3@6 |
597 char v26; // zf@6 | 601 //char v26; // zf@6 |
598 double v27; // st6@10 | 602 double v27; // st6@10 |
599 __int16 v28; // fps@10 | 603 //__int16 v28; // fps@10 |
600 unsigned __int8 v29; // c0@10 | 604 //unsigned __int8 v29; // c0@10 |
601 char v30; // c2@10 | 605 //char v30; // c2@10 |
602 unsigned __int8 v31; // c3@10 | 606 //unsigned __int8 v31; // c3@10 |
603 double v32; // st7@11 | 607 //double v32; // st7@11 |
604 Vec2_short_ v33; // ST1E_4@11 | 608 Vec2_short_ v33; // ST1E_4@11 |
605 Vec3_short_ v34; // ST04_6@11 | 609 Vec3_short_ v34; // ST04_6@11 |
606 float a5a; // [sp+30h] [bp+18h]@10 | 610 //float a5a; // [sp+30h] [bp+18h]@10 |
607 float a5b; // [sp+30h] [bp+18h]@13 | 611 //float a5b; // [sp+30h] [bp+18h]@13 |
608 | 612 |
609 v7 = a5; | 613 if (a5->TwoSided() || a5->Invisible()) |
610 result = a5->uAttributes; | 614 return false; |
611 if ( result & 1 | 615 |
612 || BYTE1(result) & 0x20 | 616 |
613 || (v9 = pRayEnd->vWorldPosition.z * a5->pFacePlane.vNormal.z | 617 int ray_dir_x = pRayEnd->vWorldPosition.x - pRayStart->vWorldPosition.x, |
614 + a5->pFacePlane.vNormal.y * pRayEnd->vWorldPosition.y | 618 ray_dir_y = pRayEnd->vWorldPosition.y - pRayStart->vWorldPosition.y, |
615 + pRayEnd->vWorldPosition.x * a5->pFacePlane.vNormal.x, | 619 ray_dir_z = pRayEnd->vWorldPosition.z - pRayStart->vWorldPosition.z; |
616 //UNDEF(v10), | 620 |
617 v11 = v9 < 0.0, | 621 v9 = ray_dir_z * a5->pFacePlane.vNormal.z |
618 v12 = 0, | 622 + ray_dir_y * a5->pFacePlane.vNormal.y |
619 v13 = v9 == 0.0, | 623 + ray_dir_x * a5->pFacePlane.vNormal.x; |
620 BYTE1(result) = HIBYTE(v10), | 624 if (v9 >= 0) // ray faces face's normal ( > 0) or parallel ( == 0) |
621 v9 == 0.0) | 625 return false; |
622 || (/*UNDEF(v14),*/ v15 = v9 < 0.0, v16 = 0, v17 = v9 == 0.0, BYTE1(result) = HIBYTE(v14), v9 > 0.0) )// ray's away (>) from face surface or parallel (==) | 626 |
623 goto LABEL_12; | 627 //ray = t dir + start |
624 v18 = -(a5->pFacePlane.vNormal.y * pRayStart->vWorldPosition.y// ray-plane intersection | 628 //plane = (p - vertex) normal = -d |
629 // | |
630 // | |
631 //(t dir + start - vertex) normal = -d | |
632 // | |
633 // -d - (start - vertex) norm | |
634 //t = -------------------- | |
635 // dir norm | |
636 | |
637 | |
638 float dir_mag = sqrtf(ray_dir_x * ray_dir_x + ray_dir_y * ray_dir_y + ray_dir_z * ray_dir_z); | |
639 float ndir_x = ray_dir_x / dir_mag, | |
640 ndir_y = ray_dir_y / dir_mag, | |
641 ndir_z = ray_dir_z / dir_mag; | |
642 | |
643 int face_center_x = (a5->pBounding.x1 + a5->pBounding.x2) / 2, | |
644 face_center_y = (a5->pBounding.y1 + a5->pBounding.y2) / 2, | |
645 face_center_z = (a5->pBounding.z1 + a5->pBounding.z2) / 2; | |
646 | |
647 int to_plane_x = pRayStart->vWorldPosition.x - face_center_x, | |
648 to_plane_y = pRayStart->vWorldPosition.y - face_center_y, | |
649 to_plane_z = pRayStart->vWorldPosition.z - face_center_z; | |
650 | |
651 float t = /*-a5->pFacePlane.dist*/ - (to_plane_x * a5->pFacePlane.vNormal.x + to_plane_y * a5->pFacePlane.vNormal.y + to_plane_y * a5->pFacePlane.vNormal.z) / | |
652 (ndir_x * a5->pFacePlane.vNormal.x + ndir_y * a5->pFacePlane.vNormal.y + ndir_z * a5->pFacePlane.vNormal.z); | |
653 if (t <= *pDepth) | |
654 { | |
655 int intersection_x = pRayStart->vWorldPosition.x + ndir_x * t, | |
656 intersection_y = pRayStart->vWorldPosition.y + ndir_y * t, | |
657 intersection_z = pRayStart->vWorldPosition.z + ndir_z * t; | |
658 | |
659 if (intersection_x < a5->pBounding.x1 || intersection_x > a5->pBounding.x2 || | |
660 intersection_y < a5->pBounding.y1 || intersection_y > a5->pBounding.y2 || | |
661 intersection_z < a5->pBounding.z1 || intersection_z > a5->pBounding.z2) | |
662 return false; | |
663 | |
664 a5->uAttributes |= 0x80000000; | |
665 return true; | |
666 } | |
667 | |
668 | |
669 return false; | |
670 | |
671 // v7 = a5; | |
672 //result = a5->uAttributes; | |
673 v9 = pRayEnd->vWorldPosition.z * a5->pFacePlane.vNormal.z | |
674 + pRayEnd->vWorldPosition.y * a5->pFacePlane.vNormal.y | |
675 + pRayEnd->vWorldPosition.x * a5->pFacePlane.vNormal.x; | |
676 if (v9 >= 0) // ray faces face's normal ( > 0) or parallel ( == 0) | |
677 return false; | |
678 | |
679 a5->uAttributes |= 0x80000000; | |
680 return false; | |
681 | |
682 v18 = -(a5->pFacePlane.vNormal.y * pRayStart->vWorldPosition.y | |
625 + pRayStart->vWorldPosition.x * a5->pFacePlane.vNormal.x | 683 + pRayStart->vWorldPosition.x * a5->pFacePlane.vNormal.x |
626 + pRayStart->vWorldPosition.z * a5->pFacePlane.vNormal.z | 684 + pRayStart->vWorldPosition.z * a5->pFacePlane.vNormal.z |
627 + a5->pFacePlane.dist); | 685 + a5->pFacePlane.dist); |
686 if (v18 > 0) | |
687 return false; | |
628 //UNDEF(v19); | 688 //UNDEF(v19); |
629 v20 = v9 < 0.0; | 689 //v20 = v9 < 0.0; |
630 v21 = 0; | 690 //v21 = 0; |
631 v22 = v9 == 0.0; | 691 //v22 = v9 == 0.0; |
632 BYTE1(result) = HIBYTE(v19); | 692 //BYTE1(result) = HIBYTE(v19); |
633 v23 = v18 < 0.0; | 693 /*v23 = v18 < 0.0; |
634 v24 = 0; | 694 v24 = 0; |
635 v25 = v18 == 0.0; | 695 v25 = v18 == 0.0; |
636 v26 = (BYTE1(result) & 0x41) == 0; | 696 v26 = (BYTE1(result) & 0x41) == 0; |
637 BYTE1(result) = HIBYTE(v19); | 697 BYTE1(result) = HIBYTE(v19); |
638 if ( v26 ) | 698 if ( v26 ) |
646 { | 706 { |
647 LABEL_12: | 707 LABEL_12: |
648 LOBYTE(result) = 0; | 708 LOBYTE(result) = 0; |
649 return result; | 709 return result; |
650 } | 710 } |
651 } | 711 }*/ |
652 a5a = v18; | 712 |
653 v27 = a5a / v9; | 713 //a5a = v18; |
654 HIWORD(result) = HIWORD(pDepth); | 714 v27 = v18 / v9; |
715 //HIWORD(result) = HIWORD(pDepth); | |
655 //UNDEF(v28); | 716 //UNDEF(v28); |
656 v29 = v27 < *pDepth; | 717 //v29 = v27 < *pDepth; |
657 v30 = 0; | 718 //v30 = 0; |
658 v31 = v27 == *pDepth; | 719 //v31 = v27 == *pDepth; |
659 BYTE1(result) = HIBYTE(v28); | 720 //BYTE1(result) = HIBYTE(v28); |
660 if ( !(v29 | v31) | 721 |
661 || (a4->vWorldPosition.x = v27 * pRayEnd->vWorldPosition.x + pRayStart->vWorldPosition.x, | 722 if (v27 > *pDepth) |
662 a4->vWorldPosition.y = v27 * pRayEnd->vWorldPosition.y + pRayStart->vWorldPosition.y, | 723 return false; |
663 v32 = v27 * pRayEnd->vWorldPosition.z + pRayStart->vWorldPosition.z, | 724 |
664 a4->vWorldPosition.z = v32, | 725 a5->uAttributes |= 0x80000000; |
665 v33.x = (signed __int64)a4->vWorldPosition.x, | 726 |
666 v33.y = (signed __int64)a4->vWorldPosition.y, | 727 a4->vWorldPosition.x = v27 * pRayEnd->vWorldPosition.x + pRayStart->vWorldPosition.x; |
667 *(int *)&v34.x = v33.x, | 728 a4->vWorldPosition.y = v27 * pRayEnd->vWorldPosition.y + pRayStart->vWorldPosition.y; |
668 v34.z = (signed __int64)v32, | 729 a4->vWorldPosition.z = v27 * pRayEnd->vWorldPosition.z + pRayStart->vWorldPosition.z; |
669 result = _4C1D2B(v7, v34, a6), | 730 v33.x = (signed __int64)a4->vWorldPosition.x; |
670 *(float *)&result == 0.0) ) | 731 v33.y = (signed __int64)a4->vWorldPosition.y; |
671 goto LABEL_12; | 732 v34.x = v33.x; |
672 *(float *)&result = v27; | 733 v34.y = 0; |
673 a5b = v27; | 734 v34.z = (signed __int64)a4->vWorldPosition.z; |
674 *(int *)pDepth = LODWORD(a5b); | 735 |
675 LOBYTE(result) = 1; | 736 if ( _4C1D2B(a5, v34, a6) == 0.0) |
676 return result; | 737 return false; |
738 | |
739 //a5b = v27; | |
740 *pDepth = v27; | |
741 return true; | |
677 } | 742 } |
678 | 743 |
679 //----- (004C1D2B) -------------------------------------------------------- | 744 //----- (004C1D2B) -------------------------------------------------------- |
680 int Vis::_4C1D2B(BLVFace *pFace, Vec3_short_ a2, unsigned int uModelID) | 745 int Vis::_4C1D2B(BLVFace *pFace, Vec3_short_ a2, unsigned int uModelID) |
681 { | 746 { |
692 signed int result; // eax@21 | 757 signed int result; // eax@21 |
693 int v15; // [sp+10h] [bp-Ch]@10 | 758 int v15; // [sp+10h] [bp-Ch]@10 |
694 signed int v16; // [sp+18h] [bp-4h]@10 | 759 signed int v16; // [sp+18h] [bp-4h]@10 |
695 | 760 |
696 v4 = pFace; | 761 v4 = pFace; |
697 if ( a2.z < pFace->pBounding.z1 | 762 if (a2.z < pFace->pBounding.z1 || a2.z > pFace->pBounding.z2 || |
698 || a2.z > pFace->pBounding.z2 | 763 a2.x < pFace->pBounding.x1 || a2.x > pFace->pBounding.x2 || |
699 || a2.x < pFace->pBounding.x1 | 764 a2.y < pFace->pBounding.y1 || a2.y > pFace->pBounding.y2) |
700 || a2.x > pFace->pBounding.x2 | 765 return false; |
701 || a2.y < pFace->pBounding.y1 | 766 |
702 || a2.y > pFace->pBounding.y2 | 767 if (uModelID != -1) |
703 || (uModelID != -1 ? _4C2186_BLV_IntersectBModel( | 768 _4C2186_BLV_IntersectBModel((int *)&pFace, (int *)&uModelID, |
704 (int *)&pFace, | 769 word_F8BC48_displaced_face_intersect_plane_coords_a, |
705 (int *)&uModelID, | 770 word_F8BD18_displaced_face_intersect_plane_coords_b, |
706 &word_F8BC48_displaced_face_intersect_plane_coords_a, | 771 &a2, pFace, uModelID); |
707 &word_F8BD18_displaced_face_intersect_plane_coords_b, | 772 else |
708 &a2, | 773 _4C1EE5_BLV_IntersectBModel_2((int *)&pFace, (int *)&uModelID, |
709 pFace, | 774 word_F8BC48_displaced_face_intersect_plane_coords_a, |
710 uModelID) : _4C1EE5_BLV_IntersectBModel_2( | 775 word_F8BD18_displaced_face_intersect_plane_coords_b, |
711 (int *)&pFace, | 776 &a2, pFace); |
712 (int *)&uModelID, | 777 |
713 &word_F8BC48_displaced_face_intersect_plane_coords_a, | 778 v5 = 2 * v4->uNumVertices; |
714 &word_F8BD18_displaced_face_intersect_plane_coords_b, | 779 v16 = 0; |
715 &a2, | 780 word_F8BC48_displaced_face_intersect_plane_coords_a[v5] = word_F8BC48_displaced_face_intersect_plane_coords_a[0]; |
716 pFace), | 781 word_F8BD18_displaced_face_intersect_plane_coords_b[v5] = word_F8BD18_displaced_face_intersect_plane_coords_b[0]; |
717 v5 = 2 * v4->uNumVertices, | 782 v15 = 0; |
718 v16 = 0, | 783 v6 = word_F8BD18_displaced_face_intersect_plane_coords_b[0] >= (signed int)uModelID; |
719 *(&word_F8BC48_displaced_face_intersect_plane_coords_a + v5) = word_F8BC48_displaced_face_intersect_plane_coords_a, | 784 if (v5 <= 0) |
720 *(&word_F8BD18_displaced_face_intersect_plane_coords_b + v5) = word_F8BD18_displaced_face_intersect_plane_coords_b, | 785 return false; |
721 v15 = 0, | 786 |
722 v6 = word_F8BD18_displaced_face_intersect_plane_coords_b >= (signed int)uModelID, | |
723 v5 <= 0) ) | |
724 goto LABEL_25; | |
725 do | 787 do |
726 { | 788 { |
727 if ( v16 >= 2 ) | 789 if ( v16 >= 2 ) |
728 break; | 790 break; |
729 v7 = 2 * v15; | 791 v7 = 2 * v15; |
730 v8 = *(&word_F8BD18_displaced_face_intersect_plane_coords_b + v15 + 1); | 792 v8 = word_F8BD18_displaced_face_intersect_plane_coords_b[ + v15 + 1]; |
731 if ( v6 ^ v8 >= (signed int)uModelID ) | 793 if ( v6 ^ v8 >= (signed int)uModelID ) |
732 { | 794 { |
733 v9 = *(__int16 *)((char *)&word_F8BC48_displaced_face_intersect_plane_coords_a + v7 + 2); | 795 v9 = word_F8BC48_displaced_face_intersect_plane_coords_a[v7/2 + 1]; |
734 if ( v9 >= (signed int)pFace ) | 796 if ( v9 >= (signed int)pFace ) |
735 v10 = 0; | 797 v10 = 0; |
736 else | 798 else |
737 v10 = 2; | 799 v10 = 2; |
738 v11 = v10 | *(__int16 *)((char *)&word_F8BC48_displaced_face_intersect_plane_coords_a + v7) < (signed int)pFace; | 800 v11 = v10 | word_F8BC48_displaced_face_intersect_plane_coords_a[v7/2] < (signed int)pFace; |
739 if ( v11 != 3 ) | 801 if ( v11 != 3 ) |
740 { | 802 { |
741 if ( !v11 | 803 if ( !v11 |
742 || (v12 = v9 - *(__int16 *)((char *)&word_F8BC48_displaced_face_intersect_plane_coords_a + v7), | 804 || (v12 = v9 - word_F8BC48_displaced_face_intersect_plane_coords_a[v7/2], |
743 LODWORD(v13) = v12 << 16, | 805 LODWORD(v13) = v12 << 16, |
744 HIDWORD(v13) = v12 >> 16, | 806 HIDWORD(v13) = v12 >> 16, |
745 *(__int16 *)((char *)&word_F8BC48_displaced_face_intersect_plane_coords_a + v7) | 807 word_F8BC48_displaced_face_intersect_plane_coords_a[v7/2] |
746 + ((signed int)(((unsigned __int64)(v13 | 808 + ((signed int)(((unsigned __int64)(v13 / (v8 - word_F8BD18_displaced_face_intersect_plane_coords_b[v7/2]) |
747 / (v8 | 809 * (signed int)((uModelID - word_F8BD18_displaced_face_intersect_plane_coords_b[v7/2]) << 16)) >> 16) + 32768) >> 16) >= (signed int)pFace) ) |
748 - *(__int16 *)((char *)&word_F8BD18_displaced_face_intersect_plane_coords_b | |
749 + v7)) | |
750 * (signed int)((uModelID | |
751 - *(__int16 *)((char *)&word_F8BD18_displaced_face_intersect_plane_coords_b | |
752 + v7)) << 16)) >> 16) | |
753 + 32768) >> 16) >= (signed int)pFace) ) | |
754 ++v16; | 810 ++v16; |
755 } | 811 } |
756 } | 812 } |
757 ++v15; | 813 ++v15; |
758 v6 = v8 >= (signed int)uModelID; | 814 v6 = v8 >= (signed int)uModelID; |
1482 PickIndoorFaces_Mouse(fDepth, pMouseRay, &default_list, face_filter); | 1538 PickIndoorFaces_Mouse(fDepth, pMouseRay, &default_list, face_filter); |
1483 else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) | 1539 else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor) |
1484 PickOutdoorFaces_Mouse(fDepth, pMouseRay, &default_list, face_filter, false); | 1540 PickOutdoorFaces_Mouse(fDepth, pMouseRay, &default_list, face_filter, false); |
1485 else | 1541 else |
1486 { | 1542 { |
1487 Log::Warning(L"Picking mouse in undefined level"); // picking in main menu is default (buggy) game behavious. should've returned false in Game::PickMouse | 1543 Log::Warning(L"Picking mouse in undefined level"); // picking in main menu is default (buggy) game behaviour. should've returned false in Game::PickMouse |
1488 return false; | 1544 return false; |
1489 } | 1545 } |
1490 default_list.create_object_pointers(Vis_SelectionList::All); | 1546 default_list.create_object_pointers(Vis_SelectionList::All); |
1491 sort_object_pointers(default_list.object_pointers, 0, default_list.uNumPointers - 1); | 1547 sort_object_pointers(default_list.object_pointers, 0, default_list.uNumPointers - 1); |
1492 | 1548 |