/// ------------------------------------------------ // /// [4/18/2014 jianglei.kinly] /// 扇形 /// ------------------------------------------------ // xObjectSet XGameMap::CaptureObjectBySector( const XVector3& vCenter, const XVector3& vDir, xgc_uint32 dwRadius, xgc_uint16 wAngle, const std::function< xgc_bool( xObject ) > &fnFilter/* = xgc_nullptr*/ ) { // 计算旋转向量 XVector3 vRotate = vDir.RotateZ( DEG2RAD( wAngle / 2 ) ); xgc_real32 fDotValue = vDir.DotProduct( vRotate ); auto fn = [&]( xObject hObject )->xgc_bool { if( xgc_nullptr == fnFilter || fnFilter( hObject ) ) { XGameObject* pObj = ObjectCast<XGameObject>( hObject ); XGC_ASSERT_RETURN( pObj, false ); XVector3 vDistance = pObj->GetPosition() - vCenter; if( vDistance.SqurLength() > dwRadius * dwRadius * 1.0f ) return false; if( vDir.DotProduct( vDistance ) < fDotValue ) return false; return true; } return false; }; iRect rc( WorldToArea( vCenter.x - dwRadius, vCenter.y - dwRadius ), WorldToArea( vCenter.x + dwRadius, vCenter.y + dwRadius ) ); return FetchObject( rc, fn ); }
//---------------------------------------------------// // [8/4/2009 Albert] // Description: 清除路径点 //---------------------------------------------------// void CDynamicObject::BeginPathPoint() { if( m_hUpdateTimer != INVALID_TIMER_HANDLE ) { unsigned int release_time = ThisTimer()->remove_event( m_hUpdateTimer ); m_hUpdateTimer = INVALID_TIMER_HANDLE; if( release_time > 0 ) { // 计算向量 XVector3 Vec = m_vNextPosition - GetPosition(); Vec.NormalizeFast(); // 剩余了多少距离 Vec *= release_time/1000.0f; // 下此更新坐标和剩余距离的差值则为当前的位置 m_vNextPosition -= Vec; CGameMap* pScene = static_cast< CGameMap* >( CXObjectPool::GetInstance().GetObj( GetParent(), TypeGameMap ) ); if( pScene ) { if( pScene->DynamicMoveTo( this, m_vNextPosition, false ) ) { OnStep( m_vNextPosition ); } } } } m_PointList.clear(); }
//---------------------------------------------------// // [8/5/2009 Albert] // Description: 移动定时器 //---------------------------------------------------// bool CDynamicObject::UpdateTimer( unsigned int handle, unsigned short& repeat, unsigned int& timer ) { repeat = 1; timer = TIMER_SECONDS(1.0f); // 先移动到当前所在的位置. CGameMap* pScene = static_cast< CGameMap* >( CXObjectPool::GetInstance().GetObj( GetParent(), TypeGameMap ) ); if( pScene ) { if( pScene->DynamicMoveTo( this, m_vNextPosition, false ) ) { //CLogger::GetInstance(_T("Log"))->WriteLog( _T("角色[%08x]移动到路点[%f,%f,%f]") // , GetObjID() // , m_vNextPosition[0], m_vNextPosition[1], m_vNextPosition[2] ); OnStep( m_vNextPosition ); } else { OnArrived( m_vNextPosition ); return true; } } else { m_hUpdateTimer = INVALID_TIMER_HANDLE; return true; } // 计算下一个点 if( m_PointList.empty() ) { m_hUpdateTimer = INVALID_TIMER_HANDLE; OnArrived( m_vNextPosition ); return true; } const PathPoint& target = m_PointList.front(); XVector3 Vec = target.vPosition - m_vNextPosition; float distance = Vec.SqurLength(); float fSpeed = target.fSpeed; if( distance < fSpeed*fSpeed ) { // 当前坐标到目标点的距离小于速度值 m_vNextPosition = target.vPosition; float t = XMath::Sqrt( distance )/fSpeed; timer = TIMER_SECONDS(t); m_PointList.pop_front(); } else { Vec.NormalizeFast(); Vec *= fSpeed; m_vNextPosition += Vec; } return false; }
/// ------------------------------------------------ // /// [4/25/2014 jianglei.kinly] /// 方向矩形(subCenter) /// ------------------------------------------------ // xObjectSet XGameMap::CaptureObjectByRectangle( const XVector3& vCenter, const XVector3& vDir, xgc_uint32 dwRadiusMax, xgc_uint32 dwRadiusMin, const std::function< xgc_bool( xObject ) > &fnFilter/* = xgc_nullptr*/ ) { /* 0,0 -------------------------------x | | ------ | / / | / / | ---|-- | subCenter | 斜线是dir的方向,dwRadiusMax | 横线是dwRadiusMin y */ // 取中心点坐标 XVector3 newDirect = vDir * ( dwRadiusMax * 1.0f ); XVector3 newCenter = vCenter + newDirect; // 取对角线直径 xgc_uint32 dwDiameter = xgc_uint32( XMath::Sqrt( XMath::Pow( 1.0f * dwRadiusMax, 2.0f ) + XMath::Pow( 1.0f * dwRadiusMin, 2.0f ) ) ); auto fn = [&]( xObject hObject )->xgc_bool { if( xgc_nullptr == fnFilter || fnFilter( hObject ) ) { XGameObject* pObj = ObjectCast<XGameObject>( hObject ); XGC_ASSERT_RETURN( pObj, false ); // 取我和目标连线的向量 XVector3 subVec = pObj->GetPosition() - vCenter; // 判断夹角(我的朝向点乘我和目标连线的向量 > 0 代表夹角在0-90范围内) auto fTemp = vDir.DotProduct( subVec ); if( fTemp < 0 ) return false; // 找两个投影,判断是否在方向矩形内 XVector3 vecy = vDir * fTemp; XVector3 vecx = subVec - vecy; return !( vecy.Length() > dwRadiusMax || vecx.Length() > dwRadiusMin / 2 ); } return false; }; iRect rc( WorldToArea( vCenter.x - dwDiameter / 2, vCenter.y - dwDiameter / 2 ), WorldToArea( vCenter.x + dwDiameter / 2, vCenter.y + dwDiameter / 2 ) ); return FetchObject( rc, fn ); }
XQuaternion::XQuaternion( const XVector3& Axis, f32 Angle ) { ASSERTMSG( Axis.Magnitude() == 1.0f, "This function requires the vector to be normalized upon entry." ); ASSERT( ((const __m128)Axis).m128_f32[ 3 ] == 0.0f ); const __m128 xSin = Axis * Angle::Sin( Angle ); const __m128 xCos = _mm_set_ss( Angle::Cos( Angle ) ); m_Vector = _mm_or_ps( xSin, xCos ); }