Example #1
0
        public CameraManager(int width, int height)
        {
            //tmp position
            Position = Vector3.Zero;
            newPosition = Vector3.Zero;

            Acceleration = 0.5f;

            //tmp lookAtPoint
            LookAtPoint = Vector3.Zero;

            //set aspect ratio
            aspectRatio = (float)width / (float)height;

            //setup projection
            ProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(
                            MathHelper.ToRadians(40.0f),//40
                            this.aspectRatio,
                            1.0f,
                            10000.0f);

            SetViewMatrix();
            rotationLeftRight = 0.0f;
            rotationUpDown = 0.0f;

            box = new CollisionBox(new Vector3(-15, -100, -15), new Vector3(15, 30, 15));
        }
 public virtual bool BoxIntersect(CollisionBox ray_box, Vector3 ray_origin, Vector3 ray_direction, Vector3[] vert_pos,
     out float intersect_distance, out Vector3 intersect_position, out Vector3 intersect_normal)
 {
     intersect_distance = 0;
     intersect_position = Vector3.Zero;
     intersect_normal = Vector3.Zero;
     return false;
 }
 public CollisionFace(int offset, short[] vert_indx, int vert_offset, Vector3[] vert_pos)
 {
     vertices = new int[3];
     box = new CollisionBox(float.MaxValue, -float.MaxValue);
     for (int i = 0; i < 3; i++)
     {
         vertices[i] = (int)vert_indx[i + offset] + vert_offset;
         box.AddPoint(vert_pos[vertices[i]]);
     }
 }
 public CollisionCameraObserver(
     Vector3 position, 
     Vector3 lookPosition, 
     float angle, 
     float aspect, 
     float radius)
     : base(position, lookPosition, angle, aspect)
 {
     box = new CollisionBox(-radius, radius);
 }
Example #5
0
        public bool BoxIntersect(
            CollisionBox box, 
            Vector3 rayStart, 
            Vector3 rayEnd, 
            Vector3[] vertices,
            out float intersectDistance, 
            out Vector3 intersectPosition, 
            out Vector3 intersectNormal)
        {
            intersectDistance = 0.0f;
            intersectPosition = rayStart;
            intersectNormal = Vector3.Zero;

            Vector3 rayDirection = rayEnd - rayStart;
            float rayLength = rayDirection.Length();
            if (rayLength == 0)
                return false;

            CollisionBox rayBox = new CollisionBox(box.min + rayStart,
                                                box.max + rayStart);
            rayBox.AddPoint(rayBox.min + rayDirection);
            rayBox.AddPoint(rayBox.max + rayDirection);
            Vector3 inflate = new Vector3(0.001f, 0.001f, 0.001f);
            rayBox.min -= inflate;
            rayBox.max += inflate;

            List<CollisionTreeElem> elems = new List<CollisionTreeElem>();
            root.GetElements(rayBox, elems, ++recurseId);

            rayDirection *= 1.0f / rayLength;
            intersectDistance = rayLength;

            bool intersected = false;

            foreach (CollisionTreeElem e in elems)
            {
                float distance;
                Vector3 position;
                Vector3 normal;
                if (true == e.BoxIntersect(box, rayStart, rayDirection, vertices,
                                    out distance, out position, out normal))
                {
                    if (distance < intersectDistance)
                    {
                        intersectDistance = distance;
                        intersectPosition = position;
                        intersectNormal = normal;
                        intersected = true;
                    }
                }
            }

            return intersected;
        }
 public CollisionTreeNode(CollisionBox b,uint subdiv_level)
 {
     box = b;
     if (subdiv_level>0)
     {
         subdiv_level--;
         childs = new CollisionTreeNode[8];
         CollisionBox[] childs_box = box.GetChilds();
         for( uint i=0;i<8;i++ )
             childs[i] = new CollisionTreeNode(childs_box[i], subdiv_level);
     }
 }
Example #7
0
 /// <summary>
 /// Virtual function to intersect a box with the element
 /// </summary>
 public virtual bool BoxIntersect(
     CollisionBox rayBox, 
     Vector3 rayOrigin, 
     Vector3 rayDirection, 
     Vector3[] vertices,
     out float intersectDistance, 
     out Vector3 intersectPosition, 
     out Vector3 intersectNormal)
 {
     intersectDistance = 0;
     intersectPosition = Vector3.Zero;
     intersectNormal = Vector3.Zero;
     return false;
 }
