render the model
This commit is contained in:
parent
184f9550d9
commit
db18de85ad
8
Cargo.lock
generated
8
Cargo.lock
generated
|
|
@ -156,9 +156,9 @@ checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "bytemuck"
|
||||||
version = "1.24.0"
|
version = "1.25.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4"
|
checksum = "95832e849adfb21180ccb6826a99da14e5d266ae5c2e668e1602cf234f153797"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck_derive",
|
"bytemuck_derive",
|
||||||
]
|
]
|
||||||
|
|
@ -505,6 +505,9 @@ name = "glam"
|
||||||
version = "0.30.10"
|
version = "0.30.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "19fc433e8437a212d1b6f1e68c7824af3aed907da60afa994e7f542d18d12aa9"
|
checksum = "19fc433e8437a212d1b6f1e68c7824af3aed907da60afa994e7f542d18d12aa9"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glow"
|
name = "glow"
|
||||||
|
|
@ -624,6 +627,7 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
|
||||||
name = "hyperboloid"
|
name = "hyperboloid"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
"glam",
|
"glam",
|
||||||
"pollster",
|
"pollster",
|
||||||
"wgpu",
|
"wgpu",
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,8 @@ debug = false
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
glam = { version = "0.30.9" }
|
bytemuck = { version = "1.25.2", features = ["derive"] }
|
||||||
|
glam = { version = "0.30.9", features = ["bytemuck"] }
|
||||||
pollster = "0.4.0"
|
pollster = "0.4.0"
|
||||||
wgpu = "27.0.1"
|
wgpu = "27.0.1"
|
||||||
winit = "0.30.12"
|
winit = "0.30.12"
|
||||||
|
|
|
||||||
47
src/camera.rs
Normal file
47
src/camera.rs
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
use glam::{Mat4, Vec3, vec3};
|
||||||
|
|
||||||
|
/// A camera always directed at the origin.
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct OrbitalCamera {
|
||||||
|
/// Horizontal position (angle), in radians from +X towards +Y.
|
||||||
|
pub position_yaw: f32,
|
||||||
|
|
||||||
|
/// Vertical position (angle), in radians from XY plane towards +Z.
|
||||||
|
pub position_pitch: f32,
|
||||||
|
|
||||||
|
/// Distance from the origin.
|
||||||
|
pub distance: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OrbitalCamera {
|
||||||
|
pub fn position(&self) -> Vec3 {
|
||||||
|
let (y, x) = self.position_yaw.sin_cos();
|
||||||
|
let (z, xy) = self.position_pitch.sin_cos();
|
||||||
|
self.distance * vec3(xy * x, xy * y, z)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn direction(&self) -> Vec3 {
|
||||||
|
let (y, x) = self.position_yaw.sin_cos();
|
||||||
|
let (z, xy) = self.position_pitch.sin_cos();
|
||||||
|
-vec3(xy * x, xy * y, z)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn transform(&self) -> Mat4 {
|
||||||
|
// for yaw=0, pitch=0:
|
||||||
|
// X -> -Z
|
||||||
|
// Y -> -X
|
||||||
|
// Z -> Y
|
||||||
|
Mat4::from_translation(vec3(0., 0., self.distance))
|
||||||
|
* Mat4::from_cols_array_2d(&[
|
||||||
|
[0., 0., -1., 0.],
|
||||||
|
[-1., 0., 0., 0.],
|
||||||
|
[0., 1., 0., 0.],
|
||||||
|
[0., 0., 0., 1.],
|
||||||
|
]) * Mat4::from_euler(
|
||||||
|
glam::EulerRot::ZYZ,
|
||||||
|
0.,
|
||||||
|
self.position_pitch,
|
||||||
|
-self.position_yaw,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
72
src/lib.rs
72
src/lib.rs
|
|
@ -1,22 +1,56 @@
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
use glam::{UVec2, Vec4, vec4};
|
use glam::{Mat4, UVec2, Vec4, vec4};
|
||||||
|
|
||||||
|
mod camera;
|
||||||
mod mesh;
|
mod mesh;
|
||||||
|
mod render;
|
||||||
|
|
||||||
const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth16Unorm;
|
const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth16Unorm;
|
||||||
const OUTPUT_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8UnormSrgb;
|
const OUTPUT_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8UnormSrgb;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct ShapeArgs {
|
||||||
|
pub sides: u32,
|
||||||
|
pub layers_up: u32,
|
||||||
|
pub layers_down: u32,
|
||||||
|
pub base_diameter: f32,
|
||||||
|
pub height: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ShapeArgs {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
sides: 24,
|
||||||
|
layers_up: 6,
|
||||||
|
layers_down: 6,
|
||||||
|
base_diameter: 36.0,
|
||||||
|
height: 120.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct RedrawArgs {
|
pub struct RedrawArgs {
|
||||||
|
pub shape: ShapeArgs,
|
||||||
pub background: Vec4,
|
pub background: Vec4,
|
||||||
|
pub camera_yaw: f32,
|
||||||
|
pub camera_pitch: f32,
|
||||||
|
pub light_yaw: f32,
|
||||||
|
pub light_pitch: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for RedrawArgs {
|
impl Default for RedrawArgs {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
shape: ShapeArgs::default(),
|
||||||
background: vec4(0.05, 0.20, 0.85, 1.00),
|
background: vec4(0.05, 0.20, 0.85, 1.00),
|
||||||
|
camera_yaw: std::f32::consts::FRAC_PI_2,
|
||||||
|
camera_pitch: std::f32::consts::FRAC_PI_3,
|
||||||
|
light_yaw: 0.,
|
||||||
|
light_pitch: 2. * std::f32::consts::FRAC_PI_3,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -33,6 +67,8 @@ pub struct Core {
|
||||||
surface: wgpu::Surface<'static>,
|
surface: wgpu::Surface<'static>,
|
||||||
|
|
||||||
depth: wgpu::Texture,
|
depth: wgpu::Texture,
|
||||||
|
|
||||||
|
pipeline: render::Pipeline,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Core {
|
impl Core {
|
||||||
|
|
@ -48,21 +84,40 @@ impl Core {
|
||||||
|
|
||||||
Self::configure_surface(&surface, &device, pixel_size);
|
Self::configure_surface(&surface, &device, pixel_size);
|
||||||
|
|
||||||
|
let pipeline = render::Pipeline::new(&device);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
device,
|
device,
|
||||||
queue,
|
queue,
|
||||||
surface,
|
surface,
|
||||||
depth,
|
depth,
|
||||||
|
pipeline,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self, output: &wgpu::Texture, args: &RedrawArgs) {
|
fn render(&self, output: &wgpu::Texture, args: &RedrawArgs) {
|
||||||
|
let mesh = mesh::generate();
|
||||||
|
let mesh = faceted_mesh(&mesh);
|
||||||
|
let mesh = render::Mesh::new(&self.device, &mesh);
|
||||||
|
|
||||||
let aspect = {
|
let aspect = {
|
||||||
let size = output.size();
|
let size = output.size();
|
||||||
let w = size.width as f32;
|
let w = size.width as f32;
|
||||||
let h = size.height as f32;
|
let h = size.height as f32;
|
||||||
w / h
|
w / h
|
||||||
};
|
};
|
||||||
|
let camera = camera::OrbitalCamera {
|
||||||
|
position_yaw: args.camera_yaw,
|
||||||
|
position_pitch: args.camera_pitch,
|
||||||
|
distance: 5. * args.shape.base_diameter,
|
||||||
|
};
|
||||||
|
let perspective = Mat4::perspective_lh(std::f32::consts::FRAC_PI_3, aspect, 1e1, 1e3);
|
||||||
|
self.pipeline.set_look(
|
||||||
|
&self.queue,
|
||||||
|
render::LookParams {
|
||||||
|
m: perspective * camera.transform(),
|
||||||
|
},
|
||||||
|
);
|
||||||
self.queue.submit([]); // flush buffer updates
|
self.queue.submit([]); // flush buffer updates
|
||||||
|
|
||||||
let view = output.create_view(&wgpu::TextureViewDescriptor::default());
|
let view = output.create_view(&wgpu::TextureViewDescriptor::default());
|
||||||
|
|
@ -98,6 +153,8 @@ impl Core {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
self.pipeline.render(&mut pass, [&mesh]);
|
||||||
|
|
||||||
drop(pass);
|
drop(pass);
|
||||||
self.queue.submit(std::iter::once(encoder.finish()));
|
self.queue.submit(std::iter::once(encoder.finish()));
|
||||||
}
|
}
|
||||||
|
|
@ -177,3 +234,16 @@ pub async fn init_gpu_inner<E: Error + 'static>(
|
||||||
surface,
|
surface,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn faceted_mesh(mesh: &mesh::Mesh) -> Vec<render::Vertex> {
|
||||||
|
let mut ret = Vec::new();
|
||||||
|
for face in &mesh.faces {
|
||||||
|
let face = face.map(|index| mesh.vertices[index]);
|
||||||
|
let u = face[1] - face[0];
|
||||||
|
let v = face[2] - face[0];
|
||||||
|
let normal = u.cross(v).normalize();
|
||||||
|
let face = face.map(|position| render::Vertex { position, normal });
|
||||||
|
ret.extend(face);
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
|
||||||
27
src/mesh.wgsl
Normal file
27
src/mesh.wgsl
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
struct LookParams {
|
||||||
|
m: mat4x4f,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Vertex {
|
||||||
|
@location(0) position: vec3f,
|
||||||
|
@location(1) normal: vec3f,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Varying {
|
||||||
|
@builtin(position) screen: vec4f,
|
||||||
|
@location(0) normal: vec3f,
|
||||||
|
}
|
||||||
|
|
||||||
|
@group(0) @binding(0) var<uniform> look: LookParams;
|
||||||
|
|
||||||
|
@vertex
|
||||||
|
fn on_vertex(in: Vertex) -> Varying {
|
||||||
|
let pos = look.m * vec4f(in.position, 1.0);
|
||||||
|
let normal = in.normal;
|
||||||
|
return Varying(pos, normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
@fragment
|
||||||
|
fn on_fragment(in: Varying) -> @location(0) vec4f {
|
||||||
|
return vec4f(0.5 + 0.5 * in.normal, 1.0);
|
||||||
|
}
|
||||||
148
src/render.rs
Normal file
148
src/render.rs
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
use std::mem::offset_of;
|
||||||
|
|
||||||
|
use bytemuck::{Pod, Zeroable, bytes_of, cast_slice};
|
||||||
|
use glam::{Mat4, Vec3};
|
||||||
|
use wgpu::util::DeviceExt as _;
|
||||||
|
|
||||||
|
use crate::{DEPTH_FORMAT, OUTPUT_FORMAT};
|
||||||
|
|
||||||
|
static MESH_SHADER: &str = include_str!("mesh.wgsl");
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Pod, Zeroable)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct LookParams {
|
||||||
|
pub m: Mat4,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct Vertex {
|
||||||
|
pub position: Vec3,
|
||||||
|
pub normal: Vec3,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Mesh {
|
||||||
|
vertex_buffer: wgpu::Buffer,
|
||||||
|
vertex_count: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mesh {
|
||||||
|
pub fn new(device: &wgpu::Device, vertices: &[Vertex]) -> Self {
|
||||||
|
let vertex_count = vertices.len().try_into().expect("too many vertices");
|
||||||
|
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
|
label: None,
|
||||||
|
usage: wgpu::BufferUsages::VERTEX,
|
||||||
|
contents: cast_slice(vertices),
|
||||||
|
});
|
||||||
|
Self {
|
||||||
|
vertex_buffer,
|
||||||
|
vertex_count,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Pipeline {
|
||||||
|
look_buf: wgpu::Buffer,
|
||||||
|
bindings: wgpu::BindGroup,
|
||||||
|
pipeline: wgpu::RenderPipeline,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Pipeline {
|
||||||
|
pub fn new(device: &wgpu::Device) -> Self {
|
||||||
|
let look_buf = device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
|
label: None,
|
||||||
|
size: size_of::<LookParams>() as u64,
|
||||||
|
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||||
|
mapped_at_creation: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
|
label: None,
|
||||||
|
source: wgpu::ShaderSource::Wgsl(MESH_SHADER.into()),
|
||||||
|
});
|
||||||
|
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
|
label: None,
|
||||||
|
layout: None,
|
||||||
|
vertex: wgpu::VertexState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: None,
|
||||||
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
|
buffers: &[wgpu::VertexBufferLayout {
|
||||||
|
array_stride: size_of::<Vertex>() as u64,
|
||||||
|
step_mode: wgpu::VertexStepMode::Vertex,
|
||||||
|
attributes: &[
|
||||||
|
wgpu::VertexAttribute {
|
||||||
|
shader_location: 0,
|
||||||
|
offset: offset_of!(Vertex, position) as u64,
|
||||||
|
format: wgpu::VertexFormat::Float32x3,
|
||||||
|
},
|
||||||
|
wgpu::VertexAttribute {
|
||||||
|
shader_location: 1,
|
||||||
|
offset: offset_of!(Vertex, normal) as u64,
|
||||||
|
format: wgpu::VertexFormat::Float32x3,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
primitive: wgpu::PrimitiveState {
|
||||||
|
topology: wgpu::PrimitiveTopology::TriangleList,
|
||||||
|
// cull_mode: Some(wgpu::Face::Front),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
|
format: DEPTH_FORMAT,
|
||||||
|
depth_write_enabled: true,
|
||||||
|
depth_compare: wgpu::CompareFunction::LessEqual,
|
||||||
|
stencil: wgpu::StencilState::default(),
|
||||||
|
bias: wgpu::DepthBiasState::default(),
|
||||||
|
}),
|
||||||
|
multisample: wgpu::MultisampleState {
|
||||||
|
count: 1,
|
||||||
|
mask: !0,
|
||||||
|
alpha_to_coverage_enabled: false,
|
||||||
|
},
|
||||||
|
fragment: Some(wgpu::FragmentState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: None,
|
||||||
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
|
targets: &[Some(wgpu::ColorTargetState {
|
||||||
|
format: OUTPUT_FORMAT,
|
||||||
|
blend: Some(wgpu::BlendState::REPLACE),
|
||||||
|
write_mask: wgpu::ColorWrites::ALL,
|
||||||
|
})],
|
||||||
|
}),
|
||||||
|
multiview: None,
|
||||||
|
cache: None,
|
||||||
|
});
|
||||||
|
let bindings = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
label: None,
|
||||||
|
layout: &pipeline.get_bind_group_layout(0),
|
||||||
|
entries: &[wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: look_buf.as_entire_binding(),
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
Self {
|
||||||
|
look_buf,
|
||||||
|
bindings,
|
||||||
|
pipeline,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_look(&self, queue: &wgpu::Queue, look: LookParams) {
|
||||||
|
queue.write_buffer(&self.look_buf, 0, bytes_of(&look));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render<'a>(
|
||||||
|
&self,
|
||||||
|
pass: &mut wgpu::RenderPass,
|
||||||
|
meshes: impl IntoIterator<Item = &'a Mesh>,
|
||||||
|
) {
|
||||||
|
pass.set_pipeline(&self.pipeline);
|
||||||
|
pass.set_bind_group(0, &self.bindings, &[]);
|
||||||
|
for mesh in meshes {
|
||||||
|
pass.set_vertex_buffer(0, mesh.vertex_buffer.slice(..));
|
||||||
|
pass.draw(0..mesh.vertex_count, 0..1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,11 +11,25 @@ struct alignas(16) Vec4 {
|
||||||
namespace ffi {
|
namespace ffi {
|
||||||
struct Core;
|
struct Core;
|
||||||
|
|
||||||
|
struct ShapeArgs {
|
||||||
|
std::uint32_t sides;
|
||||||
|
std::uint32_t layers_up;
|
||||||
|
std::uint32_t layers_down;
|
||||||
|
float base_diameter;
|
||||||
|
float height;
|
||||||
|
};
|
||||||
|
|
||||||
struct RedrawArgs {
|
struct RedrawArgs {
|
||||||
|
ShapeArgs shape;
|
||||||
Vec4 background;
|
Vec4 background;
|
||||||
|
float camera_yaw;
|
||||||
|
float camera_pitch;
|
||||||
|
float light_yaw;
|
||||||
|
float light_pitch;
|
||||||
};
|
};
|
||||||
} // namespace ffi
|
} // namespace ffi
|
||||||
|
|
||||||
|
using ffi::ShapeArgs;
|
||||||
using ffi::RedrawArgs;
|
using ffi::RedrawArgs;
|
||||||
|
|
||||||
class MutCore {
|
class MutCore {
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,20 @@ Hyperboloid::~Hyperboloid() = default;
|
||||||
|
|
||||||
void Hyperboloid::updateView() {
|
void Hyperboloid::updateView() {
|
||||||
const auto color = m_ui->inBackground->color();
|
const auto color = m_ui->inBackground->color();
|
||||||
RedrawArgs args{
|
const ShapeArgs shape {
|
||||||
|
.sides = (std::uint32_t)m_ui->sides->value(),
|
||||||
|
.layers_up = (std::uint32_t)m_ui->layersUp->value(),
|
||||||
|
.layers_down = (std::uint32_t)m_ui->layersDown->value(),
|
||||||
|
.base_diameter = (float)m_ui->dia->value(),
|
||||||
|
.height = (float)m_ui->height->value(),
|
||||||
|
};
|
||||||
|
const RedrawArgs args{
|
||||||
|
.shape = shape,
|
||||||
.background = { color.redF(), color.greenF(), color.blueF(), 1.00 },
|
.background = { color.redF(), color.greenF(), color.blueF(), 1.00 },
|
||||||
|
.camera_yaw = qDegreesToRadians((float)m_ui->camYaw->value()),
|
||||||
|
.camera_pitch = qDegreesToRadians((float)m_ui->camPitch->value()),
|
||||||
|
.light_yaw = 0.0,
|
||||||
|
.light_pitch = qDegreesToRadians((float)m_ui->lightPitch->value()),
|
||||||
};
|
};
|
||||||
m_ui->viewport->setView(args);
|
m_ui->viewport->setView(args);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,223 @@
|
||||||
</attribute>
|
</attribute>
|
||||||
<widget class="QWidget" name="dockWidgetContents">
|
<widget class="QWidget" name="dockWidgetContents">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Camera</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Yaw</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSlider" name="camYaw">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-180</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>180</number>
|
||||||
|
</property>
|
||||||
|
<property name="pageStep">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>45</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Pitch</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSlider" name="camPitch">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-90</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>90</number>
|
||||||
|
</property>
|
||||||
|
<property name="pageStep">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>30</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="title">
|
||||||
|
<string>Light</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Pitch</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSlider" name="lightPitch">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-90</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>90</number>
|
||||||
|
</property>
|
||||||
|
<property name="pageStep">
|
||||||
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>60</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
|
<property name="title">
|
||||||
|
<string>Shape</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Sides</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="sides">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>120</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>24</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>Layers up</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="layersUp">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Layers down</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="layersDown">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>11</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_4">
|
||||||
|
<property name="title">
|
||||||
|
<string>Size</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_8">
|
||||||
|
<property name="text">
|
||||||
|
<string>Base diameter</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDoubleSpinBox" name="dia">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> mm</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>4.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>100.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="stepType">
|
||||||
|
<enum>QAbstractSpinBox::AdaptiveDecimalStepType</enum>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>36.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_9">
|
||||||
|
<property name="text">
|
||||||
|
<string>Height</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDoubleSpinBox" name="height">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> mm</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>4.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>500.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>120.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_5">
|
||||||
|
<property name="title">
|
||||||
|
<string>Appearance</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
|
@ -51,13 +268,16 @@
|
||||||
<widget class="KColorCombo" name="inBackground">
|
<widget class="KColorCombo" name="inBackground">
|
||||||
<property name="color">
|
<property name="color">
|
||||||
<color>
|
<color>
|
||||||
<red>25</red>
|
<red>85</red>
|
||||||
<green>220</green>
|
<green>170</green>
|
||||||
<blue>0</blue>
|
<blue>255</blue>
|
||||||
</color>
|
</color>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
|
@ -97,8 +317,8 @@
|
||||||
<slot>updateView()</slot>
|
<slot>updateView()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>1531</x>
|
<x>1585</x>
|
||||||
<y>115</y>
|
<y>803</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>799</x>
|
<x>799</x>
|
||||||
|
|
@ -106,6 +326,134 @@
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>camYaw</sender>
|
||||||
|
<signal>valueChanged(int)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1520</x>
|
||||||
|
<y>142</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>1449</x>
|
||||||
|
<y>133</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>camPitch</sender>
|
||||||
|
<signal>valueChanged(int)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1550</x>
|
||||||
|
<y>192</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>1447</x>
|
||||||
|
<y>198</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>lightPitch</sender>
|
||||||
|
<signal>valueChanged(int)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1565</x>
|
||||||
|
<y>286</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>1445</x>
|
||||||
|
<y>265</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>sides</sender>
|
||||||
|
<signal>valueChanged(int)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1521</x>
|
||||||
|
<y>370</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>1448</x>
|
||||||
|
<y>378</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>layersUp</sender>
|
||||||
|
<signal>valueChanged(int)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1490</x>
|
||||||
|
<y>436</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>1446</x>
|
||||||
|
<y>441</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>layersDown</sender>
|
||||||
|
<signal>valueChanged(int)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1478</x>
|
||||||
|
<y>513</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>1446</x>
|
||||||
|
<y>515</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>dia</sender>
|
||||||
|
<signal>valueChanged(double)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1472</x>
|
||||||
|
<y>611</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>1446</x>
|
||||||
|
<y>629</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>height</sender>
|
||||||
|
<signal>valueChanged(double)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1476</x>
|
||||||
|
<y>686</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>1446</x>
|
||||||
|
<y>686</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
</connections>
|
</connections>
|
||||||
<slots>
|
<slots>
|
||||||
<slot>updateView()</slot>
|
<slot>updateView()</slot>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user