void CInventoryItem::PH_A_CrPr () { net_updateData* p = NetSync(); //restore recalculated data and get data for interpolation if (!object().CrPr_IsActivated()) return; //////////////////////////////////// CPHSynchronize* pSyncObj = NULL; pSyncObj = object().PHGetSyncItem (0); if (!pSyncObj) return; //////////////////////////////////// pSyncObj->get_State (p->PredictedState); //////////////////////////////////// pSyncObj->set_State (p->RecalculatedState); //////////////////////////////////// if (!m_flags.test(FInInterpolate)) return; //////////////////////////////////// Fmatrix xformX; pSyncObj->cv2obj_Xfrom(p->PredictedState.quaternion, p->PredictedState.position, xformX); VERIFY2 (_valid(xformX),*object().cName()); pSyncObj->cv2obj_Xfrom (p->PredictedState.quaternion, p->PredictedState.position, xformX); p->IEndRot.set (xformX); p->IEndPos.set (xformX.c); VERIFY2 (_valid(p->IEndPos),*object().cName()); ///////////////////////////////////////////////////////////////////////// CalculateInterpolationParams (); /////////////////////////////////////////////////// };
void CInventoryItem::PH_I_CrPr () // actions & operations between two phisic prediction steps { net_updateData* p = NetSync(); //store recalculated data, then we able to restore it after small future prediction if (!object().CrPr_IsActivated()) return; //////////////////////////////////// CPHSynchronize* pSyncObj = NULL; pSyncObj = object().PHGetSyncItem (0); if (!pSyncObj) return; //////////////////////////////////// pSyncObj->get_State (p->RecalculatedState); /////////////////////////////////////////////// Fmatrix xformX; pSyncObj->cv2obj_Xfrom(p->RecalculatedState.quaternion, p->RecalculatedState.position, xformX); VERIFY2 (_valid(xformX),*object().cName()); pSyncObj->cv2obj_Xfrom (p->RecalculatedState.quaternion, p->RecalculatedState.position, xformX); p->IRecRot.set(xformX); p->IRecPos.set(xformX.c); VERIFY2 (_valid(p->IRecPos),*object().cName()); };
void CInventoryItem::make_Interpolation () { net_updateData* p = NetSync(); p->m_dwILastUpdateTime = Level().timeServer(); if(!object().H_Parent() && object().getVisible() && object().m_pPhysicsShell && m_flags.test(FInInterpolation) ) { u32 CurTime = Level().timeServer(); if (CurTime >= p->m_dwIEndTime) { m_flags.set(FInInterpolation, FALSE); object().m_pPhysicsShell->NetInterpolationModeOFF(); CPHSynchronize* pSyncObj = NULL; pSyncObj = object().PHGetSyncItem(0); pSyncObj->set_State (p->PredictedState); Fmatrix xformI; pSyncObj->cv2obj_Xfrom (p->PredictedState.quaternion, p->PredictedState.position, xformI); VERIFY2 (_valid(object().renderable.xform),*object().cName()); object().XFORM().set (xformI); VERIFY2 (_valid(object().renderable.xform),*object().cName()); } else { VERIFY (CurTime <= p->m_dwIEndTime); float factor = float(CurTime - p->m_dwIStartTime)/(p->m_dwIEndTime - p->m_dwIStartTime); if (factor > 1) factor = 1.0f; else if (factor < 0) factor = 0; Fvector IPos; Fquaternion IRot; float c = factor; for (u32 k=0; k<3; k++) { IPos[k] = c*(c*(c*p->SCoeff[k][0]+p->SCoeff[k][1])+p->SCoeff[k][2])+p->SCoeff[k][3]; }; VERIFY2 (_valid(IPos),*object().cName()); VERIFY (factor>=0.f && factor<=1.f); IRot.slerp(p->IStartRot, p->IEndRot, factor); VERIFY2 (_valid(IRot),*object().cName()); object().XFORM().rotation(IRot); VERIFY2 (_valid(object().renderable.xform),*object().cName()); object().Position().set(IPos); VERIFY2 (_valid(object().renderable.xform),*object().cName()); }; } else { m_flags.set(FInInterpolation,FALSE); }; #ifdef DEBUG Fvector iPos = object().Position(); if (!object().H_Parent() && object().getVisible()) { if(m_net_updateData) m_net_updateData->LastVisPos.push_back(iPos); }; #endif }
void CInventoryItem::CalculateInterpolationParams() { net_updateData* p = NetSync(); p->IStartPos.set(object().Position()); p->IStartRot.set(object().XFORM()); Fvector P0, P1, P2, P3; CPHSynchronize* pSyncObj = NULL; pSyncObj = object().PHGetSyncItem(0); Fmatrix xformX0, xformX1; if (m_flags.test(FInInterpolation)) { u32 CurTime = Level().timeServer(); float factor = float(CurTime - p->m_dwIStartTime)/(p->m_dwIEndTime - p->m_dwIStartTime); if (factor > 1.0f) factor = 1.0f; float c = factor; for (u32 k=0; k<3; k++) { P0[k] = c*(c*(c*p->SCoeff[k][0]+p->SCoeff[k][1])+p->SCoeff[k][2])+p->SCoeff[k][3]; P1[k] = (c*c*p->SCoeff[k][0]*3+c*p->SCoeff[k][1]*2+p->SCoeff[k][2])/3; // сокрость из формулы в 3 раза превышает скорость при расчете коэффициентов !!!! }; P0.set(p->IStartPos); P1.add(p->IStartPos); } else { P0 = p->IStartPos; if (p->LastState.linear_vel.x == 0 && p->LastState.linear_vel.y == 0 && p->LastState.linear_vel.z == 0) { pSyncObj->cv2obj_Xfrom(p->RecalculatedState.previous_quaternion, p->RecalculatedState.previous_position, xformX0); pSyncObj->cv2obj_Xfrom(p->RecalculatedState.quaternion, p->RecalculatedState.position, xformX1); } else { pSyncObj->cv2obj_Xfrom(p->LastState.previous_quaternion, p->LastState.previous_position, xformX0); pSyncObj->cv2obj_Xfrom(p->LastState.quaternion, p->LastState.position, xformX1); }; P1.sub(xformX1.c, xformX0.c); P1.add(p->IStartPos); } P2.sub(p->PredictedState.position, p->PredictedState.linear_vel); pSyncObj->cv2obj_Xfrom(p->PredictedState.quaternion, P2, xformX0); P2.set(xformX0.c); pSyncObj->cv2obj_Xfrom(p->PredictedState.quaternion, p->PredictedState.position, xformX1); P3.set(xformX1.c); ///////////////////////////////////////////////////////////////////////////// Fvector TotalPath; TotalPath.sub(P3, P0); float TotalLen = TotalPath.magnitude(); SPHNetState State0 = (p->NET_IItem.back()).State; SPHNetState State1 = p->PredictedState; float lV0 = State0.linear_vel.magnitude(); float lV1 = State1.linear_vel.magnitude(); u32 ConstTime = u32((fixed_step - ph_world->m_frame_time)*1000)+ Level().GetInterpolationSteps()*u32(fixed_step*1000); p->m_dwIStartTime = p->m_dwILastUpdateTime; if (( lV0 + lV1) > 0.000001 && g_cl_lvInterp == 0) { u32 CulcTime = iCeil(TotalLen*2000/( lV0 + lV1)); p->m_dwIEndTime = p->m_dwIStartTime + min(CulcTime, ConstTime); } else p->m_dwIEndTime = p->m_dwIStartTime + ConstTime; ///////////////////////////////////////////////////////////////////////////// Fvector V0, V1; V0.sub(P1, P0); V1.sub(P3, P2); lV0 = V0.magnitude(); lV1 = V1.magnitude(); if (TotalLen != 0) { if (V0.x != 0 || V0.y != 0 || V0.z != 0) { if (lV0 > TotalLen/3) { V0.normalize(); V0.mul(TotalLen/3); P1.add(V0, P0); } } if (V1.x != 0 || V1.y != 0 || V1.z != 0) { if (lV1 > TotalLen/3) { V1.normalize(); V1.mul(TotalLen/3); P2.sub(P3, V1); }; } }; ///////////////////////////////////////////////////////////////////////////// for( u32 i =0; i<3; i++) { p->SCoeff[i][0] = P3[i] - 3*P2[i] + 3*P1[i] - P0[i]; p->SCoeff[i][1] = 3*P2[i] - 6*P1[i] + 3*P0[i]; p->SCoeff[i][2] = 3*P1[i] - 3*P0[i]; p->SCoeff[i][3] = P0[i]; }; ///////////////////////////////////////////////////////////////////////////// m_flags.set (FInInterpolation, TRUE); if (object().m_pPhysicsShell) object().m_pPhysicsShell->NetInterpolationModeON(); };