Example #8
0
 public CollisionFace(
     int offset,
     short[] indexBuffer,
     int vertexOffset,
     Vector3[] vertexBuffer)
 {
     indices = new int[3];
     box = new CollisionBox(float.MaxValue, -float.MaxValue);
     for (int i = 0; i < 3; i++)
     {
         indices[i] = (int)indexBuffer[i + offset] + vertexOffset;
         box.AddPoint(vertexBuffer[indices[i]]);
     }
 }
        /// <summary>
        /// Recursive function to get all elements intersecting a given bounding box
        /// </summary>
        public void GetElements(
            CollisionBox b,
            List <CollisionTreeElem> e,
            uint recurseId)
        {
            // if selection box does not intersect node box, return
            if (b.BoxIntersect(box) == false)
            {
                return;
            }

            // if any elements in this node add them to selection list
            if (elems != null)
            {
                foreach (CollisionTreeElem elem in elems)
                {
                    // elements can be repeated in many nodes
                    // only add element to selection list if not already
                    // added by another node in this same recursion
                    if (elem.lastRecurseId < recurseId)
                    {
                        // if selection box intersect the element box
                        if (elem.box.BoxIntersect(b))
                        {
                            // add element to selection list
                            e.Add(elem);
                        }
                        // set this recuse id to prevent duplicate results
                        elem.lastRecurseId = recurseId;
                    }
                }
            }

            // if not a leaf node, recurso to all children
            if (children != null)
            {
                foreach (CollisionTreeNode n in children)
                {
                    n.GetElements(b, e, recurseId);
                }
            }
        }
Example #10
0
        // split in middle point creating 8 children
        public CollisionBox[] GetChildren()
        {
            Vector3 center = 0.5f * (min + max);

            CollisionBox[] children = new CollisionBox[8];

            children[0] = new CollisionBox(min, center);
            children[1] = new CollisionBox(new Vector3(center.X, min.Y, min.Z),
                                           new Vector3(max.X, center.Y, center.Z));
            children[2] = new CollisionBox(new Vector3(min.X, center.Y, min.Z),
                                           new Vector3(center.X, max.Y, center.Z));
            children[3] = new CollisionBox(new Vector3(center.X, center.Y, min.Z),
                                           new Vector3(max.X, max.Y, center.Z));
            children[4] = new CollisionBox(new Vector3(min.X, min.Y, center.Z),
                                           new Vector3(center.X, center.Y, max.Z));
            children[5] = new CollisionBox(new Vector3(center.X, min.Y, center.Z),
                                           new Vector3(max.X, center.Y, max.Z));
            children[6] = new CollisionBox(new Vector3(min.X, center.Y, center.Z),
                                           new Vector3(center.X, max.Y, max.Z));
            children[7] = new CollisionBox(center, max);

            return(children);
        }
Example #11
0
        /// <summary>
        /// Create a new tree node
        /// </summary>
        public CollisionTreeNode(CollisionBox collisionBox, uint subdivLevel)
        {
            if (collisionBox == null)
            {
                throw new ArgumentNullException("collisionBox");
            }

            // save node box
            box = collisionBox;

            // if subdivision needed
            if (subdivLevel > 0)
            {
                // decrease subdivision level
                subdivLevel--;

                // create the 8 children
                children = new CollisionTreeNode[8];
                CollisionBox[] childrenBox = box.GetChildren();
                for (uint i = 0; i < 8; i++)
                    children[i] = new CollisionTreeNode(childrenBox[i], subdivLevel);
            }
        }
        public Vector3 velocity; // current velocity vector used only by gravity

        #endregion Fields

        #region Constructors

        public CollisionCameraPerson(Vector3 position, Vector3 look_position, float angle, float aspect,
            float width, float height, float step_height, float head_height,
            float up_down_rot, float gravity, float jump_height)
            : base(position, look_position, angle, aspect)
        {
            width *= 0.5f;
            height *= 0.5f;

            this.step_height = step_height;
            this.head_height = head_height - height;
            this.up_down_rot = up_down_rot;
            this.gravity = gravity;
            this.jump_height = jump_height;

            transform = world;

            on_ground = false;
            velocity = Vector3.Zero;

            box = new CollisionBox(
                        new Vector3(-width, -height + step_height, -width),
                        new Vector3(width, height, width));
        }
        public void GetElements(CollisionBox b, List<CollisionTreeElem> e, uint recurse_id)
        {
            if (b.BoxIntersect(box) == false)
                return;

            if (elems != null)
            {
                foreach (CollisionTreeElem elem in elems)
                {
                    if (elem.last_recurse_id < recurse_id)
                    {
                        if (elem.box.BoxIntersect(b))
                            e.Add(elem);
                        elem.last_recurse_id = recurse_id;
                    }
                }
            }

            if (childs != null)
            {
                foreach (CollisionTreeNode n in childs)
                    n.GetElements(b, e, recurse_id);
            }
        }
