IOS

[iOS] SIMD3

eigen96 2024. 2. 6. 00:10
728x90

현재 보고 있는 AR, 그래픽스 관련하여 3D모델의 위치를 추적하고 저장하는 과정에서 많이 보이는 타입이다.

 

 

예시

 

SIMD3는 단일 명령 다중 데이터(Single Instruction, Multiple Data, SIMD) 프로그래밍 모델을 따르는 벡터 타입으로,

세 개의 스칼라 값을 갖는 벡터를 표현한다.

struct SIMD3<Scalar> where Scalar : SIMDScalar

 

SIMD3는 제네릭 구조체로, Scalar 타입의 세 개의 요소를 갖는다.

이때, ScalarSIMDScalar 프로토콜을 준수해야 하며, 이는 주로 기본 수치 타입(int, float 등)을 의미한다.

연산자와 메서드

SIMD3 구조체는 연산자를 통해 벡터 간 연산을 지원한다.

예를 들어, &* 연산자는 두 벡터의 요소별 곱셈을 수행하며, 결과는 각 요소의 곱으로 구성된다.

이 연산은 Int16, UInt, UInt16, UInt32, UInt8, Int32, Int, Int64, Int8, UInt64 등 다양한 스칼라 타입에 대해 사용할 수 있다.

또한, &+=, &-=, .!=, .== 등의 연산자를 통해 요소별 덧셈, 뺄셈, 비교 등의 연산을 수행할 수 있습니다.

초기화

SIMD3는 세 개의 스칼라 값을 직접 전달하거나, 다른 벡터 타입으로부터 생성할 수 있다.

또한, 특정 스칼라 타입에 대해 제공되는 특수한 초기화 메서드를 사용할 수도 있다.

인스턴스 속성

  • var x, y, z: 각각 벡터의 첫 번째, 두 번째, 세 번째 요소에 접근할 수 있는 속성
  • var scalarCount: 벡터에 포함된 스칼라 값의 수를 반환

SIMD3는 다양한 프로토콜을 준수합니다. 예를 들어, Equatable, Hashable, SIMD 등의 프로토콜을 통해 벡터 간 비교, 해시 가능성, SIMD 연산 지원 등의 기능을 제공한다.

 

 

 

예제

 

struct SkeletonJoint{
    let name: String
    var position: SIMD3<Float>
}



let elbowJoint = SkeletonJoint(name: "elbow", position: SIMD3<Float>(x: 0.5, y: 0.5, z: 0.0))
let kneeJoint = SkeletonJoint(name: "knee", position: SIMD3<Float>(x: -0.5, y: -0.5, z: 0.0))

 



초기화 방법

1. 기본 초기화 -  모든 요소가 0인 벡터 생성:

   let vector = SIMD3<Float>()


2. 시퀀스에서 초기화 - 주어진 시퀀스의 요소를 사용하여 벡터 생성:

   let values: [Float] = [1.0, 2.0, 3.0]
   let vectorFromSequence = SIMD3<Float>(values)


3. SIMD2와 스칼라를 결합하여 초기화** - 두 요소 벡터와 하나의 스칼라 값을 결합:

   let xy = SIMD2<Float>(1.0, 2.0)
   let vectorFromSIMD2AndScalar = SIMD3<Float>(xy, 3.0)


4. 개별 요소에서 초기화 - 개별 스칼라 값으로 벡터 생성:

   let vectorFromElements = SIMD3<Float>(1.0, 2.0, 3.0)


5. 배열 리터럴에서 초기화 - 배열 리터럴을 사용한 벡터 생성:

   let vectorFromArrayLiteral: SIMD3<Float> = [1.0, 2.0, 3.0]


6. 반복 값으로 초기화 - 모든 요소가 동일한 값인 벡터 생성:

   let vectorRepeating = SIMD3<Float>(repeating: 1.0)


7. 개별 요소 명시적 초기화 - x, y, z 요소를 명시하여 벡터 생성:

   let vectorExplicit = SIMD3<Float>(x: 1.0, y: 2.0, z: 3.0)


인스턴스 변수 및 메서드 사용

- 요소 접근 및 수정:

  var vector = SIMD3<Float>(1.0, 2.0, 3.0)
  let x = vector.x // 1.0
  vector.y = 5.0   // 벡터는 이제 [1.0, 5.0, 3.0]입니다.


- 서브스크립트 접근:

  let z = vector[2] // 3.0
  vector[0] = 9.0   // 벡터는 이제 [9.0, 5.0, 3.0]입니다.


- 비교 연산:

let vectorA = SIMD3<Float>(1.0, 2.0, 3.0)
let vectorB = SIMD3<Float>(1.0, 5.0, 3.0)
let isEqual = vectorA == vectorB // false

 

728x90