import Foundation import OrderedCollections public struct ObjModel { public var positions = [Vec3f]() public var colours = [Vec3f]() public var normals = [Vec3f]() public var texCoords = [Vec2f]() public var objects = OrderedDictionary() public var materials = Dictionary() public struct Object { public var meshes = [Mesh]() } public struct Mesh { public var material = "", faces = [Face]() } public struct Index { public let p: Int, n: Int, t: Int } public enum Face { case line(p1: Int, p2: Int) case triangle(v1: Index, v2: Index, v3: Index) case quad(v1: Index, v2: Index, v3: Index, v4: Index) case ngon(_ v: [Index]) } } public struct ObjMaterial { var model: IlluminationModel = .lambert var ambient: Colour = .black var diffuse: Colour = .white var specular: Colour = .zero var specularExp: Float = 30 var refraction: Float = 1.0 var alpha: Float = 1.0 var ambientMap: TextureMap? = nil var diffuseMap: TextureMap? = nil var specularMap: TextureMap? = nil var specularExpMap: TextureMap? = nil var dissolveMap: TextureMap? = nil var bumpMap: TextureMap? = nil var displacementMap: TextureMap? = nil var decalMap: TextureMap? = nil // PBR extensions var roughness: Float = 0.5 var metallic: Float = 0.0 var sheen: Float = 0.0 var clearcoatThickness: Float = 0.0 var clearcoatRoughness: Float = 0.03 // dunno what the default should be so here's the blender one var emmision: Vec3f = .zero var anisotropy: Float = 0.0 var anisotropyRotation: Float = 0.0 var roughnessMap: TextureMap? = nil var metallicMap: TextureMap? = nil var sheenMap: TextureMap? = nil var emmisionMap: TextureMap? = nil var normalMap: TextureMap? = nil // Ft Fresnel reflectance // Ft Fresnel transmittance // Ns Specular exponent/shininess // Ia Ambient light // I Light intensity // Ir Intensity from reflected direction (reflection map and/or raytracing) // It Intensity from transmitted direction // Ka Ambient reflectance // Kd Diffuse reflectance // Ks Specular reflectance // Tf Transmission filter // H Unit vector bisector between L and V // L Unit light vector // N Unit surface normal // V Unit view vector // // j = piss // Fr = Fresnel // lambert = KaIa + Kd(N * Lj)Ij // blinnPhong = lambert + Ks((H * Hj) ^ Ns)Ij // // Notes: Clara.io only usees 0 and 1, maya always exports 4, blender can export 1, 3, 6 public enum IlluminationModel { case colour // Kd only case lambert case blinnPhong case reflectionRaytrace // + Ir = (intensity of reflection map) + (ray trace) case transparentGlassReflectionRaytrace // + Ir = (glass) + (intensity of reflection map) + (raytrace) case reflectionRaytraceFresnel // Fr(Lj * Hj, Ks, Ns)Ij + Fr(N * V, Ks, Ns)Ir case transparentRefractionReflectionRaytrace // + Ir + (1 - Ks)TfIt case transparentRefractionReflectionRaytraceFresnel // Fr(Lj * Hj, Ks, Ns)Ij + Fr(N * V, Ks, Ns)Ir case reflection // + Ir = (intensity of reflection map) case transparentGlassReflection // + Ir = (glass) + (intensity of reflection map) + (raytrace) case shadowOnly } public struct TextureMap { var path: String = .init() var flags: Flags = [ .blendHoriz, .blendVert ] var blendMul: Float = 1.0 var boost: Float = 0.0 // non-negative var imfChan: ImfChan = .l // decal ? .m : .l var mmBaseGain: (Float, Float) = (0.0, 1.0) var offset: Vec3f = .zero var scale: Vec3f = .one var turbulence: Vec3f = .zero var textureResolution: Int = 0 struct Flags: OptionSet { let rawValue: UInt8 static let blendHoriz: Self = Self(rawValue: 1 << 0) static let blendVert: Self = Self(rawValue: 1 << 1) static let colourCorrection: Self = Self(rawValue: 1 << 2) static let clamp: Self = Self(rawValue: 1 << 3) } enum ImfChan { case r, g, b, m, l, z } } }