Example #14
0
        public bool BoxMove(
            CollisionBox box, 
            Vector3 pointStart, 
            Vector3 pointEnd, 
            Vector3[] vertices,
            float frictionFactor, 
            float bumpFactor, 
            uint recurseLevel,
            out Vector3 pointResult)
        {
            pointResult = pointStart;

            Vector3 delta = pointEnd - pointStart;
            float deltaLength = delta.Length();
            if (deltaLength < 0.00001f)
                return false;

            float totalDistance = deltaLength;
            delta *= 1.0f / deltaLength;

            float bias = 0.01f;

            pointEnd += delta * bias;

            bool collisionHit = false;

            while (recurseLevel > 0)
            {
                float dist;
                Vector3 pos, norm;
                if (false == BoxIntersect(box, pointStart, pointEnd, vertices,
                                    out dist, out pos, out norm))
                {

                    pointStart = pointEnd - delta * bias;
                    break;
                }

                collisionHit = true;

                dist -= bias / Math.Abs(Vector3.Dot(delta, norm));
                if (dist > 0)
                {
                    pointStart += delta * dist;
                    totalDistance -= dist;
                }

                Vector3 reflectDirection =
                    Vector3.Normalize(Vector3.Reflect(delta, norm));

                Vector3 n = norm * Vector3.Dot(reflectDirection, norm);
                Vector3 t = reflectDirection - n;

                reflectDirection = frictionFactor * t + bumpFactor * n;

                pointEnd = pointStart + reflectDirection * totalDistance;

                delta = pointEnd - pointStart;
                deltaLength = delta.Length();
                if (deltaLength < 0.00001f)
                    break;
                delta *= 1.0f / deltaLength;

                pointEnd += delta * bias;

                recurseLevel--;
            }

            pointResult = pointStart;
            return collisionHit;
        }
Example #15
0
        /// <summary>
        /// Check collisions for dynamic objects
        /// </summary>
        public virtual void CheckCollisions(GameTime gameTime)
        {
            GameEntityList deadObjects = new GameEntityList();

            CollisionBox cameraBox = new CollisionBox(this.camera.box);

            cameraBox.min += this.camera.world.Translation;
            cameraBox.max += this.camera.world.Translation;
            cameraBox.min.Y -= this.camera.head_height + this.camera.step_height;
            cameraBox.max.Y += this.camera.head_height + this.camera.step_height;

            ///Dynamic objects with player
            foreach (GameEntity ge in this.sceneObjects.Values)
            {
                if (cameraBox.BoxIntersect(ge.Box))
                {
                    if (ge is ICatchable)
                    {
                        ((ICatchable)ge).Attach(this.player);

                        deadObjects.Add(ge.ModelMesh.Name, ge);
                        ge.ModelMesh.Tag = null;
                    }
                    else if (ge is IAttachable)
                    {
                        if (ge is GameObjectEntity)
                            this.player.Add((GameObjectEntity)ge);
                    }
                }

                ge.Update(gameTime, this.collisionMesh);
            }

            foreach (GameEntity ge in deadObjects.Values)
            {
                this.sceneObjects.Remove(ge.ModelMesh.Name);
            }

            deadObjects.Clear();

            ///Enemies with player
            foreach (Enemy e in this.enemies.Values)
            {
                if (e.ActualAnimationState != GameEntityAnimationState.Die)
                {
                    if (cameraBox.BoxIntersect(e.Box))
                    {
                        this.SendMessage(player, e, GameEntityMessageType.Hit, gameTime);
                    }
                }
                e.Update(gameTime, this.collisionMesh);
            }

            ///Bullets with enemies, static objects...

            foreach (Bullet b in this.bullets)
            {
                Vector3 position = b.Position;
                Vector3 speed = b.Speed;

                Vector3 new_pos = position + speed * (float)gameTime.ElapsedGameTime.TotalSeconds;
                this.collisionMesh.PointMove(position, new_pos, 1.0f, 1.0f, 3, out position);

                //these are discartable, just to pass to the PointIntersect method as out parameters
                float intersect_distance;
                Vector3 intersect_position = new Vector3();
                Vector3 intersection_normal = new Vector3();

                //collision of bullets with static scenario (walls, etc.)
                if (this.collisionMesh.PointIntersect(position, new_pos, out intersect_distance, out intersect_position, out intersection_normal))
                {
                    b.Dead = true;
                }

                //collision of bullets with enemies
                foreach (Enemy e in this.enemies.Values)
                {
                    if (e.Box.PointInside(b.Position))
                    {
                        b.Dead = true;
                        SendMessage(b, e, GameEntityMessageType.Damage, gameTime);
                        if (e.Health >= 10)
                            SendMessage(b, e, GameEntityMessageType.Hit, gameTime);
                    }
                }

                b.Position = position;
                b.Speed = speed;
            }
        }
Example #16
0
 public void GetElements(CollisionBox collisionBox,
                         List <CollisionTreeElem> elements)
 {
     root.GetElements(collisionBox, elements, ++recurseId);
 }
Example #17
0
 public bool BoxMove(
     CollisionBox box, Vector3 pointStart, Vector3 pointEnd,
     float frictionFactor, float bumpFactor, uint recurseLevel,
     out Vector3 pointResult)
 {
     return tree.BoxMove(box, pointStart, pointEnd,
         vertices, frictionFactor, bumpFactor, recurseLevel,
         out pointResult);
 }
