• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

djeedai / bevy_hanabi / 14348872530

09 Apr 2025 04:18AM UTC coverage: 39.38% (-0.7%) from 40.116%
14348872530

Pull #444

github

web-flow
Merge 5f906b79b into 027286d2a
Pull Request #444: Make the number of particles to emit in a GPU event an expression instead of a constant.

0 of 3 new or added lines in 1 file covered. (0.0%)

139 existing lines in 8 files now uncovered.

3022 of 7674 relevant lines covered (39.38%)

17.34 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.91
/src/graph/mod.rs
1
//! Effect graph and language definition, including *expressions*.
2
//!
3
//! This module contains the elements used to build an _effect graph_, a fully
4
//! customizable description of a visual effect.
5
//!
6
//! The effect graph API is composed of two layers:
7
//! - The [**Expression API**] provides a micro-language to build shader
8
//!   expressions ([`Expr`]) via code. Those expressions are composed together
9
//!   into complex behaviors assigned to the input values of some modifiers.
10
//!   This enables complete customizing of the modifiers. This API is focused on
11
//!   runtime execution and asset serialization. It provides the user with a way
12
//!   to _indirectly_ write effect shaders without any knowledge about shaders,
13
//!   and with a framework which guarantees the shader code generated is
14
//!   correct.
15
//! - The [**Node API**] provides a higher-level API built on top of the
16
//!   Expression API. Its use is entirely optional. It defines a node graph
17
//!   ([`Graph`]), where each node ([`Node`]) represents an expression or a
18
//!   modifier. Nodes are linked together to implicitly build expressions. This
19
//!   API focuses on asset editing, with the explicit intent to be used to build
20
//!   a (visual) effect editor.
21
//!
22
//! # API status
23
//!
24
//! Currently effect graphs are not fully available yet; only some preview
25
//! elements exist.
26
//!
27
//! The Expression API already contains a good set of expressions, and some
28
//! modifiers have already been converted to accept expressions for their input
29
//! fields. Its generally in a reasonable shape for early adoption.
30
//!
31
//! The Node API contains a basic node and graph definition, which is entirely
32
//! experimental at this stage.
33
//!
34
//! We recommend starting to familiarize yourself with effect graphs, and
35
//! starting to port your code to use expressions ([`Expr`]), as the entire
36
//! library is moving in the direction of adopting effect graphs across the
37
//! board.
38
//!
39
//! [**Expression API**]: crate::graph::expr
40
//! [**Node API**]: crate::graph::node
41

42
use std::fmt::Debug;
43

44
use bevy::{
45
    math::{
46
        BVec2, BVec3, BVec4, FloatOrd, IVec2, IVec3, IVec4, Mat2, Mat3, Mat4, UVec2, UVec3, UVec4,
47
        Vec2, Vec3, Vec3A, Vec4,
48
    },
49
    reflect::Reflect,
50
};
51
use serde::{Deserialize, Serialize};
52

53
use crate::{MatrixType, ScalarType, ToWgslString, ValueType, VectorType};
54

55
pub mod expr;
56
pub mod node;
57

58
pub use expr::{
59
    AttributeExpr, BinaryOperator, BuiltInExpr, BuiltInOperator, EvalContext, Expr, ExprError,
60
    ExprHandle, ExprWriter, LiteralExpr, Module, PropertyExpr, UnaryOperator, WriterExpr,
61
};
62
pub use node::{
63
    AddNode, AttributeNode, DivNode, Graph, MulNode, Node, NormalizeNode, Slot, SlotDir, SlotId,
64
    SubNode, TimeNode,
65
};
66

67
/// Variant storage for a scalar value.
68
#[derive(Debug)]
69
#[non_exhaustive]
70
pub enum ScalarValueMut<'a> {
71
    /// Single `bool` value.
