1use cgmath::{Vector2, Vector3, Vector4};
2
3use buffer::Buffer;
4use device::Device;
5use geometry::Geometry;
6use sys::*;
7use {BufferType, CurveType, Format, GeometryType};
8
9pub struct LinearCurve<'a> {
10 device: &'a Device,
11 pub(crate) handle: RTCGeometry,
12 pub vertex_buffer: Buffer<'a, Vector4<f32>>,
13 pub index_buffer: Buffer<'a, u32>,
14 pub flag_buffer: Buffer<'a, u32>,
15 pub normal_buffer: Option<Buffer<'a, Vector3<f32>>>,
16}
17
18impl<'a> LinearCurve<'a> {
19 pub fn flat(
20 device: &'a Device,
21 num_segments: usize,
22 num_verts: usize,
23 use_normals: bool,
24 ) -> LinearCurve<'a> {
25 LinearCurve::unanimated(
26 device,
27 num_segments,
28 num_verts,
29 CurveType::Flat,
30 use_normals,
31 )
32 }
33 pub fn round(
34 device: &'a Device,
35 num_segments: usize,
36 num_verts: usize,
37 use_normals: bool,
38 ) -> LinearCurve<'a> {
39 LinearCurve::unanimated(
40 device,
41 num_segments,
42 num_verts,
43 CurveType::Round,
44 use_normals,
45 )
46 }
47 pub fn cone(
48 device: &'a Device,
49 num_segments: usize,
50 num_verts: usize,
51 use_normals: bool,
52 ) -> LinearCurve<'a> {
53 LinearCurve::unanimated(
54 device,
55 num_segments,
56 num_verts,
57 CurveType::Cone,
58 use_normals,
59 )
60 }
61 fn unanimated(
62 device: &'a Device,
63 num_segments: usize,
64 num_verts: usize,
65 curve_type: CurveType,
66 use_normals: bool,
67 ) -> LinearCurve<'a> {
68 let h: RTCGeometry;
69 match curve_type {
70 CurveType::Cone => {
71 h = unsafe { rtcNewGeometry(device.handle, GeometryType::CONE_LINEAR_CURVE) }
72 }
73 CurveType::Round => {
74 h = unsafe { rtcNewGeometry(device.handle, GeometryType::ROUND_LINEAR_CURVE) }
75 }
76 _ => h = unsafe { rtcNewGeometry(device.handle, GeometryType::FLAT_LINEAR_CURVE) },
77 };
78 let mut vertex_buffer = Buffer::new(device, num_verts);
79 let mut index_buffer = Buffer::new(device, num_segments);
80 let mut flag_buffer = Buffer::new(device, num_segments);
81 let mut normal_buffer = None;
82
83 unsafe {
84 rtcSetGeometryBuffer(
85 h,
86 BufferType::VERTEX,
87 0,
88 Format::FLOAT4,
89 vertex_buffer.handle,
90 0,
91 16,
92 num_verts,
93 );
94 vertex_buffer.set_attachment(h, BufferType::VERTEX, 0);
95
96 rtcSetGeometryBuffer(
97 h,
98 BufferType::INDEX,
99 0,
100 Format::UINT,
101 index_buffer.handle,
102 0,
103 4,
104 num_segments,
105 );
106 index_buffer.set_attachment(h, BufferType::INDEX, 0);
107
108 rtcSetGeometryBuffer(
109 h,
110 BufferType::FLAGS,
111 0,
112 Format::UCHAR,
113 flag_buffer.handle,
114 0,
115 1,
116 num_verts,
117 );
118 flag_buffer.set_attachment(h, BufferType::FLAGS, 0);
119
120 if use_normals {
121 let mut temp_normal_buffer = Buffer::new(device, num_verts);
122 rtcSetGeometryBuffer(
123 h,
124 BufferType::NORMAL,
125 0,
126 Format::FLOAT3,
127 temp_normal_buffer.handle,
128 0,
129 12,
130 num_verts,
131 );
132 temp_normal_buffer.set_attachment(h, BufferType::NORMAL, 0);
133 normal_buffer = Some(temp_normal_buffer);
134 };
135 }
136
137 LinearCurve {
138 device: device,
139 handle: h,
140 vertex_buffer: vertex_buffer,
141 index_buffer: index_buffer,
142 flag_buffer: flag_buffer,
143 normal_buffer: normal_buffer,
144 }
145 }
146}
147
148unsafe impl<'a> Sync for LinearCurve<'a> {}