Example #18
0
        public CollisionMesh(Model model, uint subdivLevel)
        {
            int verticesCapacity = 0;
            int facesCapacity    = 0;

            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    verticesCapacity += part.VertexBuffer.VertexCount;
                    facesCapacity    += part.PrimitiveCount;
                }
            }

            vertices = new Vector3[verticesCapacity];
            faces    = new CollisionFace[facesCapacity];

            int verticesLength = 0;
            int facesLength    = 0;

            Matrix[] modelTransforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(modelTransforms);
            foreach (ModelMesh mesh in model.Meshes)
            {
                Matrix meshTransform = modelTransforms[mesh.ParentBone.Index];

                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    int            vertexCount  = part.VertexBuffer.VertexCount;
                    CustomVertex[] partVertices = new CustomVertex[vertexCount];
                    part.VertexBuffer.GetData(partVertices);

                    for (int i = 0; i < vertexCount; i++)
                    {
                        vertices[verticesLength + i] =
                            Vector3.Transform(partVertices[i].Position, meshTransform);
                    }

                    int     indexCount  = part.IndexBuffer.IndexCount;
                    short[] partIndices = new short[indexCount];
                    part.IndexBuffer.GetData(partIndices);

                    for (int i = 0; i < part.PrimitiveCount; i++)
                    {
                        faces[facesLength + i] = new CollisionFace(
                            part.StartIndex + i * 3, partIndices,
                            verticesLength + part.VertexOffset, vertices);
                    }

                    verticesLength += vertexCount;
                    facesLength    += part.PrimitiveCount;
                }
            }

            CollisionBox box = new CollisionBox(float.MaxValue, -float.MaxValue);

            for (int i = 0; i < verticesCapacity; i++)
            {
                box.AddPoint(vertices[i]);
            }

            if (subdivLevel > 6)
            {
                subdivLevel = 6; // max 8^6 nodes
            }
            tree = new CollisionTree(box, subdivLevel);
            for (int i = 0; i < facesCapacity; i++)
            {
                tree.AddElement(faces[i]);
            }
        }
Example #19
0
        // split in middle point creating 8 children
        public CollisionBox[] GetChildren()
        {
            Vector3 center = 0.5f * (min + max);

            CollisionBox[] children = new CollisionBox[8];

            children[0] = new CollisionBox(min, center);
            children[1] = new CollisionBox(new Vector3(center.X, min.Y, min.Z),
                                new Vector3(max.X, center.Y, center.Z));
            children[2] = new CollisionBox(new Vector3(min.X, center.Y, min.Z),
                                new Vector3(center.X, max.Y, center.Z));
            children[3] = new CollisionBox(new Vector3(center.X, center.Y, min.Z),
                                new Vector3(max.X, max.Y, center.Z));
            children[4] = new CollisionBox(new Vector3(min.X, min.Y, center.Z),
                                new Vector3(center.X, center.Y, max.Z));
            children[5] = new CollisionBox(new Vector3(center.X, min.Y, center.Z),
                                new Vector3(max.X, center.Y, max.Z));
            children[6] = new CollisionBox(new Vector3(min.X, center.Y, center.Z),
                                new Vector3(center.X, max.Y, max.Z));
            children[7] = new CollisionBox(center, max);

            return children;
        }
Example #20
0
 // constructor from another collision box
 public CollisionBox(CollisionBox bb)
 {
     min = bb.min;
     max = bb.max;
 }
Example #21
0
 public bool BoxIntersect(
     CollisionBox box,
     Vector3 rayStart,
     Vector3 rayEnd,
     out float intersectDistance,
     out Vector3 intersectPosition,
     out Vector3 intersectNormal)
 {
     return tree.BoxIntersect(box, rayStart, rayEnd, vertices,
         out intersectDistance, out intersectPosition, out intersectNormal);
 }