72
    Bool(&'a mut bool),
73
    /// Single `f32` value.
74
    Float(&'a mut f32),
75
    /// Single `i32` value.
76
    Int(&'a mut i32),
77
    /// Single `u32` value.
78
    Uint(&'a mut u32),
79
}
80

81
/// Variant storage for a single (scalar) value.
82
///
83
/// The value implements total equality and hashing. For [`ScalarValue::Float`],
84
/// the total equality is based on [`FloatOrd`]. Values of different types
85
/// compare inequally to each other, even if the values would be equal after
86
/// casting, and hash differently. To compare two [`ScalarValue`] taking into
87
/// account casting, use [`cast_eq()`].
88
///
89
/// [`cast_eq()`]: crate::graph::ScalarValue::cast_eq
90
#[derive(Debug, Clone, Copy, Reflect, Serialize, Deserialize)]
91
#[non_exhaustive] // f16 not supported yet
92
pub enum ScalarValue {
93
    /// Single `bool` value.
94
    Bool(bool),
95
    /// Single `f32` value.
96
    Float(f32),
97
    /// Single `i32` value.
98
    Int(i32),
99
    /// Single `u32` value.
100
    Uint(u32),
101
}
102

103
impl ScalarValue {
104
    /// The value `false` when a boolean value is stored internally.
105
    pub(crate) const BOOL_FALSE_STORAGE: u32 = 0u32;
106

107
    /// The value `true` when a boolean value is stored internally.
108
    pub(crate) const BOOL_TRUE_STORAGE: u32 = 0xFF_FF_FF_FFu32;
109

110
    /// The value `false` and `true` when a boolean value is stored internally.
111
    pub(crate) const BOOL_STORAGE: [u32; 2] = [Self::BOOL_FALSE_STORAGE, Self::BOOL_TRUE_STORAGE];
112

113
    /// Convert this value to a `bool` value.
114
    ///
115
    /// Any non-zero value converts to `true`, while a zero value converts to
116
    /// `false`.
117
    pub fn as_bool(&self) -> bool {
8✔
118
        match *self {
8✔
119
            ScalarValue::Bool(b) => b,
2✔
120
            ScalarValue::Float(f) => f != 0f32,
2✔
121
            ScalarValue::Int(i) => i != 0,
2✔
122
            ScalarValue::Uint(u) => u != 0,
2✔
123
        }
124
    }
125

126
    /// Convert this value to a floating-point value.
127
    ///
128
    /// Boolean values convert to 0 or 1. Numeric values are cast to `f32`.
129
    pub fn as_f32(&self) -> f32 {
8✔
130
        match *self {
8✔
131
            ScalarValue::Bool(b) => {
2✔
132
                if b {
2✔
133
                    1f32
1✔
134
                } else {
135
                    0f32
1✔
136
                }
137
            }
138
            ScalarValue::Float(f) => f,
2✔
139
            ScalarValue::Int(i) => i as f32,
2✔
140
            ScalarValue::Uint(u) => u as f32,
2✔
141
        }
142
    }
143

144
    /// Convert this value to an `i32` value.
145
    ///
146
    /// Boolean values convert to 0 or 1. Numeric values are cast to `i32`.
147
    pub fn as_i32(&self) -> i32 {
8✔
148
        match *self {
8✔
149
            ScalarValue::Bool(b) => {
2✔
150
                if b {
2✔
151
                    1i32
1✔
152
                } else {
153
                    0i32
1✔
154
                }
155
            }
156
            ScalarValue::Float(f) => f as i32,
2✔
157
            ScalarValue::Int(i) => i,
2✔
158
            ScalarValue::Uint(u) => u as i32,
2✔
159
        }
160
    }
161

162
    /// Convert this value to an `u32` value.
163
    ///
164
    /// Boolean values convert to 0 or 1. Numeric values are cast to `u32`.
165
    pub fn as_u32(&self) -> u32 {
8✔
166
        match *self {
8✔
167
            ScalarValue::Bool(b) => {
2✔
168
                if b {
2✔
169
                    1u32
1✔
170
                } else {
171
                    0u32
1✔
172
                }
173
            }
174
            ScalarValue::Float(f) => f as u32,
2✔
175
            ScalarValue::Int(i) => i as u32,
2✔
176
            ScalarValue::Uint(u) => u,
2✔
177
        }
178
    }
179

180
    /// Get the value as a binary blob ready for GPU upload.
181
    pub fn as_bytes(&self) -> &[u8] {
9✔
182
        match self {
9✔
183
            ScalarValue::Bool(_) => panic!("Cannot convert scalar bool to byte slice."),
×
184
            ScalarValue::Float(f) => bytemuck::cast_slice::<f32, u8>(std::slice::from_ref(f)),
3✔
185
            ScalarValue::Int(i) => bytemuck::cast_slice::<i32, u8>(std::slice::from_ref(i)),
3✔
186
            ScalarValue::Uint(u) => bytemuck::cast_slice::<u32, u8>(std::slice::from_ref(u)),
3✔
187
        }
188
    }
189

190
    /// Get the raw internal storage value representing this scalar value.
191
    ///
192
    /// Used internally for some conversion operations. The representation is
193
    /// not guaranteed to be stable.
194
    fn as_storage(&self) -> u32 {
9✔
195
        match self {
9✔
196
            ScalarValue::Bool(b) => Self::BOOL_STORAGE[*b as usize],
3✔
197
            ScalarValue::Float(f) => bytemuck::cast::<f32, u32>(*f),
3✔
198
            ScalarValue::Int(i) => bytemuck::cast::<i32, u32>(*i),
3✔
199
            ScalarValue::Uint(u) => *u,
×
200
        }
201
    }
202

203
    /// Get the scalar type of this value.
204
    pub fn scalar_type(&self) -> ScalarType {
963✔
205
        match self {
963✔
206
            ScalarValue::Bool(_) => ScalarType::Bool,
8✔
207
            ScalarValue::Float(_) => ScalarType::Float,
763✔
208
            ScalarValue::Int(_) => ScalarType::Int,
19✔
209
            ScalarValue::Uint(_) => ScalarType::Uint,
173✔
210
        }
211
    }
212

213
    /// Check equality with another value by casting the other value to this
214
    /// value's type.
215
    ///
216
    /// Floating point values ([`ScalarValue::Float`]) use [`FloatOrd`] for
217
    /// total equality.
218
    pub fn cast_eq(&self, other: &Self) -> bool {
32✔
219
        match *self {
32✔
220
            ScalarValue::Bool(b) => b == other.as_bool(),
8✔
221
            ScalarValue::Float(f) => FloatOrd(f) == FloatOrd(other.as_f32()),
8✔
222
            ScalarValue::Int(i) => i == other.as_i32(),
8✔
223
            ScalarValue::Uint(u) => u == other.as_u32(),
8✔
224
        }
225
    }
226

227
    // fn binary_op(&self, other: &Self, op: BinaryOperator) -> Self {
228
    //     match *self {
229
    //         ScalarValue::Bool(_) => panic!("Cannot apply binary operation to
230
    // boolean value."),         ScalarValue::Float(f) =>
231
    // ScalarValue::Float(op.apply_f32(f, other.as_f32())),
232
    //         ScalarValue::Int(i) => ScalarValue::Int(op.apply_i32(i,
233
    // other.as_i32())),         ScalarValue::Uint(u) =>
234
    // ScalarValue::Uint(op.apply_u32(u, other.as_u32())),     }
235
    // }
236
}
237

238
impl PartialEq for ScalarValue {
239
    fn eq(&self, other: &Self) -> bool {
64✔
240
        match *self {
64✔
241
            ScalarValue::Bool(b) => match *other {
10✔
242
                ScalarValue::Bool(b2) => b == b2,
4✔
243
                _ => false,
6✔
244
            },
245
            ScalarValue::Float(f) => match *other {
36✔
246
                ScalarValue::Float(f2) => FloatOrd(f) == FloatOrd(f2),
30✔
247
                _ => false,
6✔
248
            },
249
            ScalarValue::Int(i) => match *other {
9✔
250
                ScalarValue::Int(i2) => i == i2,
3✔
251
                _ => false,
6✔
252
            },
253
            ScalarValue::Uint(u) => match *other {
9✔
254
                ScalarValue::Uint(u2) => u == u2,
3✔
255
                _ => false,
6✔
256
            },
257
        }
258
    }
259
}
260

261
impl Eq for ScalarValue {}
262

263
impl std::hash::Hash for ScalarValue {
264
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
64✔
265
        // Hash some u8 to encode the enum variant, then the actual value
266
        match *self {
64✔
267
            ScalarValue::Bool(b) => {
16✔
268
                1_u8.hash(state);
16✔
269
                b.hash(state)
16✔
270
            }
271
            ScalarValue::Float(f) => {
16✔
272
                2_u8.hash(state);
16✔
273
                FloatOrd(f).hash(state);
16✔
274
            }
275
            ScalarValue::Int(i) => {
16✔
276
                3_u8.hash(state);
16✔
277
                i.hash(state);
16✔
278
            }
279
            ScalarValue::Uint(u) => {
16✔
280
                4_u8.hash(state);
16✔
281
                u.hash(state);
16✔
282
            }
283
        }
284
    }
285
}
286

287
impl ToWgslString for ScalarValue {
288
    fn to_wgsl_string(&self) -> String {
425✔
289
        match *self {
425✔
290
            ScalarValue::Bool(b) => b.to_wgsl_string(),
6✔
291
            ScalarValue::Float(f) => f.to_wgsl_string(),
399✔
292
            ScalarValue::Int(i) => i.to_wgsl_string(),
10✔
293
            ScalarValue::Uint(u) => u.to_wgsl_string(),
10✔
294
        }
295
    }
296
}
297

298
// impl BinaryOperation for ScalarValue {
299
//     fn apply(&self, other: &Self, op: BinaryOperator) -> Self {
300
//         match *self {
301
//             ScalarValue::Bool(_) => panic!("Cannot apply binary operation to
302
// boolean value."),             ScalarValue::Float(f) =>
303
// ScalarValue::Float(op.apply_f32(f, other.as_f32())),
304
// ScalarValue::Int(i) => ScalarValue::Int(op.apply_i32(i, other.as_i32())),
305
//             ScalarValue::Uint(u) => ScalarValue::Uint(op.apply_u32(u,
306
// other.as_u32())),         }
307
//     }
308
// }
309

310
impl From<bool> for ScalarValue {
311
    fn from(value: bool) -> Self {
12✔
312
        Self::Bool(value)
12✔
313
    }
314
}
315

316
impl From<f32> for ScalarValue {
317
    fn from(value: f32) -> Self {
84✔
318
        Self::Float(value)
84✔
319
    }
320
}
321

322
impl From<i32> for ScalarValue {
323
    fn from(value: i32) -> Self {
17✔
324
        Self::Int(value)
17✔
325
    }
326
}
327

328
impl From<u32> for ScalarValue {
329
    fn from(value: u32) -> Self {
16✔
330
        Self::Uint(value)
16✔
331
    }
332
}
333

334
/// Trait to convert the elements of a vector.
335
pub trait ElemType {
336
    /// The zero element of the type.
337
    const ZERO: Self;
338

339
    /// Get the N-th component of the vector given its raw storage.
340
    fn get_n<const N: usize>(storage: &[u32; 4]) -> Self;
341

342
    /// Get the given component of the vector given its raw storage.
343
    fn get(index: usize, storage: &[u32; 4]) -> Self;
344

345
    /// Get a slice of all the components of the vector given its raw storage.
346
    ///
347
    /// This is only valid for numeric types, and will panic for a boolean type.
348
    fn get_all(storage: &[u32; 4], count: usize) -> &[Self]
349
    where
350
        Self: Sized;
351

352
    /// Get a mutable reference to the given component of the vector from within
353
    /// its raw storage.
354
    fn get_mut(index: usize, storage: &mut [u32; 4]) -> &mut Self;
355
}
356

357
impl ElemType for bool {
358
    const ZERO: Self = false;
359

360
    fn get_n<const N: usize>(storage: &[u32; 4]) -> Self {
3✔
361
        storage[N] != 0
3✔
362
    }
363

364
    fn get(index: usize, storage: &[u32; 4]) -> Self {
×
365
        storage[index] != 0
×
366
    }
367

368
    fn get_all(_storage: &[u32; 4], _count: usize) -> &[Self] {
×
369
        panic!("Cannot get bool element type as slice.");
×
370
    }
371

372
    fn get_mut(_index: usize, _storage: &mut [u32; 4]) -> &mut Self {
×
373
        panic!("Cannot get bool element type as mutable reference.");
×
374
    }
375
}
376

377
impl ElemType for f32 {
378
    const ZERO: Self = 0f32;
379

380
    fn get_n<const N: usize>(storage: &[u32; 4]) -> Self {
322✔
381
        bytemuck::cast_slice::<u32, f32>(storage)[N]
322✔
382
    }
383

384
    fn get(index: usize, storage: &[u32; 4]) -> Self {
25✔
385
        bytemuck::cast_slice::<u32, f32>(storage)[index]
25✔
386
    }
387

388
    fn get_all(storage: &[u32; 4], count: usize) -> &[Self] {
×
389
        &bytemuck::cast_slice::<u32, f32>(storage)[..count]
×
390
    }
391

392
    fn get_mut(index: usize, storage: &mut [u32; 4]) -> &mut Self {
×
393
        bytemuck::cast_mut::<u32, f32>(&mut storage[index])
×
394
    }
395
}
396

397
impl ElemType for i32 {
398
    const ZERO: Self = 0i32;
399

400
    fn get_n<const N: usize>(storage: &[u32; 4]) -> Self {
2✔
401
        bytemuck::cast_slice::<u32, i32>(storage)[N]
2✔
402
    }
403

404
    fn get(index: usize, storage: &[u32; 4]) -> Self {
×
405
        bytemuck::cast_slice::<u32, i32>(storage)[index]
×
406
    }
407

408
    fn get_all(storage: &[u32; 4], count: usize) -> &[Self] {
×
409
        &bytemuck::cast_slice::<u32, i32>(storage)[..count]
×
410
    }
411

412
    fn get_mut(index: usize, storage: &mut [u32; 4]) -> &mut Self {
×
413
        bytemuck::cast_mut::<u32, i32>(&mut storage[index])
×
414
    }
415
}
416

417
impl ElemType for u32 {
418
    const ZERO: Self = 0u32;
419

420
    fn get_n<const N: usize>(storage: &[u32; 4]) -> Self {
×
421
        storage[N]
×
422
    }
423

424
    fn get(index: usize, storage: &[u32; 4]) -> Self {
×
425
        storage[index]
×
426
    }
427

428
    fn get_all(storage: &[u32; 4], count: usize) -> &[Self] {
×
429
        &storage[..count]
×
430
    }
431

432
    fn get_mut(index: usize, storage: &mut [u32; 4]) -> &mut Self {
×
433
        &mut storage[index]
×
434
    }
435
}
436

437
/// Variant storage for a vector value.
438
#[derive(Debug, Clone, Copy, Reflect, Serialize, Deserialize)]
439
#[serde(from = "VectorValueEnum", into = "VectorValueEnum")]
440
pub struct VectorValue {
441
    vector_type: VectorType,
442
    storage: [u32; 4],
443
}
444

445
impl VectorValue {
446
    /// Workaround for `impl const From<BVec2>`.
447
    #[allow(unsafe_code)]
448
    pub const fn new_bvec2(value: BVec2) -> Self {
4✔
449
        Self {
450
            vector_type: VectorType::VEC2B,
451
            storage: [
4✔
452
                ScalarValue::BOOL_STORAGE[value.x as usize],
453
                ScalarValue::BOOL_STORAGE[value.y as usize],
454
                0u32,
455
                0u32,
456
            ],
457
        }
458
    }
459

460
    /// Workaround for `impl const From<BVec3>`.
461
    #[allow(unsafe_code)]
462
    pub const fn new_bvec3(value: BVec3) -> Self {
2✔
463
        Self {
464
            vector_type: VectorType::VEC3B,
465
            storage: [
2✔
466
                ScalarValue::BOOL_STORAGE[value.x as usize],
467
                ScalarValue::BOOL_STORAGE[value.y as usize],
468
                ScalarValue::BOOL_STORAGE[value.z as usize],
469
                0u32,
470
            ],
471
        }
472
    }
473

474
    /// Workaround for `impl const From<BVec4>`.
475
    #[allow(unsafe_code)]
476
    pub const fn new_bvec4(value: BVec4) -> Self {
2✔
477
        Self {
478
            vector_type: VectorType::VEC4B,
479
            storage: [
2✔
480
                ScalarValue::BOOL_STORAGE[value.x as usize],
481
                ScalarValue::BOOL_STORAGE[value.y as usize],
482
                ScalarValue::BOOL_STORAGE[value.z as usize],
483
                ScalarValue::BOOL_STORAGE[value.w as usize],
484
            ],
485
        }
486
    }
487

488
    /// Workaround for `impl const From<Vec2>`.
489
    #[allow(unsafe_code, clippy::transmute_float_to_int)] // to_bits() can't be const
490
    pub const fn new_vec2(value: Vec2) -> Self {
9✔
491
        Self {
492
            vector_type: VectorType::VEC2F,
493
            storage: [
9✔
494
                unsafe { std::mem::transmute::<f32, u32>(value.x) },
495
                unsafe { std::mem::transmute::<f32, u32>(value.y) },
496
                0u32,
497
                0u32,
498
            ],
499
        }
500
    }
501

502
    /// Workaround for `impl const From<Vec3>`.
503
    #[allow(unsafe_code, clippy::transmute_float_to_int)] // to_bits() can't be const
504
    pub const fn new_vec3(value: Vec3) -> Self {
11✔
505
        Self {
506
            vector_type: VectorType::VEC3F,
507
            storage: [
11✔
508
                unsafe { std::mem::transmute::<f32, u32>(value.x) },
509
                unsafe { std::mem::transmute::<f32, u32>(value.y) },
510
                unsafe { std::mem::transmute::<f32, u32>(value.z) },
511
                0u32,
512
            ],
513
        }
514
    }
515

516
    /// Workaround for `impl const From<Vec4>`.
517
    #[allow(unsafe_code)]
518
    pub const fn new_vec4(value: Vec4) -> Self {
8✔
519
        Self {
520
            vector_type: VectorType::VEC4F,
521
            storage: unsafe { std::mem::transmute::<[f32; 4], [u32; 4]>(value.to_array()) },
8✔
522
        }
523
    }
524

525
    /// Workaround for `impl const From<IVec2>`.
526
    #[allow(unsafe_code)]
527
    pub const fn new_ivec2(value: IVec2) -> Self {
6✔
528
        Self {
529
            vector_type: VectorType::VEC2I,
530
            storage: [
6✔
531
                unsafe { std::mem::transmute::<i32, u32>(value.x) },
532
                unsafe { std::mem::transmute::<i32, u32>(value.y) },
533
                0u32,
534
                0u32,
535
            ],
536
        }
537
    }
538

539
    /// Workaround for `impl const From<IVec3>`.
540
    #[allow(unsafe_code)]
541
    pub const fn new_ivec3(value: IVec3) -> Self {
5✔
542
        Self {
543
            vector_type: VectorType::VEC3I,
544
            storage: [
5✔
545
                unsafe { std::mem::transmute::<i32, u32>(value.x) },
546
                unsafe { std::mem::transmute::<i32, u32>(value.y) },
547
                unsafe { std::mem::transmute::<i32, u32>(value.z) },
548
                0u32,
549
            ],
550
        }
551
    }
552

553
    /// Workaround for `impl const From<IVec4>`.
554
    #[allow(unsafe_code)]
555
    pub const fn new_ivec4(value: IVec4) -> Self {
5✔
556
        Self {
557
            vector_type: VectorType::VEC4I,
558
            storage: unsafe { std::mem::transmute::<[i32; 4], [u32; 4]>(value.to_array()) },
5✔
559
        }
560
    }
561

562
    /// Workaround for `impl const From<UVec2>`.
563
    pub const fn new_uvec2(v: UVec2) -> Self {
7✔
564
        Self {
565
            vector_type: VectorType::VEC2U,
566
            storage: [v.x, v.y, 0, 0],
7✔
567
        }
568
    }
569

570
    /// Workaround for `impl const From<UVec3>`.
571
    pub const fn new_uvec3(v: UVec3) -> Self {
6✔
572
        Self {
573
            vector_type: VectorType::VEC3U,
574
            storage: [v.x, v.y, v.z, 0],
6✔
575
        }
576
    }
577

578
    /// Workaround for `impl const From<UVec4>`.
579
    pub const fn new_uvec4(v: UVec4) -> Self {
6✔
580
        Self {
581
            vector_type: VectorType::VEC4U,
582
            storage: v.to_array(),
6✔
583
        }
584
    }
585

586
    /// Create a new vector by "splatting" a scalar value into all components.
587
    ///
588
    /// # Panics
589
    ///
590
    /// Panics if the component `count` is not 2/3/4.
591
    pub fn splat(value: &ScalarValue, count: u8) -> Self {
9✔
592
        let raw_value = value.as_storage();
9✔
593
        Self {
594
            vector_type: VectorType::new(value.scalar_type(), count),
9✔
595
            storage: [raw_value; 4],
9✔
596
        }
597
    }
598

599
    /// Get the type of the vector elements.
600
    ///
601
    /// This is a convenience shortcut for `self.vector_type().elem_type()`.
602
    pub fn elem_type(&self) -> ScalarType {
505✔
603
        self.vector_type.elem_type()
505✔
604
    }
605

606
    /// Get the vector type itself.
607
    pub fn vector_type(&self) -> VectorType {
1,684✔
608
        self.vector_type
1,684✔
609
    }
610

611
    /// Get the scalar value of the N-th element of the vector.
612
    pub fn value_n<const N: usize>(&self) -> ScalarValue {
327✔
613
        match self.elem_type() {
327✔
614
            ScalarType::Bool => ScalarValue::Bool(self.get_n::<bool, N>()),
3✔
615
            ScalarType::Float => ScalarValue::Float(self.get_n::<f32, N>()),
322✔
616
            ScalarType::Int => ScalarValue::Int(self.get_n::<i32, N>()),
2✔
617
            ScalarType::Uint => ScalarValue::Uint(self.get_n::<u32, N>()),
×
618
        }
619
    }
620

621
    /// Get the scalar value of an element of the vector.
622
    pub fn value(&self, index: usize) -> ScalarValue {
×
623
        match self.elem_type() {
×
624
            ScalarType::Bool => ScalarValue::Bool(self.get::<bool>(index)),
×
625
            ScalarType::Float => ScalarValue::Float(self.get::<f32>(index)),
×
626
            ScalarType::Int => ScalarValue::Int(self.get::<i32>(index)),
×
627
            ScalarType::Uint => ScalarValue::Uint(self.get::<u32>(index)),
×
628
        }
629
    }
630

631
    /// Get the scalar value of an element of the vector.
632
    pub fn value_mut(&mut self, index: usize) -> ScalarValueMut {
×
633
        match self.elem_type() {
×
634
            ScalarType::Bool => ScalarValueMut::Bool(self.get_mut::<bool>(index)),
×
635
            ScalarType::Float => ScalarValueMut::Float(self.get_mut::<f32>(index)),
×
636
            ScalarType::Int => ScalarValueMut::Int(self.get_mut::<i32>(index)),
×
637
            ScalarType::Uint => ScalarValueMut::Uint(self.get_mut::<u32>(index)),
×
638
        }
639
    }
640

641
    /// Get the value of the N-th element of the vector.
642
    pub fn get_n<T: ElemType, const N: usize>(&self) -> T {
327✔
643
        if self.vector_type.count() > N {
327✔
644
            T::get_n::<N>(&self.storage)
327✔
645
        } else {
646
            T::ZERO
×
647
        }
648
    }
649

650
    /// Get the value of an element of the vector.
651
    pub fn get<T: ElemType>(&self, index: usize) -> T {
25✔
652
        if index < self.vector_type.count() {
25✔
653
            T::get(index, &self.storage)
25✔
654
        } else {
655
            T::ZERO
×
656
        }
657
    }
658

659
    /// Get the value of an element of the vector.
660
    fn get_mut<T: ElemType>(&mut self, index: usize) -> &mut T {
×
661
        assert!(index < self.vector_type.count());
×
662
        T::get_mut(index, &mut self.storage)
×
663
    }
664

665
    /// Get a slice of all the values of the vector.
666
    ///
667
    /// This is only valid for numeric types, and will panic for a boolean type.
668
    pub fn get_all<T: ElemType>(&self) -> &[T] {
×
669
        T::get_all(&self.storage, self.vector_type.count())
×
670
    }
671

672
    /// Cast this vector value to a [`BVec2`].
673
    ///
674
    /// # Panics
675
    ///
676
    /// Panics if the current vector type is not [`VectorType::VEC2B`].
677
    pub fn as_bvec2(&self) -> BVec2 {
2✔
678
        assert_eq!(self.vector_type, VectorType::VEC2B);
2✔
679
        BVec2::new(self.storage[0] != 0, self.storage[1] != 0)
2✔
680
    }
681

682
    /// Cast this vector value to a [`BVec3`].
683
    ///
684
    /// # Panics
685
    ///
686
    /// Panics if the current vector type is not [`VectorType::VEC3B`].
687
    pub fn as_bvec3(&self) -> BVec3 {
1✔
688
        assert_eq!(self.vector_type, VectorType::VEC3B);
1✔
689
        BVec3::new(
690
            self.storage[0] != 0,
1✔
691
            self.storage[1] != 0,
1✔
692
            self.storage[2] != 0,
1✔
693
        )
694
    }
695

696
    /// Cast this vector value to a [`BVec4`].
697
    ///
698
    /// # Panics
699
    ///
700
    /// Panics if the current vector type is not [`VectorType::VEC4B`].
701
    pub fn as_bvec4(&self) -> BVec4 {
1✔
702
        assert_eq!(self.vector_type, VectorType::VEC4B);
1✔
703
        BVec4::new(
704
            self.storage[0] != 0,
1✔
705
            self.storage[1] != 0,
1✔
706
            self.storage[2] != 0,
1✔
707
            self.storage[3] != 0,
1✔
708
        )
709
    }
710

711
    /// Cast this vector value to a [`Vec2`].
712
    ///
713
    /// # Panics
714
    ///
715
    /// Panics if the current vector type is not [`VectorType::VEC2F`].
716
    pub fn as_vec2(&self) -> Vec2 {
1✔
717
        assert_eq!(self.vector_type, VectorType::VEC2F);
1✔
718
        Vec2::from_slice(bytemuck::cast_slice::<u32, f32>(&self.storage))
1✔
719
    }
720

721
    /// Cast this vector value to a [`Vec3`].
722
    ///
723
    /// # Panics
724
    ///
725
    /// Panics if the current vector type is not [`VectorType::VEC3F`].
726
    pub fn as_vec3(&self) -> Vec3 {
3✔
727
        assert_eq!(self.vector_type, VectorType::VEC3F);
3✔
728
        Vec3::from_slice(bytemuck::cast_slice::<u32, f32>(&self.storage))
3✔
729
    }
730

731
    /// Cast this vector value to a [`Vec3A`].
732
    ///
733
    /// # Panics
734
    ///
735
    /// Panics if the current vector type is not [`VectorType::VEC3F`].
736
    pub fn as_vec3a(&self) -> Vec3A {
×
737
        assert_eq!(self.vector_type, VectorType::VEC3F);
×
738
        Vec3A::from_slice(bytemuck::cast_slice::<u32, f32>(&self.storage))
×
739
    }
740

741
    /// Cast this vector value to a [`Vec4`].
742
    ///
743
    /// # Panics
744
    ///
745
    /// Panics if the current vector type is not [`VectorType::VEC4F`].
746
    pub fn as_vec4(&self) -> Vec4 {
1✔
747
        assert_eq!(self.vector_type, VectorType::VEC4F);
1✔
748
        Vec4::from_slice(bytemuck::cast_slice::<u32, f32>(&self.storage))
1✔
749
    }
750

751
    /// Cast this vector value to a [`IVec2`].
752
    ///
753
    /// # Panics
754
    ///
755
    /// Panics if the current vector type is not [`VectorType::VEC2I`].
756
    pub fn as_ivec2(&self) -> IVec2 {
1✔
757
        assert_eq!(self.vector_type, VectorType::VEC2I);
1✔
758
        IVec2::from_slice(bytemuck::cast_slice::<u32, i32>(&self.storage))
1✔
759
    }
760

761
    /// Cast this vector value to a [`IVec3`].
762
    ///
763
    /// # Panics
764
    ///
765
    /// Panics if the current vector type is not [`VectorType::VEC3I`].
766
    pub fn as_ivec3(&self) -> IVec3 {
1✔
767
        assert_eq!(self.vector_type, VectorType::VEC3I);
1✔
768
        IVec3::from_slice(bytemuck::cast_slice::<u32, i32>(&self.storage))
1✔
769
    }
770

771
    /// Cast this vector value to a [`IVec4`].
772
    ///
773
    /// # Panics
774
    ///
775
    /// Panics if the current vector type is not [`VectorType::VEC4I`].
776
    pub fn as_ivec4(&self) -> IVec4 {
1✔
777
        assert_eq!(self.vector_type, VectorType::VEC4I);
1✔
778
        IVec4::from_slice(bytemuck::cast_slice::<u32, i32>(&self.storage))
1✔
779
    }
780

781
    /// Cast this vector value to a [`UVec2`].
782
    ///
783
    /// # Panics
784
    ///
785
    /// Panics if the current vector type is not [`VectorType::VEC2U`].
786
    pub fn as_uvec2(&self) -> UVec2 {
×
787
        assert_eq!(self.vector_type, VectorType::VEC2U);
×
788
        UVec2::from_slice(&self.storage)
×
789
    }
790

791
    /// Cast this vector value to a [`UVec3`].
792
    ///
793
    /// # Panics
794
    ///
795
    /// Panics if the current vector type is not [`VectorType::VEC3U`].
796
    pub fn as_uvec3(&self) -> UVec3 {
×
797
        assert_eq!(self.vector_type, VectorType::VEC3U);
×
798
        UVec3::from_slice(&self.storage)
×
799
    }
800

801
    /// Cast this vector value to a [`UVec4`].
802
    ///
803
    /// # Panics
804
    ///
805
    /// Panics if the current vector type is not [`VectorType::VEC4U`].
806
    pub fn as_uvec4(&self) -> UVec4 {
×
807
        assert_eq!(self.vector_type, VectorType::VEC4U);
×
808
        UVec4::from_slice(&self.storage)
×
809
    }
810

811
    /// Get the value as a binary blob ready for GPU upload.
812
    pub fn as_bytes(&self) -> &[u8] {
13✔
813
        let count = self.vector_type.count();
13✔
814
        bytemuck::cast_slice::<u32, u8>(&self.storage[..count])
13✔
815
    }
816

817
    /// Check equality with another value by casting the other value to this
818
    /// value's type.
819
    ///
820
    /// Floating point values ([`ScalarValue::Float`]) use [`FloatOrd`] for
821
    /// total equality.
822
    ///
823
    /// Vectors of different size always compare inequal (returns `false`).
824
    pub fn cast_eq(&self, other: &Self) -> bool {
16✔
825
        let count = self.vector_type().count();
16✔
826
        if count != other.vector_type().count() {
16✔
827
            return false;
×
828
        }
829
        match self.elem_type() {
16✔
830
            ScalarType::Bool => {
831
                let s = self.cast_bool();
4✔
832
                let o = other.cast_bool();
4✔
833
                s[..count] == o[..count]
4✔
834
            }
835
            ScalarType::Float => {
836
                let s = self.cast_f32();
4✔
837
                let o = other.cast_f32();
4✔
838
                s[..count] == o[..count]
4✔
839
            }
840
            ScalarType::Int => {
841
                let s = self.cast_i32();
4✔
842
                let o = other.cast_i32();
4✔
843
                s[..count] == o[..count]
4✔
844
            }
845
            ScalarType::Uint => {
846
                let s = self.cast_u32();
4✔
847
                let o = other.cast_u32();
4✔
848
                s[..count] == o[..count]
4✔
849
            }
850
        }
851
    }
852

853
    fn cast_bool(&self) -> [u32; 4] {
8✔
854
        match self.elem_type() {
8✔
855
            ScalarType::Bool => self.storage,
5✔
856
            ScalarType::Float => [
1✔
857
                ScalarValue::BOOL_STORAGE
1✔
858
                    [(bytemuck::cast::<u32, f32>(self.storage[0]) != 0.) as usize],
1✔
859
                ScalarValue::BOOL_STORAGE
1✔
860
                    [(bytemuck::cast::<u32, f32>(self.storage[1]) != 0.) as usize],
1✔
861
                ScalarValue::BOOL_STORAGE
1✔
862
                    [(bytemuck::cast::<u32, f32>(self.storage[2]) != 0.) as usize],
1✔
863
                ScalarValue::BOOL_STORAGE
1✔
864
                    [(bytemuck::cast::<u32, f32>(self.storage[3]) != 0.) as usize],
1✔
865
            ],
866
            ScalarType::Int => [
1✔
867
                ScalarValue::BOOL_STORAGE
1✔
868
                    [(bytemuck::cast::<u32, i32>(self.storage[0]) != 0) as usize],
1✔
869
                ScalarValue::BOOL_STORAGE
1✔
870
                    [(bytemuck::cast::<u32, i32>(self.storage[1]) != 0) as usize],
1✔
871
                ScalarValue::BOOL_STORAGE
1✔
872
                    [(bytemuck::cast::<u32, i32>(self.storage[2]) != 0) as usize],
1✔
873
                ScalarValue::BOOL_STORAGE
1✔
874
                    [(bytemuck::cast::<u32, i32>(self.storage[3]) != 0) as usize],
1✔
875
            ],
876
            ScalarType::Uint => [
1✔
877
                ScalarValue::BOOL_STORAGE[(self.storage[0] != 0) as usize],
1✔
878
                ScalarValue::BOOL_STORAGE[(self.storage[1] != 0) as usize],
1✔
879
                ScalarValue::BOOL_STORAGE[(self.storage[2] != 0) as usize],
1✔
880
                ScalarValue::BOOL_STORAGE[(self.storage[3] != 0) as usize],
1✔
881
            ],
882
        }
883
    }
884

885
    fn cast_f32(&self) -> [FloatOrd; 4] {
50✔
886
        match self.elem_type() {
50✔
887
            ScalarType::Bool => {
888
                let ft = [FloatOrd(0.), FloatOrd(1.)];
1✔
889
                [
890
                    ft[(self.storage[0] != 0) as usize],
1✔
891
                    ft[(self.storage[1] != 0) as usize],
1✔
892
                    ft[(self.storage[2] != 0) as usize],
1✔
893
                    ft[(self.storage[3] != 0) as usize],
1✔
894
                ]
895
            }
896
            ScalarType::Float => [
47✔
897
                FloatOrd(bytemuck::cast::<u32, f32>(self.storage[0])),
47✔
898
                FloatOrd(bytemuck::cast::<u32, f32>(self.storage[1])),
47✔
899
                FloatOrd(bytemuck::cast::<u32, f32>(self.storage[2])),
47✔
900
                FloatOrd(bytemuck::cast::<u32, f32>(self.storage[3])),
47✔
901
            ],
902
            ScalarType::Int => [
1✔
903
                FloatOrd(bytemuck::cast::<u32, i32>(self.storage[0]) as f32),
1✔
904
                FloatOrd(bytemuck::cast::<u32, i32>(self.storage[1]) as f32),
1✔
905
                FloatOrd(bytemuck::cast::<u32, i32>(self.storage[2]) as f32),
1✔
906
                FloatOrd(bytemuck::cast::<u32, i32>(self.storage[3]) as f32),
1✔
907
            ],
908
            ScalarType::Uint => [
1✔
909
                FloatOrd(self.storage[0] as f32),
1✔
910
                FloatOrd(self.storage[1] as f32),
1✔
911
                FloatOrd(self.storage[2] as f32),
1✔
912
                FloatOrd(self.storage[3] as f32),
1✔
913
            ],
914
        }
915
    }
916

917
    fn cast_i32(&self) -> [i32; 4] {
8✔
918
        match self.elem_type() {
8✔
919
            ScalarType::Bool => {
920
                let ft = [0, 1];
1✔
921
                [
922
                    ft[(self.storage[0] != 0) as usize],
1✔
923
                    ft[(self.storage[1] != 0) as usize],
1✔
924
                    ft[(self.storage[2] != 0) as usize],
1✔
925
                    ft[(self.storage[3] != 0) as usize],
1✔
926
                ]
927
            }
928
            ScalarType::Float => [
1✔
929
                bytemuck::cast::<u32, f32>(self.storage[0]) as i32,
1✔
930
                bytemuck::cast::<u32, f32>(self.storage[1]) as i32,
1✔
931
                bytemuck::cast::<u32, f32>(self.storage[2]) as i32,
1✔
932
                bytemuck::cast::<u32, f32>(self.storage[3]) as i32,
1✔
933
            ],
934
            ScalarType::Int => [
5✔
935
                bytemuck::cast::<u32, i32>(self.storage[0]),
5✔
936
                bytemuck::cast::<u32, i32>(self.storage[1]),
5✔
937
                bytemuck::cast::<u32, i32>(self.storage[2]),
5✔
938
                bytemuck::cast::<u32, i32>(self.storage[3]),
5✔
939
            ],
940
            ScalarType::Uint => [
1✔
941
                self.storage[0] as i32,
1✔
942
                self.storage[1] as i32,
1✔
943
                self.storage[2] as i32,
1✔
944
                self.storage[3] as i32,
1✔
945
            ],
946
        }
947
    }
948

949
    fn cast_u32(&self) -> [u32; 4] {
8✔
950
        match self.elem_type() {
8✔
951
            ScalarType::Bool => {
952
                let ft = [0, 1];
1✔
953
                [
954
                    ft[(self.storage[0] != 0) as usize],
1✔
955
                    ft[(self.storage[1] != 0) as usize],
1✔
956
                    ft[(self.storage[2] != 0) as usize],
1✔
957
                    ft[(self.storage[3] != 0) as usize],
1✔
958
                ]
959
            }
960
            ScalarType::Float => [
1✔
961
                bytemuck::cast::<u32, f32>(self.storage[0]) as u32,
1✔
962
                bytemuck::cast::<u32, f32>(self.storage[1]) as u32,
1✔
963
                bytemuck::cast::<u32, f32>(self.storage[2]) as u32,
1✔
964
                bytemuck::cast::<u32, f32>(self.storage[3]) as u32,
1✔
965
            ],
966
            ScalarType::Int => [
1✔
967
                bytemuck::cast::<u32, i32>(self.storage[0]) as u32,
1✔
968
                bytemuck::cast::<u32, i32>(self.storage[1]) as u32,
1✔
969
                bytemuck::cast::<u32, i32>(self.storage[2]) as u32,
1✔
970
                bytemuck::cast::<u32, i32>(self.storage[3]) as u32,
1✔
971
            ],
972
            ScalarType::Uint => self.storage,
5✔
973
        }
974
    }
975

976
    // fn binary_op(&self, other: &Self, op: BinaryOperator) -> Self {
977
    //     let count = self.vector_type.count();
978
    //     let mut v = *self;
979
    //     // component-wise op
980
    //     for i in 0..count {
981
    //         v.value_mut(i).binary_op(&other.value(i), op);
982
    //     }
983
    //     v
984
    // }
985
}
986

987
impl PartialEq for VectorValue {
988
    fn eq(&self, other: &Self) -> bool {
50✔
989
        if self.vector_type() != other.vector_type() {
50✔
990
            return false;
15✔
991
        }
992
        let count = self.vector_type().count();
35✔
993
        match self.elem_type() {
35✔
994
            ScalarType::Float => {
995
                let s = self.cast_f32();
21✔
996
                let o = other.cast_f32();
21✔
997
                s[..count] == o[..count]
21✔
998
            }
999
            _ => self.storage[..count] == other.storage[..count],
14✔
1000
        }
1001
    }
1002
}
1003

1004
impl Eq for VectorValue {}
1005

1006
impl std::hash::Hash for VectorValue {
1007
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
41✔
1008
        self.vector_type.hash(state);
41✔
1009
        // Only compare the subset of storage actually in use
1010
        let count = self.vector_type.count();
41✔
1011
        let elem_type = self.elem_type();
41✔
1012
        if elem_type == ScalarType::Float {
41✔
1013
            for i in 0..count {
36✔
UNCOV
1014
                FloatOrd(self.get::<f32>(i)).hash(state);
×
1015
            }
1016
        } else {
1017
            self.storage[..count].hash(state);
30✔
1018
        }
1019
    }
1020
}
1021

1022
impl ToWgslString for VectorValue {
1023
    fn to_wgsl_string(&self) -> String {
106✔
1024
        let mut vals = format!(
106✔
1025
            "{}({},{}",
1026
            self.vector_type().to_wgsl_string(),
106✔
1027
            self.value_n::<0>().to_wgsl_string(),
106✔
1028
            self.value_n::<1>().to_wgsl_string()
106✔
1029
        );
1030
        let count = self.vector_type.count();
106✔
1031
        if count > 2 {
106✔
1032
            vals.push(',');
96✔
1033
            vals.push_str(&self.value_n::<2>().to_wgsl_string());
96✔
1034
            if count > 3 {
115✔
1035
                vals.push(',');
19✔
1036
                vals.push_str(&self.value_n::<3>().to_wgsl_string());
19✔
1037
            }
1038
        }
1039
        vals.push(')');
106✔
1040
        vals
106✔
1041
    }
1042
}
1043

1044
impl From<BVec2> for VectorValue {
1045
    fn from(value: BVec2) -> Self {
3✔
1046
        Self {
1047
            vector_type: VectorType::new(ScalarType::Bool, 2),
3✔
1048
            storage: [
3✔
1049
                ScalarValue::BOOL_STORAGE[value.x as usize],
1050
                ScalarValue::BOOL_STORAGE[value.y as usize],
1051
                0,
1052
                0,
1053
            ],
1054
        }
1055
    }
1056
}
1057

1058
impl From<BVec3> for VectorValue {
1059
    fn from(value: BVec3) -> Self {
3✔
1060
        Self {
1061
            vector_type: VectorType::new(ScalarType::Bool, 3),
3✔
1062
            storage: [
3✔
1063
                ScalarValue::BOOL_STORAGE[value.x as usize],
1064
                ScalarValue::BOOL_STORAGE[value.y as usize],
1065
                ScalarValue::BOOL_STORAGE[value.z as usize],
1066
                0,
1067
            ],
1068
        }
1069
    }
1070
}
1071

1072
impl From<BVec4> for VectorValue {
1073
    fn from(value: BVec4) -> Self {
2✔
1074
        Self {
1075
            vector_type: VectorType::new(ScalarType::Bool, 4),
2✔
1076
            storage: [
2✔
1077
                ScalarValue::BOOL_STORAGE[value.x as usize],
1078
                ScalarValue::BOOL_STORAGE[value.y as usize],
1079
                ScalarValue::BOOL_STORAGE[value.z as usize],
1080
                ScalarValue::BOOL_STORAGE[value.w as usize],
1081
            ],
1082
        }
1083
    }
1084
}
1085

1086
impl From<IVec2> for VectorValue {
1087
    fn from(value: IVec2) -> Self {
3✔
1088
        let mut s = Self {
1089
            vector_type: VectorType::VEC2I,
1090
            storage: [0u32; 4],
3✔
1091
        };
1092
        let v = bytemuck::cast_slice_mut::<u32, i32>(&mut s.storage);
3✔
1093
        value.write_to_slice(v);
3✔
1094
        s
3✔
1095
    }
1096
}
1097

1098
impl From<IVec3> for VectorValue {
1099
    fn from(value: IVec3) -> Self {
2✔
1100
        let mut s = Self {
1101
            vector_type: VectorType::VEC3I,
1102
            storage: [0u32; 4],
2✔
1103
        };
1104
        let v = bytemuck::cast_slice_mut::<u32, i32>(&mut s.storage);
2✔
1105
        value.write_to_slice(v);
2✔
1106
        s
2✔
1107
    }
1108
}
1109

1110
impl From<IVec4> for VectorValue {
1111
    fn from(value: IVec4) -> Self {
2✔
1112
        let mut s = Self {
1113
            vector_type: VectorType::VEC4I,
1114
            storage: [0u32; 4],
2✔
1115
        };
1116
        let v = bytemuck::cast_slice_mut::<u32, i32>(&mut s.storage);
2✔
1117
        value.write_to_slice(v);
2✔
1118
        s
2✔
1119
    }
1120
}
1121

1122
impl From<UVec2> for VectorValue {
1123
    fn from(value: UVec2) -> Self {
1✔
1124
        let mut s = Self {
1125
            vector_type: VectorType::VEC2U,
1126
            storage: [0u32; 4],
1✔
1127
        };
1128
        let v = &mut s.storage;
1✔
1129
        value.write_to_slice(v);
1✔
1130
        s
1✔
1131
    }
1132
}
1133

1134
impl From<UVec3> for VectorValue {
1135
    fn from(value: UVec3) -> Self {
1✔
1136
        let mut s = Self {
1137
            vector_type: VectorType::VEC3U,
1138
            storage: [0u32; 4],
1✔
1139
        };
1140
        let v = &mut s.storage;
1✔
1141
        value.write_to_slice(v);
1✔
1142
        s
1✔
1143
    }
1144
}
1145

1146
impl From<UVec4> for VectorValue {
1147
    fn from(value: UVec4) -> Self {
1✔
1148
        let mut s = Self {
1149
            vector_type: VectorType::VEC4U,
1150
            storage: [0u32; 4],
1✔
1151
        };
1152
        let v = &mut s.storage;
1✔
1153
        value.write_to_slice(v);
1✔
1154
        s
1✔
1155
    }
1156
}
1157

1158
impl From<Vec2> for VectorValue {
1159
    fn from(value: Vec2) -> Self {
22✔
1160
        let mut s = Self {
1161
            vector_type: VectorType::VEC2F,
1162
            storage: [0u32; 4],
22✔
1163
        };
1164
        let v = bytemuck::cast_slice_mut::<u32, f32>(&mut s.storage);
22✔
1165
        value.write_to_slice(v);
22✔
1166
        s
22✔
1167
    }
1168
}
1169

1170
impl From<Vec3> for VectorValue {
1171
    fn from(value: Vec3) -> Self {
62✔
1172
        let mut s = Self {
1173
            vector_type: VectorType::VEC3F,
1174
            storage: [0u32; 4],
62✔
1175
        };
1176
        let v = bytemuck::cast_slice_mut::<u32, f32>(&mut s.storage);
62✔
1177
        value.write_to_slice(v);
62✔
1178
        s
62✔
1179
    }
1180
}
1181

1182
impl From<Vec3A> for VectorValue {
1183
    fn from(value: Vec3A) -> Self {
×
1184
        let mut s = Self {
1185
            vector_type: VectorType::VEC3F,
1186
            storage: [0u32; 4],
×
1187
        };
1188
        let v = bytemuck::cast_slice_mut::<u32, f32>(&mut s.storage);
×
1189
        value.write_to_slice(v);
×
1190
        s
×
1191
    }
1192
}
1193

1194
impl From<Vec4> for VectorValue {
1195
    fn from(value: Vec4) -> Self {
17✔
1196
        let mut s = Self {
1197
            vector_type: VectorType::VEC4F,
1198
            storage: [0u32; 4],
17✔
1199
        };
1200
        let v = bytemuck::cast_slice_mut::<u32, f32>(&mut s.storage);
17✔
1201
        value.write_to_slice(v);
17✔
1202
        s
17✔
1203
    }
1204
}
1205

1206
/// Helper used as placeholder instead of [`VectorValue`] for serialization.
1207
///
1208
/// This enables serializing [`VectorValue`] as a glam type enum, instead of the
1209
/// compressed binary runtime representation actually stored inside
1210
/// [`VectorValue`].
1211
#[derive(Serialize, Deserialize)]
1212
enum VectorValueEnum {
1213
    BVec2(BVec2),
1214
    BVec3(BVec3),
1215
    BVec4(BVec4),
1216
    IVec2(IVec2),
1217
    IVec3(IVec3),
1218
    IVec4(IVec4),
1219
    UVec2(UVec2),
1220
    UVec3(UVec3),
1221
    UVec4(UVec4),
1222
    Vec2(Vec2),
1223
    Vec3(Vec3),
1224
    Vec4(Vec4),
1225
}
1226

1227
impl From<VectorValueEnum> for VectorValue {
1228
    fn from(value: VectorValueEnum) -> Self {
3✔
1229
        match value {
3✔
1230
            VectorValueEnum::BVec2(v) => VectorValue::new_bvec2(v),
1✔
1231
            VectorValueEnum::BVec3(v) => VectorValue::new_bvec3(v),
×
1232
            VectorValueEnum::BVec4(v) => VectorValue::new_bvec4(v),
×
1233
            VectorValueEnum::IVec2(v) => VectorValue::new_ivec2(v),
×
1234
            VectorValueEnum::IVec3(v) => VectorValue::new_ivec3(v),
×
1235
            VectorValueEnum::IVec4(v) => VectorValue::new_ivec4(v),
×
1236
            VectorValueEnum::UVec2(v) => VectorValue::new_uvec2(v),
×
1237
            VectorValueEnum::UVec3(v) => VectorValue::new_uvec3(v),
×
1238
            VectorValueEnum::UVec4(v) => VectorValue::new_uvec4(v),
×
1239
            VectorValueEnum::Vec2(v) => VectorValue::new_vec2(v),
×
1240
            VectorValueEnum::Vec3(v) => VectorValue::new_vec3(v),
2✔
1241
            VectorValueEnum::Vec4(v) => VectorValue::new_vec4(v),
×
1242
        }
1243
    }
1244
}
1245

1246
impl From<VectorValue> for VectorValueEnum {
1247
    fn from(value: VectorValue) -> Self {
3✔
1248
        let count = value.vector_type.count();
3✔
1249
        match value.elem_type() {
3✔
1250
            ScalarType::Bool => {
1251
                if count == 2 {
1✔
1252
                    VectorValueEnum::BVec2(value.as_bvec2())
1✔
1253
                } else if count == 3 {
×
1254
                    VectorValueEnum::BVec3(value.as_bvec3())
×
1255
                } else {
1256
                    VectorValueEnum::BVec4(value.as_bvec4())
×
1257
                }
1258
            }
1259
            ScalarType::Int => {
1260
                if count == 2 {
×
1261
                    VectorValueEnum::IVec2(value.as_ivec2())
×
1262
                } else if count == 3 {
×
1263
                    VectorValueEnum::IVec3(value.as_ivec3())
×
1264
                } else {
1265
                    VectorValueEnum::IVec4(value.as_ivec4())
×
1266
                }
1267
            }
1268
            ScalarType::Uint => {
1269
                if count == 2 {
×
1270
                    VectorValueEnum::UVec2(value.as_uvec2())
×
1271
                } else if count == 3 {
×
1272
                    VectorValueEnum::UVec3(value.as_uvec3())
×
1273
                } else {
1274
                    VectorValueEnum::UVec4(value.as_uvec4())
×
1275
                }
1276
            }
1277
            ScalarType::Float => {
1278
                if count == 2 {
2✔
1279
                    VectorValueEnum::Vec2(value.as_vec2())
×
1280
                } else if count == 3 {
2✔
1281
                    VectorValueEnum::Vec3(value.as_vec3())
2✔
1282
                } else {
1283
                    VectorValueEnum::Vec4(value.as_vec4())
×
1284
                }
1285
            }
1286
        }
1287
    }
1288
}
1289

1290
/// Floating-point matrix value.
1291
#[derive(Debug, Clone, Copy, Reflect, Serialize, Deserialize)]
1292
pub struct MatrixValue {
1293
    /// Matrix type.
1294
    matrix_type: MatrixType,
1295
    /// Raw storage for up to 16 values. Actual usage depends on matrix size.
1296
    /// Note that data is stored pre-aligned according to WGSL rules, so that we
1297
    /// can directly return a slice to it.
1298
    storage: [f32; 16],
1299
}
1300

1301
impl MatrixValue {
1302
    /// Create a new CxR matrix value from raw data.
1303
    ///
1304
    /// The matrix can be of any dimension `2..=4`, with data. The `data` slice
1305
    /// needs to be of length `cols * rows` exactly.
1306
    ///
1307
    /// # Example
1308
    ///
1309
    /// ```
1310
    /// # use bevy_hanabi::*;
1311
    /// let m = MatrixValue::new(3, 2, &[0., 1., 2., 1., 2., 3.]);
1312
    /// assert_eq!(m.matrix_type().cols(), 3);
1313
    /// assert_eq!(m.matrix_type().rows(), 2);
1314
    /// ```
1315
    ///
1316
    /// # Panics
1317
    ///
1318
    /// Panics if either `cols` or `rows` is not 2/3/4.
1319
    ///
1320
    /// Panics if `data.len() != cols * rows`.
1321
    pub fn new(cols: usize, rows: usize, data: &[f32]) -> Self {
18✔
1322
        assert!((2..=4).contains(&cols));
18✔
1323
        assert!((2..=4).contains(&rows));
18✔
1324
        assert_eq!(data.len(), cols * rows);
18✔
1325
        let mut s = Self {
1326
            matrix_type: MatrixType::new(cols as u8, rows as u8),
18✔
1327
            storage: [0.0; 16],
18✔
1328
        };
1329
        if rows != 3 {
30✔
1330
            // Easy; just copy, there's no padding
1331
            let num = cols * rows;
12✔
1332
            let dst = &mut s.storage[0..num];
12✔
1333
            dst.copy_from_slice(&data[0..num]);
12✔
1334
        } else {
1335
            // Need to pad each row vec3 -> vec4
1336
            for col in 0..cols {
24✔
1337
                let dst_offset = col * 4;
1338
                let dst = &mut s.storage[dst_offset..dst_offset + rows];
1339
                let src_offset = col * 3;
1340
                dst.copy_from_slice(&data[src_offset..src_offset + rows]);
1341
            }
1342
        }
1343
        s
18✔
1344
    }
1345

1346
    /// Scalar type of the elements of the matrix.
1347
    ///
1348
    /// This always returns [`ScalarType::Float`]. This method is provided for
1349
    /// consistency.
1350
    pub const fn elem_type(&self) -> ScalarType {
×
1351
        ScalarType::Float
×
1352
    }
1353

1354
    /// Matrix type.
1355
    pub fn matrix_type(&self) -> MatrixType {
38✔
1356
        self.matrix_type
38✔
1357
    }
1358

1359
    /// Get the scalar value of the matrix element in the R-th row and C-th
1360
    /// column.
1361
    pub fn value_n<const R: usize, const C: usize>(&self) -> ScalarValue {
×
1362
        ScalarValue::Float(self.get_n::<R, C>())
×
1363
    }
1364

1365
    /// Get the scalar value of a matrix element.
1366
    pub fn value(&self, row: usize, col: usize) -> ScalarValue {
27✔
1367
        ScalarValue::Float(self.get(row, col))
27✔
1368
    }
1369

1370
    /// Get the scalar value of an element of the matrix.
1371
    pub fn value_mut(&mut self, row: usize, col: usize) -> &mut f32 {
×
1372
        self.get_mut(row, col)
×
1373
    }
1374

1375
    /// Get the floating-point value of the matrix element in the R-th row and
1376
    /// C-th column.
1377
    pub fn get_n<const R: usize, const C: usize>(&self) -> f32 {
×
1378
        if R < self.matrix_type.rows() && C < self.matrix_type.cols() {
×
1379
            self.storage[self.matrix_type.rows() * C + R]
×
1380
        } else {
1381
            0f32
×
1382
        }
1383
    }
1384

1385
    /// Get the floating-point value of a matrix element.
1386
    pub fn get(&self, row: usize, col: usize) -> f32 {
27✔
1387
        if row < self.matrix_type.rows() && col < self.matrix_type.cols() {
54✔
1388
            self.storage[self.matrix_type.rows() * col + row]
27✔
1389
        } else {
1390
            0f32
×
1391
        }
1392
    }
1393

1394
    /// Get the value of an element of the matrix.
1395
    fn get_mut(&mut self, row: usize, col: usize) -> &mut f32 {
×
1396
        assert!(row < self.matrix_type.rows());
×
1397
        assert!(col < self.matrix_type.cols());
×
1398
        &mut self.storage[self.matrix_type.rows() * col + row]
×
1399
    }
1400

1401
    /// Get the value as a binary blob ready for GPU upload.
1402
    ///
1403
    /// The slice has a size aligned with the requirements of WGSL, and can
1404
    /// contain gaps where no actual matrix data is stored. See
1405
    /// <https://gpuweb.github.io/gpuweb/wgsl/#alignment-and-size> for details.
1406
    pub fn as_bytes(&self) -> &[u8] {
21✔
1407
        // https://gpuweb.github.io/gpuweb/wgsl/#alignment-and-size
1408
        let count = self.matrix_type.cols() * self.matrix_type.align() / 4;
21✔
1409
        bytemuck::cast_slice::<f32, u8>(&self.storage[..count])
21✔
1410
    }
1411

1412
    // fn binary_op(&self, other: &Self, op: BinaryOperator) -> Self {
1413
    //     let mut m = *self;
1414
    //     // component-wise op
1415
    //     for j in 0..self.matrix_type.cols() {
1416
    //         for i in 0..self.matrix_type.rows() {
1417
    //             let dst = m.value_mut(i, j);
1418
    //             let a = *dst;
1419
    //             let b = other.get(i, j);
1420
    //             *dst = op.apply_f32(a, b);
1421
    //         }
1422
    //     }
1423
    //     m
1424
    // }
1425
}
1426

1427
impl PartialEq for MatrixValue {
1428
    fn eq(&self, other: &Self) -> bool {
×
1429
        if self.matrix_type != other.matrix_type {
×
1430
            return false;
×
1431
        }
1432
        let count = self.matrix_type.rows() * self.matrix_type.cols();
×
1433
        self.storage[..count] == other.storage[..count]
×
1434
    }
1435
}
1436

1437
impl std::hash::Hash for MatrixValue {
1438
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
×
1439
        self.matrix_type.hash(state);
×
1440
        let count = self.matrix_type.rows() * self.matrix_type.cols();
×
1441
        for i in 0..count {
×
1442
            FloatOrd(self.storage[i]).hash(state);
×
1443
        }
1444
    }
1445
}
1446

