1use std::borrow::Cow;
2use std::marker::PhantomData;
3
4use dear_imgui_rs::texture::TextureRef;
5
6use crate::item_style::{Plot3DItemStyle, plot3d_spec_with_style};
7use crate::{
8 Image3DFlags, Item3DFlags, Plot3DDataLayout, Plot3DUi, debug_before_plot, imvec2, imvec4, sys,
9};
10
11pub struct Image3DByAxesBuilder<'ui, 'tex> {
13 pub(crate) _ui: &'ui Plot3DUi<'ui>,
14 pub(crate) label: Cow<'ui, str>,
15 pub(crate) tex_ref: sys::ImTextureRef_c,
16 pub(crate) _texture: PhantomData<&'tex mut dear_imgui_rs::texture::TextureData>,
17 pub(crate) center: [f32; 3],
18 pub(crate) axis_u: [f32; 3],
19 pub(crate) axis_v: [f32; 3],
20 pub(crate) uv0: [f32; 2],
21 pub(crate) uv1: [f32; 2],
22 pub(crate) tint: [f32; 4],
23 pub(crate) flags: Image3DFlags,
24 pub(crate) item_flags: Item3DFlags,
25 pub(crate) style: Plot3DItemStyle,
26}
27
28impl<'ui, 'tex> Image3DByAxesBuilder<'ui, 'tex> {
29 pub fn uv(mut self, uv0: [f32; 2], uv1: [f32; 2]) -> Self {
30 self.uv0 = uv0;
31 self.uv1 = uv1;
32 self
33 }
34 pub fn tint(mut self, col: [f32; 4]) -> Self {
35 self.tint = col;
36 self
37 }
38 pub fn flags(mut self, flags: Image3DFlags) -> Self {
39 self.flags = flags;
40 self
41 }
42 pub fn plot(self) {
43 self._ui.bind();
44 let label = self.label.as_ref();
45 let label = if label.contains('\0') { "image" } else { label };
46 dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
47 debug_before_plot();
48 let spec = plot3d_spec_with_style(
49 self.style,
50 self.flags.bits() | self.item_flags.bits(),
51 Plot3DDataLayout::DEFAULT,
52 );
53 sys::ImPlot3D_PlotImage_Vec2(
54 label_ptr,
55 self.tex_ref,
56 sys::ImPlot3DPoint_c {
57 x: self.center[0] as f64,
58 y: self.center[1] as f64,
59 z: self.center[2] as f64,
60 },
61 sys::ImPlot3DPoint_c {
62 x: self.axis_u[0] as f64,
63 y: self.axis_u[1] as f64,
64 z: self.axis_u[2] as f64,
65 },
66 sys::ImPlot3DPoint_c {
67 x: self.axis_v[0] as f64,
68 y: self.axis_v[1] as f64,
69 z: self.axis_v[2] as f64,
70 },
71 imvec2(self.uv0[0], self.uv0[1]),
72 imvec2(self.uv1[0], self.uv1[1]),
73 imvec4(self.tint[0], self.tint[1], self.tint[2], self.tint[3]),
74 spec,
75 );
76 })
77 }
78}
79
80pub struct Image3DByCornersBuilder<'ui, 'tex> {
82 pub(crate) _ui: &'ui Plot3DUi<'ui>,
83 pub(crate) label: Cow<'ui, str>,
84 pub(crate) tex_ref: sys::ImTextureRef_c,
85 pub(crate) _texture: PhantomData<&'tex mut dear_imgui_rs::texture::TextureData>,
86 pub(crate) p0: [f32; 3],
87 pub(crate) p1: [f32; 3],
88 pub(crate) p2: [f32; 3],
89 pub(crate) p3: [f32; 3],
90 pub(crate) uv0: [f32; 2],
91 pub(crate) uv1: [f32; 2],
92 pub(crate) uv2: [f32; 2],
93 pub(crate) uv3: [f32; 2],
94 pub(crate) tint: [f32; 4],
95 pub(crate) flags: Image3DFlags,
96 pub(crate) item_flags: Item3DFlags,
97 pub(crate) style: Plot3DItemStyle,
98}
99
100impl<'ui, 'tex> Image3DByCornersBuilder<'ui, 'tex> {
101 pub fn uvs(mut self, uv0: [f32; 2], uv1: [f32; 2], uv2: [f32; 2], uv3: [f32; 2]) -> Self {
102 self.uv0 = uv0;
103 self.uv1 = uv1;
104 self.uv2 = uv2;
105 self.uv3 = uv3;
106 self
107 }
108 pub fn tint(mut self, col: [f32; 4]) -> Self {
109 self.tint = col;
110 self
111 }
112 pub fn flags(mut self, flags: Image3DFlags) -> Self {
113 self.flags = flags;
114 self
115 }
116 pub fn plot(self) {
117 self._ui.bind();
118 let label = self.label.as_ref();
119 let label = if label.contains('\0') { "image" } else { label };
120 dear_imgui_rs::with_scratch_txt(label, |label_ptr| unsafe {
121 debug_before_plot();
122 let spec = plot3d_spec_with_style(
123 self.style,
124 self.flags.bits() | self.item_flags.bits(),
125 Plot3DDataLayout::DEFAULT,
126 );
127 sys::ImPlot3D_PlotImage_Plot3DPoint(
128 label_ptr,
129 self.tex_ref,
130 sys::ImPlot3DPoint_c {
131 x: self.p0[0] as f64,
132 y: self.p0[1] as f64,
133 z: self.p0[2] as f64,
134 },
135 sys::ImPlot3DPoint_c {
136 x: self.p1[0] as f64,
137 y: self.p1[1] as f64,
138 z: self.p1[2] as f64,
139 },
140 sys::ImPlot3DPoint_c {
141 x: self.p2[0] as f64,
142 y: self.p2[1] as f64,
143 z: self.p2[2] as f64,
144 },
145 sys::ImPlot3DPoint_c {
146 x: self.p3[0] as f64,
147 y: self.p3[1] as f64,
148 z: self.p3[2] as f64,
149 },
150 imvec2(self.uv0[0], self.uv0[1]),
151 imvec2(self.uv1[0], self.uv1[1]),
152 imvec2(self.uv2[0], self.uv2[1]),
153 imvec2(self.uv3[0], self.uv3[1]),
154 imvec4(self.tint[0], self.tint[1], self.tint[2], self.tint[3]),
155 spec,
156 );
157 })
158 }
159}
160
161impl<'ui> Plot3DUi<'ui> {
162 pub fn image_by_axes<'tex, T: Into<TextureRef<'tex>>>(
164 &'ui self,
165 label: impl Into<Cow<'ui, str>>,
166 tex: T,
167 center: [f32; 3],
168 axis_u: [f32; 3],
169 axis_v: [f32; 3],
170 ) -> Image3DByAxesBuilder<'ui, 'tex> {
171 self.bind();
172 let tr = tex.into().raw();
173 let tex_ref = sys::ImTextureRef_c {
174 _TexData: tr._TexData as *mut sys::ImTextureData,
175 _TexID: tr._TexID as sys::ImTextureID,
176 };
177 debug_before_plot();
178 Image3DByAxesBuilder {
179 _ui: self,
180 label: label.into(),
181 tex_ref,
182 _texture: PhantomData,
183 center,
184 axis_u,
185 axis_v,
186 uv0: [0.0, 0.0],
187 uv1: [1.0, 1.0],
188 tint: [1.0, 1.0, 1.0, 1.0],
189 flags: Image3DFlags::NONE,
190 item_flags: Item3DFlags::NONE,
191 style: Plot3DItemStyle::default(),
192 }
193 }
194
195 pub fn image_by_corners<'tex, T: Into<TextureRef<'tex>>>(
197 &'ui self,
198 label: impl Into<Cow<'ui, str>>,
199 tex: T,
200 p0: [f32; 3],
201 p1: [f32; 3],
202 p2: [f32; 3],
203 p3: [f32; 3],
204 ) -> Image3DByCornersBuilder<'ui, 'tex> {
205 self.bind();
206 let tr = tex.into().raw();
207 let tex_ref = sys::ImTextureRef_c {
208 _TexData: tr._TexData as *mut sys::ImTextureData,
209 _TexID: tr._TexID as sys::ImTextureID,
210 };
211 debug_before_plot();
212 Image3DByCornersBuilder {
213 _ui: self,
214 label: label.into(),
215 tex_ref,
216 _texture: PhantomData,
217 p0,
218 p1,
219 p2,
220 p3,
221 uv0: [0.0, 0.0],
222 uv1: [1.0, 0.0],
223 uv2: [1.0, 1.0],
224 uv3: [0.0, 1.0],
225 tint: [1.0, 1.0, 1.0, 1.0],
226 flags: Image3DFlags::NONE,
227 item_flags: Item3DFlags::NONE,
228 style: Plot3DItemStyle::default(),
229 }
230 }
231}