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