Created
September 8, 2025 13:29
-
-
Save TAATHub/ae8aa2b2259067e34bc04df847ad7457 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
| import SwiftUI | |
| import RealityKit | |
| import RealityKitContent | |
| import FoundationModels | |
| import OpenAI | |
| let modelName = "赤い球体" | |
| let voxelSize: Float = 0.1 | |
| let modelSize: Float = 1.0 | |
| struct ImmersiveView: View { | |
| @State private var voxelModel: VoxelModel? | |
| var body: some View { | |
| RealityView { content in | |
| if let immersiveContentEntity = try? await Entity(named: "Immersive", in: realityKitContentBundle) { | |
| content.add(immersiveContentEntity) | |
| } | |
| } update: { content in | |
| guard let voxelModel else { return } | |
| for voxel in voxelModel.voxels { | |
| let entity = ModelEntity(mesh: .generateBox(size: voxelSize), materials: [SimpleMaterial(color: .red, isMetallic: false)]) | |
| entity.position = .init(x: Float(voxel.position.x), y: Float(voxel.position.y), z: Float(voxel.position.z)) | |
| content.add(entity) | |
| } | |
| } | |
| .task { | |
| // 1. Generate Voxel Model of red sphere using Foundation Models with VoxelModelTool | |
| let session = LanguageModelSession(model: .default, tools: [VoxelModelTool()], instructions: "あなたはプロの3Dモデラーです") | |
| let response = try? await session.respond(to: """ | |
| VoxelModelToolを使って、複数のボクセル(サイズ: \(voxelSize)x\(voxelSize)x\(voxelSize)を3D空間内に配置して、\(modelName)のボクセルモデル(サイズ: \(modelSize)x\(modelSize)x\(modelSize)を作ってください | |
| """, generating: VoxelModel.self) | |
| voxelModel = response?.content | |
| print("response: \(response)") | |
| // 2. Generate Voxel Model of red sphere using OpenAI API directly | |
| let generator = VoxelModelGenerator() | |
| let prompt = generator.prompt(modelName: modelName, voxelSize: voxelSize, modelSize: modelSize) | |
| voxelModel = await generator.generateVoxelModel(prompt: prompt) | |
| print("Generated VoxelModel") | |
| } | |
| } | |
| } | |
| @Generable(description: "3D model with voxels") | |
| struct VoxelModel: Codable { | |
| @Guide(description: "Array of voxels") | |
| var voxels: [Voxel] | |
| } | |
| @Generable(description: "Voxel composing the 3D model") | |
| struct Voxel: Codable { | |
| @Guide(description: "Position of voxel in 3D space") | |
| var position: VoxelPosition | |
| } | |
| @Generable(description: "Position of voxel in 3D space") | |
| struct VoxelPosition: Codable { | |
| var x: Float | |
| var y: Float | |
| var z: Float | |
| } | |
| struct VoxelModelTool: FoundationModels.Tool { | |
| let name = "VoxelModelTool" | |
| let description = "Generates a VoxelModel based on input parameters." | |
| let generator = VoxelModelGenerator() | |
| @Generable | |
| struct Arguments { | |
| @Guide(description: "The name of voxel model to be generated") | |
| var modelName: String | |
| @Guide(description: "The size of each voxel") | |
| var voxelSize: Float | |
| @Guide(description: "The size of voxel model") | |
| var modelSize: Float | |
| } | |
| func call(arguments: Arguments) async throws -> VoxelModel? { | |
| print("Called VoxelModelTool, arguments: \(arguments)") | |
| let prompt = generator.prompt(modelName: arguments.modelName, voxelSize: arguments.voxelSize, modelSize: arguments.modelSize) | |
| let voxelModel = await generator.generateVoxelModel(prompt: prompt) | |
| return voxelModel | |
| } | |
| } | |
| struct VoxelModelGenerator { | |
| func prompt(modelName: String, voxelSize: Float, modelSize: Float) -> String { | |
| """ | |
| あなたはプロの3Dモデラーです。 | |
| 複数のボクセル(サイズ: \(voxelSize)x\(voxelSize)x\(voxelSize)を3D空間内に配置して、\(modelName)のボクセルモデル(サイズ: \(modelSize)x\(modelSize)x\(modelSize)を作ってください | |
| 回答は以下のフォーマットのJSON文字列のみ | |
| {"voxels":[{"position":{"x":1.0,"y":2.0,"z":3.0}}]} | |
| """ | |
| } | |
| func generateVoxelModel(prompt: String) async -> VoxelModel? { | |
| let configuration = OpenAI.Configuration(token: "Your OpenAI API key", timeoutInterval: 600) | |
| let openAI = OpenAI(configuration: configuration) | |
| guard let message = ChatQuery.ChatCompletionMessageParam(role: .user, content: prompt) else { return nil } | |
| let query = ChatQuery(messages: [message], model: .gpt5) | |
| guard let result = try? await openAI.chats(query: query), | |
| let jsonStr = result.choices.first?.message.content, | |
| let jsonData = jsonStr.data(using: .utf8) else { return nil } | |
| return try? JSONDecoder().decode(VoxelModel.self, from: jsonData) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment