Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save tomkrikorian/488aacf2abc2b52a79f477c0712f6fbf to your computer and use it in GitHub Desktop.

Select an option

Save tomkrikorian/488aacf2abc2b52a79f477c0712f6fbf to your computer and use it in GitHub Desktop.
/// 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