Example #22
0
        /// <summary>
        /// Recursive function to get all elements intersecting a given bounding box
        /// </summary>
        public void GetElements(
            CollisionBox b,
            List<CollisionTreeElem> e,
            uint recurseId)
        {
            // if selection box does not intersect node box, return
            if (b.BoxIntersect(box) == false)
                return;

            // if any elements in this node add them to selection list
            if (elems != null)
            {
                foreach (CollisionTreeElem elem in elems)
                {
                    // elements can be repeated in many nodes
                    // only add element to selection list if not already
                    // added by another node in this same recursion
                    if (elem.lastRecurseId < recurseId)
                    {
                        // if selection box intersect the element box
                        if (elem.box.BoxIntersect(b))
                            // add element to selection list
                            e.Add(elem);
                        // set this recuse id to prevent duplicate results
                        elem.lastRecurseId = recurseId;
                    }
                }
            }

            // if not a leaf node, recurso to all children
            if (children != null)
            {
                foreach (CollisionTreeNode n in children)
                    n.GetElements(b, e, recurseId);
            }
        }
        public bool PointIntersect(Vector3 ray_start, Vector3 ray_end, Vector3[] vert_pos,
            out float intersect_distance, out Vector3 intersect_position, out Vector3 intersect_normal)
        {
            intersect_distance = 0.0f;
            intersect_position = ray_start;
            intersect_normal = Vector3.Zero;

            Vector3 ray_direction = ray_end - ray_start;
            float ray_length = ray_direction.Length();
            if (ray_length == 0)
                return false;

            CollisionBox ray_box = new CollisionBox(float.MaxValue, -float.MaxValue);
            ray_box.AddPoint(ray_start);
            ray_box.AddPoint(ray_end);
            Vector3 inflate = new Vector3(0.001f, 0.001f, 0.001f);
            ray_box.min -= inflate;
            ray_box.max += inflate;

            List<CollisionTreeElem> elems = new List<CollisionTreeElem>();
            root.GetElements(ray_box, elems, ++recurse_id);

            ray_direction *= 1.0f / ray_length;
            intersect_distance = ray_length;

            bool intersected = false;

            foreach (CollisionTreeElem e in elems)
            {
                float distance;
                Vector3 position;
                Vector3 normal;
                if (true == e.PointIntersect(ray_start, ray_direction, vert_pos, out distance, out position, out normal))
                {
                    if (distance < intersect_distance)
                    {
                        intersect_distance = distance;
                        intersect_position = position;
                        intersect_normal = normal;
                        intersected = true;
                    }
                }
            }

            return intersected;
        }
 public void GetElements(CollisionBox b, List<CollisionTreeElem> e)
 {
     root.GetElements(b, e, ++recurse_id);
 }
        public bool BoxMove(
            CollisionBox box, Vector3 point_start, Vector3 point_end, Vector3[] vert_pos,
            float friction_factor, float bump_factor, uint recurse_level,
            out Vector3 point_result)
        {
            point_result = point_start;

            Vector3 delta = point_end - point_start;
            float delta_len = delta.Length();
            if (delta_len < 0.00001f)
                return false;

            float total_dist = delta_len;
            delta *= 1.0f / delta_len;

            float bias = 0.01f;

            point_end += delta * bias;

            bool collision_hit = false;

            while (recurse_level > 0)
            {
                float dist;
                Vector3 pos, norm;
                if (false == BoxIntersect(box, point_start, point_end, vert_pos, out dist, out pos, out norm))
                {

                    point_start = point_end - delta * bias;
                    break;
                }

                collision_hit = true;

                dist -= bias / Math.Abs(Vector3.Dot(delta, norm));
                if (dist > 0)
                {
                    point_start += delta * dist;
                    total_dist -= dist;
                }

                Vector3 reflect_dir = Vector3.Normalize(Vector3.Reflect(delta, norm));

                Vector3 n = norm * Vector3.Dot(reflect_dir, norm);
                Vector3 t = reflect_dir - n;

                reflect_dir = friction_factor * t + bump_factor * n;

                point_end = point_start + reflect_dir * total_dist;

                delta = point_end - point_start;
                delta_len = delta.Length();
                if (delta_len < 0.00001f)
                    break;
                delta *= 1.0f / delta_len;

                point_end += delta * bias;

                recurse_level--;
            }

            point_result = point_start;
            return collision_hit;
        }
Example #26
0
 public void GetElements(CollisionBox collisionBox, 
     List<CollisionTreeElem> elements)
 {
     root.GetElements(collisionBox, elements, ++recurseId);
 }
        public CollisionMesh(Model model, uint subdiv_level)
        {
            int total_num_faces = 0;
            int total_num_verts = 0;

            foreach (ModelMesh mesh in model.Meshes)
            {
                if (IsDynamicEntity(mesh))
                    continue;

                int nv, ni;
                nv = mesh.VertexBuffer.SizeInBytes / mesh.MeshParts[0].VertexStride;
                if(mesh.IndexBuffer.IndexElementSize == IndexElementSize.SixteenBits)
                    ni = mesh.IndexBuffer.SizeInBytes / sizeof(short);
                else
                    ni = mesh.IndexBuffer.SizeInBytes / sizeof(int);

                total_num_verts += nv;
                total_num_faces += ni / 3;
            }

            vertices = new Vector3[total_num_verts];
            faces = new CollisionFace[total_num_faces];

            int vcount = 0;
            int fcount = 0;

            foreach (ModelMesh mesh in model.Meshes)
            {
                if (IsDynamicEntity(mesh))
                    continue;

                int nv = mesh.VertexBuffer.SizeInBytes / mesh.MeshParts[0].VertexStride;

                if (mesh.MeshParts[0].VertexStride == 16)
                {
                    VertexPositionColor[] mesh_vertices = new VertexPositionColor[nv];
                    mesh.VertexBuffer.GetData<VertexPositionColor>(mesh_vertices);

                    for (int i = 0; i < nv; i++)
                        vertices[i + vcount] = mesh_vertices[i].Position;
                }

                if (mesh.MeshParts[0].VertexStride == 20)
                {
                    VertexPositionTexture[] mesh_vertices = new VertexPositionTexture[nv];
                    mesh.VertexBuffer.GetData<VertexPositionTexture>(mesh_vertices);

                    for (int i = 0; i < nv; i++)
                        vertices[i + vcount] = mesh_vertices[i].Position;
                }
                else if (mesh.MeshParts[0].VertexStride == 24)
                {
                    VertexPositionColorTexture[] mesh_vertices = new VertexPositionColorTexture[nv];
                    mesh.VertexBuffer.GetData<VertexPositionColorTexture>(mesh_vertices);

                    for (int i = 0; i < nv; i++)
                        vertices[i + vcount] = mesh_vertices[i].Position;
                }
                else if (mesh.MeshParts[0].VertexStride == 32)
                {
                    VertexPositionNormalTexture[] mesh_vertices = new VertexPositionNormalTexture[nv];
                    mesh.VertexBuffer.GetData<VertexPositionNormalTexture>(mesh_vertices);

                    for (int i = 0; i < nv; i++)
                        vertices[i + vcount] = mesh_vertices[i].Position;
                }

                int nf = 0;

                if (mesh.IndexBuffer.IndexElementSize == IndexElementSize.SixteenBits)
                {
                    short[] mesh_indices = new short[mesh.IndexBuffer.SizeInBytes / sizeof(short)];
                    mesh.IndexBuffer.GetData<short>(mesh_indices);

                    int count = 0;
                    foreach (ModelMeshPart mesh_part in mesh.MeshParts)
                    {
                        for (int i = 0; i < mesh_part.PrimitiveCount; i++)
                        {
                            faces[nf + fcount] = new CollisionFace(count, mesh_indices, vcount + mesh_part.BaseVertex, vertices);
                            count += 3;
                            nf++;
                        }
                    }
                }
                else
                {
                    int[] mesh_indices = new int[mesh.IndexBuffer.SizeInBytes / sizeof(int)];
                    mesh.IndexBuffer.GetData<int>(mesh_indices);

                    int count = 0;
                    foreach (ModelMeshPart mesh_part in mesh.MeshParts)
                    {
                        for (int i = 0; i < mesh_part.PrimitiveCount; i++)
                        {
                            faces[nf + fcount] = new CollisionFace(count, mesh_indices, vcount + mesh_part.BaseVertex, vertices);
                            count += 3;
                            nf++;
                        }
                    }
                }

                vcount += nv;
                fcount += nf;
            }

            CollisionBox box = new CollisionBox(float.MaxValue, -float.MaxValue);
            for (int i = 0; i < vcount; i++)
                box.AddPoint(vertices[i]);

            if (subdiv_level > 6)
                subdiv_level = 6; // max 8^6 nodes
            tree = new CollisionTree(box, subdiv_level);
            for (int i = 0; i < fcount; i++)
                tree.AddElement(faces[i]);
        }