1447
impl ToWgslString for MatrixValue {
1448
    fn to_wgsl_string(&self) -> String {
3✔
1449
        let mut vals = format!("{}(", self.matrix_type().to_wgsl_string(),);
3✔
1450
        for j in 0..self.matrix_type.cols() {
12✔
1451
            for i in 0..self.matrix_type.rows() {
27✔
1452
                vals.push_str(&self.value(i, j).to_wgsl_string());
1453
                vals.push(',');
1454
            }
1455
        }
1456
        vals.pop(); // Remove the last comma
3✔
1457
        vals.push(')');
3✔
1458
        vals
3✔
1459
    }
1460
}
1461

1462
impl From<Mat2> for MatrixValue {
1463
    fn from(value: Mat2) -> Self {
2✔
1464
        let mut s = Self {
1465
            matrix_type: MatrixType::MAT2X2F,
1466
            storage: [0.; 16],
2✔
1467
        };
1468
        value.write_cols_to_slice(&mut s.storage);
2✔
1469
        s
2✔
1470
    }
1471
}
1472

1473
impl From<Mat3> for MatrixValue {
1474
    fn from(value: Mat3) -> Self {
5✔
1475
        let mut s = Self {
1476
            matrix_type: MatrixType::MAT3X3F,
1477
            storage: [0.; 16],
5✔
1478
        };
1479
        value.write_cols_to_slice(&mut s.storage);
5✔
1480
        s
5✔
1481
    }
1482
}
1483

