static uint BoxAndHalfSpace(H1Box InBox, H1Plane InPlane, ref H1CollisionDetectResult OutResult) { if (!H1PrimitiveIntersection.Intersect(InBox, InPlane)) { return(0); } foreach (H1Vector3 BoxVertex in BoxVertices) { // calculate transformed box vertex H1Vector3 TransformedBoxVertex = H1Vector3.Transform(BoxVertex * InBox.HalfSize, InBox.Transform); // calculate the distance from the plane float VertexDistance = H1Vector3.Dot(TransformedBoxVertex, InPlane.Normal); // compare this to the plane's distance if (VertexDistance <= InPlane.Distance) { // create the contact data H1CollisionContact Contact = new H1CollisionContact(); Contact.ContactPoint = InPlane.Normal; Contact.ContactPoint *= (VertexDistance - InPlane.Distance); Contact.ContactPoint += TransformedBoxVertex; Contact.ContactNormal = InPlane.Normal; Contact.Penetration = InPlane.Distance - VertexDistance; OutResult.Contacts.Add(Contact); } } return(Convert.ToUInt32(OutResult.Contacts.Count)); }
public static H1Vector3 Transform(H1Vector3 vector, H1Matrix transform) { Vector3 Result; Vector3.Transform(ref vector.Data, ref transform.Data, out Result); return(new H1Vector3(Result)); }
public static float TransformToAxis(H1Box InBox, H1Vector3 InAxis) { // think of quater-box (halfsize) end point projecting to InAxis // which gives maximum distance(by math.abs) toward axis from box return(InBox.HalfSize.X * Math.Abs(H1Vector3.Dot(InAxis, InBox.Transform.Axis0)) + InBox.HalfSize.Y * Math.Abs(H1Vector3.Dot(InAxis, InBox.Transform.Axis1)) + InBox.HalfSize.Z * Math.Abs(H1Vector3.Dot(InAxis, InBox.Transform.Axis2))); }
public static bool Intersect(H1Ray InRay, H1Bound InBound, out float OutT0, out float OutT1) { float T0 = 0.0f; float T1 = float.MaxValue; H1Vector3 RayOrigin = InRay.Origin; for (Int32 SlabIndex = 0; SlabIndex < InBound.SafeSlabs.Count(); ++SlabIndex) { // curr slab H1Slab Slab = InBound.SafeSlabs[SlabIndex]; // slab normal H1Vector3 SlabNormal = Slab.Normal; float NominatorPlane0 = Slab[0].Distance - H1Vector3.Dot(Slab[0].Normal, InRay.Origin); float NominatorPlane1 = Slab[1].Distance - H1Vector3.Dot(Slab[1].Normal, InRay.Origin); float Denominator = H1Vector3.Dot(InRay.Direction, SlabNormal); float CurrT0 = NominatorPlane0 / Denominator; float CurrT1 = NominatorPlane1 / Denominator; // check if we need to swap if (CurrT0 > CurrT1) { float Temp = CurrT0; CurrT0 = CurrT1; CurrT1 = Temp; } // if we need to update T0 or T1, update it if (T0 < CurrT0) { T0 = CurrT0; } if (T1 > CurrT1) { T1 = CurrT1; } if (T0 > T1) { OutT0 = float.MaxValue; OutT1 = float.MinValue; return(false); } } OutT0 = T0; OutT1 = T1; return(true); }
public static bool Intersect(H1Box InBox, H1Plane InPlane) { // work out the projected radius of the box onto the plane direction float ProjectedRadius = TransformToAxis(InBox, InPlane.Normal); // work out how far the box is from the origin H1Vector3 BoxPosition = InBox.Transform.Axis3; float BoxDistance = H1Vector3.Dot(InPlane.Normal, BoxPosition) - ProjectedRadius; // check for the intersection return(BoxDistance <= InPlane.Distance); }
protected void CreateSlabs(EBoundType InBoundType, H1Vector3 InLocation, H1Vector3 InExtent) { // depending on bound type, define the number of slabs Int32 SlabNum = 0; // setting transform properties Position = InLocation; Extent = InExtent; switch (InBoundType) { case EBoundType.Box: { // total 3 slabs needed (x, y, z) SlabNum = 3; Slabs = new H1Slab[SlabNum]; // x-axis H1Vector3 DirectionX = new H1Vector3(1, 0, 0); float ExtentX = InExtent.X; Slabs[0] = new H1Slab(DirectionX, Position, ExtentX); // y-axis H1Vector3 DirectionY = new H1Vector3(0, 1, 0); float ExtentY = InExtent.Y; Slabs[1] = new H1Slab(DirectionY, Position, ExtentY); // z-axis H1Vector3 DirectionZ = new H1Vector3(0, 0, 1); float ExtentZ = InExtent.Z; Slabs[2] = new H1Slab(DirectionZ, Position, ExtentZ); break; } default: break; } }
protected void CreatePlanes(H1Vector3 InNormal, H1Vector3 InPosition, float InExtent) { H1Vector3 Origin = new H1Vector3(0, 0, 0); // generate first plane H1Vector3 PointOnPlane0 = InPosition + InNormal * InExtent; // calculate distance from origin float DistanceOnPlane0 = H1Vector3.Dot(PointOnPlane0 - Origin, InNormal); Planes[0] = new H1Plane(InNormal, DistanceOnPlane0); // generate second plane H1Vector3 PointOnPlane1 = InPosition - InNormal * InExtent; float DistanceOnPlane1 = H1Vector3.Dot(PointOnPlane1 - Origin, InNormal); Planes[1] = new H1Plane(InNormal, DistanceOnPlane1); }
public static H1Vector3 Cross(H1Vector3 left, H1Vector3 right) { return(new H1Vector3(Vector3.Cross(left.Data, right.Data))); }
public static float Dot(H1Vector3 left, H1Vector3 right) { return(Vector3.Dot(left.Data, right.Data)); }
public static H1Vector3 Normalize(H1Vector3 value) { return(new H1Vector3(Vector3.Normalize(value.Data))); }
public H1Plane(H1Vector3 InNormal, float InDistance) { Data = new Plane(InNormal.Data, InDistance); }
public H1Bound(EBoundType InType, H1Vector3 InPosition, H1Vector3 InExtent) { CreateSlabs(InType, InPosition, InExtent); }
public H1Slab(H1Vector3 InNormal, H1Vector3 InPosition, float InExtent) { CreatePlanes(InNormal, InPosition, InExtent); }
public H1Ray(H1Vector3 InOrigin, H1Vector3 InDirection) { Origin = InOrigin; Direction = InDirection; }
public H1Ray() { Origin = new H1Vector3(0, 0, 0); Direction = new H1Vector3(0, 0, 0); }