@@ -7,7 +7,11 @@ use hypermath::prelude::*;
7
7
use itertools:: Itertools ;
8
8
use parking_lot:: Mutex ;
9
9
10
- use crate :: { Axis , AxisInfo , LayerMask , LayeredTwist , PerAxis , PerPiece , Piece , PieceMask , Puzzle } ;
10
+ use crate :: {
11
+ Axis , AxisInfo , BoxDynPuzzleAnimation , BoxDynPuzzleStateRenderData , LayerMask , LayeredTwist ,
12
+ NdEuclidPuzzleAnimation , NdEuclidPuzzleStateRenderData , PerAxis , PerPiece , Piece , PieceMask ,
13
+ Puzzle , PuzzleState ,
14
+ } ;
11
15
12
16
type PerCachedTransform < T > = GenericVec < CachedTransform , T > ;
13
17
idx_struct ! {
@@ -39,7 +43,7 @@ impl CachedTransformData {
39
43
40
44
/// Instance of a puzzle with a particular state.
41
45
#[ derive( Debug , Clone ) ]
42
- pub struct PuzzleState {
46
+ pub struct HypershapePuzzleState {
43
47
/// Immutable puzzle type info.
44
48
puzzle_type : Arc < Puzzle > ,
45
49
/// Attitude (position & rotation) of each piece.
@@ -48,7 +52,47 @@ pub struct PuzzleState {
48
52
cached_transforms : Arc < Mutex < PerCachedTransform < CachedTransformData > > > ,
49
53
cached_transform_by_motor : Arc < Mutex < ApproxHashMap < pga:: Motor , CachedTransform > > > ,
50
54
}
51
- impl PuzzleState {
55
+
56
+ impl PuzzleState for HypershapePuzzleState {
57
+ fn ty ( & self ) -> & Arc < Puzzle > {
58
+ & self . puzzle_type
59
+ }
60
+
61
+ fn render_data ( & self ) -> BoxDynPuzzleStateRenderData {
62
+ NdEuclidPuzzleStateRenderData {
63
+ piece_transforms : self . piece_transforms ( ) ,
64
+ }
65
+ . into ( )
66
+ }
67
+
68
+ fn render_data_with_animation (
69
+ & self ,
70
+ anim : & BoxDynPuzzleAnimation ,
71
+ t : f32 ,
72
+ ) -> BoxDynPuzzleStateRenderData {
73
+ let anim = anim
74
+ . downcast_ref :: < NdEuclidPuzzleAnimation > ( )
75
+ . expect ( "invalid animation for puzzle" ) ;
76
+
77
+ let start = & anim. initial_transform ;
78
+ let end = & anim. final_transform ;
79
+ let m = if t == 0.0 {
80
+ start. clone ( )
81
+ } else if t == 1.0 {
82
+ end. clone ( )
83
+ } else {
84
+ pga:: Motor :: slerp_infallible ( start, end, t as _ )
85
+ } ;
86
+
87
+ let mut piece_transforms = self . piece_transforms ( ) ;
88
+ for piece in anim. pieces . iter ( ) {
89
+ piece_transforms[ piece] = & m * & piece_transforms[ piece] ;
90
+ }
91
+ NdEuclidPuzzleStateRenderData { piece_transforms } . into ( )
92
+ }
93
+ }
94
+
95
+ impl HypershapePuzzleState {
52
96
/// Constructs a new instance of a puzzle.
53
97
pub fn new ( puzzle_type : Arc < Puzzle > ) -> Self {
54
98
let ident = pga:: Motor :: ident ( puzzle_type. ndim ( ) ) ;
@@ -62,36 +106,19 @@ impl PuzzleState {
62
106
by_motor. insert ( ident, CachedTransform ( 0 ) ) ;
63
107
let cached_transform_by_motor = Arc :: new ( Mutex :: new ( by_motor) ) ;
64
108
65
- PuzzleState {
109
+ HypershapePuzzleState {
66
110
puzzle_type,
67
111
piece_transforms,
68
112
cached_transforms,
69
113
cached_transform_by_motor,
70
114
}
71
115
}
72
- /// Returns the puzzle type
73
- pub fn ty ( & self ) -> & Arc < Puzzle > {
74
- & self . puzzle_type
75
- }
76
116
/// Returns the position and rotation of each piece.
77
- pub fn piece_transforms ( & self ) -> PerPiece < pga:: Motor > {
117
+ pub ( crate ) fn piece_transforms ( & self ) -> PerPiece < pga:: Motor > {
78
118
let cached = self . cached_transforms . lock ( ) ;
79
119
self . piece_transforms
80
120
. map_ref ( |_, & i| cached[ i] . motor . clone ( ) )
81
121
}
82
- /// Returns the position and rotation of each piece during an arbitrary
83
- /// animation affecting a subset of pieces.
84
- pub fn partial_piece_transforms (
85
- & self ,
86
- grip : & PieceMask ,
87
- transform : & pga:: Motor ,
88
- ) -> PerPiece < pga:: Motor > {
89
- self . piece_transforms ( )
90
- . map ( |piece, static_transform| match grip. contains ( piece) {
91
- true => transform * static_transform,
92
- _ => static_transform. clone ( ) ,
93
- } )
94
- }
95
122
96
123
/// Does a twist, or returns an error containing the set of pieces that
97
124
/// prevented the twist.
0 commit comments