1484
impl From<Mat4> for MatrixValue {
1485
    fn from(value: Mat4) -> Self {
4✔
1486
        let mut s = Self {
1487
            matrix_type: MatrixType::MAT4X4F,
1488
            storage: [0.; 16],
4✔
1489
        };
1490
        value.write_cols_to_slice(&mut s.storage);
4✔
1491
        s
4✔
1492
    }
1493
}
1494

1495
/// Variant storage for a simple value.
1496
///
1497
/// The variant can store a scalar, vector, or matrix value.
1498
#[derive(Debug, Clone, Copy, PartialEq, Hash, Reflect, Serialize, Deserialize)]
1499
#[non_exhaustive]
1500
pub enum Value {
1501
    /// Scalar value.
1502
    Scalar(ScalarValue),
1503
    /// Vector value with 2 to 4 components.
1504
    ///
1505
    /// Note that 1-component vectors are invalid; [`Value::Scalar`] must be
1506
    /// used instead. Similarly, vectors with more than 4 components are
1507
    /// invalid.
1508
    Vector(VectorValue),
1509
    /// Floating-point matrix value of size 2x2 to 4x4.
1510
    ///
1511
    /// Note that single-row or single-column matrices are invalid;
1512
    /// [`Value::Vector`] must be used instead, or [`Value::Scalar`] for a
1513
    /// 1x1 "matrix". Similarly, matrices with more than 4 rows or columns are
1514
    /// invalid.
1515
    Matrix(MatrixValue),
1516
}
1517

