inline bool MODEL :: collision(VECTOR pos, VECTOR rotate){ MV1_COLL_RESULT_POLY_DIM result; if(!cflag){ r += 2.5f; if(r > 250.0f) r = 250.0f; VECTOR pos1 = VGet(pos.x+600*sinf(rotate.y), pos.y+100.0f+200.0f-500*sinf(rotate.x), pos.z+600*cosf(rotate.y)); VECTOR pos2 = VGet(pos.x-200*sinf(rotate.y), pos.y+100.0f+200.0f+500*sinf(rotate.x), pos.z-200*cosf(rotate.y)); result = MV1CollCheck_Capsule(ModelHandle, 39, pos1, pos2, r); }else{ r -= 5.0f; if(r < 100.0f) r = 100.0f; VECTOR pos1 = VGet(pos.x+600*sinf(rotate.y), pos.y+100.0f+200.0f-500*sinf(rotate.x), pos.z+600*cosf(rotate.y)); VECTOR pos2 = VGet(pos.x-200*sinf(rotate.y), pos.y+100.0f+200.0f+500*sinf(rotate.x), pos.z-200*cosf(rotate.y)); result = MV1CollCheck_Capsule(ModelHandle, 39, pos1, pos2, r); } if(r == 100.0){ cflag = true; return false; } if(result.HitNum > 0){ MV1CollResultPolyDimTerminate(result); cflag = true; return true; } MV1CollResultPolyDimTerminate(result); cflag = false; return false; }
bool Collision::Octree_Capsule(int modelID, const Capsule& capsule, HitInfo& hitInfo) { MV1_COLL_RESULT_POLY_DIM mv1HitInfo; mv1HitInfo = MV1CollCheck_Capsule(modelID, -1, Convert::ToVECTOR(capsule.p1), Convert::ToVECTOR(capsule.p2), capsule.radius); if (mv1HitInfo.HitNum < 1) { return false; } int hitNum = mv1HitInfo.HitNum; Vector3 pos; Vector3 normal; for (int i = 0; i < hitNum; ++i) { VECTOR p = mv1HitInfo.Dim[i].HitPosition; pos += Vector3(p.x, p.y, p.z); VECTOR n = mv1HitInfo.Dim[i].Normal; normal += Vector3(n.x, n.y, n.z); } pos /= hitNum; normal /= hitNum; hitInfo.intersect = pos; hitInfo.normal = normal.GetNormal(); MV1CollResultPolyDimTerminate(mv1HitInfo); return true; }
inline bool TARGET :: collision(VECTOR pos, VECTOR rotate){ VECTOR pos1 = VGet(pos.x+600*sinf(rotate.y), pos.y+100.0f+200.0f-500*sinf(rotate.x), pos.z+600*cosf(rotate.y)); VECTOR pos2 = VGet(pos.x-200*sinf(rotate.y), pos.y+100.0f+200.0f+500*sinf(rotate.x), pos.z-200*cosf(rotate.y)); MV1_COLL_RESULT_POLY_DIM result = MV1CollCheck_Capsule(ModelHandle, -1, pos1, pos2, 210.0f); if(result.HitNum > 0){ MV1CollResultPolyDimTerminate(result); return true; } MV1CollResultPolyDimTerminate(result); return false; }
// モデルとカプセルの当たり判定 CollisionParameter Collisin::ModelCapsule(const ModelData& model, const Capsule& c) const{ CollisionParameter colpara; MV1_COLL_RESULT_POLY_DIM HitPolyDim; HitPolyDim = MV1CollCheck_Capsule( model.MHandle, model.MFrameIndex, c.startPos.ToVECTOR(), c.endPos.ToVECTOR(), c.radius); if (HitPolyDim.HitNum > 0) colpara.colFlag = true; MV1CollResultPolyDimTerminate(HitPolyDim); return colpara; }
// カメラの処理 void Camera_Process( void ) { // パッドの3ボタンか、シフトキーが押されている場合のみ角度変更操作を行う if( CheckHitKey( KEY_INPUT_LSHIFT ) || ( inp.NowInput & PAD_INPUT_C ) ) { // 「←」ボタンが押されていたら水平角度をマイナスする if( inp.NowInput & PAD_INPUT_LEFT ) { cam.AngleH -= CAMERA_ANGLE_SPEED ; // −180度以下になったら角度値が大きくなりすぎないように360度を足す if( cam.AngleH < -DX_PI_F ) { cam.AngleH += DX_TWO_PI_F ; } } // 「→」ボタンが押されていたら水平角度をプラスする if( inp.NowInput & PAD_INPUT_RIGHT ) { cam.AngleH += CAMERA_ANGLE_SPEED ; // 180度以上になったら角度値が大きくなりすぎないように360度を引く if( cam.AngleH > DX_PI_F ) { cam.AngleH -= DX_TWO_PI_F ; } } // 「↑」ボタンが押されていたら垂直角度をマイナスする if( inp.NowInput & PAD_INPUT_UP ) { cam.AngleV -= CAMERA_ANGLE_SPEED ; // ある一定角度以下にはならないようにする if( cam.AngleV < -DX_PI_F / 2.0f + 0.6f ) { cam.AngleV = -DX_PI_F / 2.0f + 0.6f ; } } // 「↓」ボタンが押されていたら垂直角度をプラスする if( inp.NowInput & PAD_INPUT_DOWN ) { cam.AngleV += CAMERA_ANGLE_SPEED ; // ある一定角度以上にはならないようにする if( cam.AngleV > DX_PI_F / 2.0f - 0.6f ) { cam.AngleV = DX_PI_F / 2.0f - 0.6f ; } } } // カメラの注視点はプレイヤー座標から規定値分高い座標 cam.Target = VAdd( pl.CharaInfo.Position, VGet( 0.0f, CAMERA_PLAYER_TARGET_HEIGHT, 0.0f ) ) ; // カメラの座標を決定する { MATRIX RotZ, RotY ; float Camera_Player_Length ; MV1_COLL_RESULT_POLY_DIM HRes ; int HitNum ; // 水平方向の回転はY軸回転 RotY = MGetRotY( cam.AngleH ) ; // 垂直方向の回転はZ軸回転 ) RotZ = MGetRotZ( cam.AngleV ) ; // カメラからプレイヤーまでの初期距離をセット Camera_Player_Length = CAMERA_PLAYER_LENGTH ; // カメラの座標を算出 // X軸にカメラとプレイヤーとの距離分だけ伸びたベクトルを // 垂直方向回転( Z軸回転 )させたあと水平方向回転( Y軸回転 )して更に // 注視点の座標を足したものがカメラの座標 cam.Eye = VAdd( VTransform( VTransform( VGet( -Camera_Player_Length, 0.0f, 0.0f ), RotZ ), RotY ), cam.Target ) ; // 注視点からカメラの座標までの間にステージのポリゴンがあるか調べる HRes = MV1CollCheck_Capsule( stg.ModelHandle, -1, cam.Target, cam.Eye, CAMERA_COLLISION_SIZE ); HitNum = HRes.HitNum ; MV1CollResultPolyDimTerminate( HRes ) ; if( HitNum != 0 ) { float NotHitLength ; float HitLength ; float TestLength ; VECTOR TestPosition ; // あったら無い位置までプレイヤーに近づく // ポリゴンに当たらない距離をセット NotHitLength = 0.0f ; // ポリゴンに当たる距離をセット HitLength = Camera_Player_Length ; do { // 当たるかどうかテストする距離をセット( 当たらない距離と当たる距離の中間 ) TestLength = NotHitLength + ( HitLength - NotHitLength ) / 2.0f ; // テスト用のカメラ座標を算出 TestPosition = VAdd( VTransform( VTransform( VGet( -TestLength, 0.0f, 0.0f ), RotZ ), RotY ), cam.Target ) ; // 新しい座標で壁に当たるかテスト HRes = MV1CollCheck_Capsule( stg.ModelHandle, -1, cam.Target, TestPosition, CAMERA_COLLISION_SIZE ); HitNum = HRes.HitNum ; MV1CollResultPolyDimTerminate( HRes ) ; if( HitNum != 0 ) { // 当たったら当たる距離を TestLength に変更する HitLength = TestLength ; } else { // 当たらなかったら当たらない距離を TestLength に変更する NotHitLength = TestLength ; } // HitLength と NoHitLength が十分に近づいていなかったらループ }while( HitLength - NotHitLength > 0.1f ) ; // カメラの座標をセット cam.Eye = TestPosition ; } } }