Pivot to game jam game about an ice cream truck lol
This commit is contained in:
parent
8378b943cb
commit
1094afac02
24
assets/cone_convex.obj
Normal file
24
assets/cone_convex.obj
Normal file
@ -0,0 +1,24 @@
|
||||
# Blender 4.4.3
|
||||
# www.blender.org
|
||||
o Cone_Col
|
||||
v 0.033251 2.766126 0.099102
|
||||
v 0.592864 3.230694 0.103337
|
||||
v 0.500712 3.913186 -0.130586
|
||||
v -0.151054 4.131110 -0.368743
|
||||
v -0.710666 3.666542 -0.372978
|
||||
v -0.618514 2.984050 -0.139055
|
||||
v 0.428131 2.878846 -1.989048
|
||||
v -0.527696 4.062689 1.583188
|
||||
s 0
|
||||
f 1 7 2
|
||||
f 2 7 3
|
||||
f 3 7 4
|
||||
f 4 7 5
|
||||
f 5 7 6
|
||||
f 6 7 1
|
||||
f 8 3 4
|
||||
f 8 2 3
|
||||
f 8 1 2
|
||||
f 8 6 1
|
||||
f 8 5 6
|
||||
f 8 4 5
|
BIN
assets/ice_cream_truck.glb
(Stored with Git LFS)
Normal file
BIN
assets/ice_cream_truck.glb
(Stored with Git LFS)
Normal file
Binary file not shown.
21
assets/ice_cream_truck_convex.obj
Normal file
21
assets/ice_cream_truck_convex.obj
Normal file
@ -0,0 +1,21 @@
|
||||
# Blender 4.4.3
|
||||
# www.blender.org
|
||||
o Body_Col
|
||||
v 1.049841 0.369559 2.380744
|
||||
v 1.049841 1.130518 2.380744
|
||||
v 1.049841 2.734402 1.356388
|
||||
v 1.049841 0.356804 -3.483506
|
||||
v 1.049841 2.721647 -3.470500
|
||||
v -1.049841 0.369559 2.380744
|
||||
v -1.049841 1.130518 2.380744
|
||||
v -1.049841 2.734402 1.356388
|
||||
v -1.049841 0.356804 -3.483506
|
||||
v -1.049841 2.721647 -3.470500
|
||||
s 0
|
||||
f 1 6 9 4
|
||||
f 3 2 1 4 5
|
||||
f 6 1 2 7
|
||||
f 4 9 10 5
|
||||
f 5 10 8 3
|
||||
f 8 10 9 6 7
|
||||
f 8 7 2 3
|
BIN
assets/ice_cream_truck_wheel.glb
(Stored with Git LFS)
Normal file
BIN
assets/ice_cream_truck_wheel.glb
(Stored with Git LFS)
Normal file
Binary file not shown.
24
assets/left_fence_convex.obj
Normal file
24
assets/left_fence_convex.obj
Normal file
@ -0,0 +1,24 @@
|
||||
# Blender 4.4.3
|
||||
# www.blender.org
|
||||
o Left_Fence
|
||||
v 0.827589 2.728590 -0.605606
|
||||
v 0.827589 3.290456 -0.605606
|
||||
v 0.827589 2.728590 -2.598043
|
||||
v 0.827589 3.290456 -2.598043
|
||||
v 0.925107 2.728590 -0.605606
|
||||
v 0.925107 3.290456 -0.605606
|
||||
v 0.925107 2.728590 -2.598043
|
||||
v 0.925107 3.290456 -2.598043
|
||||
v 0.827589 3.432860 -0.744844
|
||||
v 0.827589 3.432860 -2.458806
|
||||
v 0.925107 3.432860 -0.744844
|
||||
v 0.925107 3.432860 -2.458806
|
||||
s 0
|
||||
f 8 12 11 6 5 7
|
||||
f 3 4 8 7
|
||||
f 5 6 2 1
|
||||
f 3 7 5 1
|
||||
f 12 10 9 11
|
||||
f 2 6 11 9
|
||||
f 8 4 10 12
|
||||
f 2 9 10 4 3 1
|
24
assets/right_fence_convex.obj
Normal file
24
assets/right_fence_convex.obj
Normal file
@ -0,0 +1,24 @@
|
||||
# Blender 4.4.3
|
||||
# www.blender.org
|
||||
o Right_Fence
|
||||
v -0.925107 2.728590 -0.605606
|
||||
v -0.925107 3.290456 -0.605606
|
||||
v -0.925107 2.728590 -2.598043
|
||||
v -0.925107 3.290456 -2.598043
|
||||
v -0.827589 2.728590 -0.605606
|
||||
v -0.827589 3.290456 -0.605606
|
||||
v -0.827589 2.728590 -2.598043
|
||||
v -0.827589 3.290456 -2.598043
|
||||
v -0.925107 3.432860 -0.744844
|
||||
v -0.925107 3.432860 -2.458806
|
||||
v -0.827589 3.432860 -0.744844
|
||||
v -0.827589 3.432860 -2.458806
|
||||
s 0
|
||||
f 8 12 11 6 5 7
|
||||
f 3 4 8 7
|
||||
f 5 6 2 1
|
||||
f 3 7 5 1
|
||||
f 12 10 9 11
|
||||
f 2 6 11 9
|
||||
f 8 4 10 12
|
||||
f 2 9 10 4 3 1
|
38
assets/shaders/water_ps.glsl
Normal file
38
assets/shaders/water_ps.glsl
Normal file
@ -0,0 +1,38 @@
|
||||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
// in vec3 worldPosition;
|
||||
in vec3 worldNormal;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 colDiffuse;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
uniform vec3 ambient;
|
||||
uniform vec3 lightDir;
|
||||
uniform vec3 lightColor;
|
||||
|
||||
|
||||
// NOTE: Add your custom variables here
|
||||
|
||||
void main()
|
||||
{
|
||||
// Texel color fetching from texture sampler
|
||||
vec4 texelColor = vec4(1); // texture(texture0, fragTexCoord);
|
||||
|
||||
// final color is the color from the texture
|
||||
// times the tint color (colDiffuse)
|
||||
// times the fragment color (interpolated vertex color)
|
||||
|
||||
float NDotL = max(dot(lightDir, -worldNormal), 0);
|
||||
// float toon = 0.5 * smoothstep(0.5, 0.51, NDotL) + 0.5;
|
||||
vec3 light = mix(vec3(ambient), lightColor, NDotL);
|
||||
|
||||
finalColor = texelColor * colDiffuse * vec4(light, 1);
|
||||
}
|
45
assets/shaders/water_vs.glsl
Normal file
45
assets/shaders/water_vs.glsl
Normal file
@ -0,0 +1,45 @@
|
||||
#version 330
|
||||
|
||||
// Input vertex attributes
|
||||
in vec3 vertexPosition;
|
||||
in vec2 vertexTexCoord;
|
||||
in vec3 vertexNormal;
|
||||
in vec4 vertexColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform mat4 mvp;
|
||||
uniform mat4 matModel;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
|
||||
// Output vertex attributes (to fragment shader)
|
||||
out vec2 fragTexCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
// NOTE: Add your custom variables here
|
||||
out vec3 worldPosition;
|
||||
out vec3 worldNormal;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Send vertex attributes to fragment shader
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragColor = vertexColor;
|
||||
|
||||
float l = textureOffset(texture0, vertexTexCoord, ivec2(-1, 0)).x;
|
||||
float r = textureOffset(texture0, vertexTexCoord, ivec2(1, 0)).x;
|
||||
float u = textureOffset(texture0, vertexTexCoord, ivec2(0, -1)).x;
|
||||
float d = textureOffset(texture0, vertexTexCoord, ivec2(0, 1)).x;
|
||||
|
||||
vec3 lr = normalize(vec3(1, 0, r - l));
|
||||
vec3 ud = normalize(vec3(0, 1, u - d));
|
||||
|
||||
vec3 normal = normalize(cross(lr, ud));
|
||||
|
||||
vec3 localPos = vertexPosition + vec3(0, texture2D(texture0, vertexTexCoord).x * 0.1, 0);
|
||||
|
||||
// Calculate final vertex position
|
||||
gl_Position = mvp*vec4(localPos, 1.0);
|
||||
worldPosition = (matModel * vec4(localPos, 1.0)).xyz;
|
||||
worldNormal = mat3(matModel) * normal;
|
||||
}
|
3147780
assets/subdiv_plane.obj
Normal file
3147780
assets/subdiv_plane.obj
Normal file
File diff suppressed because it is too large
Load Diff
@ -238,7 +238,7 @@ main :: proc() {
|
||||
opts := Options {
|
||||
tracy = true,
|
||||
debug = true,
|
||||
optimize = false,
|
||||
optimize = true,
|
||||
run = true,
|
||||
}
|
||||
flags.parse_or_exit(&opts, os.args, .Unix, context.temp_allocator)
|
||||
|
@ -79,6 +79,7 @@ Shader_Location :: enum {
|
||||
Ambient,
|
||||
LightDir,
|
||||
LightColor,
|
||||
Heightmap,
|
||||
}
|
||||
Shader_Location_Set :: bit_set[Shader_Location]
|
||||
Shader_Location_Array :: [Shader_Location]i32
|
||||
@ -87,6 +88,7 @@ SHADER_LOCATION_NAMES := [Shader_Location]cstring {
|
||||
.Ambient = "ambient",
|
||||
.LightDir = "lightDir",
|
||||
.LightColor = "lightColor",
|
||||
.Heightmap = "heightmap",
|
||||
}
|
||||
|
||||
Loaded_Shader :: struct {
|
||||
|
247
game/fluid.odin
Normal file
247
game/fluid.odin
Normal file
@ -0,0 +1,247 @@
|
||||
package game
|
||||
|
||||
import "core:log"
|
||||
import "core:math"
|
||||
import lg "core:math/linalg"
|
||||
import "game:assets"
|
||||
import rl "libs:raylib"
|
||||
|
||||
// Some fluid simulation tests
|
||||
|
||||
Vec2i32 :: [2]i32
|
||||
|
||||
Fluid :: struct {
|
||||
size: Vec2i32,
|
||||
friction: f32,
|
||||
gravity: f32,
|
||||
terrain: []f32,
|
||||
heights: []f32,
|
||||
flow_x: []f32,
|
||||
flow_y: []f32,
|
||||
}
|
||||
|
||||
fluid_init :: proc(fluid: ^Fluid, size: Vec2i32, friction: f32, gravity: f32) {
|
||||
fluid.size = size
|
||||
fluid.friction = friction
|
||||
fluid.gravity = gravity
|
||||
fluid.terrain = make([]f32, size.x * size.y)
|
||||
fluid.heights = make([]f32, size.x * size.y)
|
||||
fluid.flow_x = make([]f32, (size.x + 1) * size.y)
|
||||
fluid.flow_y = make([]f32, (size.y + 1) * size.x)
|
||||
}
|
||||
|
||||
fluid_destroy :: proc(fluid: ^Fluid) {
|
||||
delete(fluid.terrain)
|
||||
delete(fluid.heights)
|
||||
delete(fluid.flow_x)
|
||||
delete(fluid.flow_y)
|
||||
}
|
||||
|
||||
fluid_terrain :: #force_inline proc "contextless" (fluid: ^Fluid, x: i32, y: i32) -> ^f32 {
|
||||
idx := fluid.size.x * y + x
|
||||
return &fluid.terrain[idx]
|
||||
}
|
||||
|
||||
fluid_height :: #force_inline proc "contextless" (fluid: ^Fluid, x: i32, y: i32) -> ^f32 {
|
||||
idx := fluid.size.x * y + x
|
||||
return &fluid.heights[idx]
|
||||
}
|
||||
|
||||
fluid_flow_x :: #force_inline proc "contextless" (fluid: ^Fluid, x: i32, y: i32) -> ^f32 {
|
||||
idx := (fluid.size.x + 1) * y + x
|
||||
return &fluid.flow_x[idx]
|
||||
}
|
||||
|
||||
fluid_flow_y :: #force_inline proc "contextless" (fluid: ^Fluid, x: i32, y: i32) -> ^f32 {
|
||||
idx := fluid.size.x * y + x
|
||||
return &fluid.flow_y[idx]
|
||||
}
|
||||
|
||||
fluid_simulate :: proc "contextless" (fluid: ^Fluid, dt: f32) {
|
||||
dt := dt
|
||||
dt = 0.2
|
||||
cell_size := f32(1)
|
||||
dx := cell_size
|
||||
dy := cell_size
|
||||
area := f32(1)
|
||||
mult := 10 * dt * area / cell_size
|
||||
|
||||
friction := math.pow(1.0 - 0.00, dt)
|
||||
|
||||
// Flow acceleration
|
||||
{
|
||||
for y in 0 ..< fluid.size.y {
|
||||
for x in 1 ..< fluid.size.x {
|
||||
fluid_flow_x(fluid, x, y)^ =
|
||||
fluid_flow_x(fluid, x, y)^ * friction +
|
||||
(fluid_height(fluid, x - 1, y)^ +
|
||||
fluid_terrain(fluid, x - 1, y)^ -
|
||||
fluid_height(fluid, x, y)^ -
|
||||
fluid_terrain(fluid, x, y)^) *
|
||||
mult
|
||||
}
|
||||
}
|
||||
|
||||
for y in 1 ..< fluid.size.y {
|
||||
for x in 0 ..< fluid.size.x {
|
||||
fluid_flow_y(fluid, x, y)^ =
|
||||
fluid_flow_y(fluid, x, y)^ * friction +
|
||||
(fluid_height(fluid, x, y - 1)^ +
|
||||
fluid_terrain(fluid, x, y - 1)^ -
|
||||
fluid_height(fluid, x, y)^ -
|
||||
fluid_terrain(fluid, x, y)^) *
|
||||
mult
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flow Scaling to prevent water height going below 0
|
||||
{
|
||||
for y in 0 ..< fluid.size.y {
|
||||
for x in 0 ..< fluid.size.x {
|
||||
total_outflow := f32(0)
|
||||
|
||||
total_outflow -= fluid_flow_x(fluid, x, y)^
|
||||
total_outflow -= fluid_flow_y(fluid, x, y)^
|
||||
total_outflow += fluid_flow_x(fluid, x + 1, y)^
|
||||
total_outflow += fluid_flow_y(fluid, x, y + 1)^
|
||||
|
||||
max_outflow := fluid_height(fluid, x, y)^ * dx * dy / dt
|
||||
|
||||
EPS :: f32(0.0001)
|
||||
if total_outflow > 0 {
|
||||
scale := min(1, max_outflow / total_outflow)
|
||||
|
||||
if fluid_flow_x(fluid, x, y)^ < 0 {
|
||||
fluid_flow_x(fluid, x, y)^ *= scale
|
||||
}
|
||||
if fluid_flow_y(fluid, x, y)^ < 0 {
|
||||
fluid_flow_y(fluid, x, y)^ *= scale
|
||||
}
|
||||
if fluid_flow_x(fluid, x + 1, y)^ > 0 {
|
||||
fluid_flow_x(fluid, x + 1, y)^ *= scale
|
||||
}
|
||||
if fluid_flow_y(fluid, x, y + 1)^ > 0 {
|
||||
fluid_flow_y(fluid, x, y + 1)^ *= scale
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Height update
|
||||
{
|
||||
factor := dt / dx / dy
|
||||
for y in 0 ..< fluid.size.y {
|
||||
for x in 0 ..< fluid.size.x {
|
||||
fluid_height(fluid, x, y)^ +=
|
||||
(fluid_flow_x(fluid, x, y)^ +
|
||||
fluid_flow_y(fluid, x, y)^ -
|
||||
fluid_flow_x(fluid, x + 1, y)^ -
|
||||
fluid_flow_y(fluid, x, y + 1)^) *
|
||||
factor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Fluid_Scene :: struct {
|
||||
fluid: Fluid,
|
||||
texture: rl.Texture,
|
||||
}
|
||||
|
||||
fluid_scene_init :: proc(scene: ^Fluid_Scene) {
|
||||
fluid_init(&scene.fluid, {256, 256}, 0.1, 9.8)
|
||||
}
|
||||
|
||||
fluid_scene_destroy :: proc(scene: ^Fluid_Scene) {
|
||||
fluid_destroy(&scene.fluid)
|
||||
rl.UnloadTexture(scene.texture)
|
||||
}
|
||||
|
||||
fluid_scene_update :: proc(scene: ^Fluid_Scene, dt: f32) {
|
||||
if rl.IsMouseButtonDown(rl.MouseButton.LEFT) || rl.IsMouseButtonDown(rl.MouseButton.RIGHT) {
|
||||
sim_size := scene.fluid.size
|
||||
mouse_pos := rl.GetMousePosition()
|
||||
center := Vec2i32{i32(mouse_pos.x), i32(mouse_pos.y)}
|
||||
|
||||
for y in max(center.y - 100, 0) ..< min(center.y + 100, sim_size.y - 1) {
|
||||
for x in max(center.x - 100, 0) ..< max(center.x + 100, sim_size.x - 1) {
|
||||
offset_from_center := Vec2i32{x, y} - center
|
||||
if lg.length2([2]f32{f32(offset_from_center.x), f32(offset_from_center.y)}) <
|
||||
(100 * 100) {
|
||||
|
||||
if rl.IsMouseButtonDown(.LEFT) {
|
||||
fluid_height(&scene.fluid, x, y)^ = 20
|
||||
}
|
||||
|
||||
// if rl.IsMouseButtonDown(.RIGHT) {
|
||||
// fluid_terrain(&scene.fluid, x, y)^ += 10
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fluid_simulate(&scene.fluid, dt)
|
||||
}
|
||||
|
||||
fluid_scene_draw_3d :: proc(assetman: ^assets.Asset_Manager, scene: ^Fluid_Scene) {
|
||||
sim_size := scene.fluid.size
|
||||
image: rl.Image
|
||||
image.format = rl.PixelFormat.UNCOMPRESSED_R32
|
||||
image.width = sim_size.x
|
||||
image.height = sim_size.y
|
||||
image.mipmaps = 1
|
||||
image_data := make([]f32, sim_size.x * sim_size.y, context.temp_allocator)
|
||||
image.data = rawptr(&image_data[0])
|
||||
|
||||
for y in 0 ..< sim_size.y {
|
||||
for x in 0 ..< sim_size.x {
|
||||
image_data[y * sim_size.x + x] = fluid_height(&scene.fluid, x, y)^ * 0.01
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if !rl.IsTextureValid(scene.texture) ||
|
||||
scene.texture.width != sim_size.x ||
|
||||
scene.texture.height != sim_size.y {
|
||||
rl.UnloadTexture(scene.texture)
|
||||
|
||||
scene.texture = rl.LoadTextureFromImage(image)
|
||||
} else {
|
||||
rl.UpdateTexture(scene.texture, image.data)
|
||||
}
|
||||
}
|
||||
|
||||
if !rl.IsTextureValid(scene.texture) || !rl.IsTextureReady(scene.texture) {
|
||||
log.warnf("texture is not valid")
|
||||
}
|
||||
|
||||
water_shader := assets.get_shader(
|
||||
assetman,
|
||||
"assets/shaders/water_vs.glsl",
|
||||
"assets/shaders/water_ps.glsl",
|
||||
assets.Shader_Location_Set{.LightDir, .LightColor, .Ambient},
|
||||
)
|
||||
|
||||
light_dir := lg.normalize(rl.Vector3{1, -1, 0})
|
||||
ambient := rl.Vector3{0.1, 0.1, 0.1}
|
||||
light_color := rl.Vector3{0.816, 0.855, 0.89}
|
||||
rl.SetShaderValue(water_shader.shader, water_shader.locations[.LightDir], &light_dir, .VEC3)
|
||||
rl.SetShaderValue(water_shader.shader, water_shader.locations[.Ambient], &ambient, .VEC3)
|
||||
rl.SetShaderValue(
|
||||
water_shader.shader,
|
||||
water_shader.locations[.LightColor],
|
||||
&light_color,
|
||||
.VEC3,
|
||||
)
|
||||
|
||||
model := assets.get_model(assetman, "assets/subdiv_plane.obj")
|
||||
model.materials[0].shader = water_shader.shader
|
||||
model.materials[0].maps[rl.MaterialMapIndex.ALBEDO].texture = scene.texture
|
||||
rl.DrawModel(model, {0, 1, 0}, 1, rl.WHITE)
|
||||
}
|
||||
|
||||
fluid_scene_draw_2d :: proc(assetman: ^assets.Asset_Manager, scene: ^Fluid_Scene) {
|
||||
rl.DrawTexture(scene.texture, 0, 0, rl.WHITE)
|
||||
}
|
@ -126,6 +126,7 @@ Game_Memory :: struct {
|
||||
name_container: name.Container,
|
||||
assetman: assets.Asset_Manager,
|
||||
runtime_world: Runtime_World,
|
||||
fluid_scene: Fluid_Scene,
|
||||
es: Editor_State,
|
||||
ui_context: ui.Context,
|
||||
default_font: rl.Font,
|
||||
@ -362,7 +363,7 @@ World_Update_Config :: struct {
|
||||
|
||||
update_world :: proc(world: ^World, dt: f32, config: World_Update_Config) {
|
||||
if !world.pause {
|
||||
car_model := assets.get_model(&g_mem.assetman, "assets/toyota_corolla_ae86_trueno.glb")
|
||||
car_model := assets.get_model(&g_mem.assetman, "assets/ice_cream_truck.glb")
|
||||
car_bounds := rl.GetModelBoundingBox(car_model)
|
||||
world.car_com = (car_bounds.min + car_bounds.max) / 2
|
||||
|
||||
@ -400,7 +401,10 @@ update_world :: proc(world: ^World, dt: f32, config: World_Update_Config) {
|
||||
)
|
||||
}
|
||||
|
||||
car_convex := assets.get_convex(&g_mem.assetman, "assets/car_convex.obj")
|
||||
car_convex := assets.get_convex(&g_mem.assetman, "assets/ice_cream_truck_convex.obj")
|
||||
cone_convex := assets.get_convex(&g_mem.assetman, "assets/cone_convex.obj")
|
||||
left_fence_convex := assets.get_convex(&g_mem.assetman, "assets/left_fence_convex.obj")
|
||||
right_fence_convex := assets.get_convex(&g_mem.assetman, "assets/right_fence_convex.obj")
|
||||
|
||||
world.car_handle = physics.immediate_body(
|
||||
&world.physics_scene,
|
||||
@ -426,13 +430,38 @@ update_world :: proc(world: ^World, dt: f32, config: World_Update_Config) {
|
||||
},
|
||||
},
|
||||
{
|
||||
rel_x = {0, 1, 0},
|
||||
rel_q = linalg.QUATERNIONF32_IDENTITY,
|
||||
density_minus_one = 0.1 - 1,
|
||||
inner_shape = physics.Shape_Box{size = 1},
|
||||
density_minus_one = 0.2 - 1,
|
||||
inner_shape = physics.Shape_Convex {
|
||||
mesh = cone_convex.mesh,
|
||||
center_of_mass = cone_convex.center_of_mass,
|
||||
inertia_tensor = auto_cast cone_convex.inertia_tensor,
|
||||
total_volume = cone_convex.total_volume,
|
||||
},
|
||||
},
|
||||
{
|
||||
rel_q = linalg.QUATERNIONF32_IDENTITY,
|
||||
density_minus_one = 0.2 - 1,
|
||||
inner_shape = physics.Shape_Convex {
|
||||
mesh = left_fence_convex.mesh,
|
||||
center_of_mass = left_fence_convex.center_of_mass,
|
||||
inertia_tensor = auto_cast left_fence_convex.inertia_tensor,
|
||||
total_volume = left_fence_convex.total_volume,
|
||||
},
|
||||
},
|
||||
{
|
||||
rel_q = linalg.QUATERNIONF32_IDENTITY,
|
||||
density_minus_one = 0.2 - 1,
|
||||
inner_shape = physics.Shape_Convex {
|
||||
mesh = right_fence_convex.mesh,
|
||||
center_of_mass = right_fence_convex.center_of_mass,
|
||||
inertia_tensor = auto_cast right_fence_convex.inertia_tensor,
|
||||
total_volume = right_fence_convex.total_volume,
|
||||
},
|
||||
},
|
||||
},
|
||||
mass = 1000,
|
||||
com_shift = physics.Vec3{0, 0, -0.5},
|
||||
},
|
||||
)
|
||||
|
||||
@ -480,15 +509,15 @@ update_world :: proc(world: ^World, dt: f32, config: World_Update_Config) {
|
||||
|
||||
sim_state := physics.get_sim_state(&world.physics_scene)
|
||||
|
||||
wheel_extent_x_front := f32(1.355) / 2
|
||||
wheel_extent_x_back := f32(1.345) / 2
|
||||
wheel_y := f32(-0.4)
|
||||
rest := f32(0.2)
|
||||
natural_frequency := f32(1.2)
|
||||
damping := f32(0.15)
|
||||
radius := f32(0.2888)
|
||||
wheel_front_z := f32(1.35)
|
||||
wheel_back_z := f32(-1.05)
|
||||
wheel_extent_x_front := f32(2) / 2
|
||||
wheel_extent_x_back := f32(2) / 2
|
||||
wheel_y := f32(0.5)
|
||||
rest := f32(0.7)
|
||||
natural_frequency := f32(0.4)
|
||||
damping := f32(0.06)
|
||||
radius := f32(0.737649) / 2
|
||||
wheel_front_z := f32(1.6)
|
||||
wheel_back_z := f32(-1.63)
|
||||
wheel_mass := f32(14)
|
||||
|
||||
pacejka_long := physics.slice_to_pacejka94_long(
|
||||
@ -629,7 +658,7 @@ update_world :: proc(world: ^World, dt: f32, config: World_Update_Config) {
|
||||
}
|
||||
|
||||
car_body := physics.get_body(sim_state, world.car_handle)
|
||||
turn_vel_correction := clamp(10.0 / linalg.length(car_body.v), 0, 1)
|
||||
turn_vel_correction := clamp(4.0 / linalg.length(car_body.v), 0, 1)
|
||||
|
||||
turn_input := rl.GetGamepadAxisMovement(0, .LEFT_X)
|
||||
if abs(turn_input) < GAMEPAD_DEADZONE {
|
||||
@ -987,7 +1016,7 @@ draw_world :: proc(world: ^World) {
|
||||
sim_state := physics.get_sim_state(&world.physics_scene)
|
||||
|
||||
car_body := physics.get_body(sim_state, world.car_handle)
|
||||
car_model := assets.get_model(&g_mem.assetman, "assets/toyota_corolla_ae86_trueno.glb")
|
||||
car_model := assets.get_model(&g_mem.assetman, "assets/ice_cream_truck.glb")
|
||||
engine := physics.get_engine(sim_state, world.engine_handle)
|
||||
|
||||
{
|
||||
@ -1327,6 +1356,8 @@ game_init :: proc() {
|
||||
init_physifs_raylib_callbacks()
|
||||
assets.assetman_init(&g_mem.assetman)
|
||||
|
||||
fluid_scene_init(&g_mem.fluid_scene)
|
||||
|
||||
editor_state_init(&g_mem.es, 100)
|
||||
runtime_world_init(&g_mem.runtime_world, DEV_BUILD ? 100 : 2)
|
||||
|
||||
@ -1348,6 +1379,7 @@ game_shutdown :: proc() {
|
||||
editor_state_destroy(&g_mem.es)
|
||||
delete(g_mem.es.point_selection)
|
||||
runtime_world_destroy(&g_mem.runtime_world)
|
||||
fluid_scene_destroy(&g_mem.fluid_scene)
|
||||
|
||||
free(g_mem)
|
||||
}
|
||||
@ -1377,7 +1409,7 @@ game_hot_reloaded :: proc(mem: rawptr) {
|
||||
render.init(&g_mem.assetman)
|
||||
ui.rl_init()
|
||||
|
||||
g_mem.runtime_world.orbit_camera.distance = 4
|
||||
g_mem.runtime_world.orbit_camera.distance = 6
|
||||
log.debugf("hot reloaded")
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,11 @@ draw_debug_scene :: proc(scene: ^Scene) {
|
||||
|
||||
pos := body.x
|
||||
rot := body.q
|
||||
pos += lg.quaternion_mul_vector3(rot, wheel.rel_pos)
|
||||
pos += lg.quaternion_mul_vector3(rot, wheel.rel_pos + body.shape_offset)
|
||||
|
||||
wheel_world_pos := body_local_to_world(body, wheel.rel_pos + body.shape_offset)
|
||||
dir := body_local_to_world_vec(body, wheel.rel_dir)
|
||||
rl.DrawLine3D(wheel_world_pos, wheel_world_pos + dir, rl.BLUE)
|
||||
|
||||
rel_wheel_pos := wheel_get_rel_wheel_pos(body, wheel)
|
||||
wheel_pos := body_local_to_world(body, rel_wheel_pos)
|
||||
|
@ -127,7 +127,7 @@ wheel_get_rel_wheel_pos :: #force_inline proc(
|
||||
wheel: Suspension_Constraint_Ptr,
|
||||
) -> Vec3 {
|
||||
t := wheel.hit_t > 0 ? wheel.hit_t : wheel.rest
|
||||
return wheel.rel_pos + wheel.rel_dir * (t - wheel.radius)
|
||||
return wheel.rel_pos + body.shape_offset + wheel.rel_dir * (t - wheel.radius)
|
||||
}
|
||||
|
||||
wheel_get_right_vec :: #force_inline proc(
|
||||
|
@ -529,6 +529,8 @@ Body_Config :: struct {
|
||||
inertia_mode: Body_Config_Inertia_Mode,
|
||||
// Unit inertia tensor
|
||||
inertia_tensor: Matrix3,
|
||||
// Allows shifting the autocalculated center of mass
|
||||
com_shift: Vec3,
|
||||
}
|
||||
|
||||
// TODO: rename to wheel
|
||||
@ -664,7 +666,7 @@ initialize_body_from_config :: proc(sim_state: ^Sim_State, body: ^Body, config:
|
||||
body.w = config.initial_ang_vel
|
||||
|
||||
body.shape = add_shape(sim_state, config.shapes)
|
||||
body.shape_offset = -combined_center_of_mass(config.shapes)
|
||||
body.shape_offset = -combined_center_of_mass(config.shapes) + config.com_shift
|
||||
body.shape_aabb = input_shape_get_aabb(config.shapes)
|
||||
body.name = config.name
|
||||
|
||||
@ -675,7 +677,7 @@ update_body_from_config :: proc(sim_state: ^Sim_State, body: Body_Ptr, config: B
|
||||
// Inefficient, but eh
|
||||
remove_shape(sim_state, body.shape)
|
||||
body.shape = add_shape(sim_state, config.shapes)
|
||||
body.shape_offset = -combined_center_of_mass(config.shapes)
|
||||
body.shape_offset = -combined_center_of_mass(config.shapes) + config.com_shift
|
||||
body.shape_aabb = input_shape_get_aabb(config.shapes)
|
||||
body.name = config.name
|
||||
|
||||
|
@ -1158,7 +1158,7 @@ pgs_solve_suspension :: proc(
|
||||
body := get_body(sim_state, v.body)
|
||||
|
||||
if body.alive {
|
||||
wheel_world_pos := body_local_to_world(body, v.rel_pos)
|
||||
wheel_world_pos := body_local_to_world(body, v.rel_pos + body.shape_offset)
|
||||
dir := body_local_to_world_vec(body, v.rel_dir)
|
||||
v.hit_t, v.hit_normal, v.hit = raycast(
|
||||
sim_state,
|
||||
@ -1442,8 +1442,11 @@ pgs_substep :: proc(
|
||||
|
||||
if s.hit {
|
||||
body := get_body(sim_state, s.body)
|
||||
p := body_local_to_world(body, s.rel_pos)
|
||||
hit_p := body_local_to_world(body, s.rel_pos + s.rel_dir * s.hit_t)
|
||||
p := body_local_to_world(body, s.rel_pos + body.shape_offset)
|
||||
hit_p := body_local_to_world(
|
||||
body,
|
||||
s.rel_pos + body.shape_offset + s.rel_dir * s.hit_t,
|
||||
)
|
||||
forward := wheel_get_forward_vec(body, s)
|
||||
right := wheel_get_right_vec(body, s)
|
||||
|
||||
|
BIN
src_assets/ice_cream_truck.blend
(Stored with Git LFS)
Normal file
BIN
src_assets/ice_cream_truck.blend
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
src_assets/ice_cream_truck.blend1
(Stored with Git LFS)
Normal file
BIN
src_assets/ice_cream_truck.blend1
(Stored with Git LFS)
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user