1518
impl Value {
1519
    /// Get the value as a binary blob ready for GPU upload.
1520
    pub fn as_bytes(&self) -> &[u8] {
11✔
1521
        match self {
11✔
1522
            Value::Scalar(s) => s.as_bytes(),
4✔
1523
            Value::Vector(v) => v.as_bytes(),
4✔
1524
            Value::Matrix(m) => m.as_bytes(),
3✔
1525
        }
1526
    }
1527

1528
    /// Get the type of the value.
1529
    ///
1530
    /// # Example
1531
    ///
1532
    /// ```
1533
    /// # use bevy_hanabi::*;
1534
    /// let value = graph::Value::Scalar(3_f32.into());
1535
    /// assert_eq!(ValueType::Scalar(ScalarType::Float), value.value_type());
1536
    /// ```
1537
    pub fn value_type(&self) -> ValueType {
2,323✔
1538
        match self {
2,323✔
1539
            Value::Scalar(s) => ValueType::Scalar(s.scalar_type()),
940✔
1540
            Value::Vector(v) => ValueType::Vector(v.vector_type()),
1,375✔
1541
            Value::Matrix(m) => ValueType::Matrix(m.matrix_type()),
8✔
1542
        }
1543
    }
1544

1545
    /// Cast this value to a [`ScalarValue`].
1546
    ///
1547
    /// # Panics
1548
    ///
1549
    /// Panics if this value is not a [`ScalarValue`].
1550
    pub fn as_scalar(&self) -> &ScalarValue {
×
1551
        match self {
×
1552
            Value::Scalar(s) => s,
×
1553
            _ => panic!("Cannot cast from {:?} to ScalarType.", self.value_type()),
×
1554
        }
1555
    }
1556

1557
    /// Cast this value to a [`VectorValue`].
1558
    ///
1559
    /// # Panics
1560
    ///
1561
    /// Panics if this value is not a [`VectorValue`].
1562
    pub fn as_vector(&self) -> &VectorValue {
×
1563
        match self {
×
1564
            Value::Vector(v) => v,
×
1565
            _ => panic!("Cannot cast from {:?} to VectorType.", self.value_type()),
×
1566
        }
1567
    }
1568

1569
    /// Cast this value to a [`MatrixValue`].
1570
    ///
1571
    /// # Panics
1572
    ///
1573
    /// Panics if this value is not a [`MatrixValue`].
1574
    pub fn as_matrix(&self) -> &MatrixValue {
×
1575
        match self {
×
1576
            Value::Matrix(m) => m,
×
1577
            _ => panic!("Cannot cast from {:?} to MatrixType.", self.value_type()),
×
1578
        }
1579
    }
1580

1581
    // /// Apply a binary arithmetic operator between self and another operand.
1582
    // pub fn binary_op(&self, other: &Value, op: BinaryOperator) -> Value {
1583
    //     match self {
1584
    //         Value::Scalar(s) => Value::Scalar(s.binary_op(other.as_scalar(),
1585
    // op)),         Value::Vector(v) =>
1586
    // Value::Vector(v.binary_op(other.as_vector(), op)),
1587
    //         Value::Matrix(m) => Value::Matrix(m.binary_op(other.as_matrix(),
1588
    // op)),     }
1589
    // }
1590
}
1591