Example #28
0
 public CollisionTree(CollisionBox box, uint subdivLevel)
 {
     root = new CollisionTreeNode(box, subdivLevel);
     recurseId = 0;
 }
Example #29
0
        public bool BoxMove(
            CollisionBox box,
            Vector3 pointStart,
            Vector3 pointEnd,
            Vector3[] vertices,
            float frictionFactor,
            float bumpFactor,
            uint recurseLevel,
            out Vector3 pointResult)
        {
            pointResult = pointStart;

            Vector3 delta       = pointEnd - pointStart;
            float   deltaLength = delta.Length();

            if (deltaLength < 0.00001f)
            {
                return(false);
            }

            float totalDistance = deltaLength;

            delta *= 1.0f / deltaLength;

            float bias = 0.01f;

            pointEnd += delta * bias;

            bool collisionHit = false;

            while (recurseLevel > 0)
            {
                float   dist;
                Vector3 pos, norm;
                if (false == BoxIntersect(box, pointStart, pointEnd, vertices,
                                          out dist, out pos, out norm))
                {
                    pointStart = pointEnd - delta * bias;
                    break;
                }

                collisionHit = true;

                dist -= bias / Math.Abs(Vector3.Dot(delta, norm));
                if (dist > 0)
                {
                    pointStart    += delta * dist;
                    totalDistance -= dist;
                }

                Vector3 reflectDirection =
                    Vector3.Normalize(Vector3.Reflect(delta, norm));

                Vector3 n = norm * Vector3.Dot(reflectDirection, norm);
                Vector3 t = reflectDirection - n;

                reflectDirection = frictionFactor * t + bumpFactor * n;

                pointEnd = pointStart + reflectDirection * totalDistance;

                delta       = pointEnd - pointStart;
                deltaLength = delta.Length();
                if (deltaLength < 0.00001f)
                {
                    break;
                }
                delta *= 1.0f / deltaLength;

                pointEnd += delta * bias;

                recurseLevel--;
            }

            pointResult = pointStart;
            return(collisionHit);
        }
Example #30
0
 public void GetElements(CollisionBox b, List <CollisionTreeElem> e)
 {
     tree.GetElements(b, e);
 }
