{"id":19141065,"url":"https://github.com/computer-graphics-tools/simulation-tools","last_synced_at":"2026-03-01T10:33:48.596Z","repository":{"id":245916865,"uuid":"812036276","full_name":"computer-graphics-tools/simulation-tools","owner":"computer-graphics-tools","description":null,"archived":false,"fork":false,"pushed_at":"2024-08-08T20:46:19.000Z","size":73,"stargazers_count":53,"open_issues_count":0,"forks_count":3,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-07-24T08:26:13.783Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/computer-graphics-tools.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-07T20:24:59.000Z","updated_at":"2025-07-18T23:00:51.000Z","dependencies_parsed_at":"2024-06-24T20:24:30.937Z","dependency_job_id":"ddd85008-191b-488d-b68c-cd01d24b8bc6","html_url":"https://github.com/computer-graphics-tools/simulation-tools","commit_stats":null,"previous_names":["computer-graphics-tools/simulation-tools"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/computer-graphics-tools/simulation-tools","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/computer-graphics-tools%2Fsimulation-tools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/computer-graphics-tools%2Fsimulation-tools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/computer-graphics-tools%2Fsimulation-tools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/computer-graphics-tools%2Fsimulation-tools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/computer-graphics-tools","download_url":"https://codeload.github.com/computer-graphics-tools/simulation-tools/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/computer-graphics-tools%2Fsimulation-tools/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29966842,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T09:33:09.965Z","status":"ssl_error","status_checked_at":"2026-03-01T09:25:48.915Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T07:20:17.628Z","updated_at":"2026-03-01T10:33:48.574Z","avatar_url":"https://github.com/computer-graphics-tools.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SimulationTools\n\n## Description\n\nSimulationTools is a GPU-accelerated library using Metal for various high-performance algorithms in 3D simulations and computational geometry.\n\n## Key Components\n\n### Spatial Hashing\n\nSpatial hashing divides 3D space into a grid, enabling efficient neighbor searches and collision detection.\n\n#### Algorithm Details:\n1. Hash Computation: Each vertex is assigned to a cell based on its position.\n2. Bitonic Sort: Hash-index pairs are sorted to resolve collisions and build cell buckets.\n3. Cell Boundary Identification: Start and end indices for each cell are determined.\n4. Collision Candidate Search: Potential colliders are identified within the same and adjacent cells.\n5. Insertion Sort Storage: Collision candidates are stored using an insertion sort mechanism, maintaining a sorted list of the closest candidates.\n\n#### Key Features:\n- Efficient for both self-collision and external collision detection\n- Insertion sort storage allows for temporal and structural reuse of candidates, improving performance in scenarios with coherent motion or stable structures\n\n### Triangle Spatial Hashing\n\nOptimized for triangle meshes, this variant enables efficient point-triangle collision detection.\n\n#### Algorithm Details:\n1. Triangle Hashing: Triangles are hashed into multiple cells they overlap.\n2. Bucket Storage: Each cell maintains a fixed-size bucket of triangle indices.\n3. Collision Candidate Search: For each query point, nearby triangles are identified through cell lookups.\n4. Candidate Refinement: Distance computations are performed to sort and store the closest triangle candidates.\n\n#### Key Features:\n- Specialized for triangle mesh collision detection\n- Supports both self-collision and external collision queries\n- Efficient spatial reuse of collision information for improved performance in temporally coherent scenarios\n\n## Performance Considerations\n\n- GPU-optimized using Metal for scalability with large numbers of elements\n- Insertion sort storage of candidates enables efficient updates in scenarios with small position changes\n- Triangle spatial hashing optimizes memory usage through fixed-size buckets per cell\n- Performance is sensitive to cell size: smaller cells increase precision but may reduce efficiency for large objects\n\n## Usage Examples\n\n### Spatial Hashing\n\nHere are a few examples demonstrating the use of SpatialHashing for both self-collision and external collision scenarios:\n\n```swift\nimport Metal\nimport SimulationTools\n\n// MARK: - Basic Spatial Hashing Example\n\n// Initialize Metal device and command queue\nguard let device = MTLCreateSystemDefaultDevice() else { return }\nguard let commandQueue = device.makeCommandQueue() else { return }\n\n// Create a set of test positions\nlet positions: [SIMD3\u003cFloat\u003e] = [\n    [0.0, 0.0, 0.0],\n    [0.5, 0.0, 0.0],\n    [0.0, 0.5, 0.0],\n    [1.0, 1.0, 1.0],\n    [1.1, 1.1, 1.1]\n]\n\n// Configure spatial hashing\nlet config = SpatialHashing.Configuration(cellSize: 1.0, radius: 0.5)\n\n// Create SpatialHashing instance\nlet spatialHashing = try SpatialHashing(\n    device: device,\n    configuration: config,\n    maxPositionsCount: positions.count\n)\n\n// Create buffers\nlet positionsBuffer = try device.buffer(with: positions)\nlet typedPositionsBuffer = try device.typedBuffer(with: positions, valueType: .float3)\nlet collisionCandidatesBuffer = try device.typedBuffer(\n    with: Array(repeating: UInt32.max, count: positions.count * 8),\n    valueType: .uint\n)\n\n// Create and execute command buffer\nguard let commandBuffer = commandQueue.makeCommandBuffer() else { return }\nspatialHashing.build(positions: typedPositionsBuffer, in: commandBuffer)\nspatialHashing.find(\n    collidablePositions: nil,\n    collisionCandidates: collisionCandidatesBuffer,\n    connectedVertices: nil,\n    in: commandBuffer\n)\ncommandBuffer.commit()\ncommandBuffer.waitUntilCompleted()\n\n// Process results\nguard let collisionCandidates: [[UInt32]] = collisionCandidatesBuffer.values()?.chunked(into: 8) else { return }\nfor (index, candidates) in collisionCandidates.enumerated() {\n    print(\"Collision candidates for position \\(index): \\(candidates.filter { $0 != .max })\")\n}\n\n// MARK: - External Collision Example\n\n// Create a set of mesh positions and external query positions\nlet meshPositions: [SIMD3\u003cFloat\u003e] = [\n    [0.0, 0.0, 0.0],\n    [1.0, 0.0, 0.0],\n    [0.0, 1.0, 0.0],\n    [1.0, 1.0, 0.0]\n]\nlet queryPositions: [SIMD3\u003cFloat\u003e] = [\n    [0.5, 0.5, 0.0],\n    [1.5, 1.5, 0.0]\n]\n\n// Configure spatial hashing\nlet externalConfig = SpatialHashing.Configuration(cellSize: 1.0, radius: 0.5)\n\n// Create SpatialHashing instance\nlet externalSpatialHashing = try SpatialHashing(\n    device: device,\n    configuration: externalConfig,\n    maxPositionsCount: max(meshPositions.count, queryPositions.count)\n)\n\n// Create buffers\nlet meshPositionsBuffer = try device.typedBuffer(with: meshPositions, valueType: .float3)\nlet queryPositionsBuffer = try device.typedBuffer(with: queryPositions, valueType: .float3)\nlet externalCollisionCandidatesBuffer = try device.typedBuffer(\n    with: Array(repeating: UInt32.max, count: queryPositions.count * 8),\n    valueType: .uint\n)\n\n// Create and execute command buffer\nguard let externalCommandBuffer = commandQueue.makeCommandBuffer() else { return }\nexternalSpatialHashing.build(positions: meshPositionsBuffer, in: externalCommandBuffer)\nexternalSpatialHashing.find(\n    collidablePositions: queryPositionsBuffer,\n    collisionCandidates: externalCollisionCandidatesBuffer,\n    connectedVertices: nil,\n    in: externalCommandBuffer\n)\nexternalCommandBuffer.commit()\nexternalCommandBuffer.waitUntilCompleted()\n\n// Process results\nguard let externalCollisionCandidates: [[UInt32]] = externalCollisionCandidatesBuffer.values()?.chunked(into: 8) else { return }\nfor (index, candidates) in externalCollisionCandidates.enumerated() {\n    print(\"Collision candidates for query position \\(index): \\(candidates.filter { $0 != .max })\")\n}\n\n// MARK: - Triangle Spatial Hashing Example\n\n// Create a simple triangle mesh\nlet triangleMeshPositions: [SIMD3\u003cFloat\u003e] = [\n    [0.0, 0.0, 0.0],\n    [1.0, 0.0, 0.0],\n    [0.0, 1.0, 0.0],\n    [1.0, 1.0, 0.0]\n]\nlet triangles: [SIMD3\u003cUInt32\u003e] = [\n    [0, 1, 2],\n    [1, 3, 2]\n]\n\n// Create query positions\nlet triangleQueryPositions: [SIMD3\u003cFloat\u003e] = [\n    [0.5, 0.5, 0.0],\n    [1.5, 1.5, 0.0]\n]\n\n// Configure triangle spatial hashing\nlet triangleConfig = TriangleSpatialHashing.Configuration(cellSize: 1.0, bucketSize: 8)\n\n// Create TriangleSpatialHashing instance\nlet triangleSpatialHashing = try TriangleSpatialHashing(\n    device: device,\n    configuration: triangleConfig,\n    maxTrianglesCount: triangles.count\n)\n\n// Create buffers\nlet triangleMeshPositionsBuffer = try device.typedBuffer(with: triangleMeshPositions, valueType: .float3)\nlet trianglesBuffer = try device.typedBuffer(with: triangles, valueType: .uint3)\nlet triangleQueryPositionsBuffer = try device.typedBuffer(with: triangleQueryPositions, valueType: .float3)\nlet triangleCollisionCandidatesBuffer = try device.typedBuffer(\n    with: Array(repeating: UInt32.max, count: triangleQueryPositions.count * 8),\n    valueType: .uint\n)\n\n// Create and execute command buffer\nguard let triangleCommandBuffer = commandQueue.makeCommandBuffer() else { return }\ntriangleSpatialHashing.build(\n    colliderPositions: triangleMeshPositionsBuffer,\n    indices: trianglesBuffer,\n    in: triangleCommandBuffer\n)\ntriangleSpatialHashing.find(\n    collidablePositions: triangleQueryPositionsBuffer,\n    colliderPositions: triangleMeshPositionsBuffer,\n    indices: trianglesBuffer,\n    collisionCandidates: triangleCollisionCandidatesBuffer,\n    in: triangleCommandBuffer\n)\ntriangleCommandBuffer.commit()\ntriangleCommandBuffer.waitUntilCompleted()\n\n// Process results\nguard let triangleCollisionCandidates: [[UInt32]] = triangleCollisionCandidatesBuffer.values()?.chunked(into: 8) else { return }\nfor (index, candidates) in triangleCollisionCandidates.enumerated() {\n    print(\"Collision candidates for triangle query position \\(index): \\(candidates.filter { $0 != .max })\")\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcomputer-graphics-tools%2Fsimulation-tools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcomputer-graphics-tools%2Fsimulation-tools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcomputer-graphics-tools%2Fsimulation-tools/lists"}