private AlignedBox3Tree CalculateAlignedBox3Tree( NodeContent input, ContentProcessorContext context, bool ignoreCollisionNodes ) { // collect positions and indices List <Vector3> positionList = new List <Vector3>(); List <UInt16> indexList = new List <UInt16>(); CalculateAlignedBox3Tree(input, context, ignoreCollisionNodes, positionList, indexList); if (indexList.Count % 3 != 0) { throw new Exception("invalid number of indices!"); } Vector3[] positions = new Vector3[positionList.Count]; for (int i = 0; i < positionList.Count; ++i) { positions[i] = positionList[i]; } UInt16[] indices = new UInt16[indexList.Count]; for (int i = 0; i < indexList.Count; ++i) { indices[i] = indexList[i]; } AlignedBox3Tree tree = new AlignedBox3Tree(positions, indices); #if DEBUG context.Logger.LogImportantMessage(" average number of triangles per leaf in collision mesh is {0}", tree.Root.AverageNumTrianglesPerLeaf); #endif return(tree); }
public static void Test( Entity entity1, object[] boundingVolumes1, ref Matrix worldTransform1, ref Vector3 translation1, ref Quaternion rotation1, ref Vector3 scale1, Entity entity2, object[] boundingVolumes2, ref Matrix worldTransform2, ref Vector3 translation2, ref Quaternion rotation2, ref Vector3 scale2, bool needAllContacts, ref Contact contact ) { for (int i = 0; i < boundingVolumes1.Length; ++i) { AlignedBox3Tree tree1 = (AlignedBox3Tree)boundingVolumes1[i]; for (int j = 0; j < boundingVolumes2.Length; ++j) { AlignedBox3Tree tree2 = (AlignedBox3Tree)boundingVolumes2[j]; // early exit if they do not intersect... Box3 box1, box2; tree1.BoundingBox.CreateBox3(ref worldTransform1, out box1); tree2.BoundingBox.CreateBox3(ref worldTransform2, out box2); if (!Intersection.IntersectBox3Box3(ref box1, ref box2)) { continue; } Context context = new Context(); context.entity1 = entity1; context.positions1 = tree1.Positions; context.worldTransform1 = worldTransform1; context.entity2 = entity2; context.positions2 = tree2.Positions; context.worldTransform2 = worldTransform2; context.needAllContacts = needAllContacts; context.contact = contact; if (tree1.Root.HasChildren) { if (tree2.Root.HasChildren) { CollideInnerInner(ref context, tree1.Root, tree2.Root); } else { CollideInnerLeaf(ref context, tree1.Root, tree2.Root); } } else { if (tree2.Root.HasChildren) { CollideLeafInner(ref context, tree1.Root, tree2.Root); } else { CollideLeafLeaf(ref context, tree1.Root, tree2.Root); } } } } }
/// <summary> /// this method is a bit hacky since I did not know where to place it. I may move it to a better /// place somewhen in the future /// </summary> /// <param name="ray"></param> /// <param name="entity"></param> public bool GetIntersectionPoint( ref Ray3 ray, Entity entity, out Vector3 outIsectPt ) { // find the matching collision entity (in order to get the alignedbox3tree CollisionEntity collisionEntity = testList.GetCollisionEntity(entity); if (collisionEntity == null) { outIsectPt = Vector3.Zero; return(false); } Debug.Assert(collisionEntity.VolumeType == VolumeType.AlignedBox3Tree); if (collisionEntity.VolumeType != VolumeType.AlignedBox3Tree) { outIsectPt = Vector3.Zero; return(false); } // get world transform of from the given entity Matrix worldTransform; AlignedBox3Tree tree = (AlignedBox3Tree)collisionEntity.Volumes[0]; OrientationHelper.CalculateWorldTransform(entity, out worldTransform); // transform the ray into the coordinate system of the entity Matrix worldToEntityTransform = Matrix.Invert(worldTransform); Matrix inverseTransposeWorldToEntityTransform = Matrix.Transpose(Matrix.Invert(worldToEntityTransform)); Vector3 entitySpaceRayOrigin = Vector3.Transform(ray.Origin, worldToEntityTransform); Vector3 entitySpaceRayDirection = Vector3.Transform(ray.Direction, inverseTransposeWorldToEntityTransform); entitySpaceRayDirection.Normalize(); Ray3 entitySpaceRay = new Ray3(entitySpaceRayOrigin, entitySpaceRayDirection); float t; // parameter on ray, outIsectPt = ray.Origin + t * ray.Direction; bool intersection = GetIntersectionPoint(ref entitySpaceRay, tree.Root, tree.Positions, out t); if (intersection) { outIsectPt = Vector3.Transform(entitySpaceRay.Origin + t * entitySpaceRay.Direction, worldTransform); } else { outIsectPt = Vector3.Zero; } return(intersection); }
public static void Test( Entity entity1, object[] boundingVolumes1, ref Matrix worldTransform1, ref Vector3 translation1, ref Quaternion rotation1, ref Vector3 scale1, Entity entity2, object[] boundingVolumes2, ref Matrix worldTransform2, ref Vector3 translation2, ref Quaternion rotation2, ref Vector3 scale2, bool needAllContacts, ref Contact contact ) { for (int i = 0; i < boundingVolumes1.Length; ++i) { AlignedBox3Tree tree1 = (AlignedBox3Tree)boundingVolumes1[i]; for (int j = 0; j < boundingVolumes2.Length; ++j) { Sphere3 sphere2 = (Sphere3)boundingVolumes2[j]; Debug.Assert(scale2.X == scale2.Y && scale2.Y == scale2.Z); Sphere3 transformedSphere2 = new Sphere3(Vector3.Transform(sphere2.Center, worldTransform2), sphere2.Radius * scale2.X); Test(entity1, tree1.Root, tree1.Positions, ref worldTransform1, ref translation1, ref rotation1, ref scale1, entity2, ref transformedSphere2, ref worldTransform2, ref translation2, ref rotation2, ref scale2, needAllContacts, ref contact); } } }