1
1
use blade_graphics as gpu;
2
- use vandals_and_heroes:: { config, Camera , ModelDesc , Object , Physics , Render , TerrainBody } ;
2
+ use vandals_and_heroes:: {
3
+ config, Camera , Loader , ModelDesc , ModelInstance , Physics , PhysicsBodyHandle , Render , Terrain ,
4
+ TerrainBody ,
5
+ } ;
3
6
7
+ use nalgebra:: Matrix4 ;
4
8
use std:: { f32, fs, path, sync:: Arc , thread, time} ;
5
9
6
- struct Car {
7
- body : Object ,
10
+ pub struct Object {
11
+ pub model_instance : ModelInstance ,
12
+ pub rigid_body : rapier3d:: dynamics:: RigidBodyHandle ,
8
13
}
9
14
10
15
pub struct Game {
@@ -22,7 +27,8 @@ pub struct Game {
22
27
last_mouse_pos : [ i32 ; 2 ] ,
23
28
// game
24
29
terrain_body : TerrainBody ,
25
- car : Car ,
30
+ terrain : Terrain ,
31
+ car : Object ,
26
32
}
27
33
28
34
pub struct QuitEvent ;
@@ -65,29 +71,15 @@ impl Game {
65
71
66
72
let mut loader = render. start_loading ( ) ;
67
73
68
- let car_body = {
69
- log:: info!( "Loading car: {}" , config. car) ;
70
- let car_path = path:: PathBuf :: from ( "data/cars" ) . join ( config. car ) ;
71
- let car_config: config:: Car = ron:: de:: from_bytes (
72
- & fs:: read ( car_path. join ( "car.ron" ) ) . expect ( "Unable to open the car config" ) ,
73
- )
74
- . expect ( "Unable to parse the car config" ) ;
75
- let desc = ModelDesc {
76
- scale : car_config. scale ,
77
- density : car_config. density ,
78
- } ;
79
- loader. load_gltf ( & car_path. join ( "body.glb" ) , desc)
80
- } ;
81
-
82
- let map_config = {
74
+ let terrain = {
83
75
log:: info!( "Loading map: {}" , config. map) ;
84
76
let map_path = path:: PathBuf :: from ( "data/maps" ) . join ( config. map ) ;
85
77
let mut map_config: config:: Map = ron:: de:: from_bytes (
86
78
& fs:: read ( map_path. join ( "map.ron" ) ) . expect ( "Unable to open the map config" ) ,
87
79
)
88
80
. expect ( "Unable to parse the map config" ) ;
89
81
90
- let ( map_texture , map_extent) = loader. load_png ( & map_path. join ( "map.png" ) ) ;
82
+ let ( texture , map_extent) = loader. load_png ( & map_path. join ( "map.png" ) ) ;
91
83
92
84
if map_config. length == 0.0 {
93
85
let circumference = 2.0 * f32:: consts:: PI * map_config. radius . start ;
@@ -96,44 +88,50 @@ impl Game {
96
88
log:: info!( "Derived map length to be {}" , map_config. length) ;
97
89
}
98
90
99
- let submission = loader. finish ( ) ;
100
- render. accept_submission ( submission) ;
101
- render. set_map ( map_texture, & map_config) ;
102
-
103
- map_config
91
+ Terrain {
92
+ config : map_config,
93
+ texture,
94
+ }
104
95
} ;
96
+ let mut physics = Physics :: default ( ) ;
97
+ let terrain_body = physics. create_terrain ( & terrain. config ) ;
98
+
99
+ let car = Self :: load_car (
100
+ & mut loader,
101
+ & mut physics,
102
+ & config. car ,
103
+ nalgebra:: Isometry3 {
104
+ translation : nalgebra:: Vector3 :: new (
105
+ 0.0 ,
106
+ 0.35 * terrain. config . radius . start + 0.65 * terrain. config . radius . end ,
107
+ 0.1 * terrain. config . length ,
108
+ )
109
+ . into ( ) ,
110
+ rotation : nalgebra:: UnitQuaternion :: from_axis_angle (
111
+ & nalgebra:: Vector3 :: y_axis ( ) ,
112
+ 0.5 * f32:: consts:: PI ,
113
+ ) ,
114
+ } ,
115
+ ) ;
116
+
117
+ let submission = loader. finish ( ) ;
118
+ render. accept_submission ( submission) ;
119
+ render. wait_for_gpu ( ) ;
105
120
106
121
let camera = Camera {
107
- pos : nalgebra:: Vector3 :: new ( 0.0 , map_config. radius . end , 0.1 * map_config. length ) ,
122
+ pos : nalgebra:: Vector3 :: new (
123
+ 0.0 ,
124
+ terrain. config . radius . end ,
125
+ 0.1 * terrain. config . length ,
126
+ ) ,
108
127
rot : nalgebra:: UnitQuaternion :: from_axis_angle (
109
128
& nalgebra:: Vector3 :: x_axis ( ) ,
110
129
0.3 * f32:: consts:: PI ,
111
130
) ,
112
- clip : 1.0 ..map_config . length ,
131
+ clip : 1.0 ..terrain . config . length ,
113
132
..Default :: default ( )
114
133
} ;
115
134
116
- let mut physics = Physics :: default ( ) ;
117
- let terrain_body = physics. create_terrain ( & map_config) ;
118
-
119
- let car = Car {
120
- body : physics. create_object (
121
- Arc :: new ( car_body) ,
122
- nalgebra:: Isometry3 {
123
- translation : nalgebra:: Vector3 :: new (
124
- 0.0 ,
125
- 0.35 * map_config. radius . start + 0.65 * map_config. radius . end ,
126
- 0.1 * map_config. length ,
127
- )
128
- . into ( ) ,
129
- rotation : nalgebra:: UnitQuaternion :: from_axis_angle (
130
- & nalgebra:: Vector3 :: y_axis ( ) ,
131
- 0.5 * f32:: consts:: PI ,
132
- ) ,
133
- } ,
134
- ) ,
135
- } ;
136
-
137
135
Self {
138
136
choir,
139
137
render,
@@ -144,28 +142,71 @@ impl Game {
144
142
in_camera_drag : false ,
145
143
last_mouse_pos : [ 0 ; 2 ] ,
146
144
terrain_body,
145
+ terrain,
147
146
car,
148
147
}
149
148
}
150
149
150
+ fn load_car (
151
+ loader : & mut Loader ,
152
+ physics : & mut Physics ,
153
+ car_path : & str ,
154
+ transform : nalgebra:: Isometry3 < f32 > ,
155
+ ) -> Object {
156
+ log:: info!( "Loading car: {}" , car_path) ;
157
+ let car_path = path:: PathBuf :: from ( "data/cars" ) . join ( car_path) ;
158
+ let car_config: config:: Car = ron:: de:: from_bytes (
159
+ & fs:: read ( car_path. join ( "car.ron" ) ) . expect ( "Unable to open the car config" ) ,
160
+ )
161
+ . expect ( "Unable to parse the car config" ) ;
162
+ let model_desc = Loader :: read_gltf (
163
+ & car_path. join ( "body.glb" ) ,
164
+ Matrix4 :: identity ( ) . scale ( car_config. scale ) ,
165
+ ) ;
166
+ let model = loader. load_model ( & model_desc) ;
167
+ let collider = Self :: create_mesh_collider ( model_desc, car_config. density ) ;
168
+
169
+ let rigid_body = rapier3d:: dynamics:: RigidBodyBuilder :: dynamic ( )
170
+ . position ( transform)
171
+ . build ( ) ;
172
+
173
+ let PhysicsBodyHandle {
174
+ rigid_body_handle, ..
175
+ } = physics. add_rigid_body ( rigid_body, vec ! [ collider] ) ;
176
+ Object {
177
+ model_instance : ModelInstance {
178
+ model : Arc :: new ( model) ,
179
+ transform,
180
+ } ,
181
+ rigid_body : rigid_body_handle,
182
+ }
183
+ }
184
+
185
+ fn create_mesh_collider ( model_desc : ModelDesc , density : f32 ) -> rapier3d:: geometry:: Collider {
186
+ rapier3d:: geometry:: ColliderBuilder :: trimesh ( model_desc. positions ( ) , model_desc. indices ( ) )
187
+ . density ( density)
188
+ . build ( )
189
+ }
190
+
151
191
fn update_physics ( & mut self ) {
152
- let mut objects = [ & mut self . car . body ] ;
192
+ let mut objects = [ & mut self . car ] ;
153
193
for object in objects. iter_mut ( ) {
154
194
self . physics
155
195
. update_gravity ( object. rigid_body , & self . terrain_body ) ;
156
196
}
157
197
self . physics . step ( ) ;
158
198
for object in objects. iter_mut ( ) {
159
- object. transform = self . physics . get_transform ( object. rigid_body ) ;
199
+ object. model_instance . transform = self . physics . get_transform ( object. rigid_body ) ;
160
200
}
161
201
}
162
202
163
203
fn redraw ( & mut self ) -> time:: Duration {
164
204
//TODO: detach from rendering
165
205
self . update_physics ( ) ;
166
206
167
- let objects = [ & self . car . body ] ;
168
- self . render . draw ( & self . camera , & objects) ;
207
+ let model_instances = vec ! [ & self . car. model_instance] ;
208
+ self . render
209
+ . draw ( & self . camera , & self . terrain , & model_instances) ;
169
210
170
211
time:: Duration :: from_millis ( 16 )
171
212
}
@@ -269,7 +310,7 @@ impl Drop for Game {
269
310
}
270
311
log:: info!( "Deinitializing" ) ;
271
312
self . render . wait_for_gpu ( ) ;
272
- self . car . body . model . free ( self . render . context ( ) ) ;
313
+ self . car . model_instance . model . free ( self . render . context ( ) ) ;
273
314
self . render . deinit ( ) ;
274
315
}
275
316
}
0 commit comments