public bool CollideRingWithMouse(int MouseX, int MouseY, Viewport ActiveViewport, Matrix View, Matrix Projection, Matrix World) { Vector3 NearSource = new Vector3(MouseX, MouseY, 0f); Vector3 FarSource = new Vector3(MouseX, MouseY, 1f); Vector3 NearPoint = ActiveViewport.Unproject(NearSource, Projection, View, World); Vector3 FarPoint = ActiveViewport.Unproject(FarSource, Projection, View, World); // Create a ray from the near clip plane to the far clip plane. Vector3 RayDirection = FarPoint - NearPoint; RayDirection.Normalize(); Matrix RotationMatrix = Matrix.Identity; RotationMatrix.Forward = RayDirection; RotationMatrix.Right = Vector3.Normalize(Vector3.Cross(RotationMatrix.Forward, Vector3.Up)); RotationMatrix.Up = Vector3.Cross(RotationMatrix.Right, RotationMatrix.Forward); Vector3 Forward = Vector3.Transform(Vector3.Forward, RotationMatrix); Vector3 Right = Vector3.Transform(Vector3.Right, RotationMatrix); Vector3 Up = Vector3.Transform(Vector3.Up, RotationMatrix); PolygonMesh MouseCollisionBox = CreateMouseObject(MouseX, MouseY, ActiveViewport, View, Projection, World); var Axis1 = ComputePerpendicularAxis(0, 24); var Axis2 = ComputePerpendicularAxis(24, 24); var Axis3 = ComputePerpendicularAxis(48, 24); var Axis4 = ComputePerpendicularAxis(72, 24); var Vertex1 = new Vector3[24]; var Vertex2 = new Vector3[24]; var Vertex3 = new Vector3[24]; var Vertex4 = new Vector3[24]; for (int V = 0; V < 24; V++) { Vertex1[V] = ArrayVertex[V].Position; Vertex2[V] = ArrayVertex[V + 24].Position; Vertex3[V] = ArrayVertex[V + 48].Position; Vertex4[V] = ArrayVertex[V + 72].Position; } var col1 = CollideWithQuarterRing(MouseCollisionBox, Vertex1, Axis1); var col2 = CollideWithQuarterRing(MouseCollisionBox, Vertex2, Axis2); var col3 = CollideWithQuarterRing(MouseCollisionBox, Vertex3, Axis3); var col4 = CollideWithQuarterRing(MouseCollisionBox, Vertex4, Axis4); return(col1 || col2 || col3 || col4); }
public Object3D() { _CollisionBox = new PolygonMesh(); PositionMatrix = Matrix.Identity; RotationMatrix = Matrix.Identity; ScaleMatrix = Matrix.Identity; _Forward = Vector3.Forward; _Right = Vector3.Right; _Up = Vector3.Up; _Position = Vector3.Zero; TotalYaw = 0; TotalPitch = 0; TotalRoll = 0; TotalScale = Vector3.One; }
public PolygonMesh.PolygonMeshCollisionResult GetClosestObject(List <Object3D> ListOther, Vector3 Speed) { PolygonMesh.PolygonMeshCollisionResult FinalCollisionResult = new PolygonMesh.PolygonMeshCollisionResult(Vector3.Zero, -1); Object3D FinalLayerPolygon = null; foreach (Object3D ActiveObject3D in ListOther) { PolygonMesh.PolygonMeshCollisionResult CollisionResult = PolygonMesh.PolygonCollisionSAT(CollisionBox, ActiveObject3D.CollisionBox, Speed); if (FinalCollisionResult.Distance < 0 || (CollisionResult.Distance >= 0 && CollisionResult.Distance > FinalCollisionResult.Distance)) { FinalCollisionResult = CollisionResult; FinalLayerPolygon = ActiveObject3D; } } return(FinalCollisionResult); }
public static void ProjectPolygon(Vector3 Axis, PolygonMesh Polygon, out float Min, out float Max) { float DotProduct = Vector3.Dot(Axis, Polygon.ArrayVertex[0]); Min = DotProduct; Max = DotProduct; for (int i = 0; i < Polygon.ArrayVertex.Length; i++) { DotProduct = Vector3.Dot(Axis, Polygon.ArrayVertex[i]); if (DotProduct < Min) { Min = DotProduct; } else if (DotProduct > Max) { Max = DotProduct; } } }
public void MoveWithMouse(int MouseX, int MouseY, int OldMouseX, int OldMouseY, Viewport ActiveViewport, Matrix View, Matrix Projection, Matrix World) { Vector3 NearSource = new Vector3(MouseX, MouseY, 0f); Vector3 FarSource = new Vector3(MouseX, MouseY, 1f); Vector3 NearSourceOld = new Vector3(OldMouseX, OldMouseY, 0f); Vector3 NearPoint = ActiveViewport.Unproject(NearSource, Projection, View, World); Vector3 NearPointOld = ActiveViewport.Unproject(NearSourceOld, Projection, View, World); Vector3 FarPoint = ActiveViewport.Unproject(FarSource, Projection, View, World); // Create a ray from the near clip plane to the far clip plane. Vector3 RayDirection = FarPoint - NearPoint; RayDirection.Normalize(); Matrix RotationMatrix = Matrix.Identity; RotationMatrix.Forward = RayDirection; RotationMatrix.Right = Vector3.Normalize(Vector3.Cross(RotationMatrix.Forward, Vector3.Up)); RotationMatrix.Up = Vector3.Cross(RotationMatrix.Right, RotationMatrix.Forward); Vector3 Forward = Vector3.Transform(Vector3.Forward, RotationMatrix); Vector3 Right = Vector3.Transform(Vector3.Right, RotationMatrix); Vector3 Up = Vector3.Transform(Vector3.Up, RotationMatrix); float MinRight, MaxRight; float MinUp, MaxUp; PolygonMesh.ProjectPolygon(Right, CollisionBox, out MinRight, out MaxRight); PolygonMesh.ProjectPolygon(Up, CollisionBox, out MinUp, out MaxUp); float MouseRight = Vector3.Dot(Right, NearPoint); float MouseUp = Vector3.Dot(Up, NearPoint); float MouseRightOld = Vector3.Dot(Right, NearPointOld); float MouseUpOld = Vector3.Dot(Up, NearPointOld); Position += Right * (MouseRightOld - MouseRight); Position += Right * (MouseUpOld - MouseUp); }
public bool CollideWith(Object3D Other) { return(PolygonMesh.PolygonCollisionSAT(CollisionBox, Other.CollisionBox, Vector3.Zero).Collided); }
private bool CollideWithQuarterRing(PolygonMesh MouseCollision, Vector3[] CollisionVertex, Vector3[] ArrayAxis) { PolygonMesh QuarterRightCollisionBox = new PolygonMesh(CollisionVertex, ArrayAxis); return(PolygonMesh.PolygonCollisionSAT(MouseCollision, QuarterRightCollisionBox, Vector3.Zero).Collided); }
public static PolygonMeshCollisionResult PolygonCollisionSAT(PolygonMesh PolygonA, PolygonMesh PolygonB, Vector3 Speed) { bool Intersection = true; bool IntersectionNext = true; float minA = 0, maxA = 0; float minB = 0, maxB = 0; int AxisCountA = PolygonA.ArrayAxis.Length; int AxisCountB = PolygonB.ArrayAxis.Length; int EdgeCountA = PolygonA.ArrayEdge.Length; int EdgeCountB = PolygonB.ArrayEdge.Length; Vector3 Axis; Vector3 AxisTranslation = Vector3.Zero; float minIntervalDistance = float.MaxValue; float intervalDistance; Vector3[] CrossProduct = new Vector3[EdgeCountA * EdgeCountB]; for (int EdgeIndexA = EdgeCountA - 1; EdgeIndexA >= 0; --EdgeIndexA) { for (int EdgeIndexB = EdgeCountB - 1; EdgeIndexB >= 0; --EdgeIndexB) { CrossProduct[EdgeIndexA + EdgeIndexB * EdgeCountA] = Vector3.Cross(PolygonA.ArrayEdge[EdgeIndexA], PolygonB.ArrayEdge[EdgeIndexB]); } } for (int AxisIndex = 0; AxisIndex < AxisCountA + AxisCountB + CrossProduct.Length; AxisIndex++) { if (AxisIndex < AxisCountA) { Axis = PolygonA.ArrayAxis[AxisIndex]; } else if (AxisIndex < AxisCountA + AxisCountB) { Axis = PolygonB.ArrayAxis[AxisIndex - AxisCountA]; } else { Axis = CrossProduct[AxisIndex - AxisCountA - AxisCountB]; } ProjectPolygon(Axis, PolygonA, out minA, out maxA); ProjectPolygon(Axis, PolygonB, out minB, out maxB); if (IntervalDistance(minA, maxA, minB, maxB) >= 0) { Intersection = false; } float AxeVitesse = Vector3.Dot(Axis, Speed); if (AxeVitesse < 0) { minA += AxeVitesse; } else { maxA += AxeVitesse; } intervalDistance = IntervalDistance(minA, maxA, minB, maxB); if (intervalDistance >= 0) { IntersectionNext = false; } if (Intersection || IntersectionNext) { intervalDistance = Math.Abs(intervalDistance); if (intervalDistance < minIntervalDistance) { minIntervalDistance = intervalDistance; AxisTranslation = Axis; Vector3 p = PolygonA.Center - PolygonB.Center; if (Vector3.Dot(p, AxisTranslation) < 0) { AxisTranslation = -AxisTranslation; } } } } if (IntersectionNext) { PolygonMeshCollisionResult CollisionResult = new PolygonMeshCollisionResult(AxisTranslation, minIntervalDistance); return(CollisionResult); } return(new PolygonMeshCollisionResult(Vector3.Zero, -1)); }