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 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]]); } }
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; }
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]); } }