X operations(XOPS)に非常に近いFPSゲームを制作・リメイクし、成果物をオープンソースとして公開することを目的としたプロジェクトです。
リビジョン | 340 (tree) |
---|---|
日時 | 2022-12-10 13:58:21 |
作者 | ![]() |
人とマップの当たり判定処理を改善、一部当たり判定関係の処理を関数化
@@ -232,6 +232,46 @@ | ||
232 | 232 | return 0; |
233 | 233 | } |
234 | 234 | |
235 | +//! @brief AABBによる全てのブロックとの当たり判定 | |
236 | +//! @param id 判定するブロック番号 | |
237 | +//! @param min_x 物体の最少 X座標 | |
238 | +//! @param min_y 物体の最少 Y座標 | |
239 | +//! @param min_z 物体の最少 Z座標 | |
240 | +//! @param max_x 物体の最大 X座標 | |
241 | +//! @param max_y 物体の最大 Y座標 | |
242 | +//! @param max_z 物体の最大 Z座標 | |
243 | +//! @return 当たっている:true 当たっていない:false | |
244 | +//! @attention エラーがある場合「当たっていない:false」が返されます。 | |
245 | +bool Collision::CheckBlockAABB(int id, float min_x, float min_y, float min_z, float max_x, float max_y, float max_z) | |
246 | +{ | |
247 | + if( BlockDataIF == NULL ){ return false; } | |
248 | + if( (id < 0)||(BlockDataIF->GetTotaldatas() <= id) ){ return false; } | |
249 | + | |
250 | + return CollideBoxAABB(min_x, min_y, min_z, max_x, max_y, max_z, cbdata[id].min_x, cbdata[id].min_y, cbdata[id].min_z, cbdata[id].max_x, cbdata[id].max_y, cbdata[id].max_z); | |
251 | +} | |
252 | + | |
253 | +//! @brief AABBによるブロックとの当たり判定 | |
254 | +//! @param min_x 物体の最少 X座標 | |
255 | +//! @param min_y 物体の最少 Y座標 | |
256 | +//! @param min_z 物体の最少 Z座標 | |
257 | +//! @param max_x 物体の最大 X座標 | |
258 | +//! @param max_y 物体の最大 Y座標 | |
259 | +//! @param max_z 物体の最大 Z座標 | |
260 | +//! @return 当たっている:true 当たっていない:false | |
261 | +//! @attention エラーがある場合「当たっていない:false」が返されます。 | |
262 | +bool Collision::CheckALLBlockAABB(float min_x, float min_y, float min_z, float max_x, float max_y, float max_z) | |
263 | +{ | |
264 | + if( BlockDataIF == NULL ){ return false; } | |
265 | + | |
266 | + int bs = BlockDataIF->GetTotaldatas(); | |
267 | + | |
268 | + for(int i=0; i<bs; i++){ | |
269 | + if( CheckBlockAABB(i, min_x, min_y, min_z, max_x, max_y, max_z) == true ){ return true; } | |
270 | + } | |
271 | + | |
272 | + return false; | |
273 | +} | |
274 | + | |
235 | 275 | //! @brief 特定の座標が、ブロックの面の表側か調べる |
236 | 276 | //! @param id 判定するブロック番号 |
237 | 277 | //! @param face 判定する面番号 |
@@ -429,7 +469,7 @@ | ||
429 | 469 | if( cbdata[blockid].BoardBlock == true ){ return false; } |
430 | 470 | |
431 | 471 | |
432 | - //判定の荒削り | |
472 | + //判定の粗削り | |
433 | 473 | if( worldgroup == true ){ |
434 | 474 | |
435 | 475 | //空間分割 |
@@ -524,26 +564,7 @@ | ||
524 | 564 | |
525 | 565 | if( maxDist > 0.0f ){ |
526 | 566 | //レイのAABBを作る |
527 | - rmin_x = RayPos_x + RayDir_x * maxDist; | |
528 | - rmin_y = RayPos_y + RayDir_y * maxDist; | |
529 | - rmin_z = RayPos_z + RayDir_z * maxDist; | |
530 | - rmax_x = rmin_x; | |
531 | - rmax_y = rmin_y; | |
532 | - rmax_z = rmin_z; | |
533 | - if( rmin_x > RayPos_x ){ rmin_x = RayPos_x; } | |
534 | - if( rmin_y > RayPos_y ){ rmin_y = RayPos_y; } | |
535 | - if( rmin_z > RayPos_z ){ rmin_z = RayPos_z; } | |
536 | - if( rmax_x < RayPos_x ){ rmax_x = RayPos_x; } | |
537 | - if( rmax_y < RayPos_y ){ rmax_y = RayPos_y; } | |
538 | - if( rmax_z < RayPos_z ){ rmax_z = RayPos_z; } | |
539 | - | |
540 | - //計算誤差対策のため、わずかに大きめにする。 | |
541 | - rmin_x -= COLLISION_ADDSIZE; | |
542 | - rmin_y -= COLLISION_ADDSIZE; | |
543 | - rmin_z -= COLLISION_ADDSIZE; | |
544 | - rmax_x += COLLISION_ADDSIZE; | |
545 | - rmax_y += COLLISION_ADDSIZE; | |
546 | - rmax_z += COLLISION_ADDSIZE; | |
567 | + GetAABBRay(RayPos_x, RayPos_y, RayPos_z, RayDir_x, RayDir_y, RayDir_z, maxDist, &rmin_x, &rmin_y, &rmin_z, &rmax_x, &rmax_y, &rmax_z); | |
547 | 568 | } |
548 | 569 | |
549 | 570 | if( maxDist > 0.0f ){ |
@@ -649,26 +670,7 @@ | ||
649 | 670 | |
650 | 671 | if( maxDist > 0.0f ){ |
651 | 672 | //レイのAABBを作る |
652 | - rmin_x = RayPos_x + RayDir_x * maxDist; | |
653 | - rmin_y = RayPos_y + RayDir_y * maxDist; | |
654 | - rmin_z = RayPos_z + RayDir_z * maxDist; | |
655 | - rmax_x = rmin_x; | |
656 | - rmax_y = rmin_y; | |
657 | - rmax_z = rmin_z; | |
658 | - if( rmin_x > RayPos_x ){ rmin_x = RayPos_x; } | |
659 | - if( rmin_y > RayPos_y ){ rmin_y = RayPos_y; } | |
660 | - if( rmin_z > RayPos_z ){ rmin_z = RayPos_z; } | |
661 | - if( rmax_x < RayPos_x ){ rmax_x = RayPos_x; } | |
662 | - if( rmax_y < RayPos_y ){ rmax_y = RayPos_y; } | |
663 | - if( rmax_z < RayPos_z ){ rmax_z = RayPos_z; } | |
664 | - | |
665 | - //計算誤差対策のため、わずかに大きめにする。 | |
666 | - rmin_x -= COLLISION_ADDSIZE; | |
667 | - rmin_y -= COLLISION_ADDSIZE; | |
668 | - rmin_z -= COLLISION_ADDSIZE; | |
669 | - rmax_x += COLLISION_ADDSIZE; | |
670 | - rmax_y += COLLISION_ADDSIZE; | |
671 | - rmax_z += COLLISION_ADDSIZE; | |
673 | + GetAABBRay(RayPos_x, RayPos_y, RayPos_z, RayDir_x, RayDir_y, RayDir_z, maxDist, &rmin_x, &rmin_y, &rmin_z, &rmax_x, &rmax_y, &rmax_z); | |
672 | 674 | } |
673 | 675 | |
674 | 676 | if( maxDist > 0.0f ){ |
@@ -907,6 +909,54 @@ | ||
907 | 909 | return true; |
908 | 910 | } |
909 | 911 | |
912 | +//! @brief レイのAABBを求める | |
913 | +//! @param RayPos_x 始点 X座標 | |
914 | +//! @param RayPos_y 始点 Y座標 | |
915 | +//! @param RayPos_z 始点 Z座標 | |
916 | +//! @param RayDir_x ベクトル X成分 | |
917 | +//! @param RayDir_y ベクトル Y成分 | |
918 | +//! @param RayDir_z ベクトル Z成分 | |
919 | +//! @param maxDist 判定を行う最大距離 | |
920 | +//! @param *min_x 最小 X座標を返すポインタ | |
921 | +//! @param *min_y 最小 Y座標を返すポインタ | |
922 | +//! @param *min_z 最小 Z座標を返すポインタ | |
923 | +//! @param *max_x 最大 X座標を返すポインタ | |
924 | +//! @param *max_y 最大 Y座標を返すポインタ | |
925 | +//! @param *max_z 最大 Z座標を返すポインタ | |
926 | +void GetAABBRay(float RayPos_x, float RayPos_y, float RayPos_z, float RayDir_x, float RayDir_y, float RayDir_z, float maxDist, float *min_x, float *min_y, float *min_z, float *max_x, float *max_y, float *max_z) | |
927 | +{ | |
928 | + float rmin_x, rmin_y, rmin_z, rmax_x, rmax_y, rmax_z; | |
929 | + | |
930 | + //レイのAABBを作る | |
931 | + rmin_x = RayPos_x + RayDir_x * maxDist; | |
932 | + rmin_y = RayPos_y + RayDir_y * maxDist; | |
933 | + rmin_z = RayPos_z + RayDir_z * maxDist; | |
934 | + rmax_x = rmin_x; | |
935 | + rmax_y = rmin_y; | |
936 | + rmax_z = rmin_z; | |
937 | + if( rmin_x > RayPos_x ){ rmin_x = RayPos_x; } | |
938 | + if( rmin_y > RayPos_y ){ rmin_y = RayPos_y; } | |
939 | + if( rmin_z > RayPos_z ){ rmin_z = RayPos_z; } | |
940 | + if( rmax_x < RayPos_x ){ rmax_x = RayPos_x; } | |
941 | + if( rmax_y < RayPos_y ){ rmax_y = RayPos_y; } | |
942 | + if( rmax_z < RayPos_z ){ rmax_z = RayPos_z; } | |
943 | + | |
944 | + //計算誤差対策のため、わずかに大きめにする。 | |
945 | + rmin_x -= COLLISION_ADDSIZE; | |
946 | + rmin_y -= COLLISION_ADDSIZE; | |
947 | + rmin_z -= COLLISION_ADDSIZE; | |
948 | + rmax_x += COLLISION_ADDSIZE; | |
949 | + rmax_y += COLLISION_ADDSIZE; | |
950 | + rmax_z += COLLISION_ADDSIZE; | |
951 | + | |
952 | + *min_x = rmin_x; | |
953 | + *min_y = rmin_y; | |
954 | + *min_z = rmin_z; | |
955 | + *max_x = rmax_x; | |
956 | + *max_y = rmax_y; | |
957 | + *max_z = rmax_z; | |
958 | +} | |
959 | + | |
910 | 960 | //! @brief AABBによる当たり判定 |
911 | 961 | //! @param box1_min_x 物体Aの最少 X座標 |
912 | 962 | //! @param box1_min_y 物体Aの最少 Y座標 |
@@ -1027,27 +1077,8 @@ | ||
1027 | 1077 | float pmin_x, pmin_y, pmin_z, pmax_x, pmax_y, pmax_z; |
1028 | 1078 | |
1029 | 1079 | //レイのAABBを作る |
1030 | - pmin_x = RayPos_x + RayDir_x * maxDist; | |
1031 | - pmin_y = RayPos_y + RayDir_y * maxDist; | |
1032 | - pmin_z = RayPos_z + RayDir_z * maxDist; | |
1033 | - pmax_x = pmin_x; | |
1034 | - pmax_y = pmin_y; | |
1035 | - pmax_z = pmin_z; | |
1036 | - if( pmin_x > RayPos_x ){ pmin_x = RayPos_x; } | |
1037 | - if( pmin_y > RayPos_y ){ pmin_y = RayPos_y; } | |
1038 | - if( pmin_z > RayPos_z ){ pmin_z = RayPos_z; } | |
1039 | - if( pmax_x < RayPos_x ){ pmax_x = RayPos_x; } | |
1040 | - if( pmax_y < RayPos_y ){ pmax_y = RayPos_y; } | |
1041 | - if( pmax_z < RayPos_z ){ pmax_z = RayPos_z; } | |
1080 | + GetAABBRay(RayPos_x, RayPos_y, RayPos_z, RayDir_x, RayDir_y, RayDir_z, maxDist, &pmin_x, &pmin_y, &pmin_z, &pmax_x, &pmax_y, &pmax_z); | |
1042 | 1081 | |
1043 | - //計算誤差対策のため、わずかに大きめにする。 | |
1044 | - pmin_x -= COLLISION_ADDSIZE; | |
1045 | - pmin_y -= COLLISION_ADDSIZE; | |
1046 | - pmin_z -= COLLISION_ADDSIZE; | |
1047 | - pmax_x += COLLISION_ADDSIZE; | |
1048 | - pmax_y += COLLISION_ADDSIZE; | |
1049 | - pmax_z += COLLISION_ADDSIZE; | |
1050 | - | |
1051 | 1082 | //境界ボックス同士で判定 |
1052 | 1083 | if( CollideBoxAABB(s_x - s_r, s_y - s_r, s_z - s_r, s_x + s_r, s_y + s_r, s_z + s_r, pmin_x, pmin_y, pmin_z, pmax_x, pmax_y, pmax_z) == false ){ |
1053 | 1084 | return false; |
@@ -1122,27 +1153,8 @@ | ||
1122 | 1153 | float pmin_x, pmin_y, pmin_z, pmax_x, pmax_y, pmax_z; |
1123 | 1154 | |
1124 | 1155 | //レイのAABBを作る |
1125 | - pmin_x = RayPos_x + RayDir_x * maxDist; | |
1126 | - pmin_y = RayPos_y + RayDir_y * maxDist; | |
1127 | - pmin_z = RayPos_z + RayDir_z * maxDist; | |
1128 | - pmax_x = pmin_x; | |
1129 | - pmax_y = pmin_y; | |
1130 | - pmax_z = pmin_z; | |
1131 | - if( pmin_x > RayPos_x ){ pmin_x = RayPos_x; } | |
1132 | - if( pmin_y > RayPos_y ){ pmin_y = RayPos_y; } | |
1133 | - if( pmin_z > RayPos_z ){ pmin_z = RayPos_z; } | |
1134 | - if( pmax_x < RayPos_x ){ pmax_x = RayPos_x; } | |
1135 | - if( pmax_y < RayPos_y ){ pmax_y = RayPos_y; } | |
1136 | - if( pmax_z < RayPos_z ){ pmax_z = RayPos_z; } | |
1156 | + GetAABBRay(RayPos_x, RayPos_y, RayPos_z, RayDir_x, RayDir_y, RayDir_z, maxDist, &pmin_x, &pmin_y, &pmin_z, &pmax_x, &pmax_y, &pmax_z); | |
1137 | 1157 | |
1138 | - //計算誤差対策のため、わずかに大きめにする。 | |
1139 | - pmin_x -= COLLISION_ADDSIZE; | |
1140 | - pmin_y -= COLLISION_ADDSIZE; | |
1141 | - pmin_z -= COLLISION_ADDSIZE; | |
1142 | - pmax_x += COLLISION_ADDSIZE; | |
1143 | - pmax_y += COLLISION_ADDSIZE; | |
1144 | - pmax_z += COLLISION_ADDSIZE; | |
1145 | - | |
1146 | 1158 | //境界ボックス同士で判定 |
1147 | 1159 | if( CollideBoxAABB(box_min_x, box_min_y, box_min_z, box_max_x, box_max_y, box_max_z, pmin_x, pmin_y, pmin_z, pmax_x, pmax_y, pmax_z) == false ){ |
1148 | 1160 | return false; |
@@ -75,6 +75,8 @@ | ||
75 | 75 | int InitCollision(BlockDataInterface* in_BlockDataIF); |
76 | 76 | void GetBlockPosMINMAX(int id, float *min_x, float *min_y, float *min_z, float *max_x, float *max_y, float *max_z); |
77 | 77 | int GetWorldGroup(float x, float z); |
78 | + bool CheckBlockAABB(int id, float min_x, float min_y, float min_z, float max_x, float max_y, float max_z); | |
79 | + bool CheckALLBlockAABB(float min_x, float min_y, float min_z, float max_x, float max_y, float max_z); | |
78 | 80 | bool CheckPolygonFront(int id, int face, float x, float y, float z); |
79 | 81 | bool CheckPolygonFrontRx(int id, int face, float rx); |
80 | 82 | bool CheckBlockInside(int blockid, float x, float y, float z, bool worldgroup, int *planeid); |
@@ -88,6 +90,7 @@ | ||
88 | 90 | bool ScratchAngleVector(int id, int face, float in_vx, float in_vy, float in_vz, float *out_vx, float *out_vy, float *out_vz, float *out_angle); |
89 | 91 | }; |
90 | 92 | |
93 | +void GetAABBRay(float RayPos_x, float RayPos_y, float RayPos_z, float RayDir_x, float RayDir_y, float RayDir_z, float maxDist, float *min_x, float *min_y, float *min_z, float *max_x, float *max_y, float *max_z); | |
91 | 94 | bool CollideBoxAABB(float box1_min_x, float box1_min_y, float box1_min_z, float box1_max_x, float box1_max_y, float box1_max_z, float box2_min_x, float box2_min_y, float box2_min_z, float box2_max_x, float box2_max_y, float box2_max_z); |
92 | 95 | bool CollideCylinder(float c1_x, float c1_y, float c1_z, float c1_r, float c1_h, float c2_x, float c2_y, float c2_z, float c2_r, float c2_h, float *angle, float *length); |
93 | 96 | bool CollideSphereInside(float s_x, float s_y, float s_z, float s_r, float p_x, float p_y, float p_z); |
@@ -3390,7 +3390,6 @@ | ||
3390 | 3390 | int bs = BlockData.GetTotaldatas(); |
3391 | 3391 | for(int i=0; i< bs; i++){ |
3392 | 3392 | blockdata bdata; |
3393 | - float x_min, y_min, z_min, x_max, y_max, z_max; | |
3394 | 3393 | int vid[4]; |
3395 | 3394 | int bvx[4], bvy[4]; |
3396 | 3395 |
@@ -3397,9 +3396,8 @@ | ||
3397 | 3396 | //ブロックのデータを取得 |
3398 | 3397 | BlockData.Getdata(&bdata, i); |
3399 | 3398 | |
3400 | - //描画候補のブロックを検出(荒削り) | |
3401 | - CollD.GetBlockPosMINMAX(i, &x_min, &y_min, &z_min, &x_max, &y_max, &z_max); | |
3402 | - if( CollideBoxAABB(x_min, y_min, z_min, x_max, y_max, z_max, camera_x-RadarWorldR*2, camera_y-1.0f, camera_z-RadarWorldR*2, camera_x+RadarWorldR*2, camera_y+1.0f, camera_z+RadarWorldR*2) == true ){ | |
3399 | + //描画候補のブロックを検出(粗削り) | |
3400 | + if( CollD.CheckBlockAABB(i, camera_x-RadarWorldR*2, camera_y-1.0f, camera_z-RadarWorldR*2, camera_x+RadarWorldR*2, camera_y+1.0f, camera_z+RadarWorldR*2) == true ){ | |
3403 | 3401 | |
3404 | 3402 | //各面ごとに処理する |
3405 | 3403 | for(int j=0; j<6; j++){ |
@@ -1540,23 +1540,61 @@ | ||
1540 | 1540 | speed = sqrtf(dist_x*dist_x + dist_z*dist_z); |
1541 | 1541 | if( (speed != 0.0f)||(move_y != 0.0f) ){ |
1542 | 1542 | |
1543 | + float box_min_x, box_min_y, box_min_z, box_max_x, box_max_y, box_max_z; | |
1544 | + | |
1543 | 1545 | //頭部で当たり判定 |
1544 | - if( CollisionBlockScratch(CollD, inblockdata, &pos_x, &pos_y, &pos_z, pos_x2, pos_y2, pos_z2, pos_x, pos_y + HUMAN_HEIGHT-0.22f, pos_z, 0x01) == true ){ | |
1545 | - if( move_y > 0.0f ){ move_y = 0.0f; } | |
1546 | + // ※AABB判定で粗削りする | |
1547 | + box_min_x = pos_x - speed - COLLISION_ADDSIZE; | |
1548 | + box_min_y = (pos_y + HUMAN_HEIGHT-0.22f) - speed - COLLISION_ADDSIZE; | |
1549 | + box_min_z = pos_z - speed - COLLISION_ADDSIZE; | |
1550 | + box_max_x = pos_x + speed + COLLISION_ADDSIZE; | |
1551 | + box_max_y = (pos_y + HUMAN_HEIGHT-0.22f) + speed + COLLISION_ADDSIZE; | |
1552 | + box_max_z = pos_z + speed + COLLISION_ADDSIZE; | |
1553 | + if( CollD->CheckALLBlockAABB(box_min_x, box_min_y, box_min_z, box_max_x, box_max_y, box_max_z) == true ){ | |
1554 | + if( CollisionBlockScratch(CollD, inblockdata, &pos_x, &pos_y, &pos_z, pos_x2, pos_y2, pos_z2, pos_x, pos_y + HUMAN_HEIGHT-0.22f, pos_z, 0x01) == true ){ | |
1555 | + if( move_y > 0.0f ){ move_y = 0.0f; } | |
1556 | + } | |
1546 | 1557 | } |
1547 | 1558 | |
1548 | 1559 | //足元で当たり判定 |
1549 | - CollisionBlockScratch(CollD, inblockdata, &pos_x, &pos_y, &pos_z, pos_x2, pos_y2, pos_z2, pos_x, pos_y, pos_z, 0x00); | |
1560 | + // ※AABB判定で粗削りする | |
1561 | + box_min_x = pos_x - speed - COLLISION_ADDSIZE; | |
1562 | + box_min_y = pos_y - speed - COLLISION_ADDSIZE; | |
1563 | + box_min_z = pos_z - speed - COLLISION_ADDSIZE; | |
1564 | + box_max_x = pos_x + speed + COLLISION_ADDSIZE; | |
1565 | + box_max_y = pos_y + speed + COLLISION_ADDSIZE; | |
1566 | + box_max_z = pos_z + speed + COLLISION_ADDSIZE; | |
1567 | + if( CollD->CheckALLBlockAABB(box_min_x, box_min_y, box_min_z, box_max_x, box_max_y, box_max_z) == true ){ | |
1568 | + CollisionBlockScratch(CollD, inblockdata, &pos_x, &pos_y, &pos_z, pos_x2, pos_y2, pos_z2, pos_x, pos_y, pos_z, 0x00); | |
1569 | + } | |
1550 | 1570 | |
1551 | 1571 | //腰くらいで当たり判定 |
1552 | - CollisionBlockScratch(CollD, inblockdata, &pos_x, &pos_y, &pos_z, pos_x2, pos_y2, pos_z2, pos_x + dist_x*HUMAN_MAPCOLLISION_R, pos_y + HUMAN_MAPCOLLISION_HEIGHT, pos_z + dist_z*HUMAN_MAPCOLLISION_R, 0x02); | |
1553 | - CollisionBlockScratch(CollD, inblockdata, &pos_x, &pos_y, &pos_z, pos_x2, pos_y2, pos_z2, pos_x + dist_z*HUMAN_MAPCOLLISION_R, pos_y + HUMAN_MAPCOLLISION_HEIGHT, pos_z + dist_x*HUMAN_MAPCOLLISION_R, 0x02); | |
1554 | - CollisionBlockScratch(CollD, inblockdata, &pos_x, &pos_y, &pos_z, pos_x2, pos_y2, pos_z2, pos_x + dist_z*HUMAN_MAPCOLLISION_R*-1, pos_y + HUMAN_MAPCOLLISION_HEIGHT, pos_z + dist_x*HUMAN_MAPCOLLISION_R*-1, 0x02); | |
1572 | + // ※AABB判定で粗削りする | |
1573 | + box_min_x = (pos_x - speed*HUMAN_MAPCOLLISION_R) - speed - COLLISION_ADDSIZE; | |
1574 | + box_min_y = (pos_y + HUMAN_MAPCOLLISION_HEIGHT) - speed - COLLISION_ADDSIZE; | |
1575 | + box_min_z = (pos_z - speed*HUMAN_MAPCOLLISION_R) - speed - COLLISION_ADDSIZE; | |
1576 | + box_max_x = (pos_x + speed*HUMAN_MAPCOLLISION_R) + speed + COLLISION_ADDSIZE; | |
1577 | + box_max_y = (pos_y + HUMAN_MAPCOLLISION_HEIGHT) + speed + COLLISION_ADDSIZE; | |
1578 | + box_max_z = (pos_z + speed*HUMAN_MAPCOLLISION_R) + speed + COLLISION_ADDSIZE; | |
1579 | + if( CollD->CheckALLBlockAABB(box_min_x, box_min_y, box_min_z, box_max_x, box_max_y, box_max_z) == true ){ | |
1580 | + CollisionBlockScratch(CollD, inblockdata, &pos_x, &pos_y, &pos_z, pos_x2, pos_y2, pos_z2, pos_x + dist_x*HUMAN_MAPCOLLISION_R, pos_y + HUMAN_MAPCOLLISION_HEIGHT, pos_z + dist_z*HUMAN_MAPCOLLISION_R, 0x02); | |
1581 | + CollisionBlockScratch(CollD, inblockdata, &pos_x, &pos_y, &pos_z, pos_x2, pos_y2, pos_z2, pos_x + dist_z*HUMAN_MAPCOLLISION_R, pos_y + HUMAN_MAPCOLLISION_HEIGHT, pos_z + dist_x*HUMAN_MAPCOLLISION_R, 0x02); | |
1582 | + CollisionBlockScratch(CollD, inblockdata, &pos_x, &pos_y, &pos_z, pos_x2, pos_y2, pos_z2, pos_x + dist_z*HUMAN_MAPCOLLISION_R*-1, pos_y + HUMAN_MAPCOLLISION_HEIGHT, pos_z + dist_x*HUMAN_MAPCOLLISION_R*-1, 0x02); | |
1583 | + } | |
1555 | 1584 | |
1556 | 1585 | if( AddCollisionFlag == true ){ |
1557 | 1586 | //腰付近の追加当たり判定 |
1558 | - CollisionBlockScratch(CollD, inblockdata, &pos_x, &pos_y, &pos_z, pos_x2, pos_y2, pos_z2, pos_x, pos_y + HUMAN_MAPCOLLISION_ADD_HEIGHT_A, pos_z, 0x02); | |
1559 | - CollisionBlockScratch(CollD, inblockdata, &pos_x, &pos_y, &pos_z, pos_x2, pos_y2, pos_z2, pos_x, pos_y + HUMAN_MAPCOLLISION_ADD_HEIGHT_B, pos_z, 0x02); | |
1587 | + // ※AABB判定で粗削りする | |
1588 | + box_min_x = pos_x - speed - COLLISION_ADDSIZE; | |
1589 | + box_min_y = pos_y - speed - COLLISION_ADDSIZE; | |
1590 | + box_min_z = pos_z - speed - COLLISION_ADDSIZE; | |
1591 | + box_max_x = pos_x + speed + COLLISION_ADDSIZE; | |
1592 | + box_max_y = (pos_y + HUMAN_HEIGHT) + speed + COLLISION_ADDSIZE; | |
1593 | + box_max_z = pos_x + speed + COLLISION_ADDSIZE; | |
1594 | + if( CollD->CheckALLBlockAABB(box_min_x, box_min_y, box_min_z, box_max_x, box_max_y, box_max_z) == true ){ | |
1595 | + CollisionBlockScratch(CollD, inblockdata, &pos_x, &pos_y, &pos_z, pos_x2, pos_y2, pos_z2, pos_x, pos_y + HUMAN_MAPCOLLISION_ADD_HEIGHT_A, pos_z, 0x02); | |
1596 | + CollisionBlockScratch(CollD, inblockdata, &pos_x, &pos_y, &pos_z, pos_x2, pos_y2, pos_z2, pos_x, pos_y + HUMAN_MAPCOLLISION_ADD_HEIGHT_B, pos_z, 0x02); | |
1597 | + } | |
1560 | 1598 | } |
1561 | 1599 | |
1562 | 1600 | //斜面を登る |
@@ -1591,23 +1629,32 @@ | ||
1591 | 1629 | } |
1592 | 1630 | |
1593 | 1631 | //移動先がブロックへめり込んでいるなら移動を無効にする |
1594 | - if( | |
1595 | - (CollD->CheckALLBlockInside(pos_x, pos_y + 2.0f, pos_z) == true)|| | |
1596 | - (CollD->CheckALLBlockIntersectRay(pos_x, pos_y + 2.0f, pos_z, 0.0f, 1.0f, 0.0f, NULL, NULL, &Dist, (HUMAN_HEIGHT-2.0f*2)) == true) | |
1597 | - ){ | |
1598 | - pos_x = pos_x2; | |
1599 | - pos_z = pos_z2; | |
1600 | - } | |
1601 | - | |
1602 | - //移動先がブロックにめり込む&移動先もめり込む ならば、移動を無効にする | |
1603 | - if( CollD->CheckALLBlockInside(pos_x, pos_y + HUMAN_HEIGHT-0.6f, pos_z) == true ){ | |
1604 | - //メモ:↓この判定怪しい。十分に遠い位置であれば良く、11倍である必要はない? | |
1605 | - if( CollD->CheckALLBlockInside(pos_x + move_x*11.0f, pos_y + HUMAN_HEIGHT-0.6f, pos_z + move_z*11.0f) == true ){ | |
1632 | + // ※AABB判定で粗削りする | |
1633 | + box_min_x = pos_x - 1.0f - COLLISION_ADDSIZE; | |
1634 | + box_min_y = (pos_y + 2.0f) - 1.0f - COLLISION_ADDSIZE; | |
1635 | + box_min_z = pos_z - 1.0f - COLLISION_ADDSIZE; | |
1636 | + box_max_x = pos_x + 1.0f + COLLISION_ADDSIZE; | |
1637 | + box_max_y = (pos_y + (HUMAN_HEIGHT-2.0f*2)) + 1.0f + COLLISION_ADDSIZE; | |
1638 | + box_max_z = pos_z + 1.0f + COLLISION_ADDSIZE; | |
1639 | + if( CollD->CheckALLBlockAABB(box_min_x, box_min_y, box_min_z, box_max_x, box_max_y, box_max_z) == true ){ | |
1640 | + if( | |
1641 | + (CollD->CheckALLBlockInside(pos_x, pos_y + 2.0f, pos_z) == true)|| | |
1642 | + (CollD->CheckALLBlockIntersectRay(pos_x, pos_y + 2.0f, pos_z, 0.0f, 1.0f, 0.0f, NULL, NULL, &Dist, (HUMAN_HEIGHT-2.0f*2)) == true) | |
1643 | + ){ | |
1606 | 1644 | pos_x = pos_x2; |
1607 | - pos_y = pos_y2; | |
1608 | 1645 | pos_z = pos_z2; |
1609 | - if( move_y > 0.0f ){ move_y = 0.0f; } | |
1610 | 1646 | } |
1647 | + | |
1648 | + //移動先がブロックにめり込む&移動先もめり込む ならば、移動を無効にする | |
1649 | + if( CollD->CheckALLBlockInside(pos_x, pos_y + HUMAN_HEIGHT-0.6f, pos_z) == true ){ | |
1650 | + //メモ:↓この判定怪しい。十分に遠い位置であれば良く、11倍である必要はない? | |
1651 | + if( CollD->CheckALLBlockInside(pos_x + move_x*11.0f, pos_y + HUMAN_HEIGHT-0.6f, pos_z + move_z*11.0f) == true ){ | |
1652 | + pos_x = pos_x2; | |
1653 | + pos_y = pos_y2; | |
1654 | + pos_z = pos_z2; | |
1655 | + if( move_y > 0.0f ){ move_y = 0.0f; } | |
1656 | + } | |
1657 | + } | |
1611 | 1658 | } |
1612 | 1659 | } |
1613 | 1660 |
@@ -1808,8 +1855,18 @@ | ||
1808 | 1855 | dist = VectorNormalization(&vx, &vy, &vz); |
1809 | 1856 | |
1810 | 1857 | //追突したブロック面取得 |
1811 | - if( CollD->CheckALLBlockIntersectDummyRay(in_vx - vx, in_vy - vy, in_vz - vz, vx, vy, vz, NULL, NULL, &temp, dist) == false ){ return false; } | |
1812 | - if( CollD->CheckALLBlockIntersectRay(in_vx - vx, in_vy - vy, in_vz - vz, vx, vy, vz, &id, &face, &temp, dist) == false ){ return false; } | |
1858 | + float rmin_x, rmin_y, rmin_z, rmax_x, rmax_y, rmax_z; | |
1859 | + id = -1; | |
1860 | + GetAABBRay(in_vx - vx, in_vy - vy, in_vz - vz, vx, vy, vz, dist, &rmin_x, &rmin_y, &rmin_z, &rmax_x, &rmax_y, &rmax_z); | |
1861 | + for(int i=0; i<inblockdata->GetTotaldatas(); i++){ | |
1862 | + if( CollD->CheckBlockAABB(i, rmin_x, rmin_y, rmin_z, rmax_x, rmax_y, rmax_z) == true ){ | |
1863 | + if( CollD->CheckBlockIntersectRay(i, in_vx - vx, in_vy - vy, in_vz - vz, vx, vy, vz, &face, &temp, dist) == true ){ | |
1864 | + id = i; | |
1865 | + break; | |
1866 | + } | |
1867 | + } | |
1868 | + } | |
1869 | + if( id == -1 ){ return false; } | |
1813 | 1870 | |
1814 | 1871 | //ブロックに沿って移動するベクトルと進入角度を求める |
1815 | 1872 | if( CollD->ScratchAngleVector(id, face, vx, vy, vz, &vx, &vy, &vz, &face_angle) == false ){ return false; } |