Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save TAATHub/ae8aa2b2259067e34bc04df847ad7457 to your computer and use it in GitHub Desktop.

Select an option

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