1592
impl ToWgslString for Value {
1593
    fn to_wgsl_string(&self) -> String {
180✔
1594
        match self {
180✔
1595
            Value::Scalar(s) => s.to_wgsl_string(),
71✔
1596
            Value::Vector(v) => v.to_wgsl_string(),
106✔
1597
            Value::Matrix(m) => m.to_wgsl_string(),
3✔
1598
        }
1599
    }
1600
}
1601

1602
impl From<ScalarValue> for Value {
1603
    fn from(value: ScalarValue) -> Self {
1✔
1604
        Self::Scalar(value)
1✔
1605
    }
1606
}
1607

1608
impl From<VectorValue> for Value {
1609
    fn from(value: VectorValue) -> Self {
×
1610
        Self::Vector(value)
×
1611
    }
1612
}
1613

1614
impl From<MatrixValue> for Value {
1615
    fn from(value: MatrixValue) -> Self {
×
1616
        Self::Matrix(value)
×
1617
    }
1618
}
1619

1620
macro_rules! impl_scalar_value {
1621
    ($t:ty, $sv:ident) => {
1622
        impl From<$t> for Value {
1623
            fn from(value: $t) -> Self {
83✔
1624
                Self::Scalar(value.into())
83✔
1625
            }
1626
        }
1627

1628
        impl TryInto<$t> for ScalarValue {
1629
            type Error = ExprError;
1630

1631
            fn try_into(self) -> Result<$t, Self::Error> {
12✔
1632
                match self {
12✔
1633
                    ScalarValue::$sv(b) => Ok(b),
4✔
1634
                    _ => Err(ExprError::TypeError(format!(
8✔
1635
                        "Expected {:?} type, found {:?} instead.",
8✔
1636
                        ScalarType::$sv,
8✔
1637
                        self.scalar_type()
8✔
1638
                    ))),
1639
                }
1640
            }
1641
        }
1642

1643
        impl TryInto<$t> for Value {
1644
            type Error = ExprError;
1645

1646
            fn try_into(self) -> Result<$t, Self::Error> {
12✔
1647
                match self {
12✔
1648
                    Value::Scalar(s) => s.try_into(),
12✔
1649
                    _ => Err(ExprError::TypeError(format!(
×
1650
                        "Expected ValueType::Scalar type, found {:?} instead.",
×
1651
                        self.value_type()
×
1652
                    ))),
1653
                }
1654
            }
1655
        }
1656
    };
1657
}
1658

1659
impl_scalar_value!(bool, Bool);
1660
impl_scalar_value!(f32, Float);
1661
impl_scalar_value!(i32, Int);
1662
impl_scalar_value!(u32, Uint);
1663

1664
macro_rules! impl_vec_value {
1665
    ($t:ty, $vt:ident, $cast:tt) => {
1666
        impl From<$t> for Value {
1667
            fn from(value: $t) -> Self {
70✔
1668
                Self::Vector(value.into())
70✔
1669
            }
1670
        }
1671

1672
        impl TryInto<$t> for VectorValue {
1673
            type Error = ExprError;
1674

1675
            fn try_into(self) -> Result<$t, Self::Error> {
9✔
1676
                if self.vector_type() == VectorType::$vt {
9✔
1677
                    Ok(self.$cast())
9✔
1678
                } else {
1679
                    Err(ExprError::TypeError(format!(
×
1680
                        "Expected {:?} type, found {:?} instead.",
×
1681
                        VectorType::$vt,
×
1682
                        self.vector_type()
×
1683
                    )))
1684
                }
1685
            }
1686
        }
1687

1688
        impl TryInto<$t> for Value {
1689
            type Error = ExprError;
1690

1691
            fn try_into(self) -> Result<$t, Self::Error> {
5✔
1692
                match self {
5✔
1693
                    Value::Vector(v) => v.try_into(),
×
1694
                    _ => Err(ExprError::TypeError(format!(
5✔
1695
                        "Expected ValueType::Scalar type, found {:?} instead.",
5✔
1696
                        self.value_type()
5✔
1697
                    ))),
1698
                }
1699
            }
1700
        }
1701
    };
1702
}
1703

1704
impl_vec_value!(BVec2, VEC2B, as_bvec2);
1705
impl_vec_value!(BVec3, VEC3B, as_bvec3);
1706
impl_vec_value!(BVec4, VEC4B, as_bvec4);
1707
impl_vec_value!(Vec2, VEC2F, as_vec2);
1708
impl_vec_value!(Vec3, VEC3F, as_vec3);
1709
impl_vec_value!(Vec3A, VEC3F, as_vec3a);
1710
impl_vec_value!(Vec4, VEC4F, as_vec4);
1711
impl_vec_value!(IVec2, VEC2I, as_ivec2);
1712
impl_vec_value!(IVec3, VEC3I, as_ivec3);
1713
impl_vec_value!(IVec4, VEC4I, as_ivec4);
1714
impl_vec_value!(UVec2, VEC2U, as_uvec2);
1715
impl_vec_value!(UVec3, VEC3U, as_uvec3);
1716
impl_vec_value!(UVec4, VEC4U, as_uvec4);
1717