Example #31
0
 public CollisionTree(CollisionBox box, uint subdivLevel)
 {
     root      = new CollisionTreeNode(box, subdivLevel);
     recurseId = 0;
 }
        // box intersect face and return intersection distance, point and normal
        public override bool BoxIntersect(CollisionBox ray_box, Vector3 ray_origin, Vector3 ray_direction, Vector3[] vert_pos,
            out float intersect_distance, out Vector3 intersect_position, out Vector3 intersect_normal)
        {
            intersect_distance = float.MaxValue;
            intersect_position = ray_origin;
            intersect_normal = Vector3.Zero;

            bool intersected = false;
            Vector3 p1, p2, p3, p4;
            uint i, j;

            CollisionBox world_box = new CollisionBox(ray_box.min + ray_origin, ray_box.max + ray_origin);

            Vector3[] box_verts = world_box.GetVertices();
            Vector3[] box_edges = world_box.GetEdges();

            // intersect box edges to face edges
            for (i = 0; i < 12; i++)
            {
                // cull edges with normal more than 135 degree from moving direction
                if (Vector3.Dot(CollisionBox.edge_normals[i], ray_direction) < -0.70710678)
                    continue;

                p1 = box_edges[i * 2];
                p2 = box_edges[i * 2 + 1];
                p4 = vert_pos[vertices[0]];
                for (j = 0; j < vertices.Length; j++)
                {
                    p3 = p4;
                    p4 = vert_pos[vertices[(j + 1) % vertices.Length]];

                    float distance;
                    Vector3 position;
                    if (CollisionFace.EdgeIntersect(p1, p2, ray_direction, p3, p4, out distance, out position))
                    {
                        if (distance < intersect_distance)
                        {
                            intersect_distance = distance;
                            intersect_position = position;
                            intersect_normal = Vector3.Normalize(Vector3.Cross(p2-p1,p3-p4));
                            if (Vector3.Dot(ray_direction, intersect_normal) > 0)
                                intersect_normal = Vector3.Negate(intersect_normal);
                            intersected = true;
                        }
                    }
                }
            }

            // intersect from face vertices to box
            for (i = 0; i < 3; i++)
            {
                float tnear, tfar;
                p1 = vert_pos[vertices[i]];
                int box_face_id = world_box.RayIntersect(p1, -ray_direction, out tnear, out tfar);
                if (box_face_id > -1)
                {
                    if (tnear < intersect_distance)
                    {
                        intersect_distance = tnear;
                        intersect_position = p1;
                        intersect_normal = -CollisionBox.face_normals[box_face_id];
                        intersected = true;
                    }
                }
            }

            // intersect from box vertices to face polygon
            Vector3 v1 = vert_pos[vertices[0]];
            Vector3 v2 = vert_pos[vertices[1]];
            Vector3 v3 = vert_pos[vertices[2]];
            for (i = 0; i < 8; i++)
            {
                // cull vertices with normal more than 135 degree from moving direction
                if (Vector3.Dot(CollisionBox.vertex_normals[i], ray_direction) < -0.70710678)
                    continue;

                Vector3 uvt;
                if (CollisionFace.RayTriangleIntersect(box_verts[i], ray_direction, v1, v2, v3, out uvt.Z, out uvt.X, out uvt.Y))
                {
                    if (uvt.Z < intersect_distance)
                    {
                        intersect_distance = uvt.Z;
                        intersect_position = (1.0f - uvt.X - uvt.Y) * v1 + uvt.X * v2 + uvt.Y * v3;
                        intersect_normal = Vector3.Normalize(Vector3.Cross(v3 - v1, v2 - v1));
                        intersected = true;
                    }
                }
            }

            return intersected;
        }
Example #33
0
        public CollisionMesh(Model model, uint subdivLevel)
        {
            int verticesCapacity = 0;
            int facesCapacity = 0;
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    verticesCapacity += part.VertexBuffer.VertexCount;
                    facesCapacity += part.PrimitiveCount;
                }
            }

            vertices = new Vector3[verticesCapacity];
            faces = new CollisionFace[facesCapacity];

            int verticesLength = 0;
            int facesLength = 0;

            Matrix[] modelTransforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(modelTransforms);
            foreach (ModelMesh mesh in model.Meshes)
            {
                Matrix meshTransform = modelTransforms[mesh.ParentBone.Index];

                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    int vertexCount = part.VertexBuffer.VertexCount;
                    CustomVertex[] partVertices = new CustomVertex[vertexCount];
                    part.VertexBuffer.GetData(partVertices);

                    for (int i = 0; i < vertexCount; i++)
                    {
                        vertices[verticesLength + i] =
                            Vector3.Transform(partVertices[i].Position, meshTransform);
                    }

                    int indexCount = part.IndexBuffer.IndexCount;
                    short[] partIndices = new short[indexCount];
                    part.IndexBuffer.GetData(partIndices);

                    for (int i = 0; i < part.PrimitiveCount; i++)
                    {
                        faces[facesLength + i] = new CollisionFace(
                            part.StartIndex + i * 3, partIndices,
                            verticesLength + part.VertexOffset, vertices);
                    }

                    verticesLength += vertexCount;
                    facesLength += part.PrimitiveCount;

                }

            }

            CollisionBox box = new CollisionBox(float.MaxValue, -float.MaxValue);
            for (int i = 0; i < verticesCapacity; i++)
                box.AddPoint(vertices[i]);

            if (subdivLevel > 6)
                subdivLevel = 6; // max 8^6 nodes
            tree = new CollisionTree(box, subdivLevel);
            for (int i = 0; i < facesCapacity; i++)
                tree.AddElement(faces[i]);
        }
 public bool BoxIntersect(
     CollisionBox box, Vector3 ray_start, Vector3 ray_end,
     out float intersect_distance, out Vector3 intersect_position, out Vector3 intersect_normal)
 {
     return tree.BoxIntersect(box, ray_start, ray_end, vertices,
         out intersect_distance, out intersect_position, out intersect_normal);
 }
 public bool BoxMove(
     CollisionBox box, Vector3 point_start, Vector3 point_end,
     float friction_factor, float bump_factor, uint recurse_level,
     out Vector3 point_result)
 {
     return tree.BoxMove(box, point_start, point_end, vertices, friction_factor, bump_factor, recurse_level,
         out point_result);
 }
