Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
                        }
                    }
                }
            }
        }
Esempio n. 3
0
        /// <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);
        }
Esempio n. 4
0
        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);
                }
            }
        }