1718
#[cfg(test)]
1719
mod tests {
1720
    use std::{
1721
        collections::hash_map::DefaultHasher,
1722
        hash::{Hash, Hasher},
1723
    };
1724

1725
    use super::*;
1726

1727
    #[test]
1728
    fn as_bytes() {
1729
        // let v = Value::Scalar(true.into());
1730
        // let b = v.as_bytes();
1731
        // assert_eq!(b, &[0xFFu8, 0xFFu8, 0xFFu8, 0xFFu8]);
1732

1733
        let v = Value::Scalar(3f32.into());
1734
        let b = v.as_bytes();
1735
        assert_eq!(b, &[0u8, 0u8, 0x40u8, 0x40u8]); // 0x40400000
1736

1737
        let v = Value::Scalar(0x12FF89ACu32.into());
1738
        let b = v.as_bytes();
1739
        assert_eq!(b, &[0xACu8, 0x89u8, 0xFFu8, 0x12u8]);
1740

1741
        let v = Value::Scalar(0x12FF89ACi32.into());
1742
        let b = v.as_bytes();
1743
        assert_eq!(b, &[0xACu8, 0x89u8, 0xFFu8, 0x12u8]);
1744

1745
        let v = Value::Vector(Vec2::new(-2., 3.).into());
1746
        let b = v.as_bytes();
1747
        assert_eq!(b, &[0u8, 0u8, 0u8, 0xC0u8, 0u8, 0u8, 0x40u8, 0x40u8]); // 0xc0000000 0x40400000
1748

1749
        let v = Value::Vector(Vec3::new(-2., 3., 4.).into());
1750
        let b = v.as_bytes();
1751
        assert_eq!(
1752
            b,
1753
            &[0u8, 0u8, 0u8, 0xC0u8, 0u8, 0u8, 0x40u8, 0x40u8, 0u8, 0u8, 0x80u8, 0x40u8]
1754
        ); // 0xc0000000 0x40400000 0x40800000
1755

1756
        let v = Value::Vector(Vec4::new(-2., 3., 4., -5.).into());
1757
        let b = v.as_bytes();
1758
        assert_eq!(
1759
            b,
1760
            &[
1761
                0u8, 0u8, 0u8, 0xC0u8, 0u8, 0u8, 0x40u8, 0x40u8, 0u8, 0u8, 0x80u8, 0x40u8, 0u8,
1762
                0u8, 0xa0u8, 0xc0u8
1763
            ]
1764
        ); // 0xc0000000 0x40400000 0x40800000 0xc0a00000
1765

1766
        let v = Value::Matrix(Mat2::IDENTITY.into());
1767
        let b = v.as_bytes();
1768
        assert_eq!(b.len(), v.value_type().align() * 2);
1769
        assert_eq!(b.len(), 16);
1770
        let v = Value::Matrix(Mat3::IDENTITY.into());
1771
        let b = v.as_bytes();
1772
        assert_eq!(b.len(), v.value_type().align() * 3);
1773
        assert_eq!(b.len(), 48); // sizeof(vec4) * 3
1774
        let v = Value::Matrix(Mat4::IDENTITY.into());
1775
        let b = v.as_bytes();
1776
        assert_eq!(b.len(), v.value_type().align() * 4);
1777
        assert_eq!(b.len(), 64);
1778

1779
        // https://gpuweb.github.io/gpuweb/wgsl/#alignment-and-size
1780
        assert_eq!(ScalarValue::Float(0.0).as_bytes().len(), 4);
1781
        assert_eq!(ScalarValue::Float(0.0).scalar_type().size(), 4);
1782
        assert_eq!(ScalarValue::Float(0.0).scalar_type().align(), 4);
1783
        assert_eq!(ScalarValue::Int(0).as_bytes().len(), 4);
1784
        assert_eq!(ScalarValue::Int(0).scalar_type().size(), 4);
1785
        assert_eq!(ScalarValue::Int(0).scalar_type().align(), 4);
1786
        assert_eq!(ScalarValue::Uint(0).as_bytes().len(), 4);
1787
        assert_eq!(ScalarValue::Uint(0).scalar_type().size(), 4);
1788
        assert_eq!(ScalarValue::Uint(0).scalar_type().align(), 4);
1789
        assert_eq!(VectorValue::new_vec2(Vec2::ZERO).as_bytes().len(), 8);
1790
        assert_eq!(VectorValue::new_vec2(Vec2::ZERO).vector_type().size(), 8);
1791
        assert_eq!(VectorValue::new_vec2(Vec2::ZERO).vector_type().align(), 8);
1792
        assert_eq!(VectorValue::new_vec3(Vec3::ZERO).as_bytes().len(), 12);
1793
        assert_eq!(VectorValue::new_vec3(Vec3::ZERO).vector_type().size(), 12);
1794
        assert_eq!(VectorValue::new_vec3(Vec3::ZERO).vector_type().align(), 16); // padding!
1795
        assert_eq!(VectorValue::new_vec4(Vec4::ZERO).as_bytes().len(), 16);
1796
        assert_eq!(VectorValue::new_vec4(Vec4::ZERO).vector_type().size(), 16);
1797
        assert_eq!(VectorValue::new_vec4(Vec4::ZERO).vector_type().align(), 16);
1798
        assert_eq!(VectorValue::new_ivec2(IVec2::ZERO).as_bytes().len(), 8);
1799
        assert_eq!(VectorValue::new_ivec2(IVec2::ZERO).vector_type().size(), 8);
1800
        assert_eq!(VectorValue::new_ivec2(IVec2::ZERO).vector_type().align(), 8);
1801
        assert_eq!(VectorValue::new_ivec3(IVec3::ZERO).as_bytes().len(), 12);
1802
        assert_eq!(VectorValue::new_ivec3(IVec3::ZERO).vector_type().size(), 12);
1803
        assert_eq!(
1804
            VectorValue::new_ivec3(IVec3::ZERO).vector_type().align(),
1805
            16
1806
        ); // padding!
1807
        assert_eq!(VectorValue::new_ivec4(IVec4::ZERO).as_bytes().len(), 16);
1808
        assert_eq!(VectorValue::new_ivec4(IVec4::ZERO).vector_type().size(), 16);
1809
        assert_eq!(
1810
            VectorValue::new_ivec4(IVec4::ZERO).vector_type().align(),
1811
            16
1812
        );
1813
        assert_eq!(VectorValue::new_uvec2(UVec2::ZERO).as_bytes().len(), 8);
1814
        assert_eq!(VectorValue::new_uvec2(UVec2::ZERO).vector_type().size(), 8);
1815
        assert_eq!(VectorValue::new_uvec2(UVec2::ZERO).vector_type().align(), 8);
1816
        assert_eq!(VectorValue::new_uvec3(UVec3::ZERO).as_bytes().len(), 12);
1817
        assert_eq!(VectorValue::new_uvec3(UVec3::ZERO).vector_type().size(), 12);
1818
        assert_eq!(
1819
            VectorValue::new_uvec3(UVec3::ZERO).vector_type().align(),
1820
            16
1821
        ); // padding!
1822
        assert_eq!(VectorValue::new_uvec4(UVec4::ZERO).as_bytes().len(), 16);
1823
        assert_eq!(VectorValue::new_uvec4(UVec4::ZERO).vector_type().size(), 16);
1824
        assert_eq!(
1825
            VectorValue::new_uvec4(UVec4::ZERO).vector_type().align(),
1826
            16
1827
        );
1828
        assert_eq!(ScalarValue::Int(0).as_bytes().len(), 4);
1829
        assert_eq!(ScalarValue::Uint(0).as_bytes().len(), 4);
1830
        assert_eq!(MatrixValue::new(2, 2, &[0.0; 4]).as_bytes().len(), 16);
1831
        assert_eq!(MatrixValue::new(3, 2, &[0.0; 6]).as_bytes().len(), 24);
1832
        assert_eq!(MatrixValue::new(4, 2, &[0.0; 8]).as_bytes().len(), 32);
1833
        assert_eq!(MatrixValue::new(2, 3, &[0.0; 6]).as_bytes().len(), 32); // padding!
1834
        assert_eq!(MatrixValue::new(3, 3, &[0.0; 9]).as_bytes().len(), 48); // padding!
1835
        assert_eq!(MatrixValue::new(4, 3, &[0.0; 12]).as_bytes().len(), 64); // padding!
1836
        assert_eq!(MatrixValue::new(2, 4, &[0.0; 8]).as_bytes().len(), 32);
1837
        assert_eq!(MatrixValue::new(3, 4, &[0.0; 12]).as_bytes().len(), 48);
1838
        assert_eq!(MatrixValue::new(4, 4, &[0.0; 16]).as_bytes().len(), 64);
1839

1840
        // MatrixValue
1841
        let f: [f32; 16] = [
1842
            0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15.,
1843
        ];
1844
        let expected24: &[u8] = bytemuck::cast_slice(&f[..]);
1845
        // R=3 requires extra padding to AlignOf(vec4) = 16
1846
        let expected3: &[f32] = &[
1847
            0., 1., 2., 0., 3., 4., 5., 0., 6., 7., 8., 0., 9., 10., 11., 0.,
1848
        ];
1849
        let expected3: &[u8] = bytemuck::cast_slice(expected3);
1850
        for j in 2..=4 {
1851
            for i in 2..=4 {
1852
                let v = MatrixValue::new(i, j, &f[..i * j]);
1853
                assert_eq!(v.matrix_type().cols(), i);
1854
                assert_eq!(v.matrix_type().rows(), j);
1855

1856
                let b = v.as_bytes();
1857
                assert_eq!(b.len(), v.matrix_type().align() * i);
1858
                if j != 3 {
1859
                    assert_eq!(b, &expected24[..b.len()], "(i={},j={})", i, j);
1860
                } else {
1861
                    assert_eq!(b, &expected3[..b.len()], "(i={},j={})", i, j);
1862
                }
1863
            }
1864
        }
1865
    }
1866

1867
    #[test]
1868
    fn value_type() {
1869
        assert_eq!(
1870
            Value::Scalar(true.into()).value_type(),
1871
            ValueType::Scalar(ScalarType::Bool)
1872
        );
1873
        assert_eq!(
1874
            Value::Scalar(0f32.into()).value_type(),
1875
            ValueType::Scalar(ScalarType::Float)
1876
        );
1877
        assert_eq!(
1878
            Value::Scalar(0i32.into()).value_type(),
1879
            ValueType::Scalar(ScalarType::Int)
1880
        );
1881
        assert_eq!(
1882
            Value::Scalar(0u32.into()).value_type(),
1883
            ValueType::Scalar(ScalarType::Uint)
1884
        );
1885
        assert_eq!(
1886
            Value::Vector(Vec2::ZERO.into()).value_type(),
1887
            ValueType::Vector(VectorType::VEC2F)
1888
        );
1889
        assert_eq!(
1890
            Value::Vector(Vec3::ZERO.into()).value_type(),
1891
            ValueType::Vector(VectorType::VEC3F)
1892
        );
1893
        assert_eq!(
1894
            Value::Vector(Vec4::ZERO.into()).value_type(),
1895
            ValueType::Vector(VectorType::VEC4F)
1896
        );
1897
        assert_eq!(
1898
            Value::Vector(BVec2::TRUE.into()).value_type(),
1899
            ValueType::Vector(VectorType::VEC2B)
1900
        );
1901
        assert_eq!(
1902
            Value::Vector(BVec3::TRUE.into()).value_type(),
1903
            ValueType::Vector(VectorType::VEC3B)
1904
        );
1905
        assert_eq!(
1906
            Value::Vector(BVec4::TRUE.into()).value_type(),
1907
            ValueType::Vector(VectorType::VEC4B)
1908
        );
1909
        assert_eq!(
1910
            Value::Matrix(Mat2::IDENTITY.into()).value_type(),
1911
            ValueType::Matrix(MatrixType::MAT2X2F)
1912
        );
1913
        assert_eq!(
1914
            Value::Matrix(Mat3::IDENTITY.into()).value_type(),
1915
            ValueType::Matrix(MatrixType::MAT3X3F)
1916
        );
1917
        assert_eq!(
1918
            Value::Matrix(Mat4::IDENTITY.into()).value_type(),
1919
            ValueType::Matrix(MatrixType::MAT4X4F)
1920
        );
1921
    }
1922

1923
    #[test]
1924
    fn to_wgsl_string() {
1925
        for b in [true, false] {
1926
            assert_eq!(Value::Scalar(b.into()).to_wgsl_string(), b.to_wgsl_string());
1927
        }
1928
        for f in [0_f32, -1., 1., 1e-5] {
1929
            assert_eq!(Value::Scalar(f.into()).to_wgsl_string(), f.to_wgsl_string());
1930
        }
1931
        for u in [0_u32, 1, 42, 999999] {
1932
            assert_eq!(Value::Scalar(u.into()).to_wgsl_string(), u.to_wgsl_string());
1933
        }
1934
        for i in [0_i32, -1, 1, -42, 42, -100000, 100000] {
1935
            assert_eq!(Value::Scalar(i.into()).to_wgsl_string(), i.to_wgsl_string());
1936
        }
1937
        for v in [
1938
            Vec2::ZERO,
1939
            Vec2::ONE,
1940
            Vec2::NEG_ONE,
1941
            Vec2::X,
1942
            Vec2::Y,
1943
            Vec2::NEG_X,
1944
            Vec2::NEG_Y,
1945
            Vec2::new(-42.578, 663.449),
1946
        ] {
1947
            assert_eq!(Value::Vector(v.into()).to_wgsl_string(), v.to_wgsl_string());
1948
        }
1949
        for v in [
1950
            Vec3::ZERO,
1951
            Vec3::ONE,
1952
            Vec3::NEG_ONE,
1953
            Vec3::X,
1954
            Vec3::Y,
1955
            Vec3::Z,
1956
            Vec3::NEG_X,
1957
            Vec3::NEG_Y,
1958
            Vec3::NEG_Z,
1959
            Vec3::new(-42.578, 663.449, -42558.35),
1960
        ] {
1961
            assert_eq!(Value::Vector(v.into()).to_wgsl_string(), v.to_wgsl_string());
1962
        }
1963
        for v in [
1964
            Vec4::ZERO,
1965
            Vec4::ONE,
1966
            Vec4::NEG_ONE,
1967
            Vec4::X,
1968
            Vec4::Y,
1969
            Vec4::Z,
1970
            Vec4::NEG_X,
1971
            Vec4::NEG_Y,
1972
            Vec4::NEG_Z,
1973
            Vec4::new(-42.578, 663.449, -42558.35, -4.2),
1974
        ] {
1975
            assert_eq!(Value::Vector(v.into()).to_wgsl_string(), v.to_wgsl_string());
1976
        }
1977

1978
        for (m, expected) in [
1979
            (Mat3::IDENTITY, "mat3x3<f32>(1.,0.,0.,0.,1.,0.,0.,0.,1.)"),
1980
            (Mat3::ZERO, "mat3x3<f32>(0.,0.,0.,0.,0.,0.,0.,0.,0.)"),
1981
            (
1982
                Mat3::from_cols(
1983
                    Vec3::new(1., 2., 3.),
1984
                    Vec3::new(4., 5., 6.),
1985
                    Vec3::new(7., 8., 9.),
1986
                ),
1987
                "mat3x3<f32>(1.,2.,3.,4.,5.,6.,7.,8.,9.)",
1988
            ),
1989
        ] {
1990
            assert_eq!(
1991
                Value::Matrix(m.into()).to_wgsl_string(),
1992
                expected.to_string()
1993
            );
1994
        }
1995
    }
1996

1997
    #[test]
1998
    fn vector_value() {
1999
        let v = BVec2::new(false, true);
2000
        let vv = VectorValue::new_bvec2(v);
2001
        assert_eq!(ScalarValue::BOOL_FALSE_STORAGE, vv.storage[0]);
2002
        assert_eq!(ScalarValue::BOOL_TRUE_STORAGE, vv.storage[1]);
2003
        assert_eq!(0u32, vv.storage[2]);
2004
        assert_eq!(0u32, vv.storage[3]);
2005

2006
        let v = BVec3::new(false, true, false);
2007
        let vv = VectorValue::new_bvec3(v);
2008
        assert_eq!(ScalarValue::BOOL_FALSE_STORAGE, vv.storage[0]);
2009
        assert_eq!(ScalarValue::BOOL_TRUE_STORAGE, vv.storage[1]);
2010
        assert_eq!(ScalarValue::BOOL_FALSE_STORAGE, vv.storage[2]);
2011
        assert_eq!(0u32, vv.storage[3]);
2012

2013
        let v = BVec4::new(false, true, false, true);
2014
        let vv = VectorValue::new_bvec4(v);
2015
        assert_eq!(ScalarValue::BOOL_FALSE_STORAGE, vv.storage[0]);
2016
        assert_eq!(ScalarValue::BOOL_TRUE_STORAGE, vv.storage[1]);
2017
        assert_eq!(ScalarValue::BOOL_FALSE_STORAGE, vv.storage[2]);
2018
        assert_eq!(ScalarValue::BOOL_TRUE_STORAGE, vv.storage[3]);
2019

2020
        let v = Vec2::new(-3.2, 5.);
2021
        let vv = VectorValue::new_vec2(v);
2022
        assert_eq!(v.x.to_bits(), vv.storage[0]);
2023
        assert_eq!(v.y.to_bits(), vv.storage[1]);
2024
        assert_eq!(0u32, vv.storage[2]);
2025
        assert_eq!(0u32, vv.storage[3]);
2026

2027
        let v = Vec3::new(-3.2, 5., 64.5);
2028
        let vv = VectorValue::new_vec3(v);
2029
        assert_eq!(v.x.to_bits(), vv.storage[0]);
2030
        assert_eq!(v.y.to_bits(), vv.storage[1]);
2031
        assert_eq!(v.z.to_bits(), vv.storage[2]);
2032
        assert_eq!(0u32, vv.storage[3]);
2033

2034
        let v = Vec4::new(-3.2, 5., 64.5, -42.);
2035
        let vv = VectorValue::new_vec4(v);
2036
        assert_eq!(v.x.to_bits(), vv.storage[0]);
2037
        assert_eq!(v.y.to_bits(), vv.storage[1]);
2038
        assert_eq!(v.z.to_bits(), vv.storage[2]);
2039
        assert_eq!(v.w.to_bits(), vv.storage[3]);
2040

2041
        #[allow(unsafe_code)]
2042
        {
2043
            let v = IVec2::new(-3, 5);
2044
            let vv = VectorValue::new_ivec2(v);
2045
            assert_eq!(
2046
                unsafe { std::mem::transmute::<i32, u32>(v.x) },
2047
                vv.storage[0]
2048
            );
2049
            assert_eq!(
2050
                unsafe { std::mem::transmute::<i32, u32>(v.y) },
2051
                vv.storage[1]
2052
            );
2053
            assert_eq!(0u32, vv.storage[2]);
2054
            assert_eq!(0u32, vv.storage[3]);
2055

2056
            let v = IVec3::new(-3, 5, 64);
2057
            let vv = VectorValue::new_ivec3(v);
2058
            assert_eq!(
2059
                unsafe { std::mem::transmute::<i32, u32>(v.x) },
2060
                vv.storage[0]
2061
            );
2062
            assert_eq!(
2063
                unsafe { std::mem::transmute::<i32, u32>(v.y) },
2064
                vv.storage[1]
2065
            );
2066
            assert_eq!(
2067
                unsafe { std::mem::transmute::<i32, u32>(v.z) },
2068
                vv.storage[2]
2069
            );
2070
            assert_eq!(0u32, vv.storage[3]);
2071

2072
            let v = IVec4::new(-3, 5, 64, -42);
2073
            let vv = VectorValue::new_ivec4(v);
2074
            assert_eq!(
2075
                unsafe { std::mem::transmute::<i32, u32>(v.x) },
2076
                vv.storage[0]
2077
            );
2078
            assert_eq!(
2079
                unsafe { std::mem::transmute::<i32, u32>(v.y) },
2080
                vv.storage[1]
2081
            );
2082
            assert_eq!(
2083
                unsafe { std::mem::transmute::<i32, u32>(v.z) },
2084
                vv.storage[2]
2085
            );
2086
            assert_eq!(
2087
                unsafe { std::mem::transmute::<i32, u32>(v.w) },
2088
                vv.storage[3]
2089
            );
2090
        }
2091

2092
        let v = UVec2::new(3, 5);
2093
        let vv = VectorValue::new_uvec2(v);
2094
        assert_eq!(v.x, vv.storage[0]);
2095
        assert_eq!(v.y, vv.storage[1]);
2096
        assert_eq!(0u32, vv.storage[2]);
2097
        assert_eq!(0u32, vv.storage[3]);
2098

2099
        let v = UVec3::new(3, 5, 64);
2100
        let vv = VectorValue::new_uvec3(v);
2101
        assert_eq!(v.x, vv.storage[0]);
2102
        assert_eq!(v.y, vv.storage[1]);
2103
        assert_eq!(v.z, vv.storage[2]);
2104
        assert_eq!(0u32, vv.storage[3]);
2105

2106
        let v = UVec4::new(3, 5, 64, 42);
2107
        let vv = VectorValue::new_uvec4(v);
2108
        assert_eq!(v.x, vv.storage[0]);
2109
        assert_eq!(v.y, vv.storage[1]);
2110
        assert_eq!(v.z, vv.storage[2]);
2111
        assert_eq!(v.w, vv.storage[3]);
2112
    }
2113

2114
    #[test]
2115
    fn from() {
2116
        assert_eq!(Value::Scalar(ScalarValue::Bool(true)), true.into());
2117
        assert_eq!(Value::Scalar(ScalarValue::Float(0.)), 0_f32.into());
2118
        assert_eq!(Value::Scalar(ScalarValue::Int(-42)), (-42_i32).into());
2119
        assert_eq!(Value::Scalar(ScalarValue::Uint(0)), 0_u32.into());
2120

2121
        let v = BVec2::new(false, true);
2122
        let vv: VectorValue = v.into();
2123
        assert_eq!(vv, VectorValue::new_bvec2(v));
2124
        assert_eq!(ScalarValue::BOOL_FALSE_STORAGE, vv.storage[0]);
2125
        assert_eq!(ScalarValue::BOOL_TRUE_STORAGE, vv.storage[1]);
2126
        assert_eq!(0, vv.storage[2]);
2127
        assert_eq!(0, vv.storage[3]);
2128

2129
        let v = BVec3::new(false, true, false);
2130
        let vv: VectorValue = v.into();
2131
        assert_eq!(vv, VectorValue::new_bvec3(v));
2132
        assert_eq!(ScalarValue::BOOL_FALSE_STORAGE, vv.storage[0]);
2133
        assert_eq!(ScalarValue::BOOL_TRUE_STORAGE, vv.storage[1]);
2134
        assert_eq!(ScalarValue::BOOL_FALSE_STORAGE, vv.storage[2]);
2135
        assert_eq!(0, vv.storage[3]);
2136

2137
        let v = BVec4::new(false, true, false, true);
2138
        let vv: VectorValue = v.into();
2139
        assert_eq!(vv, VectorValue::new_bvec4(v));
2140
        assert_eq!(ScalarValue::BOOL_FALSE_STORAGE, vv.storage[0]);
2141
        assert_eq!(ScalarValue::BOOL_TRUE_STORAGE, vv.storage[1]);
2142
        assert_eq!(ScalarValue::BOOL_FALSE_STORAGE, vv.storage[2]);
2143
        assert_eq!(ScalarValue::BOOL_TRUE_STORAGE, vv.storage[3]);
2144

2145
        assert_eq!(
2146
            Value::Vector(VectorValue::new_vec2(Vec2::Y)),
2147
            Vec2::Y.into()
2148
        );
2149
        assert_eq!(
2150
            Value::Vector(VectorValue::new_vec3(Vec3::Z)),
2151
            Vec3::Z.into()
2152
        );
2153
        assert_eq!(
2154
            Value::Vector(VectorValue::new_vec4(Vec4::W)),
2155
            Vec4::W.into()
2156
        );
2157

2158
        assert_eq!(
2159
            Value::Vector(VectorValue::new_ivec2(IVec2::Y)),
2160
            IVec2::Y.into()
2161
        );
2162
        assert_eq!(
2163
            Value::Vector(VectorValue::new_ivec3(IVec3::Z)),
2164
            IVec3::Z.into()
2165
        );
2166
        assert_eq!(
2167
            Value::Vector(VectorValue::new_ivec4(IVec4::W)),
2168
            IVec4::W.into()
2169
        );
2170

2171
        assert_eq!(
2172
            Value::Vector(VectorValue::new_uvec2(UVec2::Y)),
2173
            UVec2::Y.into()
2174
        );
2175
        assert_eq!(
2176
            Value::Vector(VectorValue::new_uvec3(UVec3::Z)),
2177
            UVec3::Z.into()
2178
        );
2179
        assert_eq!(
2180
            Value::Vector(VectorValue::new_uvec4(UVec4::W)),
2181
            UVec4::W.into()
2182
        );
2183
    }
2184

2185
    fn calc_hash<H: Hash>(value: &H) -> u64 {
2186
        let mut hasher = DefaultHasher::default();
2187
        value.hash(&mut hasher);
2188
        hasher.finish()
2189
    }
2190

2191
    fn calc_f32_vector_hash(vector_type: VectorType, values: &[f32]) -> u64 {
2192
        let mut hasher = DefaultHasher::default();
2193
        vector_type.hash(&mut hasher);
2194
        for f in values {
2195
            FloatOrd(*f).hash(&mut hasher);
2196
        }
2197
        hasher.finish()
2198
    }
2199

2200
    fn calc_i32_vector_hash(vector_type: VectorType, values: &[i32]) -> u64 {
2201
        let mut hasher = DefaultHasher::default();
2202
        vector_type.hash(&mut hasher);
2203
        let v = bytemuck::cast_slice::<i32, u32>(values);
2204
        let c = vector_type.count();
2205
        v[..c].hash(&mut hasher);
2206
        hasher.finish()
2207
    }
2208

2209
    fn calc_u32_vector_hash(vector_type: VectorType, values: &[u32]) -> u64 {
2210
        let mut hasher = DefaultHasher::default();
2211
        vector_type.hash(&mut hasher);
2212
        let c = vector_type.count();
2213
        values[..c].hash(&mut hasher);
2214
        hasher.finish()
2215
    }
2216

2217
    #[test]
2218
    fn hash() {
2219
        // Different types must not be equal
2220
        let zeros = [
2221
            Into::<ScalarValue>::into(false),
2222
            Into::<ScalarValue>::into(0_f32),
2223
            Into::<ScalarValue>::into(0_u32),
2224
            Into::<ScalarValue>::into(0_i32),
2225
        ];
2226
        let ones = [
2227
            Into::<ScalarValue>::into(true),
2228
            Into::<ScalarValue>::into(1_f32),
2229
            Into::<ScalarValue>::into(1_u32),
2230
            Into::<ScalarValue>::into(1_i32),
2231
        ];
2232
        for arr in [zeros, ones] {
2233
            for i in 0..=3 {
2234
                for j in 0..=3 {
2235
                    if i == j {
2236
                        // Equal to self
2237
                        assert_eq!(arr[i], arr[j]);
2238
                        assert_eq!(calc_hash(&arr[i]), calc_hash(&arr[j]));
2239
                    } else {
2240
                        // Different types must be different and hash to different values
2241
                        assert_ne!(arr[i], arr[j]);
2242
                        assert_ne!(calc_hash(&arr[i]), calc_hash(&arr[j]));
2243
                    }
2244
                    // With casting however, values can be equal
2245
                    assert!(arr[i].cast_eq(&arr[j]));
2246
                }
2247
            }
2248
        }
2249

2250
        // Different types must not be equal
2251
        let vecs = [
2252
            VectorValue::new_vec2(Vec2::new(1., 0.)),
2253
            VectorValue::new_ivec2(IVec2::new(1, 0)),
2254
            VectorValue::new_uvec2(UVec2::new(1, 0)),
2255
            VectorValue::new_bvec2(BVec2::new(true, false)),
2256
        ];
2257
        for i in 0..=3 {
2258
            for j in 0..=3 {
2259
                if i == j {
2260
                    // Equal to self
2261
                    assert_eq!(vecs[i], vecs[j]);
2262
                    assert_eq!(calc_hash(&vecs[i]), calc_hash(&vecs[j]));
2263
                } else {
2264
                    // Different types must be different and hash to different values
2265
                    assert_ne!(vecs[i], vecs[j]);
2266
                    assert_ne!(calc_hash(&vecs[i]), calc_hash(&vecs[j]));
2267
                }
2268
                // With casting however, values can be equal
2269
                assert!(vecs[i].cast_eq(&vecs[j]));
2270
            }
2271
        }
2272

2273
        // Vectors with different sizes are always inequal
2274
        assert_ne!(
2275
            VectorValue::new_vec2(Vec2::ZERO),
2276
            VectorValue::new_vec3(Vec3::ZERO)
2277
        );
2278
        assert_ne!(
2279
            VectorValue::new_vec2(Vec2::ZERO),
2280
            VectorValue::new_vec4(Vec4::ZERO)
2281
        );
2282
        assert_ne!(
2283
            VectorValue::new_vec3(Vec3::ZERO),
2284
            VectorValue::new_vec4(Vec4::ZERO)
2285
        );
2286

2287
        assert_eq!(
2288
            calc_hash(&Into::<VectorValue>::into(Vec2::new(3.5, -42.))),
2289
            calc_f32_vector_hash(VectorType::VEC2F, &[3.5, -42.])
2290
        );
2291
        assert_eq!(
2292
            calc_hash(&Into::<VectorValue>::into(Vec3::new(3.5, -42., 999.99))),
2293
            calc_f32_vector_hash(VectorType::VEC3F, &[3.5, -42., 999.99])
2294
        );
2295
        assert_eq!(
2296
            calc_hash(&Into::<VectorValue>::into(Vec4::new(
2297
                3.5, -42., 999.99, -0.01,
2298
            ))),
2299
            calc_f32_vector_hash(VectorType::VEC4F, &[3.5, -42., 999.99, -0.01])
2300
        );
2301

2302
        assert_eq!(
2303
            calc_hash(&Into::<VectorValue>::into(IVec2::new(3, -42))),
2304
            calc_i32_vector_hash(VectorType::VEC2I, &[3, -42])
2305
        );
2306
        assert_eq!(
2307
            calc_hash(&Into::<VectorValue>::into(IVec3::new(3, -42, 999))),
2308
            calc_i32_vector_hash(VectorType::VEC3I, &[3, -42, 999])
2309
        );
2310
        assert_eq!(
2311
            calc_hash(&Into::<VectorValue>::into(IVec4::new(3, -42, 999, -1))),
2312
            calc_i32_vector_hash(VectorType::VEC4I, &[3, -42, 999, -1])
2313
        );
2314

2315
        assert_eq!(
2316
            calc_hash(&VectorValue::new_uvec2(UVec2::new(3, 42))),
2317
            calc_u32_vector_hash(VectorType::VEC2U, &[3, 42])
2318
        );
2319
        assert_eq!(
2320
            calc_hash(&VectorValue::new_uvec3(UVec3::new(3, 42, 999))),
2321
            calc_u32_vector_hash(VectorType::VEC3U, &[3, 42, 999])
2322
        );
2323
        assert_eq!(
2324
            calc_hash(&VectorValue::new_uvec4(UVec4::new(3, 42, 999, 1))),
2325
            calc_u32_vector_hash(VectorType::VEC4U, &[3, 42, 999, 1])
2326
        );
2327
    }
2328

2329
    #[test]
2330
    fn try_into() {
2331
        let b: Value = true.into();
2332
        let ret: Result<bool, _> = b.try_into();
2333
        assert_eq!(ret, Ok(true));
2334
        assert!(matches!(
2335
            TryInto::<f32>::try_into(b),
2336
            Err(ExprError::TypeError(_))
2337
        ));
2338
        assert!(matches!(
2339
            TryInto::<i32>::try_into(b),
2340
            Err(ExprError::TypeError(_))
2341
        ));
2342
        assert!(matches!(
2343
            TryInto::<Vec3>::try_into(b),
2344
            Err(ExprError::TypeError(_))
2345
        ));
2346

2347
        let f: Value = 3.4_f32.into();
2348
        let ret: Result<f32, _> = f.try_into();
2349
        assert_eq!(ret, Ok(3.4_f32));
2350
        assert!(matches!(
2351
            TryInto::<bool>::try_into(f),
2352
            Err(ExprError::TypeError(_))
2353
        ));
2354
        assert!(matches!(
2355
            TryInto::<u32>::try_into(f),
2356
            Err(ExprError::TypeError(_))
2357
        ));
2358
        assert!(matches!(
2359
            TryInto::<Vec2>::try_into(f),
2360
            Err(ExprError::TypeError(_))
2361
        ));
2362

2363
        let u: Value = 42_u32.into();
2364
        let ret: Result<u32, _> = u.try_into();
2365
        assert_eq!(ret, Ok(42_u32));
2366
        assert!(matches!(
2367
            TryInto::<bool>::try_into(u),
2368
            Err(ExprError::TypeError(_))
2369
        ));
2370
        assert!(matches!(
2371
            TryInto::<f32>::try_into(u),
2372
            Err(ExprError::TypeError(_))
2373
        ));
2374
        assert!(matches!(
2375
            TryInto::<Vec4>::try_into(u),
2376
            Err(ExprError::TypeError(_))
2377
        ));
2378

2379
        let i: Value = 42_i32.into();
2380
        let ret: Result<i32, _> = i.try_into();
2381
        assert_eq!(ret, Ok(42_i32));
2382
        assert!(matches!(
2383
            TryInto::<bool>::try_into(i),
2384
            Err(ExprError::TypeError(_))
2385
        ));
2386
        assert!(matches!(
2387
            TryInto::<f32>::try_into(i),
2388
            Err(ExprError::TypeError(_))
2389
        ));
2390
        assert!(matches!(
2391
            TryInto::<Vec4>::try_into(i),
2392
            Err(ExprError::TypeError(_))
2393
        ));
2394
    }
2395

2396
    #[test]
2397
    fn splat() {
2398
        let b = true;
2399
        for c in 2..=4 {
2400
            let x = VectorValue::splat(&b.into(), c);
2401
            assert_eq!(x.elem_type(), ScalarType::Bool);
2402
            assert_eq!(x.vector_type().count(), c as usize);
2403
            if c == 2 {
2404
                assert_eq!(TryInto::<BVec2>::try_into(x), Ok(BVec2::splat(b)));
2405
            } else if c == 3 {
2406
                assert_eq!(TryInto::<BVec3>::try_into(x), Ok(BVec3::splat(b)));
2407
            } else {
2408
                assert_eq!(TryInto::<BVec4>::try_into(x), Ok(BVec4::splat(b)));
2409
            }
2410
        }
2411

2412
        let f = 3.4_f32;
2413
        for c in 2..=4 {
2414
            let x = VectorValue::splat(&f.into(), c);
2415
            assert_eq!(x.elem_type(), ScalarType::Float);
2416
            assert_eq!(x.vector_type().count(), c as usize);
2417
            if c == 2 {
2418
                assert_eq!(TryInto::<Vec2>::try_into(x), Ok(Vec2::splat(f)));
2419
            } else if c == 3 {
2420
                assert_eq!(TryInto::<Vec3>::try_into(x), Ok(Vec3::splat(f)));
2421
            } else {
2422
                assert_eq!(TryInto::<Vec4>::try_into(x), Ok(Vec4::splat(f)));
2423
            }
2424
        }
2425

2426
        let i = -46458_i32;
2427
        for c in 2..=4 {
2428
            let x = VectorValue::splat(&i.into(), c);
2429
            assert_eq!(x.elem_type(), ScalarType::Int);
2430
            assert_eq!(x.vector_type().count(), c as usize);
2431
            if c == 2 {
2432
                assert_eq!(TryInto::<IVec2>::try_into(x), Ok(IVec2::splat(i)));
2433
            } else if c == 3 {
2434
                assert_eq!(TryInto::<IVec3>::try_into(x), Ok(IVec3::splat(i)));
2435
            } else {
2436
                assert_eq!(TryInto::<IVec4>::try_into(x), Ok(IVec4::splat(i)));
2437
            }
2438
        }
2439
    }
2440
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc