void updateDirAndTimeByEdge(FP _percent, tableEdge _tbe, BallObj ball, FP _deltaTime) { ball.UpdateBallPos(_deltaTime * _percent); //先更新到撞击点 var curReflcDir = Detection.CheckCircle_LineCollision(_tbe, ball.GetPos(), ball.GetRadius(), ball.GetMoveDir()); //计算碰撞响应 ball.UpdateMoveDir(curReflcDir); //更新实时方向 }
void _updateDirAndTimeByEdge(FP _percent, TSVector2 hitNormal, BallObj ball, FP _deltaTime) { ball.UpdateBallPos(_deltaTime * _percent); //先更新到撞击点 var curReflcDir = Detection.CheckCircle_EdgeCollision(hitNormal, ball.GetMoveDir()); //计算碰撞响应 ball.UpdateMoveDir(curReflcDir); //更新实时方向 }
void updateDirAndTimeByBall(FP _percent, BallObj runball, BallObj staticball, FP _deltaTime) { runball.UpdateBallPos(_deltaTime * _percent);//先更新到撞击点 staticball.UpdateBallPos(_deltaTime * _percent); //var runcrd = new CircleRunData(runball.GetPos(), runball.PredictPos(_deltaTime), runball.GetRadius()); //var staticcrd = new CircleRunData(staticball.GetPos(), staticball.PredictPos(_deltaTime), staticball.GetRadius()); var curReflcDir = Detection.CheckCircle_CircleCollision(runball.GetPos(), runball.GetMoveDir(), staticball.GetPos(), staticball.GetMoveDir());//计算碰撞响应 runball.UpdateMoveDir(curReflcDir[0]); staticball.UpdateMoveDir(curReflcDir[1]); }
void UpdatePhysicStep(FP _deltaTime) { step++; //AddTestData(step,balls); for (int k = 0; k < balls.Count; k++) { var ball = balls[k]; ball.deltaTime = _deltaTime; ball.lockcheck = false; } testnumber = 0; FP leftSyncTime = _deltaTime; while (true) { testnumber++; if (testnumber > 100) { if (testnumber > 200) { Debug.Log("防止死循环"); break; } } //List<BaseHit> baseHits = new List<BaseHit>(); baseHits.Clear(); FP _percent = 0; for (int i = 0; i < balls.Count - 1; i++) { var ball = balls[i]; //CircleRunData run_crd = new CircleRunData(ball.GetPos(), ball.PredictPos(leftSyncTime), ball.GetRadius()); CircleRunData run_crd = run_crdPool.New(); run_crd.Init(ball.GetPos(), ball.PredictPos(leftSyncTime), ball.GetRadius()); for (int j = i + 1; j < balls.Count; j++) { var otherball = balls[j]; //CircleRunData static_crd = new CircleRunData(otherball.GetPos(), otherball.PredictPos(leftSyncTime), otherball.GetRadius()); CircleRunData static_crd = run_crdPool.New(); static_crd.Init(otherball.GetPos(), otherball.PredictPos(leftSyncTime), otherball.GetRadius()); if (Detection.CheckCircle_CircleContact(run_crd, static_crd, ball.deltaTime, ref _percent)) { var obj = fastHitBallPool.New(); obj.Init(ball, otherball, _percent); baseHits.Add(obj); //baseHits.Add(new fastHitBall(ball, otherball, _percent)); } } } for (int ii = 0; ii < balls.Count; ii++) { var ball = balls[ii]; TSVector2 predictEndPos = ball.GetPos() + ball.GetMoveDir() * 100; //CircleRunData run_crd = new CircleRunData(ball.GetPos(), ball.PredictPos(leftSyncTime), ball.GetRadius()); CircleRunData run_crd = run_crdPool.New(); run_crd.Init(ball.GetPos(), ball.PredictPos(leftSyncTime), ball.GetRadius()); //在当前速度下,预测圆最先和哪条边碰撞 for (int jj = 0; jj < tableEdges.Count; jj++) { TSVector2 predictCirclePos = TSVector2.zero; if (Detection.CheckCloseSegement(tableEdges[jj], ball.moveDir)) //if (Detection.CheckCloseEdge(tableEdges[jj].start, tableEdges[jj].end, ball.GetPos(), predictEndPos)) { //预测是否和边所在平面碰撞 if (Detection.CheckCircle_LineContact(tableEdges[jj], run_crd, ref _percent) /*|| Detection.CheckCircle_tableEdgeEndContact(run_crd, tableEdges[jj], ref _percent)*/) { predictCirclePos = ball.PredictPos(leftSyncTime * _percent); if (Detection.CheckCircle_SegementContact(predictCirclePos, tableEdges[jj], ball.radius))//然后检测离真实线段最近的点是否符合要求 { var obj = fastEdgePool.New(); obj.Init(ball, tableEdges[jj], _percent, tableEdges[jj].normal); baseHits.Add(obj); } else { _percent = 0; } } else { //TSVector2 nearestPos = TSVector2.zero; //if(Detection.CheckCircle_tableEdgeEndContact(run_crd, tableEdges[jj], ref _percent,ref nearestPos))//检测是否和线段的端点产生了碰撞 } } if (Detection._CheckCircle_tableEdgeEndContact(run_crd, tableEdges[jj].start, ref _percent))//检测是否和线段的左端点产生了碰撞 { predictCirclePos = ball.PredictPos(leftSyncTime * _percent); if (Detection.CheckCircle_SegementContact(predictCirclePos, tableEdges[jj], ball.radius))//然后检测离真实线段最近的点是否符合要求 { var obj = fastEdgePool.New(); obj.Init(ball, tableEdges[jj], _percent, (predictCirclePos - tableEdges[jj].start).normalized); baseHits.Add(obj); } else { _percent = 0; } } else if (Detection._CheckCircle_tableEdgeEndContact(run_crd, tableEdges[jj].end, ref _percent))//检测是否和线段的右端点产生了碰撞 { predictCirclePos = ball.PredictPos(leftSyncTime * _percent); if (Detection.CheckCircle_SegementContact(predictCirclePos, tableEdges[jj], ball.radius))//然后检测离真实线段最近的点是否符合要求 { var obj = fastEdgePool.New(); obj.Init(ball, tableEdges[jj], _percent, (predictCirclePos - tableEdges[jj].end).normalized); baseHits.Add(obj); } else { _percent = 0; } } else { _percent = 0; } } } if (baseHits.Count > 0) { var closedHit = baseHits.OrderBy((m) => m.t_percent).First(); closedHit.TagProcess(); var syncTime = closedHit.t_percent * leftSyncTime; leftSyncTime -= syncTime; if (leftSyncTime <= 0) { leftSyncTime = 0; } if (closedHit.hitType == HitType.Ball) { var _baseHit = closedHit as fastHitBall; //_baseHit.runballObj.CalBallPos(_baseHit.t_percent * _baseHit.runballObj.deltaTime); //_baseHit.staticballObj.CalBallPos(_baseHit.t_percent * _baseHit.staticballObj.deltaTime); updateDirAndTimeByBall(_baseHit.t_percent, _baseHit.runballObj, _baseHit.staticballObj, syncTime); } else if (closedHit.hitType == HitType.Edge) { var _baseHit = closedHit as fastEdge; //_baseHit.ball.CalBallPos(_baseHit.t_percent * _baseHit.ball.deltaTime); //updateDirAndTimeByEdge(_baseHit.t_percent, _baseHit.tbe, _baseHit.ball, syncTime); _updateDirAndTimeByEdge(_baseHit.t_percent, _baseHit.hitNormal, _baseHit.ball, syncTime); } for (int m = 0; m < balls.Count; m++) { var nothitBall = balls[m]; if (nothitBall.lockcheck == false) { nothitBall.UpdateBallPos(syncTime); } } } else { for (int n = 0; n < balls.Count; n++) { var nothitBall = balls[n]; //if (nothitBall.deltaTime > 0) nothitBall.UpdateBallPos(leftSyncTime); } break; } run_crdPool.ResetAll(); fastEdgePool.ResetAll(); fastHitBallPool.ResetAll(); UnLockBalls(); } //ClearTestData(); }