/// <summary> /// 点到OBB最近点 /// </summary> public static Vector2d ClosestPointOBB(Vector2d p, FPObb b) { Vector2d d = p - b.center; Vector2d q = b.center; FixedPoint distX = Vector2d.Dot(d, b.u[0]); if (distX > b.e.x) { distX = b.e.x; } if (distX < -b.e.x) { distX = -b.e.x; } q += b.u[0] * distX; FixedPoint distY = Vector2d.Dot(d, b.u[1]); if (distY > b.e.y) { distY = b.e.y; } if (distY < -b.e.y) { distY = -b.e.y; } q += b.u[1] * distY; return(q); }
private void InitObstacle(Vector2d pos) { if (!m_triggerData.Obstacle) { return; } if (m_triggerData.ShapeType == (int)eBuffTriggerShapeType.Circle) { Circle cir = new Circle(); cir.c = pos; cir.r = new FixedPoint(m_triggerData.Length); cir.bAirWall = false; m_collider = cir; PhysicsManager.Inst.Add(m_collider); } else if (m_triggerData.ShapeType == (int)eBuffTriggerShapeType.Rect) { int angle = (int)FPCollide.GetAngle(GetDir()).value; FPObb obb = new FPObb(pos, new Vector2d(m_triggerData.Width, m_triggerData.Length), angle); Polygon pol = new Polygon(); pol.c = pos; pol.isObstacle = true; pol.bAirWall = true; pol.Init(obb.GetVert2d()); m_collider = pol; PhysicsManager.Inst.Add(m_collider); } }
/// <summary> /// 圆与OBB相交 /// </summary> public static bool bSphereOBB(FPSphere s, FPObb b) { // p为交点 Vector2d p = ClosestPointOBB(s.c, b); Vector2d v = p - s.c; return(Vector2d.Dot(v, v) <= s.r * s.r); }
// 矩形检测,获取最近的单位,进行激光链接 public override void Trigger() { FixedPoint minDis = new FixedPoint(999999); CCreature minCC = null; List <long> list = CCreatureMgr.GetCreatureList(); for (int i = 0; i < list.Count; i++) { CCreature creature = CCreatureMgr.Get(list[i]); if (m_caster.bCamp(creature) || creature.IsDie()) { continue; } FPSphere playerS = new FPSphere(); playerS.c = creature.GetPos(); playerS.r = creature.GetR(); Vector2d pos = m_caster.GetPos() + GetDir().normalized *new FixedPoint((m_triggerData.Length + m_triggerData.vBulletDeltaPos.z) * 0.5f); int angle = (int)FPCollide.GetAngle(GetDir()).value; FPObb obb = new FPObb(pos, new Vector2d(m_triggerData.Width, m_triggerData.Length), angle); if (FPCollide.bSphereOBB(playerS, obb)) { FixedPoint dis = Vector2d.Distance(creature.GetPos(), GetPos()); if (dis < minDis) { minDis = dis; minCC = creature; } } } if (minCC != null) { OnHitAddBuff(m_caster, minCC); Vector2d targetPos = GetPos() + GetDir().normalized *minDis; if (m_vCreature != null) { Vector3 tH = minCC.GetVObject().GetHitHeight(); GetVTrigger().SetLineTargetPos(targetPos.ToVector3() + tH); } } else { _CheckObstacle(); } }
/// <summary> /// 通过BUFF区域检测触发 /// </summary> public virtual void Trigger() { if (m_triggerData.ShapeType == (int)eBuffTriggerShapeType.Circle) { FPSphere tSphere = new FPSphere(); tSphere.c = GetPos(); tSphere.r = new FixedPoint(m_triggerData.Length); List <long> list = CCreatureMgr.GetCreatureList(); for (int i = 0; i < list.Count; i++) { CCreature creature = CCreatureMgr.Get(list[i]); if (m_caster.bCamp(creature) || creature.IsDie()) { continue; } FPSphere playerS = new FPSphere(); playerS.c = creature.GetPos(); playerS.r = creature.GetR(); if (FPCollide.bSphereSphere(tSphere, playerS)) { OnHitAddBuff(m_caster, creature); } } } else if (m_triggerData.ShapeType == (int)eBuffTriggerShapeType.Sector) { List <long> list = CCreatureMgr.GetCreatureList(); for (int i = 0; i < list.Count; i++) { CCreature creature = CCreatureMgr.Get(list[i]); if (m_caster.bCamp(creature) || creature.IsDie()) { continue; } FPSphere playerS = new FPSphere(); playerS.c = creature.GetPos(); playerS.r = creature.GetR(); FPSector sec = new FPSector(); sec.pos = GetPos(); sec.dir = GetDir(); sec.angle = new FixedPoint(m_triggerData.Width); sec.r = new FixedPoint(m_triggerData.Length); if (FPCollide.bSectorInside(sec, creature.GetPos())) { OnHitAddBuff(m_caster, creature); } } } else if (m_triggerData.ShapeType == (int)eBuffTriggerShapeType.Rect) { List <long> list = CCreatureMgr.GetCreatureList(); for (int i = 0; i < list.Count; i++) { CCreature creature = CCreatureMgr.Get(list[i]); if (m_caster.bCamp(creature) || creature.IsDie()) { continue; } FPSphere playerS = new FPSphere(); playerS.c = creature.GetPos(); playerS.r = creature.GetR(); Vector2d pos = GetPos(); int angle = (int)FPCollide.GetAngle(GetDir()).value; FPObb obb = new FPObb(pos, new Vector2d(m_triggerData.Width, m_triggerData.Length), angle); if (FPCollide.bSphereOBB(playerS, obb)) { OnHitAddBuff(m_caster, creature); } } } if (m_triggerData.PosType == (int)eBuffTriggerPosType.CasterStartPos_SkillDir) { // 障碍碰撞 if (CMapMgr.m_map.IsblockNotAirWal((int)m_curPos.x.value, (int)m_curPos.y.value)) { Destory(); return; } if (PhysicsManager.Inst.IsblockNotAirWal((int)m_curPos.x, (int)m_curPos.y)) { Destory(); return; } // 子弹碰撞 FPSphere cur = new FPSphere(); cur.c = GetPos(); cur.r = GetR(); foreach (KeyValuePair <long, CBuffTrigger> item in CBuffTriggerMgr.m_dicSkill) { CBuffTrigger tri = item.Value; if (tri.m_triggerData.PosType == (int)eBuffTriggerPosType.CasterStartPos_SkillDir && tri != this && tri.m_caster != m_caster) { FPSphere triItem = new FPSphere(); triItem.c = tri.GetPos(); triItem.r = tri.GetR(); if (FPCollide.bSphereSphere(cur, triItem)) { Destory(); tri.Destory(); } } } } }