Created
October 25, 2024 16:45
-
-
Save tomkrikorian/488aacf2abc2b52a79f477c0712f6fbf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// Generates a collision shape from the model's bounding box | |
| /// - Returns: A `ShapeResource` representing the collision shape, or `nil` if the generation fails | |
| func generateShapeResourceFromBoundingBox() async -> ShapeResource? { | |
| // Get the model entity and its mesh | |
| guard let modelEntity = self.children.first as? ModelEntity, | |
| let modelMesh = modelEntity.model?.mesh else { | |
| Logger.realitykit.error("Required model components not found") | |
| return nil | |
| } | |
| // Get bounding boxes and calculate scale factors | |
| let entityBoundingBox = self.visualBounds(relativeTo: nil) | |
| guard modelMesh.bounds.extents != .zero else { | |
| Logger.realitykit.error("Invalid mesh bounds") | |
| return nil | |
| } | |
| let scaleFactors = simd_float3( | |
| entityBoundingBox.extents.x / modelMesh.bounds.extents.x, | |
| entityBoundingBox.extents.y / modelMesh.bounds.extents.y, | |
| entityBoundingBox.extents.z / modelMesh.bounds.extents.z | |
| ) | |
| // Transform mesh instances | |
| let newInstances = modelMesh.contents.instances.map { instance -> MeshResource.Instance in | |
| var newInstance = instance | |
| let transform = instance.transform | |
| // Extract current scale | |
| let currentScale = simd_float3( | |
| simd_length(transform.columns.0), | |
| simd_length(transform.columns.1), | |
| simd_length(transform.columns.2) | |
| ) | |
| // Extract rotation | |
| let upperLeft = simd_float3x3( | |
| simd_normalize(simd_float3(transform.columns.0.x, transform.columns.0.y, transform.columns.0.z)), | |
| simd_normalize(simd_float3(transform.columns.1.x, transform.columns.1.y, transform.columns.1.z)), | |
| simd_normalize(simd_float3(transform.columns.2.x, transform.columns.2.y, transform.columns.2.z)) | |
| ) | |
| // Create rotation matrix at origin | |
| let rotationMatrix = float4x4( | |
| [upperLeft[0].x, upperLeft[0].y, upperLeft[0].z, 0], | |
| [upperLeft[1].x, upperLeft[1].y, upperLeft[1].z, 0], | |
| [upperLeft[2].x, upperLeft[2].y, upperLeft[2].z, 0], | |
| [0, 0, 0, 1] | |
| ) | |
| // Apply combined scale | |
| let combinedScale = currentScale * scaleFactors | |
| newInstance.transform = rotationMatrix * float4x4(scale: combinedScale) | |
| return newInstance | |
| } | |
| // Generate new mesh resource | |
| do { | |
| var transformedContents = MeshResource.Contents() | |
| transformedContents.models = modelMesh.contents.models | |
| transformedContents.instances = MeshInstanceCollection(newInstances) | |
| let transformedMesh = try MeshResource.generate(from: transformedContents) | |
| return try await ShapeResource.generateConvex(from: transformedMesh) | |
| } catch { | |
| Logger.realitykit.error("Failed to generate collision shape: \(error)") | |
| return nil | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment