1use std::ffi::c_void;
6use std::ptr::NonNull;
7
8use mtl_foundation::{Referencing, UInteger};
9use mtl_sys::{msg_send_0, msg_send_1, sel};
10
11use crate::Buffer;
12use crate::enums::{AttributeFormat, CurveBasis, CurveEndCaps, CurveType, IndexType};
13
14pub struct AccelerationStructureCurveGeometryDescriptor(pub(crate) NonNull<c_void>);
15
16impl AccelerationStructureCurveGeometryDescriptor {
17 pub fn new() -> Option<Self> {
21 unsafe {
22 let class = mtl_sys::Class::get("MTLAccelerationStructureCurveGeometryDescriptor")?;
23 let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
24 if ptr.is_null() {
25 return None;
26 }
27 let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
28 Self::from_raw(ptr)
29 }
30 }
31
32 #[inline]
38 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
39 NonNull::new(ptr).map(Self)
40 }
41
42 #[inline]
44 pub fn as_raw(&self) -> *mut c_void {
45 self.0.as_ptr()
46 }
47
48 #[inline]
52 pub fn allow_duplicate_intersection_function_invocation(&self) -> bool {
53 unsafe {
54 msg_send_0(
55 self.as_ptr(),
56 sel!(allowDuplicateIntersectionFunctionInvocation),
57 )
58 }
59 }
60
61 #[inline]
63 pub fn set_allow_duplicate_intersection_function_invocation(&self, allow: bool) {
64 unsafe {
65 msg_send_1::<(), bool>(
66 self.as_ptr(),
67 sel!(setAllowDuplicateIntersectionFunctionInvocation:),
68 allow,
69 );
70 }
71 }
72
73 #[inline]
75 pub fn intersection_function_table_offset(&self) -> UInteger {
76 unsafe { msg_send_0(self.as_ptr(), sel!(intersectionFunctionTableOffset)) }
77 }
78
79 #[inline]
81 pub fn set_intersection_function_table_offset(&self, offset: UInteger) {
82 unsafe {
83 msg_send_1::<(), UInteger>(
84 self.as_ptr(),
85 sel!(setIntersectionFunctionTableOffset:),
86 offset,
87 );
88 }
89 }
90
91 #[inline]
93 pub fn opaque(&self) -> bool {
94 unsafe { msg_send_0(self.as_ptr(), sel!(opaque)) }
95 }
96
97 #[inline]
99 pub fn set_opaque(&self, opaque: bool) {
100 unsafe {
101 msg_send_1::<(), bool>(self.as_ptr(), sel!(setOpaque:), opaque);
102 }
103 }
104
105 pub fn label(&self) -> Option<String> {
107 unsafe {
108 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(label));
109 if ptr.is_null() {
110 return None;
111 }
112 let utf8_ptr: *const std::ffi::c_char =
113 mtl_sys::msg_send_0(ptr as *const c_void, sel!(UTF8String));
114 if utf8_ptr.is_null() {
115 return None;
116 }
117 let c_str = std::ffi::CStr::from_ptr(utf8_ptr);
118 Some(c_str.to_string_lossy().into_owned())
119 }
120 }
121
122 pub fn set_label(&self, label: &str) {
124 if let Some(ns_label) = mtl_foundation::String::from_str(label) {
125 unsafe {
126 msg_send_1::<(), *const c_void>(self.as_ptr(), sel!(setLabel:), ns_label.as_ptr());
127 }
128 }
129 }
130
131 pub fn primitive_data_buffer(&self) -> Option<Buffer> {
133 unsafe {
134 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(primitiveDataBuffer));
135 if ptr.is_null() {
136 return None;
137 }
138 let _: *mut c_void = msg_send_0(ptr, sel!(retain));
139 Buffer::from_raw(ptr)
140 }
141 }
142
143 pub fn set_primitive_data_buffer(&self, buffer: Option<&Buffer>) {
145 unsafe {
146 msg_send_1::<(), *const c_void>(
147 self.as_ptr(),
148 sel!(setPrimitiveDataBuffer:),
149 buffer.map_or(std::ptr::null(), |b| b.as_ptr()),
150 );
151 }
152 }
153
154 #[inline]
156 pub fn primitive_data_buffer_offset(&self) -> UInteger {
157 unsafe { msg_send_0(self.as_ptr(), sel!(primitiveDataBufferOffset)) }
158 }
159
160 #[inline]
162 pub fn set_primitive_data_buffer_offset(&self, offset: UInteger) {
163 unsafe {
164 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setPrimitiveDataBufferOffset:), offset);
165 }
166 }
167
168 #[inline]
170 pub fn primitive_data_element_size(&self) -> UInteger {
171 unsafe { msg_send_0(self.as_ptr(), sel!(primitiveDataElementSize)) }
172 }
173
174 #[inline]
176 pub fn set_primitive_data_element_size(&self, size: UInteger) {
177 unsafe {
178 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setPrimitiveDataElementSize:), size);
179 }
180 }
181
182 #[inline]
184 pub fn primitive_data_stride(&self) -> UInteger {
185 unsafe { msg_send_0(self.as_ptr(), sel!(primitiveDataStride)) }
186 }
187
188 #[inline]
190 pub fn set_primitive_data_stride(&self, stride: UInteger) {
191 unsafe {
192 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setPrimitiveDataStride:), stride);
193 }
194 }
195
196 pub fn control_point_buffer(&self) -> Option<Buffer> {
202 unsafe {
203 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(controlPointBuffer));
204 if ptr.is_null() {
205 return None;
206 }
207 let _: *mut c_void = msg_send_0(ptr, sel!(retain));
208 Buffer::from_raw(ptr)
209 }
210 }
211
212 pub fn set_control_point_buffer(&self, buffer: Option<&Buffer>) {
216 unsafe {
217 msg_send_1::<(), *const c_void>(
218 self.as_ptr(),
219 sel!(setControlPointBuffer:),
220 buffer.map_or(std::ptr::null(), |b| b.as_ptr()),
221 );
222 }
223 }
224
225 #[inline]
229 pub fn control_point_buffer_offset(&self) -> UInteger {
230 unsafe { msg_send_0(self.as_ptr(), sel!(controlPointBufferOffset)) }
231 }
232
233 #[inline]
237 pub fn set_control_point_buffer_offset(&self, offset: UInteger) {
238 unsafe {
239 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setControlPointBufferOffset:), offset);
240 }
241 }
242
243 #[inline]
247 pub fn control_point_count(&self) -> UInteger {
248 unsafe { msg_send_0(self.as_ptr(), sel!(controlPointCount)) }
249 }
250
251 #[inline]
255 pub fn set_control_point_count(&self, count: UInteger) {
256 unsafe {
257 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setControlPointCount:), count);
258 }
259 }
260
261 #[inline]
265 pub fn control_point_format(&self) -> AttributeFormat {
266 unsafe { msg_send_0(self.as_ptr(), sel!(controlPointFormat)) }
267 }
268
269 #[inline]
273 pub fn set_control_point_format(&self, format: AttributeFormat) {
274 unsafe {
275 msg_send_1::<(), AttributeFormat>(self.as_ptr(), sel!(setControlPointFormat:), format);
276 }
277 }
278
279 #[inline]
283 pub fn control_point_stride(&self) -> UInteger {
284 unsafe { msg_send_0(self.as_ptr(), sel!(controlPointStride)) }
285 }
286
287 #[inline]
291 pub fn set_control_point_stride(&self, stride: UInteger) {
292 unsafe {
293 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setControlPointStride:), stride);
294 }
295 }
296
297 #[inline]
301 pub fn curve_basis(&self) -> CurveBasis {
302 unsafe { msg_send_0(self.as_ptr(), sel!(curveBasis)) }
303 }
304
305 #[inline]
309 pub fn set_curve_basis(&self, basis: CurveBasis) {
310 unsafe {
311 msg_send_1::<(), CurveBasis>(self.as_ptr(), sel!(setCurveBasis:), basis);
312 }
313 }
314
315 #[inline]
319 pub fn curve_end_caps(&self) -> CurveEndCaps {
320 unsafe { msg_send_0(self.as_ptr(), sel!(curveEndCaps)) }
321 }
322
323 #[inline]
327 pub fn set_curve_end_caps(&self, end_caps: CurveEndCaps) {
328 unsafe {
329 msg_send_1::<(), CurveEndCaps>(self.as_ptr(), sel!(setCurveEndCaps:), end_caps);
330 }
331 }
332
333 #[inline]
337 pub fn curve_type(&self) -> CurveType {
338 unsafe { msg_send_0(self.as_ptr(), sel!(curveType)) }
339 }
340
341 #[inline]
345 pub fn set_curve_type(&self, curve_type: CurveType) {
346 unsafe {
347 msg_send_1::<(), CurveType>(self.as_ptr(), sel!(setCurveType:), curve_type);
348 }
349 }
350
351 pub fn index_buffer(&self) -> Option<Buffer> {
355 unsafe {
356 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(indexBuffer));
357 if ptr.is_null() {
358 return None;
359 }
360 let _: *mut c_void = msg_send_0(ptr, sel!(retain));
361 Buffer::from_raw(ptr)
362 }
363 }
364
365 pub fn set_index_buffer(&self, buffer: Option<&Buffer>) {
369 unsafe {
370 msg_send_1::<(), *const c_void>(
371 self.as_ptr(),
372 sel!(setIndexBuffer:),
373 buffer.map_or(std::ptr::null(), |b| b.as_ptr()),
374 );
375 }
376 }
377
378 #[inline]
382 pub fn index_buffer_offset(&self) -> UInteger {
383 unsafe { msg_send_0(self.as_ptr(), sel!(indexBufferOffset)) }
384 }
385
386 #[inline]
390 pub fn set_index_buffer_offset(&self, offset: UInteger) {
391 unsafe {
392 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setIndexBufferOffset:), offset);
393 }
394 }
395
396 #[inline]
400 pub fn index_type(&self) -> IndexType {
401 unsafe { msg_send_0(self.as_ptr(), sel!(indexType)) }
402 }
403
404 #[inline]
408 pub fn set_index_type(&self, index_type: IndexType) {
409 unsafe {
410 msg_send_1::<(), IndexType>(self.as_ptr(), sel!(setIndexType:), index_type);
411 }
412 }
413
414 pub fn radius_buffer(&self) -> Option<Buffer> {
418 unsafe {
419 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(radiusBuffer));
420 if ptr.is_null() {
421 return None;
422 }
423 let _: *mut c_void = msg_send_0(ptr, sel!(retain));
424 Buffer::from_raw(ptr)
425 }
426 }
427
428 pub fn set_radius_buffer(&self, buffer: Option<&Buffer>) {
432 unsafe {
433 msg_send_1::<(), *const c_void>(
434 self.as_ptr(),
435 sel!(setRadiusBuffer:),
436 buffer.map_or(std::ptr::null(), |b| b.as_ptr()),
437 );
438 }
439 }
440
441 #[inline]
445 pub fn radius_buffer_offset(&self) -> UInteger {
446 unsafe { msg_send_0(self.as_ptr(), sel!(radiusBufferOffset)) }
447 }
448
449 #[inline]
453 pub fn set_radius_buffer_offset(&self, offset: UInteger) {
454 unsafe {
455 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setRadiusBufferOffset:), offset);
456 }
457 }
458
459 #[inline]
463 pub fn radius_format(&self) -> AttributeFormat {
464 unsafe { msg_send_0(self.as_ptr(), sel!(radiusFormat)) }
465 }
466
467 #[inline]
471 pub fn set_radius_format(&self, format: AttributeFormat) {
472 unsafe {
473 msg_send_1::<(), AttributeFormat>(self.as_ptr(), sel!(setRadiusFormat:), format);
474 }
475 }
476
477 #[inline]
481 pub fn radius_stride(&self) -> UInteger {
482 unsafe { msg_send_0(self.as_ptr(), sel!(radiusStride)) }
483 }
484
485 #[inline]
489 pub fn set_radius_stride(&self, stride: UInteger) {
490 unsafe {
491 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setRadiusStride:), stride);
492 }
493 }
494
495 #[inline]
499 pub fn segment_control_point_count(&self) -> UInteger {
500 unsafe { msg_send_0(self.as_ptr(), sel!(segmentControlPointCount)) }
501 }
502
503 #[inline]
507 pub fn set_segment_control_point_count(&self, count: UInteger) {
508 unsafe {
509 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setSegmentControlPointCount:), count);
510 }
511 }
512
513 #[inline]
517 pub fn segment_count(&self) -> UInteger {
518 unsafe { msg_send_0(self.as_ptr(), sel!(segmentCount)) }
519 }
520
521 #[inline]
525 pub fn set_segment_count(&self, count: UInteger) {
526 unsafe {
527 msg_send_1::<(), UInteger>(self.as_ptr(), sel!(setSegmentCount:), count);
528 }
529 }
530}
531
532impl Default for AccelerationStructureCurveGeometryDescriptor {
533 fn default() -> Self {
534 Self::new().expect("failed to create curve geometry descriptor")
535 }
536}
537
538impl Clone for AccelerationStructureCurveGeometryDescriptor {
539 fn clone(&self) -> Self {
540 unsafe {
541 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(copy));
542 Self::from_raw(ptr).expect("failed to copy curve geometry descriptor")
543 }
544 }
545}
546
547impl Drop for AccelerationStructureCurveGeometryDescriptor {
548 fn drop(&mut self) {
549 unsafe {
550 msg_send_0::<()>(self.as_ptr(), sel!(release));
551 }
552 }
553}
554
555impl Referencing for AccelerationStructureCurveGeometryDescriptor {
556 #[inline]
557 fn as_ptr(&self) -> *const c_void {
558 self.0.as_ptr()
559 }
560}
561
562unsafe impl Send for AccelerationStructureCurveGeometryDescriptor {}
563unsafe impl Sync for AccelerationStructureCurveGeometryDescriptor {}