Skip to content

Commit

Permalink
Add ability write splat files (PLY and .splat) in addition to reading…
Browse files Browse the repository at this point in the history
… them, as well as writing general-purpose .ply

- Add PLYIO.PLYWriter (with both binary and ascii support)
- Add SplatIO.SceneWriter protocol and implementations: DotSplatSceneWriter, SplatPLYSceneWriter
- Add SplatConverter CLI package
  • Loading branch information
scier committed Jul 18, 2024
1 parent 07661f9 commit 20336eb
Show file tree
Hide file tree
Showing 29 changed files with 2,239 additions and 688 deletions.
39 changes: 3 additions & 36 deletions MetalSplatter/Sources/SplatRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -464,43 +464,10 @@ public class SplatRenderer {

extension SplatRenderer.Splat {
init(_ splat: SplatScenePoint) {
let scale: SIMD3<Float>
switch splat.scale {
case let .exponent(x, y, z):
scale = SIMD3(exp(x), exp(y), exp(z))
case let .linearFloat(x, y, z):
scale = SIMD3(x, y, z)
}

let rotation = splat.rotation.normalized

var color: SIMD3<Float>
switch splat.color {
case let .sphericalHarmonic(r, g, b, _), let .firstOrderSphericalHarmonic(r, g, b):
let SH_C0: Float = 0.28209479177387814
color = SIMD3(x: max(0, min(1, 0.5 + SH_C0 * r)),
y: max(0, min(1, 0.5 + SH_C0 * g)),
z: max(0, min(1, 0.5 + SH_C0 * b)))
case let .linearFloat256(r, g, b):
color = SIMD3(x: r / 255.0, y: g / 255.0, z: b / 255.0)
case let .linearUInt8(r, g, b):
color = SIMD3(x: Float(r) / 255.0, y: Float(g) / 255.0, z: Float(b) / 255.0)
}

let opacity: Float
switch splat.opacity {
case let .logitFloat(value):
opacity = 1 / (1 + exp(-value))
case let .linearFloat(value):
opacity = value
case let .linearUInt8(value):
opacity = Float(value) / 255.0
}

self.init(position: splat.position,
color: .init(color.sRGBToLinear, opacity),
scale: scale,
rotation: rotation)
color: .init(splat.color.asLinearFloat.sRGBToLinear, splat.opacity.asLinearFloat),
scale: splat.scale.asLinearFloat,
rotation: splat.rotation.normalized)
}

init(position: SIMD3<Float>,
Expand Down
66 changes: 63 additions & 3 deletions PLYIO/Sources/DataConvertible.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Foundation

public protocol DataConvertible {
// MARK: Reading from DataProtocol

// Assumes that data.count - offset >= byteWidth
init<D: DataProtocol>(_ data: D, from offset: D.Index, bigEndian: Bool)
// Assumes that data.count >= byteWidth
Expand All @@ -10,6 +12,12 @@ public protocol DataConvertible {
static func array<D: DataProtocol>(_ data: D, from offset: D.Index, count: Int, bigEndian: Bool) -> [Self]
// Assumes that data.count >= count * byteWidth
static func array<D: DataProtocol>(_ data: D, count: Int, bigEndian: Bool) -> [Self]

// MARK: Writing to MutableDataProtocol

func append<D: MutableDataProtocol>(to data: inout D, bigEndian: Bool)

static func append<D: MutableDataProtocol>(_ values: [Self], to data: inout D, bigEndian: Bool)
}

fileprivate enum DataConvertibleConstants {
Expand All @@ -18,6 +26,8 @@ fileprivate enum DataConvertibleConstants {

public extension BinaryInteger
where Self: DataConvertible, Self: EndianConvertible {
// MARK: Reading from DataProtocol

init<D: DataProtocol>(_ data: D, from offset: D.Index, bigEndian: Bool) {
var value: Self = .zero
withUnsafeMutableBytes(of: &value) {
Expand Down Expand Up @@ -63,10 +73,36 @@ where Self: DataConvertible, Self: EndianConvertible {
}
return values
}

// MARK: Writing to MutableDataProtocol

func append<D: MutableDataProtocol>(to data: inout D, bigEndian: Bool) {
let value = (bigEndian == DataConvertibleConstants.isBigEndian) ? self : byteSwapped
withUnsafeBytes(of: value) {
data.append(contentsOf: $0)
}
}

static func append<D: MutableDataProtocol>(_ values: [Self], to data: inout D, bigEndian: Bool) {
if bigEndian == DataConvertibleConstants.isBigEndian {
withUnsafeBytes(of: values) {
data.append(contentsOf: $0)
}
} else {
for value in values {
let byteSwapped = value.byteSwapped
withUnsafeBytes(of: byteSwapped) {
data.append(contentsOf: $0)
}
}
}
}
}

public extension BinaryFloatingPoint
where Self: DataConvertible, Self: BitPatternConvertible, Self.BitPattern: ZeroProviding, Self.BitPattern: EndianConvertible {
// MARK: Reading from DataProtocol

init<D: DataProtocol>(_ data: D, from offset: D.Index, bigEndian: Bool) {
if bigEndian == DataConvertibleConstants.isBigEndian {
self = .zero
Expand All @@ -83,7 +119,7 @@ where Self: DataConvertible, Self: BitPatternConvertible, Self.BitPattern: ZeroP
self = Self(bitPattern: value.byteSwapped)
}
}

init<D: DataProtocol>(_ data: D, bigEndian: Bool) {
if bigEndian == DataConvertibleConstants.isBigEndian {
self = .zero
Expand All @@ -100,7 +136,7 @@ where Self: DataConvertible, Self: BitPatternConvertible, Self.BitPattern: ZeroP
self = Self(bitPattern: value.byteSwapped)
}
}

static func array<D: DataProtocol>(_ data: D, from offset: D.Index, count: Int, bigEndian: Bool) -> [Self] {
var values: [Self] = Array(repeating: .zero, count: count)
values.withUnsafeMutableBytes {
Expand All @@ -114,7 +150,7 @@ where Self: DataConvertible, Self: BitPatternConvertible, Self.BitPattern: ZeroP
}
return values
}

static func array<D: DataProtocol>(_ data: D, count: Int, bigEndian: Bool) -> [Self] {
var values: [Self] = Array(repeating: .zero, count: count)
values.withUnsafeMutableBytes {
Expand All @@ -128,6 +164,30 @@ where Self: DataConvertible, Self: BitPatternConvertible, Self.BitPattern: ZeroP
}
return values
}

// MARK: Writing to MutableDataProtocol

func append<D: MutableDataProtocol>(to data: inout D, bigEndian: Bool) {
let value = (bigEndian == DataConvertibleConstants.isBigEndian) ? bitPattern : bitPattern.byteSwapped
withUnsafeBytes(of: value) {
data.append(contentsOf: $0)
}
}

static func append<D: MutableDataProtocol>(_ values: [Self], to data: inout D, bigEndian: Bool) {
if bigEndian == DataConvertibleConstants.isBigEndian {
withUnsafeBytes(of: values) {
data.append(contentsOf: $0)
}
} else {
for value in values {
let byteSwapped = value.bitPattern.byteSwapped
withUnsafeBytes(of: byteSwapped) {
data.append(contentsOf: $0)
}
}
}
}
}

extension Int8: DataConvertible {}
Expand Down
Loading

0 comments on commit 20336eb

Please sign in to comment.