Example #1
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);
        }
Example #2
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 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]]);
     }
 }
Example #4
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]]);
     }
 }
Example #5
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]]);
     }
 }
        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]);
        }
        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;
        }
Example #8
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 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]);
            }
        }