Example #36
0
 // check if two bounding boxes have any intersection
 public bool BoxIntersect(CollisionBox bb)
 {
     if (max.X >= bb.min.X && min.X <= bb.max.X &&
         max.Y >= bb.min.Y && min.Y <= bb.max.Y &&
         max.Z >= bb.min.Z && min.Z <= bb.max.Z)
         return true;
     return false;
 }
 public void GetElements(CollisionBox b, List<CollisionTreeElem> e)
 {
     tree.GetElements(b, e);
 }
Example #38
0
 // constructor from another collision box
 public CollisionBox(CollisionBox bb)
 {
     min = bb.min;
     max = bb.max;
 }
Example #39
0
        // box intersect face and return intersection distance, point and normal
        public override bool BoxIntersect(
            CollisionBox rayBox,
            Vector3 rayOrigin,
            Vector3 rayDirection,
            Vector3[] vertices,
            out float intersectDistance,
            out Vector3 intersectPosition,
            out Vector3 intersectNormal)
        {
            intersectDistance = float.MaxValue;
            intersectPosition = rayOrigin;
            intersectNormal   = Vector3.Zero;

            bool    intersected = false;
            Vector3 p1, p2, p3, p4;
            uint    i, j;

            CollisionBox worldBox = new CollisionBox(rayBox.min + rayOrigin,
                                                     rayBox.max + rayOrigin);

            Vector3[] boxVerts = worldBox.GetVertices();
            Vector3[] boxEdges = worldBox.GetEdges();

            float   distance;
            Vector3 position;

            // intersect box edges to face edges
            for (i = 0; i < 12; i++)
            {
                // cull edges with normal more than 135 degree from moving direction
                float dot = Vector3.Dot(CollisionBox.edgeNormals[i], rayDirection);
                if (dot < -0.70710678)
                {
                    continue;
                }

                p1 = boxEdges[i * 2];
                p2 = boxEdges[i * 2 + 1];
                p4 = vertices[indices[0]];
                for (j = 0; j < indices.Length; j++)
                {
                    p3 = p4;
                    p4 = vertices[indices[(j + 1) % indices.Length]];

                    if (CollisionFace.EdgeIntersect(p1, p2, rayDirection,
                                                    p3, p4, out distance, out position))
                    {
                        if (distance < intersectDistance)
                        {
                            intersectDistance = distance;
                            intersectPosition = position;
                            intersectNormal   = Vector3.Cross(p2 - p1, p3 - p4);
                            intersectNormal   = Vector3.Normalize(intersectNormal);
                            if (Vector3.Dot(rayDirection, intersectNormal) > 0)
                            {
                                intersectNormal = Vector3.Negate(intersectNormal);
                            }
                            intersected = true;
                        }
                    }
                }
            }

            // intersect from face vertices to box
            for (i = 0; i < 3; i++)
            {
                float tnear, tfar;
                p1 = vertices[indices[i]];
                int box_face_id = worldBox.RayIntersect(p1, -rayDirection,
                                                        out tnear, out tfar);
                if (box_face_id > -1)
                {
                    if (tnear < intersectDistance)
                    {
                        intersectDistance = tnear;
                        intersectPosition = p1;
                        intersectNormal   = -CollisionBox.faceNormals[box_face_id];
                        intersected       = true;
                    }
                }
            }

            // intersect from box vertices to face polygon
            Vector3 v1 = vertices[indices[0]];
            Vector3 v2 = vertices[indices[1]];
            Vector3 v3 = vertices[indices[2]];
            Vector3 uvt;

            for (i = 0; i < 8; i++)
            {
                // cull vertices with normal more than 135 degree from moving direction
                float dot = Vector3.Dot(CollisionBox.vertexNormals[i], rayDirection);
                if (dot < -0.70710678)
                {
                    continue;
                }

                if (CollisionFace.RayTriangleIntersect(boxVerts[i], rayDirection,
                                                       v1, v2, v3, out uvt.Z, out uvt.X, out uvt.Y))
                {
                    if (uvt.Z < intersectDistance)
                    {
                        intersectDistance = uvt.Z;
                        intersectPosition = (1.0f - uvt.X - uvt.Y) *
                                            v1 + uvt.X * v2 + uvt.Y * v3;
                        intersectNormal = Vector3.Cross(v3 - v1, v2 - v1);
                        intersectNormal = Vector3.Normalize(intersectNormal);
                        intersected     = true;
                    }
                }
            }

            return(intersected);
        }