void CCamera::Update(float ftDelta) { SRotator Rot = this->Location().Rotation; if(m_bImpact) { if(m_ftElapsedTime < m_ftImpactTime/2.0f) { m_vctTargetEye = m_vctTargetEye*m_ftElapsedTime + m_vctCurrentEye*(m_ftImpactTime/2.0f-m_ftElapsedTime); m_vctTargetEye *= m_ftImpactTime/2.0f; } else { m_vctTargetEye = m_vctTargetEye*(m_ftElapsedTime-m_ftImpactTime/2.0f) + m_vctCurrentEye*(m_ftImpactTime-m_ftElapsedTime); m_vctTargetEye *= m_ftImpactTime/2.0f; } } float ftVelocityEye = 10.0f; SVector vctDelta = m_vctTargetEye - m_vctCurrentEye; if(vctDelta.Size2D() < ftDelta * ftVelocityEye) { m_vctCurrentEye = m_vctTargetEye; } else { vctDelta.Normalize(); m_vctCurrentEye = m_vctCurrentEye + vctDelta * ftDelta * ftVelocityEye; } m_vctCurrentEye = m_vctTargetEye; if(m_bJerk) { // if(((int)(m_fFlashTime * 5.0f)) % 2 == 0) SVector vctDelta = m_vctCurrentEye - m_vctCurrentAt; m_vctCurrentAt.Y += float(rand()%10-5)/10.0f * m_ftJerk * vctDelta.Size() / 20.0f; } CreateLookAt(m_vctCurrentEye, m_vctCurrentAt, SVector(0.0f, 1.0f, 0.0f)); }
void CCamera::Tick(float ftDelta) { if(m_bImpact) { m_ftElapsedTime += ftDelta; if(m_ftElapsedTime > m_ftImpactTime) { m_bImpact = false; } else { if(m_pImpactCharacter) { m_vctTargetAt = m_pImpactCharacter->GetLocation()->Location; m_vctTargetAt.Y = m_ftFocusHeight; if(m_ftElapsedTime < m_ftImpactTime/2.0f) { m_vctTargetAt = m_vctTargetAt*m_ftElapsedTime + m_vctCurrentAt*(m_ftImpactTime/2.0f-m_ftElapsedTime); m_vctTargetAt *= m_ftImpactTime/2.0f; } else { m_vctTargetAt = m_vctTargetAt*(m_ftElapsedTime-m_ftImpactTime/2.0f) + m_vctCurrentAt*(m_ftImpactTime-m_ftElapsedTime); m_vctTargetAt *= m_ftImpactTime/2.0f; } } } } else { if(m_pCharacter&&m_pBall&&m_pRim) { SVector vctRim(0.0f, 0.0f, 0.0f); vctRim.X = m_pRim->X; if(vctRim.X > 0) { vctRim.X += m_ftRimOffset; } else { vctRim.X -= m_ftRimOffset; } SVector vctBall = m_pBall->GetLocation()->Location; SVector vctChar = m_pCharacter->GetLocation()->Location; if(m_pBall->Ani()) { vctBall = m_pBall->GetCharacter()->GetLocation()->Location; } m_vctTargetAt = (m_ftRatioChar*vctChar+m_ftRatioBall*vctBall+m_ftRatioRim*vctRim)/ (m_ftRatioChar+m_ftRatioBall+m_ftRatioRim); m_vctTargetAt.Y = m_ftFocusHeight; } } float ftVelocityAt = 5.0f; SVector vctDelta = m_vctTargetAt - m_vctCurrentAt; if(vctDelta.Size2D() < ftDelta*ftVelocityAt) { m_vctCurrentAt = m_vctTargetAt; } else { vctDelta.Normalize(); m_vctCurrentAt = m_vctCurrentAt + vctDelta * ftDelta * ftVelocityAt; } // m_vctCurrentAt = m_vctTargetAt; m_bJerk = false; if(m_ftJerk > 0.0f) { for(int i=0; i<30; i++) { if( m_ftJerk-ftDelta < 0.03*i && m_ftJerk > 0.03*i ) { m_bJerk = true; } } m_ftJerk -= ftDelta; } }
bool DDynamicActor::Collision_LineCheck( int ) { DLogWriteSystem(" Collision_LineCheck : %p", this ); SVector Location = m_Locus.Location; SVector StartTest = Physics::g_vStartTest; SVector End = Physics::g_vEnd; if( m_dwColFlag & CF_COLLIDEDBY_ROOT_INTERNAL ) { Location = GMath.ZeroVector; SMatrix Matrix = (this->m_matRootMatrixForCollision * m_Locus.LocalToWorld).Inverse(); StartTest = Matrix.TransformVector( StartTest ); End = Matrix.TransformVector( End ); } // quick rejecct SVector vExtent = Physics::g_vExtent + this->m_vExtent; SVector MaxLocation = Location + vExtent; SVector MinLocation = Location - vExtent; if( StartTest.X > MaxLocation.X && End.X > MaxLocation.X ) return false; if( StartTest.X < MinLocation.X && End.X < MinLocation.X ) return false; if( StartTest.Y > MaxLocation.Y && End.Y > MaxLocation.Y ) return false; if( StartTest.Y < MinLocation.Y && End.Y < MinLocation.Y ) return false; if( StartTest.Z > MaxLocation.Z && End.Z > MaxLocation.Z ) return false; if( StartTest.Z < MinLocation.Z && End.Z < MinLocation.Z ) return false; // top of cylinder Physics::g_fT0 = 0.f; Physics::g_fT1 = Physics::g_SingleResult.m_fTime; SVector Normal = GMath.YAxis; // DEBUG!! if( StartTest.Y > MaxLocation.Y && End.Y < MaxLocation.Y ) { float T = ( MaxLocation.Y - StartTest.Y ) / ( End.Y - StartTest.Y ); if( T > Physics::g_fT0 ) { Physics::g_fT0 = ::Max( Physics::g_fT0 , T ); Normal = GMath.YAxis; } } else if( StartTest.Y < MaxLocation.Y && End.Y > MaxLocation.Y ) Physics::g_fT1 = ::Min( Physics::g_fT1, ( MaxLocation.Y - StartTest.Y ) / ( End.Y - StartTest.Y ) ); // bottom of cylinder if( StartTest.Y < MinLocation.Y && End.Y > MinLocation.Y ) { float T = ( MinLocation.Y - StartTest.Y ) / ( End.Y - StartTest.Y ); if( T > Physics::g_fT0 ) { Physics::g_fT0 = ::Max( Physics::g_fT0, T ); Normal = -GMath.YAxis; } } else if( StartTest.Y > MinLocation.Y && End.Y < MinLocation.Y ) Physics::g_fT1 = ::Min( Physics::g_fT1, ( MinLocation.Y - StartTest.Y ) / ( End.Y - StartTest.Y ) ); if( Physics::g_fT0 >= Physics::g_fT1 ) return false; // Test float A, B, C; { float DX = End.X - StartTest.X; float DZ = End.Z - StartTest.Z; float TX = StartTest.X - Location.X; float TZ = StartTest.Z - Location.Z; A = DX*DX + DZ*DZ; B = 2.f * (TX*DX + TZ*DZ); C = TX*TX + TZ*TZ - vExtent.X*vExtent.X; } if( C < DYNAMIC_DIST_ERROR && StartTest.Y > MinLocation.Y && StartTest.Y < MaxLocation.Y ) { A = StartTest.X - Location.X; B = StartTest.Z - Location.Z; if( A * (End.X-StartTest.X) + B * (End.Z-StartTest.Z) < -0.1f ) { SColResult *Result = ( Physics::g_bMultiCheck ? new(Physics::g_aMultiResult) SColResult : &Physics::g_SingleResult ); Result->m_nActorIndex = m_dwID; Result->m_nMeshIndex = -1; Result->m_fTime = 0.f; Result->m_vNormal = SVector(A,0,B).SafeNormal(); Result->m_vLocation= Physics::g_vStart; Result->m_vContactPoint = Location + this->m_vExtent.X * Result->m_vNormal; return true; } else return false; } float D = B*B - 4.f*A*C; if( D < 0.f ) return false; if( A < DYNAMIC_DIST_ERROR*DYNAMIC_DIST_ERROR ) { if( C > 0.f ) return false; } else { A = 0.5f / A; D = appSqrt(D); Physics::g_fT1 = ::Min( Physics::g_fT1, (D-B) * A ); float T = -(D+B) * A; if( ::Max(T,Physics::g_fT0) >= Physics::g_fT1 ) return false; if( T > Physics::g_fT0 ) { Physics::g_fT0 = T; Normal.X = StartTest.X + (End.X-StartTest.X)*Physics::g_fT0 - Location.X; Normal.Y = 0; Normal.Z = StartTest.Z + (End.Z-StartTest.Z)*Physics::g_fT0 - Location.Z; Normal.Normalize(); } } SColResult *Result = ( Physics::g_bMultiCheck ? new(Physics::g_aMultiResult) SColResult : &Physics::g_SingleResult ); Result->m_nActorIndex = m_dwID; Result->m_nMeshIndex = -1; Result->m_fTime = Physics::g_fT0; Result->m_vLocation = CalcInterpolatedValue( Result->m_fTime, Physics::g_vStart, Physics::g_vEnd ); Result->m_vNormal = Normal; Result->m_vContactPoint = Location + this->m_vExtent.X * Normal; Result->m_ActorType = this->m_ActorType; return true; }